aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Prichard <rprichard@google.com>2018-11-22 02:41:36 -0800
committerRyan Prichard <rprichard@google.com>2018-11-28 14:26:14 -0800
commit48b1159bb82b12bdd75be9228bd43db45168bdba (patch)
tree876b546289ca58c6bb0a923c325aedeef7fd5cf8
parent7752bcb234a9960d2e9e89766d143b7ac0c5f332 (diff)
downloadandroid_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.cpp12
-rw-r--r--libc/bionic/libc_init_common.h4
-rw-r--r--libc/bionic/libc_init_dynamic.cpp2
-rw-r--r--libc/bionic/libc_init_static.cpp5
-rw-r--r--libc/private/bionic_globals.h4
-rw-r--r--linker/linker_main.cpp3
-rw-r--r--tests/dl_test.cpp2
-rw-r--r--tests/libs/exec_linker_helper.cpp4
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;
}