summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ldso/dlstart.c22
1 files changed, 8 insertions, 14 deletions
diff --git a/src/ldso/dlstart.c b/src/ldso/dlstart.c
index eb919ab4..a968baab 100644
--- a/src/ldso/dlstart.c
+++ b/src/ldso/dlstart.c
@@ -9,6 +9,14 @@
#include "crt_arch.h"
+#ifndef GETFUNCSYM
+#define GETFUNCSYM(fp, sym, got) do { \
+ __attribute__((__visibility__("hidden"))) void sym(); \
+ static void (*static_func_ptr)() = sym; \
+ __asm__ __volatile__ ( "" : "+m"(static_func_ptr) : : "memory"); \
+ *(fp) = static_func_ptr; } while(0)
+#endif
+
__attribute__((__visibility__("hidden")))
void _dlstart_c(size_t *sp, size_t *dynv)
{
@@ -74,23 +82,9 @@ void _dlstart_c(size_t *sp, size_t *dynv)
*rel_addr = (size_t)base + rel[2];
}
-#ifndef GETFUNCSYM
- const char *strings = (void *)(base + dyn[DT_STRTAB]);
- const Sym *syms = (void *)(base + dyn[DT_SYMTAB]);
-
- /* Call dynamic linker stage-2, __dls2 */
- 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]=='2' && !s[6])
- break;
- }
- ((stage2_func)(base + syms[i].st_value))(base, sp);
-#else
stage2_func dls2;
GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);
dls2(base, sp);
-#endif
}
#endif