Use shared globals to init __progname + environ
Initialize the __progname and environ global variables using
libc_shared_globals rather than KernelArgumentBlock.
Also: suppose the linker is invoked on an executable:
linker prog [args...]
The first argument passed to main() and constructor functions is "prog"
rather than "linker". For consistency, this CL changes the BSD
__progname global from "linker" to "prog".
Bug: none
Test: bionic unit tests
Change-Id: I376d76953c9436706dbc53911ef6585c1acc1c31
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index f78a11a..4702e1c 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -91,11 +91,11 @@
__pthread_internal_add(main_thread);
}
-void __libc_init_common(KernelArgumentBlock& args) {
+void __libc_init_common() {
// Initialize various globals.
- environ = args.envp;
+ environ = __libc_shared_globals()->init_environ;
errno = 0;
- __progname = args.argv[0] ? args.argv[0] : "<unknown>";
+ __progname = __libc_shared_globals()->init_progname ?: "<unknown>";
#if !defined(__LP64__)
__check_max_thread_id();
@@ -294,7 +294,7 @@
#endif
}
-void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
+void __libc_init_AT_SECURE(char** env) {
// Check that the kernel provided a value for AT_SECURE.
errno = 0;
unsigned long is_AT_SECURE = getauxval(AT_SECURE);
@@ -305,11 +305,11 @@
// https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
__nullify_closed_stdio();
- __sanitize_environment_variables(args.envp);
+ __sanitize_environment_variables(env);
}
// Now the environment has been sanitized, make it available.
- environ = args.envp;
+ environ = __libc_shared_globals()->init_environ = env;
__initialize_personality();
}
diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h
index 6ce4d10..84b59ca 100644
--- a/libc/bionic/libc_init_common.h
+++ b/libc/bionic/libc_init_common.h
@@ -54,8 +54,8 @@
__LIBC_HIDDEN__ void __libc_init_globals(KernelArgumentBlock& args);
-__LIBC_HIDDEN__ void __libc_init_common(KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_common();
-__LIBC_HIDDEN__ void __libc_init_AT_SECURE(KernelArgumentBlock& args);
+__LIBC_HIDDEN__ void __libc_init_AT_SECURE(char** envp);
#endif
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 24f40ba..25d462f 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -85,7 +85,7 @@
#endif
__libc_init_globals(args);
- __libc_init_common(args);
+ __libc_init_common();
// Hooks for various libraries to let them know that we're starting up.
__libc_globals.mutate(__libc_init_malloc);
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index f2168b8..51fbe07 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -96,14 +96,15 @@
BIONIC_STOP_UNWIND;
KernelArgumentBlock args(raw_args);
+ __libc_shared_globals()->init_progname = args.argv[0];
// Initializing the globals requires TLS to be available for errno.
__libc_init_main_thread(args);
__libc_init_globals(args);
- __libc_init_AT_SECURE(args);
- __libc_init_common(args);
+ __libc_init_AT_SECURE(args.envp);
+ __libc_init_common();
apply_gnu_relro();
diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h
index e9eaee0..906d569 100644
--- a/libc/private/bionic_globals.h
+++ b/libc/private/bionic_globals.h
@@ -58,6 +58,10 @@
pthread_mutex_t abort_msg_lock;
abort_msg_t* abort_msg;
+
+ // Values passed from the linker to libc.so.
+ const char* init_progname;
+ char** init_environ;
};
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();