Expose libc_shared_globals to libc.so with symbol
Previously, the address of the global variable was communicated from the dynamic linker to libc.so using a field of KernelArgumentBlock, which is communicated using the TLS_SLOT_BIONIC_PREINIT slot. As long as this function isn't called during relocations (i.e. while executing an ifunc), it always return a non-NULL value. If it's called before its PLT entry is relocated, I expect a crash. I removed the __libc_init_shared_globals function. It's currently empty, and I don't think there's one point in libc's initialization where shared globals should be initialized. Bug: http://b/25751302 Test: bionic unit tests Change-Id: I614d25e7ef5e0d2ccc40d5c821dee10f1ec61c2e
This commit is contained in:
parent
12ed389ca5
commit
abf736a780
11 changed files with 35 additions and 55 deletions
|
@ -132,17 +132,13 @@ void __libc_init_fdsan() {
|
|||
nullptr);
|
||||
}
|
||||
|
||||
static FdTable* GetFdTable() {
|
||||
if (!__libc_shared_globals) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &__libc_shared_globals->fd_table;
|
||||
static FdTable& GetFdTable() {
|
||||
return __libc_shared_globals()->fd_table;
|
||||
}
|
||||
|
||||
// Exposed to the platform to allow crash_dump to print out the fd table.
|
||||
extern "C" void* android_fdsan_get_fd_table() {
|
||||
return GetFdTable();
|
||||
return &GetFdTable();
|
||||
}
|
||||
|
||||
static FdEntry* GetFdEntry(int fd) {
|
||||
|
@ -150,21 +146,13 @@ static FdEntry* GetFdEntry(int fd) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto* fd_table = GetFdTable();
|
||||
if (!fd_table) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return fd_table->at(fd);
|
||||
return GetFdTable().at(fd);
|
||||
}
|
||||
|
||||
__printflike(1, 0) static void fdsan_error(const char* fmt, ...) {
|
||||
auto* fd_table = GetFdTable();
|
||||
if (!fd_table) {
|
||||
return;
|
||||
}
|
||||
auto& fd_table = GetFdTable();
|
||||
|
||||
auto error_level = atomic_load(&fd_table->error_level);
|
||||
auto error_level = atomic_load(&fd_table.error_level);
|
||||
if (error_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
|
||||
return;
|
||||
}
|
||||
|
@ -198,7 +186,7 @@ __printflike(1, 0) static void fdsan_error(const char* fmt, ...) {
|
|||
|
||||
switch (error_level) {
|
||||
case ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE:
|
||||
atomic_compare_exchange_strong(&fd_table->error_level, &error_level,
|
||||
atomic_compare_exchange_strong(&fd_table.error_level, &error_level,
|
||||
ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
|
||||
__BIONIC_FALLTHROUGH;
|
||||
case ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS:
|
||||
|
@ -360,21 +348,11 @@ void android_fdsan_exchange_owner_tag(int fd, uint64_t expected_tag, uint64_t ne
|
|||
}
|
||||
|
||||
android_fdsan_error_level android_fdsan_get_error_level() {
|
||||
auto* fd_table = GetFdTable();
|
||||
if (!fd_table) {
|
||||
async_safe_fatal("attempted to get fdsan error level before libc initialization?");
|
||||
}
|
||||
|
||||
return fd_table->error_level;
|
||||
return GetFdTable().error_level;
|
||||
}
|
||||
|
||||
android_fdsan_error_level android_fdsan_set_error_level(android_fdsan_error_level new_level) {
|
||||
auto* fd_table = GetFdTable();
|
||||
if (!fd_table) {
|
||||
async_safe_fatal("attempted to get fdsan error level before libc initialization?");
|
||||
}
|
||||
|
||||
return atomic_exchange(&fd_table->error_level, new_level);
|
||||
return atomic_exchange(&GetFdTable().error_level, new_level);
|
||||
}
|
||||
|
||||
int close(int fd) {
|
||||
|
|
|
@ -56,7 +56,6 @@ extern "C" abort_msg_t** __abort_message_ptr;
|
|||
extern "C" int __system_properties_init(void);
|
||||
|
||||
__LIBC_HIDDEN__ WriteProtected<libc_globals> __libc_globals;
|
||||
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals;
|
||||
|
||||
// Not public, but well-known in the BSDs.
|
||||
const char* __progname;
|
||||
|
@ -72,9 +71,6 @@ void __libc_init_globals(KernelArgumentBlock& args) {
|
|||
});
|
||||
}
|
||||
|
||||
void __libc_init_shared_globals(libc_shared_globals*) {
|
||||
}
|
||||
|
||||
#if !defined(__LP64__)
|
||||
static void __check_max_thread_id() {
|
||||
if (gettid() > 65535) {
|
||||
|
|
|
@ -84,7 +84,6 @@ static void __libc_preinit_impl(KernelArgumentBlock& args) {
|
|||
__libc_init_sysinfo(args);
|
||||
#endif
|
||||
|
||||
__libc_shared_globals = args.shared_globals;
|
||||
__libc_init_globals(args);
|
||||
__libc_init_common(args);
|
||||
|
||||
|
@ -138,7 +137,13 @@ __noreturn void __libc_init(void* raw_args,
|
|||
__cxa_atexit(__libc_fini,structors->fini_array,nullptr);
|
||||
}
|
||||
|
||||
exit(slingshot(args.argc - __libc_shared_globals->initial_linker_arg_count,
|
||||
args.argv + __libc_shared_globals->initial_linker_arg_count,
|
||||
exit(slingshot(args.argc - __libc_shared_globals()->initial_linker_arg_count,
|
||||
args.argv + __libc_shared_globals()->initial_linker_arg_count,
|
||||
args.envp));
|
||||
}
|
||||
|
||||
extern "C" libc_shared_globals* __loader_shared_globals();
|
||||
|
||||
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
|
||||
return __loader_shared_globals();
|
||||
}
|
||||
|
|
|
@ -100,10 +100,6 @@ __noreturn static void __real_libc_init(void *raw_args,
|
|||
// Initializing the globals requires TLS to be available for errno.
|
||||
__libc_init_main_thread(args);
|
||||
|
||||
static libc_shared_globals shared_globals;
|
||||
__libc_shared_globals = &shared_globals;
|
||||
__libc_init_shared_globals(&shared_globals);
|
||||
|
||||
__libc_init_globals(args);
|
||||
|
||||
__libc_init_AT_SECURE(args);
|
||||
|
@ -155,3 +151,8 @@ extern "C" int android_get_application_target_sdk_version() {
|
|||
extern "C" void android_set_application_target_sdk_version(int target) {
|
||||
g_target_sdk_version = target;
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals() {
|
||||
static libc_shared_globals globals;
|
||||
return &globals;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "private/bionic_macros.h"
|
||||
|
||||
struct abort_msg_t;
|
||||
struct libc_shared_globals;
|
||||
|
||||
// When the kernel starts the dynamic linker, it passes a pointer to a block
|
||||
// of memory containing argc, the argv array, the environment variable array,
|
||||
|
@ -67,7 +66,6 @@ class KernelArgumentBlock {
|
|||
|
||||
// Other data that we want to pass from the dynamic linker to libc.so.
|
||||
abort_msg_t** abort_message_ptr;
|
||||
libc_shared_globals* shared_globals;
|
||||
|
||||
private:
|
||||
BIONIC_DISALLOW_COPY_AND_ASSIGN(KernelArgumentBlock);
|
||||
|
|
|
@ -54,8 +54,7 @@ struct libc_shared_globals {
|
|||
int initial_linker_arg_count;
|
||||
};
|
||||
|
||||
__LIBC_HIDDEN__ extern libc_shared_globals* __libc_shared_globals;
|
||||
__LIBC_HIDDEN__ void __libc_init_shared_globals(libc_shared_globals*);
|
||||
__LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals();
|
||||
__LIBC_HIDDEN__ void __libc_init_fdsan();
|
||||
|
||||
class KernelArgumentBlock;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <android/api-level.h>
|
||||
|
||||
#include <bionic/pthread_internal.h>
|
||||
#include "private/bionic_globals.h"
|
||||
#include "private/bionic_tls.h"
|
||||
#include "private/ScopedPthreadMutexLocker.h"
|
||||
|
||||
|
@ -86,6 +87,7 @@ void* __loader_dlvsym(void* handle,
|
|||
const void* caller_addr) __LINKER_PUBLIC__;
|
||||
void __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
|
||||
void __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__;
|
||||
libc_shared_globals* __loader_shared_globals() __LINKER_PUBLIC__;
|
||||
#if defined(__arm__)
|
||||
_Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__;
|
||||
#endif
|
||||
|
@ -299,6 +301,10 @@ void __loader_remove_thread_local_dtor(void* dso_handle) {
|
|||
decrement_dso_handle_reference_counter(dso_handle);
|
||||
}
|
||||
|
||||
libc_shared_globals* __loader_shared_globals() {
|
||||
return __libc_shared_globals();
|
||||
}
|
||||
|
||||
static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8)));
|
||||
static soinfo* __libdl_info = nullptr;
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ __strong_alias(__loader_dlsym, __internal_linker_error);
|
|||
__strong_alias(__loader_dlvsym, __internal_linker_error);
|
||||
__strong_alias(__loader_add_thread_local_dtor, __internal_linker_error);
|
||||
__strong_alias(__loader_remove_thread_local_dtor, __internal_linker_error);
|
||||
__strong_alias(__loader_shared_globals, __internal_linker_error);
|
||||
#if defined(__arm__)
|
||||
__strong_alias(__loader_dl_unwind_find_exidx, __internal_linker_error);
|
||||
#endif
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
__loader_dl_unwind_find_exidx;
|
||||
__loader_add_thread_local_dtor;
|
||||
__loader_remove_thread_local_dtor;
|
||||
__loader_shared_globals;
|
||||
rtld_db_dlactivity;
|
||||
local:
|
||||
*;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
__loader_android_get_exported_namespace;
|
||||
__loader_add_thread_local_dtor;
|
||||
__loader_remove_thread_local_dtor;
|
||||
__loader_shared_globals;
|
||||
rtld_db_dlactivity;
|
||||
local:
|
||||
*;
|
||||
|
|
|
@ -622,12 +622,6 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so)
|
|||
// couldn't make system calls on x86 at that point, but we can now...
|
||||
if (!tmp_linker_so.protect_relro()) __linker_cannot_link(args.argv[0]);
|
||||
|
||||
// Initialize the linker/libc.so shared global inside the linker.
|
||||
static libc_shared_globals shared_globals;
|
||||
__libc_shared_globals = &shared_globals;
|
||||
__libc_init_shared_globals(&shared_globals);
|
||||
args.shared_globals = __libc_shared_globals;
|
||||
|
||||
// Initialize the linker's static libc's globals
|
||||
__libc_init_globals(args);
|
||||
|
||||
|
@ -655,12 +649,12 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so)
|
|||
exit(0);
|
||||
}
|
||||
exe_to_load = args.argv[1];
|
||||
__libc_shared_globals->initial_linker_arg_count = 1;
|
||||
__libc_shared_globals()->initial_linker_arg_count = 1;
|
||||
}
|
||||
|
||||
// store argc/argv/envp to use them for calling constructors
|
||||
g_argc = args.argc - __libc_shared_globals->initial_linker_arg_count;
|
||||
g_argv = args.argv + __libc_shared_globals->initial_linker_arg_count;
|
||||
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;
|
||||
|
||||
// Initialize static variables. Note that in order to
|
||||
|
|
Loading…
Reference in a new issue