summaryrefslogtreecommitdiff
path: root/src/ldso
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldso')
-rw-r--r--src/ldso/dlstart.c11
-rw-r--r--src/ldso/dynlink.c8
2 files changed, 8 insertions, 11 deletions
diff --git a/src/ldso/dlstart.c b/src/ldso/dlstart.c
index 5f84465c..3aaa200f 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 93595a0f..3842aeba 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