diff options
author | Rich Felker <dalias@aerifal.cx> | 2015-06-07 20:55:23 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2015-06-07 21:23:23 +0000 |
commit | 75ce4503950621b11fcc7f1fd1187dbcf3cde312 (patch) | |
tree | 7a2f3c2d25e88d08af7c50a24dc0f4b648f6cd07 /src/ldso | |
parent | 32f3c4f70633488550c29a2444f819aafdf345ff (diff) | |
download | musl-75ce4503950621b11fcc7f1fd1187dbcf3cde312.tar.gz musl-75ce4503950621b11fcc7f1fd1187dbcf3cde312.tar.bz2 musl-75ce4503950621b11fcc7f1fd1187dbcf3cde312.tar.xz musl-75ce4503950621b11fcc7f1fd1187dbcf3cde312.zip |
fix regression in pre-v7 arm on kernels with kuser helper removed
the arm atomics/TLS runtime selection code is called from
__set_thread_area and depends on having libc.auxv and __hwcap
available. commit 71f099cb7db821c51d8f39dfac622c61e54d794c moved the
first call to __set_thread_area to the top of dynamic linking stage 3,
before this data is made available, causing the runtime detection code
to always see __hwcap as zero and thereby select the atomics/TLS
implementations based on kuser helper.
upcoming work on superh will use similar runtime detection.
ideally this early-init code should be cleanly refactored and shared
between the dynamic linker and static-linked startup.
Diffstat (limited to 'src/ldso')
-rw-r--r-- | src/ldso/dynlink.c | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 42b056d2..71252d03 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -1192,6 +1192,17 @@ _Noreturn void __dls3(size_t *sp) char **argv_orig = argv; char **envp = argv+argc+1; + /* Find aux vector just past environ[] and use it to initialize + * global data that may be needed before we can make syscalls. */ + __environ = envp; + for (i=argc+1; argv[i]; i++); + libc.auxv = auxv = (void *)(argv+i+1); + decode_vec(auxv, aux, AUX_CNT); + __hwcap = aux[AT_HWCAP]; + libc.page_size = aux[AT_PAGESZ]; + libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] + || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]); + /* Setup early thread pointer in builtin_tls for ldso/libc itself to * use during dynamic linking. If possible it will also serve as the * thread pointer at runtime. */ @@ -1200,25 +1211,11 @@ _Noreturn void __dls3(size_t *sp) a_crash(); } - /* Find aux vector just past environ[] */ - for (i=argc+1; argv[i]; i++) - if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16)) - env_path = argv[i]+16; - else if (!memcmp(argv[i], "LD_PRELOAD=", 11)) - env_preload = argv[i]+11; - auxv = (void *)(argv+i+1); - - decode_vec(auxv, aux, AUX_CNT); - /* Only trust user/env if kernel says we're not suid/sgid */ - if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] - || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) { - env_path = 0; - env_preload = 0; - libc.secure = 1; + if (!libc.secure) { + env_path = getenv("LD_LIBRARY_PATH"); + env_preload = getenv("LD_PRELOAD"); } - libc.page_size = aux[AT_PAGESZ]; - libc.auxv = auxv; /* If the main program was already loaded by the kernel, * AT_PHDR will point to some location other than the dynamic |