about summary refs log tree commit diff
path: root/arch/x86_64
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2015-04-13 02:56:26 -0400
committerRich Felker <dalias@aerifal.cx>2015-04-13 03:04:42 -0400
commitf3ddd173806fd5c60b3f034528ca24542aecc5b9 (patch)
tree63cc7432a3c40f011c4818de32ef6257acbf0e73 /arch/x86_64
parent385c01112c083eb383d972da45836d497cc0556d (diff)
downloadmusl-f3ddd173806fd5c60b3f034528ca24542aecc5b9.tar.gz
musl-f3ddd173806fd5c60b3f034528ca24542aecc5b9.tar.xz
musl-f3ddd173806fd5c60b3f034528ca24542aecc5b9.zip
dynamic linker bootstrap overhaul
this overhaul further reduces the amount of arch-specific code needed
by the dynamic linker and removes a number of assumptions, including:

- that symbolic function references inside libc are bound at link time
  via the linker option -Bsymbolic-functions.

- that libc functions used by the dynamic linker do not require
  access to data symbols.

- that static/internal function calls and data accesses can be made
  without performing any relocations, or that arch-specific startup
  code handled any such relocations needed.

removing these assumptions paves the way for allowing libc.so itself
to be built with stack protector (among other things), and is achieved
by a three-stage bootstrap process:

1. relative relocations are processed with a flat function.
2. symbolic relocations are processed with no external calls/data.
3. main program and dependency libs are processed with a
   fully-functional libc/ldso.

reduction in arch-specific code is achived through the following:

- crt_arch.h, used for generating crt1.o, now provides the entry point
  for the dynamic linker too.

- asm is no longer responsible for skipping the beginning of argv[]
  when ldso is invoked as a command.

- the functionality previously provided by __reloc_self for heavily
  GOT-dependent RISC archs is now the arch-agnostic stage-1.

- arch-specific relocation type codes are mapped directly as macros
  rather than via an inline translation function/switch statement.
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/crt_arch.h21
-rw-r--r--arch/x86_64/reloc.h43
2 files changed, 25 insertions, 39 deletions
diff --git a/arch/x86_64/crt_arch.h b/arch/x86_64/crt_arch.h
index db692950..3eec61bd 100644
--- a/arch/x86_64/crt_arch.h
+++ b/arch/x86_64/crt_arch.h
@@ -1,9 +1,12 @@
-__asm__("\
-.text \n\
-.global _start \n\
-_start: \n\
-	xor %rbp,%rbp \n\
-	mov %rsp,%rdi \n\
-	andq $-16,%rsp \n\
-	call __cstart \n\
-");
+__asm__(
+".text \n"
+".global " START " \n"
+START ": \n"
+"	xor %rbp,%rbp \n"
+"	mov %rsp,%rdi \n"
+".weak _DYNAMIC \n"
+".hidden _DYNAMIC \n"
+"	lea _DYNAMIC(%rip),%rsi \n"
+"	andq $-16,%rsp \n"
+"	call " START "_c \n"
+);
diff --git a/arch/x86_64/reloc.h b/arch/x86_64/reloc.h
index 9bc58496..84c075c3 100644
--- a/arch/x86_64/reloc.h
+++ b/arch/x86_64/reloc.h
@@ -1,32 +1,15 @@
-#include <stdint.h>
-#include <string.h>
-#include <elf.h>
-
 #define LDSO_ARCH "x86_64"
 
-static int remap_rel(int type)
-{
-	switch(type) {
-	case R_X86_64_64:
-		return REL_SYMBOLIC;
-	case R_X86_64_PC32:
-		return REL_OFFSET32;
-	case R_X86_64_GLOB_DAT:
-		return REL_GOT;
-	case R_X86_64_JUMP_SLOT:
-		return REL_PLT;
-	case R_X86_64_RELATIVE:
-		return REL_RELATIVE;
-	case R_X86_64_COPY:
-		return REL_COPY;
-	case R_X86_64_DTPMOD64:
-		return REL_DTPMOD;
-	case R_X86_64_DTPOFF64:
-		return REL_DTPOFF;
-	case R_X86_64_TPOFF64:
-		return REL_TPOFF;
-	case R_X86_64_TLSDESC:
-		return REL_TLSDESC;
-	}
-	return 0;
-}
+#define REL_SYMBOLIC    R_X86_64_64
+#define REL_OFFSET32    R_X86_64_PC32
+#define REL_GOT         R_X86_64_GLOB_DAT
+#define REL_PLT         R_X86_64_JUMP_SLOT
+#define REL_RELATIVE    R_X86_64_RELATIVE
+#define REL_COPY        R_X86_64_COPY
+#define REL_DTPMOD      R_X86_64_DTPMOD64
+#define REL_DTPOFF      R_X86_64_DTPOFF64
+#define REL_TPOFF       R_X86_64_TPOFF64
+#define REL_TLSDESC     R_X86_64_TLSDESC
+
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+	"mov %1,%%rsp ; jmp *%0" : : "r"(pc), "r"(sp) : "memory" )