diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h index 53661d62ffa62bd223acc9acd206827c7ac3b7c5..8621d2dddc88d7d701824321906c38b91fd94470 100644 --- a/src/internal/dynlink.h +++ b/src/internal/dynlink.h @@ -51,7 +51,7 @@ enum { #define AUX_CNT 32 #define DYN_CNT 32 -typedef void (*stage2_func)(unsigned char *); +typedef void (*stage2_func)(unsigned char *, size_t *); typedef _Noreturn void (*stage3_func)(size_t *); #endif diff --git a/src/ldso/dlstart.c b/src/ldso/dlstart.c index 5f84465c6182d549fec5350aba79d2edef72a91b..3aaa200fbbb5c55df7e1e5179ab1471df99c0d5e 100644 --- a/src/ldso/dlstart.c +++ b/src/ldso/dlstart.c @@ -84,16 +84,7 @@ void _dlstart_c(size_t *sp, size_t *dynv) && s[3]=='l' && s[4]=='s' && s[5]=='2' && !s[6]) break; } - ((stage2_func)(base + syms[i].st_value))(base); - - /* Call dynamic linker stage-3, __dls3 */ - for (i=0; ;i++) { - const char *s = strings + syms[i].st_name; - if (s[0]=='_' && s[1]=='_' && s[2]=='d' - && s[3]=='l' && s[4]=='s' && s[5]=='3' && !s[6]) - break; - } - ((stage3_func)(base + syms[i].st_value))(sp); + ((stage2_func)(base + syms[i].st_value))(base, sp); } #endif diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 93595a0f62e58c2a7df7ddcdfa377800f0a50266..3842aeba1e7b494bed9c624fecad3c5bd74ed284 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -1116,7 +1116,7 @@ static void update_tls_size() * linker itself, but some of the relocations performed may need to be * replaced later due to copy relocations in the main program. */ -void __dls2(unsigned char *base) +void __dls2(unsigned char *base, size_t *sp) { Ehdr *ehdr = (void *)base; ldso.base = base; @@ -1134,6 +1134,12 @@ void __dls2(unsigned char *base) ldso.relocated = 0; ldso.rel_update_got = 1; + + /* Call dynamic linker stage-3, __dls3, looking it up + * symbolically as a barrier against moving the address + * load across the above relocation processing. */ + struct symdef dls3_def = find_sym(&ldso, "__dls3", 0); + ((stage3_func)(ldso.base+dls3_def.sym->st_value))(sp); } /* Stage 3 of the dynamic linker is called with the dynamic linker/libc