]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/nolibc: pass argc, argv and envp to constructors
authorThomas Weißschuh <linux@weissschuh.net>
Sun, 28 Jul 2024 20:34:11 +0000 (22:34 +0200)
committerThomas Weißschuh <linux@weissschuh.net>
Fri, 9 Aug 2024 05:40:18 +0000 (07:40 +0200)
Since 2005 glibc has passed argc, argv, and envp to all constructors.
As it is cheap and easy to do so, mirror that behaviour in nolibc.
This makes it easier to migrate applications to nolibc.

Link: https://lore.kernel.org/r/20240728-nolibc-constructor-args-v1-1-36d0bf5cd4c0@weissschuh.net
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
tools/include/nolibc/crt.h
tools/testing/selftests/nolibc/nolibc-test.c

index 43b551468c2a85ecdf6f830d0ed9d9b390326917..ac291574f6c0f2ca2617a4baf906f7acb47b3763 100644 (file)
@@ -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);
 }
index 093d0512f4c57aa338808516b8b760470f968550..0800b10fc3f761ff70612d35244cc4aeeb01ede1 100644 (file)
@@ -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)