diff options
author | Rich Felker <dalias@aerifal.cx> | 2015-04-13 02:56:26 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2015-04-13 03:04:42 -0400 |
commit | f3ddd173806fd5c60b3f034528ca24542aecc5b9 (patch) | |
tree | 63cc7432a3c40f011c4818de32ef6257acbf0e73 /arch/or1k/reloc.h | |
parent | 385c01112c083eb383d972da45836d497cc0556d (diff) | |
download | musl-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/or1k/reloc.h')
-rw-r--r-- | arch/or1k/reloc.h | 54 |
1 files changed, 11 insertions, 43 deletions
diff --git a/arch/or1k/reloc.h b/arch/or1k/reloc.h index 830a800a..ddee45c5 100644 --- a/arch/or1k/reloc.h +++ b/arch/or1k/reloc.h @@ -1,47 +1,15 @@ -#include <string.h> -#include <elf.h> -#include <endian.h> - #define LDSO_ARCH "or1k" #define TPOFF_K 0 -static int remap_rel(int type) -{ - switch(type) { - case R_OR1K_32: - return REL_SYMBOLIC; - case R_OR1K_GLOB_DAT: - return REL_GOT; - case R_OR1K_JMP_SLOT: - return REL_PLT; - case R_OR1K_RELATIVE: - return REL_RELATIVE; - case R_OR1K_COPY: - return REL_COPY; - case R_OR1K_TLS_DTPMOD: - return REL_DTPMOD; - case R_OR1K_TLS_DTPOFF: - return REL_DTPOFF; - case R_OR1K_TLS_TPOFF: - return REL_TPOFF; - } - return 0; -} - -#include "syscall.h" -void __reloc_self(int c, size_t *a, size_t *dynv) -{ - char dot = '.', ex = 'x'; - char *base; - size_t t[20], n; - for (a+=c+1; *a; a++); - for (a++; *a; a+=2) if (*a<20) t[*a] = a[1]; - base = (char *)t[AT_BASE]; - if (!base) base = (char *)(t[AT_PHDR] & -t[AT_PAGESZ]); - for (a=dynv; *a; a+=2) if (*a<20) t[*a] = a[1]; - n = t[DT_RELASZ]; - for (a=(void *)(base+t[DT_RELA]); n; a+=3, n-=12) - if (a[1]%256 == R_OR1K_RELATIVE) - *(size_t *)(base+a[0]) = (size_t)base + a[2]; -} +#define REL_SYMBOLIC R_OR1K_32 +#define REL_GOT R_OR1K_GLOB_DAT +#define REL_PLT R_OR1K_JMP_SLOT +#define REL_RELATIVE R_OR1K_RELATIVE +#define REL_COPY R_OR1K_COPY +#define REL_DTPMOD R_OR1K_TLS_DTPMOD +#define REL_DTPOFF R_OR1K_TLS_DTPOFF +#define REL_TPOFF R_OR1K_TLS_TPOFF + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "l.jr %0 ; l.ori r1,%1,0" : : "r"(pc), "r"(sp) : "memory" ) |