[PATCH] tools/nolibc: pass argc, argv and envp to constructors

From: Thomas Weißschuh
Date: Sun Jul 28 2024 - 16:34:30 EST


Mirror glibc behavior for compatibility.

Signed-off-by: Thomas Weißschuh <linux@xxxxxxxxxxxxxx>
---
tools/include/nolibc/crt.h | 23 ++++++++++++-----------
tools/testing/selftests/nolibc/nolibc-test.c | 5 +++--
2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index 43b551468c2a..ac291574f6c0 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -13,11 +13,11 @@ const unsigned long *_auxv __attribute__((weak));
static void __stack_chk_init(void);
static void exit(int);

-extern void (*const __preinit_array_start[])(void) __attribute__((weak));
-extern void (*const __preinit_array_end[])(void) __attribute__((weak));
+extern void (*const __preinit_array_start[])(int, char **, char**) __attribute__((weak));
+extern void (*const __preinit_array_end[])(int, char **, char**) __attribute__((weak));

-extern void (*const __init_array_start[])(void) __attribute__((weak));
-extern void (*const __init_array_end[])(void) __attribute__((weak));
+extern void (*const __init_array_start[])(int, char **, char**) __attribute__((weak));
+extern void (*const __init_array_end[])(int, char **, char**) __attribute__((weak));

extern void (*const __fini_array_start[])(void) __attribute__((weak));
extern void (*const __fini_array_end[])(void) __attribute__((weak));
@@ -29,7 +29,8 @@ void _start_c(long *sp)
char **argv;
char **envp;
int exitcode;
- void (* const *func)(void);
+ void (* const *ctor_func)(int, char **, char **);
+ void (* const *dtor_func)(void);
const unsigned long *auxv;
/* silence potential warning: conflicting types for 'main' */
int _nolibc_main(int, char **, char **) __asm__ ("main");
@@ -66,16 +67,16 @@ void _start_c(long *sp)
;
_auxv = auxv;

- for (func = __preinit_array_start; func < __preinit_array_end; func++)
- (*func)();
- for (func = __init_array_start; func < __init_array_end; func++)
- (*func)();
+ for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++)
+ (*ctor_func)(argc, argv, envp);
+ for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++)
+ (*ctor_func)(argc, argv, envp);

/* go to application */
exitcode = _nolibc_main(argc, argv, envp);

- for (func = __fini_array_end; func > __fini_array_start;)
- (*--func)();
+ for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;)
+ (*--dtor_func)();

exit(exitcode);
}
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 093d0512f4c5..0800b10fc3f7 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -686,9 +686,10 @@ static void constructor1(void)
}

__attribute__((constructor))
-static void constructor2(void)
+static void constructor2(int argc, char **argv, char **envp)
{
- constructor_test_value *= 2;
+ if (argc && argv && envp)
+ constructor_test_value *= 2;
}

int run_startup(int min, int max)

---
base-commit: 0db287736bc586fcd5a2925518ef09eec6924803
change-id: 20240728-nolibc-constructor-args-68bf56ff7438

Best regards,
--
Thomas Weißschuh <linux@xxxxxxxxxxxxxx>