about summary refs log tree commit diff
path: root/src/ldso/dlstart.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldso/dlstart.c')
-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