mirror of git://git.musl-libc.org/musl
fix crashing ldso on archs where __set_thread_area examines auxv
commit 1c84c99913
moved the call to
__init_tp above the initialization of libc.auxv, inadvertently
breaking archs where __set_thread_area examines auxv for the sake of
determining the TLS/atomic model needed at runtime. this broke armv6
and sh2.
This commit is contained in:
parent
b529ec9b52
commit
b82cd6c78d
|
@ -107,7 +107,7 @@ struct symdef {
|
||||||
struct dso *dso;
|
struct dso *dso;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*stage3_func)(size_t *);
|
typedef void (*stage3_func)(size_t *, size_t *);
|
||||||
|
|
||||||
static struct builtin_tls {
|
static struct builtin_tls {
|
||||||
char c;
|
char c;
|
||||||
|
@ -1596,13 +1596,14 @@ static void install_new_tls(void)
|
||||||
|
|
||||||
hidden void __dls2(unsigned char *base, size_t *sp)
|
hidden void __dls2(unsigned char *base, size_t *sp)
|
||||||
{
|
{
|
||||||
|
size_t *auxv;
|
||||||
|
for (auxv=sp+1+*sp+1; *auxv; auxv++);
|
||||||
|
auxv++;
|
||||||
if (DL_FDPIC) {
|
if (DL_FDPIC) {
|
||||||
void *p1 = (void *)sp[-2];
|
void *p1 = (void *)sp[-2];
|
||||||
void *p2 = (void *)sp[-1];
|
void *p2 = (void *)sp[-1];
|
||||||
if (!p1) {
|
if (!p1) {
|
||||||
size_t *auxv, aux[AUX_CNT];
|
size_t aux[AUX_CNT];
|
||||||
for (auxv=sp+1+*sp+1; *auxv; auxv++);
|
|
||||||
auxv++;
|
|
||||||
decode_vec(auxv, aux, AUX_CNT);
|
decode_vec(auxv, aux, AUX_CNT);
|
||||||
if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
|
if (aux[AT_BASE]) ldso.base = (void *)aux[AT_BASE];
|
||||||
else ldso.base = (void *)(aux[AT_PHDR] & -4096);
|
else ldso.base = (void *)(aux[AT_PHDR] & -4096);
|
||||||
|
@ -1648,8 +1649,8 @@ hidden void __dls2(unsigned char *base, size_t *sp)
|
||||||
* symbolically as a barrier against moving the address
|
* symbolically as a barrier against moving the address
|
||||||
* load across the above relocation processing. */
|
* load across the above relocation processing. */
|
||||||
struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0);
|
struct symdef dls2b_def = find_sym(&ldso, "__dls2b", 0);
|
||||||
if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp);
|
if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls2b_def.sym-ldso.syms])(sp, auxv);
|
||||||
else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp);
|
else ((stage3_func)laddr(&ldso, dls2b_def.sym->st_value))(sp, auxv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stage 2b sets up a valid thread pointer, which requires relocations
|
/* Stage 2b sets up a valid thread pointer, which requires relocations
|
||||||
|
@ -1658,11 +1659,12 @@ hidden void __dls2(unsigned char *base, size_t *sp)
|
||||||
* so that loads of the thread pointer and &errno can be pure/const and
|
* so that loads of the thread pointer and &errno can be pure/const and
|
||||||
* thereby hoistable. */
|
* thereby hoistable. */
|
||||||
|
|
||||||
void __dls2b(size_t *sp)
|
void __dls2b(size_t *sp, size_t *auxv)
|
||||||
{
|
{
|
||||||
/* Setup early thread pointer in builtin_tls for ldso/libc itself to
|
/* Setup early thread pointer in builtin_tls for ldso/libc itself to
|
||||||
* use during dynamic linking. If possible it will also serve as the
|
* use during dynamic linking. If possible it will also serve as the
|
||||||
* thread pointer at runtime. */
|
* thread pointer at runtime. */
|
||||||
|
libc.auxv = auxv;
|
||||||
libc.tls_size = sizeof builtin_tls;
|
libc.tls_size = sizeof builtin_tls;
|
||||||
libc.tls_align = tls_align;
|
libc.tls_align = tls_align;
|
||||||
if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
|
if (__init_tp(__copy_tls((void *)builtin_tls)) < 0) {
|
||||||
|
@ -1670,8 +1672,8 @@ void __dls2b(size_t *sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
|
struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
|
||||||
if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp);
|
if (DL_FDPIC) ((stage3_func)&ldso.funcdescs[dls3_def.sym-ldso.syms])(sp, auxv);
|
||||||
else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp);
|
else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp, auxv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
|
/* Stage 3 of the dynamic linker is called with the dynamic linker/libc
|
||||||
|
@ -1679,10 +1681,10 @@ void __dls2b(size_t *sp)
|
||||||
* process dependencies and relocations for the main application and
|
* process dependencies and relocations for the main application and
|
||||||
* transfer control to its entry point. */
|
* transfer control to its entry point. */
|
||||||
|
|
||||||
void __dls3(size_t *sp)
|
void __dls3(size_t *sp, size_t *auxv)
|
||||||
{
|
{
|
||||||
static struct dso app, vdso;
|
static struct dso app, vdso;
|
||||||
size_t aux[AUX_CNT], *auxv;
|
size_t aux[AUX_CNT];
|
||||||
size_t i;
|
size_t i;
|
||||||
char *env_preload=0;
|
char *env_preload=0;
|
||||||
char *replace_argv0=0;
|
char *replace_argv0=0;
|
||||||
|
@ -1695,8 +1697,6 @@ void __dls3(size_t *sp)
|
||||||
/* Find aux vector just past environ[] and use it to initialize
|
/* Find aux vector just past environ[] and use it to initialize
|
||||||
* global data that may be needed before we can make syscalls. */
|
* global data that may be needed before we can make syscalls. */
|
||||||
__environ = envp;
|
__environ = envp;
|
||||||
for (i=argc+1; argv[i]; i++);
|
|
||||||
libc.auxv = auxv = (void *)(argv+i+1);
|
|
||||||
decode_vec(auxv, aux, AUX_CNT);
|
decode_vec(auxv, aux, AUX_CNT);
|
||||||
__hwcap = aux[AT_HWCAP];
|
__hwcap = aux[AT_HWCAP];
|
||||||
search_vec(auxv, &__sysinfo, AT_SYSINFO);
|
search_vec(auxv, &__sysinfo, AT_SYSINFO);
|
||||||
|
|
Loading…
Reference in New Issue