diff options
author | Ryan Prichard <rprichard@google.com> | 2018-11-22 02:41:36 -0800 |
---|---|---|
committer | Ryan Prichard <rprichard@google.com> | 2018-11-28 14:26:14 -0800 |
commit | 48b1159bb82b12bdd75be9228bd43db45168bdba (patch) | |
tree | 876b546289ca58c6bb0a923c325aedeef7fd5cf8 | |
parent | 7752bcb234a9960d2e9e89766d143b7ac0c5f332 (diff) | |
download | android_bionic-48b1159bb82b12bdd75be9228bd43db45168bdba.tar.gz android_bionic-48b1159bb82b12bdd75be9228bd43db45168bdba.tar.bz2 android_bionic-48b1159bb82b12bdd75be9228bd43db45168bdba.zip |
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
-rw-r--r-- | libc/bionic/libc_init_common.cpp | 12 | ||||
-rw-r--r-- | libc/bionic/libc_init_common.h | 4 | ||||
-rw-r--r-- | libc/bionic/libc_init_dynamic.cpp | 2 | ||||
-rw-r--r-- | libc/bionic/libc_init_static.cpp | 5 | ||||
-rw-r--r-- | libc/private/bionic_globals.h | 4 | ||||
-rw-r--r-- | linker/linker_main.cpp | 3 | ||||
-rw-r--r-- | tests/dl_test.cpp | 2 | ||||
-rw-r--r-- | tests/libs/exec_linker_helper.cpp | 4 |
8 files changed, 23 insertions, 13 deletions
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index f78a11ab6..4702e1c9a 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -91,11 +91,11 @@ void __libc_add_main_thread() { __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 @@ static void __initialize_personality() { #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 @@ void __libc_init_AT_SECURE(KernelArgumentBlock& args) { // 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 6ce4d10ef..84b59ca2d 100644 --- a/libc/bionic/libc_init_common.h +++ b/libc/bionic/libc_init_common.h @@ -54,8 +54,8 @@ class KernelArgumentBlock; __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 24f40bab0..25d462f8c 100644 --- a/libc/bionic/libc_init_dynamic.cpp +++ b/libc/bionic/libc_init_dynamic.cpp @@ -85,7 +85,7 @@ static void __libc_preinit_impl(KernelArgumentBlock& args) { #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 f2168b89e..51fbe07bf 100644 --- a/libc/bionic/libc_init_static.cpp +++ b/libc/bionic/libc_init_static.cpp @@ -96,14 +96,15 @@ __noreturn static void __real_libc_init(void *raw_args, 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 e9eaee096..906d569d9 100644 --- a/libc/private/bionic_globals.h +++ b/libc/private/bionic_globals.h @@ -58,6 +58,10 @@ struct libc_shared_globals { 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(); diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index 442ecd909..7edfd54ea 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -290,7 +290,7 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load #endif // Sanitize the environment. - __libc_init_AT_SECURE(args); + __libc_init_AT_SECURE(args.envp); // Initialize system properties __system_properties_init(); // may use 'environ' @@ -655,6 +655,7 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so) g_argc = args.argc - __libc_shared_globals()->initial_linker_arg_count; g_argv = args.argv + __libc_shared_globals()->initial_linker_arg_count; g_envp = args.envp; + __libc_shared_globals()->init_progname = g_argv[0]; // Initialize static variables. Note that in order to // get correct libdl_info we need to call constructors diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp index 18ba011b0..57d04e94a 100644 --- a/tests/dl_test.cpp +++ b/tests/dl_test.cpp @@ -104,6 +104,7 @@ TEST(dl, exec_linker_load_file) { std::string expected_output = "ctor: argc=1 argv[0]=" + helper + "\n" + "main: argc=1 argv[0]=" + helper + "\n" + + "__progname=" + helper + "\n" + "helper_func called\n"; ExecTestHelper eth; eth.SetArgs({ kPathToLinker, helper.c_str(), nullptr }); @@ -118,6 +119,7 @@ TEST(dl, exec_linker_load_from_zip) { std::string expected_output = "ctor: argc=1 argv[0]=" + helper + "\n" + "main: argc=1 argv[0]=" + helper + "\n" + + "__progname=" + helper + "\n" + "helper_func called\n"; ExecTestHelper eth; eth.SetArgs({ kPathToLinker, helper.c_str(), nullptr }); diff --git a/tests/libs/exec_linker_helper.cpp b/tests/libs/exec_linker_helper.cpp index 01a61e091..56b1eafe0 100644 --- a/tests/libs/exec_linker_helper.cpp +++ b/tests/libs/exec_linker_helper.cpp @@ -28,7 +28,8 @@ #include <stdio.h> -extern "C" void _start(); +extern "C" const char* __progname; + const char* helper_func(); __attribute__((constructor)) @@ -38,6 +39,7 @@ static void ctor(int argc, char* argv[]) { int main(int argc, char* argv[]) { printf("main: argc=%d argv[0]=%s\n", argc, argv[0]); + printf("__progname=%s\n", __progname); printf("%s\n", helper_func()); return 0; } |