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 | |
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')
-rw-r--r-- | arch/aarch64/crt_arch.h | 13 | ||||
-rw-r--r-- | arch/aarch64/reloc.h | 38 | ||||
-rw-r--r-- | arch/arm/crt_arch.h | 25 | ||||
-rw-r--r-- | arch/arm/reloc.h | 36 | ||||
-rw-r--r-- | arch/i386/crt_arch.h | 29 | ||||
-rw-r--r-- | arch/i386/reloc.h | 45 | ||||
-rw-r--r-- | arch/microblaze/crt_arch.h | 27 | ||||
-rw-r--r-- | arch/microblaze/reloc.h | 47 | ||||
-rw-r--r-- | arch/mips/crt_arch.h | 49 | ||||
-rw-r--r-- | arch/mips/reloc.h | 78 | ||||
-rw-r--r-- | arch/or1k/crt_arch.h | 28 | ||||
-rw-r--r-- | arch/or1k/reloc.h | 54 | ||||
-rw-r--r-- | arch/powerpc/crt_arch.h | 31 | ||||
-rw-r--r-- | arch/powerpc/reloc.h | 51 | ||||
-rw-r--r-- | arch/sh/crt_arch.h | 28 | ||||
-rw-r--r-- | arch/sh/reloc.h | 36 | ||||
-rw-r--r-- | arch/sh/src/__fpscr_values.c | 2 | ||||
-rw-r--r-- | arch/x32/crt_arch.h | 21 | ||||
-rw-r--r-- | arch/x32/reloc.h | 48 | ||||
-rw-r--r-- | arch/x86_64/crt_arch.h | 21 | ||||
-rw-r--r-- | arch/x86_64/reloc.h | 43 |
21 files changed, 285 insertions, 465 deletions
diff --git a/arch/aarch64/crt_arch.h b/arch/aarch64/crt_arch.h index 32066881..3a4b321e 100644 --- a/arch/aarch64/crt_arch.h +++ b/arch/aarch64/crt_arch.h @@ -1,9 +1,14 @@ __asm__( -".global _start\n" -".type _start,%function\n" -"_start:\n" +".global " START "\n" +".type " START ",%function\n" +START ":\n" " mov x29, #0\n" " mov x30, #0\n" " mov x0, sp\n" +".weak _DYNAMIC\n" +".hidden _DYNAMIC\n" +" adrp x1, _DYNAMIC\n" +" add x1, x1, #:lo12:_DYNAMIC\n" " and sp, x0, #-16\n" -" b __cstart\n"); +" b " START "_c\n" +); diff --git a/arch/aarch64/reloc.h b/arch/aarch64/reloc.h index e95ae9a8..1b0402bc 100644 --- a/arch/aarch64/reloc.h +++ b/arch/aarch64/reloc.h @@ -1,5 +1,3 @@ -#include <string.h> -#include <elf.h> #include <endian.h> #if __BYTE_ORDER == __BIG_ENDIAN @@ -14,27 +12,15 @@ #define TPOFF_K 16 -static int remap_rel(int type) -{ - switch(type) { - case R_AARCH64_ABS64: - return REL_SYMBOLIC; - case R_AARCH64_GLOB_DAT: - return REL_GOT; - case R_AARCH64_JUMP_SLOT: - return REL_PLT; - case R_AARCH64_RELATIVE: - return REL_RELATIVE; - case R_AARCH64_COPY: - return REL_COPY; - case R_AARCH64_TLS_DTPMOD64: - return REL_DTPMOD; - case R_AARCH64_TLS_DTPREL64: - return REL_DTPOFF; - case R_AARCH64_TLS_TPREL64: - return REL_TPOFF; - case R_AARCH64_TLSDESC: - return REL_TLSDESC; - } - return 0; -} +#define REL_SYMBOLIC R_AARCH64_ABS64 +#define REL_GOT R_AARCH64_GLOB_DAT +#define REL_PLT R_AARCH64_JUMP_SLOT +#define REL_RELATIVE R_AARCH64_RELATIVE +#define REL_COPY R_AARCH64_COPY +#define REL_DTPMOD R_AARCH64_TLS_DTPMOD64 +#define REL_DTPOFF R_AARCH64_TLS_DTPREL64 +#define REL_TPOFF R_AARCH64_TLS_TPREL64 +#define REL_TLSDESC R_AARCH64_TLSDESC + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/arm/crt_arch.h b/arch/arm/crt_arch.h index bed99c27..d1f9a662 100644 --- a/arch/arm/crt_arch.h +++ b/arch/arm/crt_arch.h @@ -1,10 +1,15 @@ -__asm__("\ -.global _start \n\ -.type _start,%function \n\ -_start: \n\ - mov fp, #0 \n\ - mov lr, #0 \n\ - mov a1, sp \n\ - and sp, sp, #-16 \n\ - bl __cstart \n\ -"); +__asm__( +".global " START " \n" +".type " START ",%function \n" +START ": \n" +" mov fp, #0 \n" +" mov lr, #0 \n" +" mov a1, sp \n" +" ldr a2, 1f \n" +"2: add a2, pc, a2 \n" +" and sp, sp, #-16 \n" +" bl " START "_c \n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +"1: .word _DYNAMIC-2b-8 \n" +); diff --git a/arch/arm/reloc.h b/arch/arm/reloc.h index ee39b7fd..dec0031e 100644 --- a/arch/arm/reloc.h +++ b/arch/arm/reloc.h @@ -1,5 +1,3 @@ -#include <string.h> -#include <elf.h> #include <endian.h> #if __BYTE_ORDER == __BIG_ENDIAN @@ -20,25 +18,15 @@ #define TPOFF_K 8 -static int remap_rel(int type) -{ - switch(type) { - case R_ARM_ABS32: - return REL_SYMBOLIC; - case R_ARM_GLOB_DAT: - return REL_GOT; - case R_ARM_JUMP_SLOT: - return REL_PLT; - case R_ARM_RELATIVE: - return REL_RELATIVE; - case R_ARM_COPY: - return REL_COPY; - case R_ARM_TLS_DTPMOD32: - return REL_DTPMOD; - case R_ARM_TLS_DTPOFF32: - return REL_DTPOFF; - case R_ARM_TLS_TPOFF32: - return REL_TPOFF; - } - return 0; -} +#define REL_SYMBOLIC R_ARM_ABS32 +#define REL_GOT R_ARM_GLOB_DAT +#define REL_PLT R_ARM_JUMP_SLOT +#define REL_RELATIVE R_ARM_RELATIVE +#define REL_COPY R_ARM_COPY +#define REL_DTPMOD R_ARM_TLS_DTPMOD32 +#define REL_DTPOFF R_ARM_TLS_DTPOFF32 +#define REL_TPOFF R_ARM_TLS_TPOFF32 +//#define REL_TLSDESC R_ARM_TLS_DESC + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "mov sp,%1 ; tst %0,#1 ; moveq pc,%0 ; bx %0" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/i386/crt_arch.h b/arch/i386/crt_arch.h index ae694f99..43c8477a 100644 --- a/arch/i386/crt_arch.h +++ b/arch/i386/crt_arch.h @@ -1,13 +1,16 @@ -__asm__("\ -.text \n\ -.global _start \n\ -_start: \n\ - xor %ebp,%ebp \n\ - mov %esp,%eax \n\ - and $-16,%esp \n\ - push %eax \n\ - push %eax \n\ - push %eax \n\ - push %eax \n\ - call __cstart \n\ -"); +__asm__( +".text\n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +".global " START "\n" +START ":\n" +" xor %ebp,%ebp \n" +" mov %esp,%eax \n" +" and $-16,%esp \n" +" push %eax \n" +" push %eax \n" +" call 1f \n" +"1: addl $_DYNAMIC-1b,(%esp) \n" +" push %eax \n" +" call " START "_c \n" +); diff --git a/arch/i386/reloc.h b/arch/i386/reloc.h index eaf5aae0..b52ef402 100644 --- a/arch/i386/reloc.h +++ b/arch/i386/reloc.h @@ -1,33 +1,16 @@ -#include <string.h> -#include <elf.h> - #define LDSO_ARCH "i386" -static int remap_rel(int type) -{ - switch(type) { - case R_386_32: - return REL_SYMBOLIC; - case R_386_PC32: - return REL_OFFSET; - case R_386_GLOB_DAT: - return REL_GOT; - case R_386_JMP_SLOT: - return REL_PLT; - case R_386_RELATIVE: - return REL_RELATIVE; - case R_386_COPY: - return REL_COPY; - case R_386_TLS_DTPMOD32: - return REL_DTPMOD; - case R_386_TLS_DTPOFF32: - return REL_DTPOFF; - case R_386_TLS_TPOFF: - return REL_TPOFF; - case R_386_TLS_TPOFF32: - return REL_TPOFF_NEG; - case R_386_TLS_DESC: - return REL_TLSDESC; - } - return 0; -} +#define REL_SYMBOLIC R_386_32 +#define REL_OFFSET R_386_PC32 +#define REL_GOT R_386_GLOB_DAT +#define REL_PLT R_386_JMP_SLOT +#define REL_RELATIVE R_386_RELATIVE +#define REL_COPY R_386_COPY +#define REL_DTPMOD R_386_TLS_DTPMOD32 +#define REL_DTPOFF R_386_TLS_DTPOFF32 +#define REL_TPOFF R_386_TLS_TPOFF +#define REL_TPOFF_NEG R_386_TLS_TPOFF32 +#define REL_TLSDESC R_386_TLS_DESC + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "mov %1,%%esp ; jmp *%0" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/microblaze/crt_arch.h b/arch/microblaze/crt_arch.h index 8917c695..ada98c86 100644 --- a/arch/microblaze/crt_arch.h +++ b/arch/microblaze/crt_arch.h @@ -1,11 +1,16 @@ -__asm__("\ -.global _start \n\ -.align 2 \n\ -_start: \n\ - add r19, r0, r0 \n\ - ori r5, r1, 0 \n\ - andi r1, r1, -8 \n\ - addik r1, r1, -8 \n\ - bri __cstart \n\ - nop \n\ -"); +__asm__( +".global " START " \n" +".align 2 \n" +START ": \n" +" add r19, r0, r0 \n" +" ori r5, r1, 0 \n" +"1: mfs r6, rpc \n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +" addik r6, r6, _GLOBAL_OFFSET_TABLE_+8 \n" +" addik r6, r6, _DYNAMIC@GOTOFF \n" +" andi r1, r1, -8 \n" +" addik r1, r1, -8 \n" +" bri " START "_c \n" +" nop \n" +); diff --git a/arch/microblaze/reloc.h b/arch/microblaze/reloc.h index 71a6219c..611db465 100644 --- a/arch/microblaze/reloc.h +++ b/arch/microblaze/reloc.h @@ -1,5 +1,3 @@ -#include <string.h> -#include <elf.h> #include <endian.h> #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -12,40 +10,13 @@ #define TPOFF_K 0 -static int remap_rel(int type) -{ - switch(type) { - case R_MICROBLAZE_32: - return REL_SYMBOLIC; - case R_MICROBLAZE_GLOB_DAT: - return REL_GOT; - case R_MICROBLAZE_JUMP_SLOT: - return REL_PLT; - case R_MICROBLAZE_REL: - return REL_RELATIVE; - case R_MICROBLAZE_COPY: - return REL_COPY; - case R_MICROBLAZE_TLSDTPMOD32: - return REL_DTPMOD; - case R_MICROBLAZE_TLSDTPREL32: - return REL_DTPOFF; - } - return 0; -} +#define REL_SYMBOLIC R_MICROBLAZE_32 +#define REL_GOT R_MICROBLAZE_GLOB_DAT +#define REL_PLT R_MICROBLAZE_JUMP_SLOT +#define REL_RELATIVE R_MICROBLAZE_REL +#define REL_COPY R_MICROBLAZE_COPY +#define REL_DTPMOD R_MICROBLAZE_TLSDTPMOD32 +#define REL_DTPOFF R_MICROBLAZE_TLSDTPREL32 -#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_MICROBLAZE_REL) - *(size_t *)(base+a[0]) = (size_t)base + a[2]; -} +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "addik r1,%1,0 ; bra %0" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/mips/crt_arch.h b/arch/mips/crt_arch.h index d4ae52d1..33bde4e6 100644 --- a/arch/mips/crt_arch.h +++ b/arch/mips/crt_arch.h @@ -1,21 +1,28 @@ -__asm__("\n\ -.set push\n\ -.set noreorder\n\ -.global __start\n\ -.global _start\n\ -.type __start, @function\n\ -.type _start, @function\n\ -__start:\n\ -_start:\n\ - bal 1f \n\ - move $fp, $0 \n\ -2: .gpword 2b \n\ -1: lw $gp, 0($ra) \n\ - subu $gp, $ra, $gp \n\ - move $4, $sp \n\ - subu $sp, $sp, 16 \n\ - and $sp, $sp, -8 \n\ - lw $25, %call16(__cstart)($gp) \n\ - jalr $25 \n\ - nop \n\ -.set pop"); +__asm__( +".set push\n" +".set noreorder\n" +".global _" START "\n" +".global " START "\n" +".type _" START ", @function\n" +".type " START ", @function\n" +"_" START ":\n" +"" START ":\n" +" bal 1f \n" +" move $fp, $0 \n" +"2: .gpword 2b \n" + .gpword " START "_c \n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +" .gpword _DYNAMIC \n" +"1: lw $gp, 0($ra) \n" +" subu $gp, $ra, $gp \n" +" move $4, $sp \n" +" lw $5, 8($ra) \n" +" addu $5, $5, $gp \n" +" lw $25, 4($ra) \n" +" addu $25, $25, $gp \n" +" subu $sp, $sp, 16 \n" +" jalr $25 \n" +" and $sp, $sp, -8 \n" +".set pop \n" +); diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h index 4b81d328..8aa02852 100644 --- a/arch/mips/reloc.h +++ b/arch/mips/reloc.h @@ -1,5 +1,3 @@ -#include <string.h> -#include <elf.h> #include <endian.h> #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -18,72 +16,16 @@ #define TPOFF_K (-0x7000) -static int remap_rel(int type) -{ - switch(type) { - case R_MIPS_REL32: - return REL_SYM_OR_REL; - case R_MIPS_JUMP_SLOT: - return REL_PLT; - case R_MIPS_COPY: - return REL_COPY; - case R_MIPS_TLS_DTPMOD32: - return REL_DTPMOD; - case R_MIPS_TLS_DTPREL32: - return REL_DTPOFF; - case R_MIPS_TLS_TPREL32: - return REL_TPOFF; - } - return 0; -} +#define REL_SYM_OR_REL R_MIPS_REL32 +#define REL_PLT R_MIPS_JUMP_SLOT +#define REL_COPY R_MIPS_COPY +#define REL_DTPMOD R_MIPS_TLS_DTPMOD32 +#define REL_DTPOFF R_MIPS_TLS_DTPREL32 +#define REL_TPOFF R_MIPS_TLS_TPREL32 -void __reloc_self(int c, size_t *a, size_t *dynv, size_t *got) -{ - 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-0x70000000UL<20) t[*a&31] = a[1]; - n = t[DT_MIPS_LOCAL_GOTNO - 0x70000000]; - for (a=got; n; a++, n--) *a += (size_t)base; -} - -static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride); - -static void do_arch_relocs(struct dso *this, struct dso *head) -{ - unsigned char *base = this->base; - size_t *dynv = this->dynv; - size_t dyn[20] = {0}; - size_t i; - size_t rel[2], got=0; - Sym *sym; - - for (i=0; dynv[i]; i+=2) { - if (dynv[i]-0x70000000UL<20) - dyn[dynv[i]&31] = dynv[i+1]; - else if (dynv[i] == DT_PLTGOT) - got = dynv[i+1]; - } - i = dyn[DT_MIPS_LOCAL_GOTNO-0x70000000]; - if (this->shortname && !strcmp(this->shortname, "libc.so")) { - got += sizeof(size_t) * i; - } else { - for (; i; i--, got+=sizeof(size_t)) - *(size_t *)(base+got) += (size_t)base; - } - sym = this->syms + dyn[DT_MIPS_GOTSYM-0x70000000]; - i = dyn[DT_MIPS_SYMTABNO-0x70000000] - dyn[DT_MIPS_GOTSYM-0x70000000]; - for (; i; i--, got+=sizeof(size_t), sym++) { - rel[0] = got; - rel[1] = sym-this->syms << 8 | R_MIPS_JUMP_SLOT; - *(size_t *)(base+got) = 0; - do_relocs(this, rel, sizeof rel, 2); - } -} - -#define NEED_ARCH_RELOCS 1 +#define NEED_MIPS_GOT_RELOCS 1 #define DYNAMIC_IS_RO 1 #define ARCH_SYM_REJECT_UND(s) (!((s)->st_other & STO_MIPS_PLT)) + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "move $sp,%1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/or1k/crt_arch.h b/arch/or1k/crt_arch.h index 0f381d2d..84415561 100644 --- a/arch/or1k/crt_arch.h +++ b/arch/or1k/crt_arch.h @@ -1,11 +1,17 @@ -__asm__("\ -.global _start \n\ -.align 4 \n\ -_start: \n\ - l.ori r3, r1, 0 \n\ - l.addi r2, r0, -8 \n\ - l.and r1, r1, r2 \n\ - l.addi r1, r1, -8 \n\ - l.jal __cstart \n\ - l.ori r2, r0, 0 \n\ -"); +__asm__( +".global " START " \n" +".align 4 \n" +START ": \n" +" l.jal 1f \n" +" l.ori r3, r1, 0 \n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +" .word _DYNAMIC-. \n" +"1: l.lwz r4, 0(r9) \n" +" l.add r4, r4, r9 \n" +" l.addi r2, r0, -8 \n" +" l.and r1, r1, r2 \n" +" l.addi r1, r1, -16 \n" +" l.jal " START "_c \n" +" l.ori r2, r0, 0 \n" +); 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" ) diff --git a/arch/powerpc/crt_arch.h b/arch/powerpc/crt_arch.h index 8cc53d98..ec3cd29e 100644 --- a/arch/powerpc/crt_arch.h +++ b/arch/powerpc/crt_arch.h @@ -1,12 +1,19 @@ -__asm__("\ -.global _start \n\ -.type _start, %function \n\ -_start: \n\ - mr 3, 1 \n\ - clrrwi 1, 1, 4 \n\ - li 0, 0 \n\ - stwu 1, -16(1) \n\ - mtlr 0 \n\ - stw 0, 0(1) \n\ - bl __cstart \n\ -"); +__asm__( +".global " START " \n" +".type " START ", %function \n" +START ": \n" +" bl 1f \n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +" .long _DYNAMIC-. \n" +"1: mflr 4 \n" +" lwz 3, 0(4) \n" +" add 4, 3, 4 \n" +" mr 3, 1 \n" +" clrrwi 1, 1, 4 \n" +" li 0, 0 \n" +" stwu 1, -16(1) \n" +" mtlr 0 \n" +" stw 0, 0(1) \n" +" bl " START "_c \n" +); diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h index 73c583b7..aa5f8c93 100644 --- a/arch/powerpc/reloc.h +++ b/arch/powerpc/reloc.h @@ -1,44 +1,15 @@ -#include <string.h> -#include <elf.h> - #define LDSO_ARCH "powerpc" #define TPOFF_K (-0x7000) -static int remap_rel(int type) -{ - switch(type) { - case R_PPC_ADDR32: - return REL_SYMBOLIC; - case R_PPC_GLOB_DAT: - return REL_GOT; - case R_PPC_JMP_SLOT: - return REL_PLT; - case R_PPC_RELATIVE: - return REL_RELATIVE; - case R_PPC_COPY: - return REL_COPY; - case R_PPC_DTPMOD32: - return REL_DTPMOD; - case R_PPC_DTPREL32: - return REL_DTPOFF; - case R_PPC_TPREL32: - return REL_TPOFF; - } - return 0; -} - -void __reloc_self(int c, size_t *a, size_t *dynv) -{ - 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_PPC_RELATIVE) - *(size_t *)(base+a[0]) = (size_t)base + a[2]; -} +#define REL_SYMBOLIC R_PPC_ADDR32 +#define REL_GOT R_PPC_GLOB_DAT +#define REL_PLT R_PPC_JMP_SLOT +#define REL_RELATIVE R_PPC_RELATIVE +#define REL_COPY R_PPC_COPY +#define REL_DTPMOD R_PPC_DTPMOD32 +#define REL_DTPOFF R_PPC_DTPREL32 +#define REL_TPOFF R_PPC_TPREL32 + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "mr 1,%1 ; mtlr %0 ; blr" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/sh/crt_arch.h b/arch/sh/crt_arch.h index 5fd39fc6..a873ffdb 100644 --- a/arch/sh/crt_arch.h +++ b/arch/sh/crt_arch.h @@ -1,12 +1,22 @@ -__asm__("\ -.global _start \n\ -_start: \n\ - mov r15, r4 \n\ - mov #-16, r0 \n\ - and r0, r15 \n\ - bsr __cstart \n\ - nop \n\ -"); +__asm__( +".global " START " \n" +START ": \n" +" mova 1f, r0 \n" +" mov.l 1f, r5 \n" +" add r0, r5 \n" +" mov r15, r4 \n" +" mov #-16, r0 \n" +" and r0, r15 \n" +" bsr " START "_c \n" +" nop \n" +".align 2 \n" +".weak _DYNAMIC \n" +".hidden _DYNAMIC \n" +"1: .long _DYNAMIC-. \n" +); /* used by gcc for switching the FPU between single and double precision */ +#ifdef SHARED +__attribute__((__visibility__("hidden"))) +#endif const unsigned long __fpscr_values[2] = { 0, 0x80000 }; diff --git a/arch/sh/reloc.h b/arch/sh/reloc.h index aeb02d05..e7e4b38f 100644 --- a/arch/sh/reloc.h +++ b/arch/sh/reloc.h @@ -8,27 +8,15 @@ #define TPOFF_K 8 -static int remap_rel(int type) -{ - switch(type) { - case R_SH_DIR32: - return REL_SYMBOLIC; - case R_SH_REL32: - return REL_OFFSET; - case R_SH_GLOB_DAT: - return REL_GOT; - case R_SH_JMP_SLOT: - return REL_PLT; - case R_SH_RELATIVE: - return REL_RELATIVE; - case R_SH_COPY: - return REL_COPY; - case R_SH_TLS_DTPMOD32: - return REL_DTPMOD; - case R_SH_TLS_DTPOFF32: - return REL_DTPOFF; - case R_SH_TLS_TPOFF32: - return REL_TPOFF; - } - return 0; -} +#define REL_SYMBOLIC R_SH_DIR32 +#define REL_OFFSET R_SH_REL32 +#define REL_GOT R_SH_GLOB_DAT +#define REL_PLT R_SH_JMP_SLOT +#define REL_RELATIVE R_SH_RELATIVE +#define REL_COPY R_SH_COPY +#define REL_DTPMOD R_SH_TLS_DTPMOD32 +#define REL_DTPOFF R_SH_TLS_DTPOFF32 +#define REL_TPOFF R_SH_TLS_TPOFF32 + +#define CRTJMP(pc,sp) __asm__ __volatile__( \ + "jmp @%0 ; mov %1,r15" : : "r"(pc), "r"(sp) : "memory" ) diff --git a/arch/sh/src/__fpscr_values.c b/arch/sh/src/__fpscr_values.c index 64b458f9..374df30e 100644 --- a/arch/sh/src/__fpscr_values.c +++ b/arch/sh/src/__fpscr_values.c @@ -1,5 +1,5 @@ #include "libc.h" /* used by gcc for switching the FPU between single and double precision */ -const unsigned long __fpscr_values[2] ATTR_LIBC_VISIBILITY = { 0, 0x80000 }; +//const unsigned long __fpscr_values[2] ATTR_LIBC_VISIBILITY = { 0, 0x80000 }; diff --git a/arch/x32/crt_arch.h b/arch/x32/crt_arch.h index db692950..3eec61bd 100644 --- a/arch/x32/crt_arch.h +++ b/arch/x32/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/x32/reloc.h b/arch/x32/reloc.h index fcfbf99e..7c72d266 100644 --- a/arch/x32/reloc.h +++ b/arch/x32/reloc.h @@ -1,7 +1,3 @@ -#include <stdint.h> -#include <string.h> -#include <elf.h> - #define LDSO_ARCH "x32" /* FIXME: x32 is very strange in its use of 64-bit relocation types in @@ -11,30 +7,20 @@ * checked. In particular, R_X86_64_64, R_X86_64_DTPOFF64, and * R_X86_64_TPOFF64 may need checking. */ -static int remap_rel(int type) -{ - switch(type) { - case R_X86_64_64: - case R_X86_64_32: - return REL_SYMBOLIC; - case R_X86_64_PC32: - return REL_OFFSET; - 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: - case R_X86_64_DTPOFF32: - return REL_DTPOFF; - case R_X86_64_TPOFF64: - case R_X86_64_TPOFF32: - return REL_TPOFF; - } - return 0; -} +/* The R_X86_64_64, R_X86_64_DTPOFF32, and R_X86_64_TPOFF32 reloc types + * were previously mapped in the switch table form of this file; however, + * they do not seem to be used/usable for anything. If needed, new + * mappings will have to be added. */ + +#define REL_SYMBOLIC R_X86_64_32 +#define REL_OFFSET 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 CRTJMP(pc,sp) __asm__ __volatile__( \ + "mov %1,%%esp ; jmp *%0" : : "r"(pc), "r"(sp) : "memory" ) 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" ) |