about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--arch/i386/reloc.h7
-rw-r--r--src/ldso/dlstart.c6
2 files changed, 13 insertions, 0 deletions
diff --git a/arch/i386/reloc.h b/arch/i386/reloc.h
index b52ef402..032f454b 100644
--- a/arch/i386/reloc.h
+++ b/arch/i386/reloc.h
@@ -14,3 +14,10 @@
 
 #define CRTJMP(pc,sp) __asm__ __volatile__( \
 	"mov %1,%%esp ; jmp *%0" : : "r"(pc), "r"(sp) : "memory" )
+
+#define GETFUNCSYM(fp, sym, got) __asm__ ( \
+	".hidden " #sym "\n" \
+	"	call 1f\n" \
+	"1:	addl $" #sym "-.,(%%esp)\n" \
+	"	pop %0" \
+	: "=r"(*fp) : : "memory" )
diff --git a/src/ldso/dlstart.c b/src/ldso/dlstart.c
index 3aaa200f..eb919ab4 100644
--- a/src/ldso/dlstart.c
+++ b/src/ldso/dlstart.c
@@ -74,6 +74,7 @@ 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]);
 
@@ -85,6 +86,11 @@ void _dlstart_c(size_t *sp, size_t *dynv)
 			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