summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-06-07 20:55:23 +0000
committerRich Felker <dalias@aerifal.cx>2015-06-07 21:23:23 +0000
commit75ce4503950621b11fcc7f1fd1187dbcf3cde312 (patch)
tree7a2f3c2d25e88d08af7c50a24dc0f4b648f6cd07 /src
parent32f3c4f70633488550c29a2444f819aafdf345ff (diff)
downloadmusl-75ce4503950621b11fcc7f1fd1187dbcf3cde312.tar.gz
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')
-rw-r--r--src/ldso/dynlink.c31
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