diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/reloc.h | 37 | ||||
-rw-r--r-- | arch/i386/reloc.h | 41 | ||||
-rw-r--r-- | arch/microblaze/reloc.h | 26 | ||||
-rw-r--r-- | arch/mips/reloc.h | 32 | ||||
-rw-r--r-- | arch/powerpc/reloc.h | 36 | ||||
-rw-r--r-- | arch/sh/reloc.h | 38 | ||||
-rw-r--r-- | arch/x32/reloc.h | 47 | ||||
-rw-r--r-- | arch/x86_64/reloc.h | 41 |
8 files changed, 98 insertions, 200 deletions
diff --git a/arch/arm/reloc.h b/arch/arm/reloc.h index 27c606d4..ee39b7fd 100644 --- a/arch/arm/reloc.h +++ b/arch/arm/reloc.h @@ -16,42 +16,29 @@ #define LDSO_ARCH "arm" ENDIAN_SUFFIX FP_SUFFIX -#define IS_COPY(x) ((x)==R_ARM_COPY) -#define IS_PLT(x) ((x)==R_ARM_JUMP_SLOT) +#define NO_LEGACY_INITFINI + +#define TPOFF_K 8 -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +static int remap_rel(int type) { switch(type) { case R_ARM_ABS32: - *reloc_addr += sym_val; - break; + return REL_SYMBOLIC; case R_ARM_GLOB_DAT: + return REL_GOT; case R_ARM_JUMP_SLOT: - *reloc_addr = sym_val; - break; + return REL_PLT; case R_ARM_RELATIVE: - *reloc_addr += (size_t)base_addr; - break; + return REL_RELATIVE; case R_ARM_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_ARM_TLS_DTPMOD32: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_ARM_TLS_DTPOFF32: - *reloc_addr += def.sym->st_value; - break; + return REL_DTPOFF; case R_ARM_TLS_TPOFF32: - *reloc_addr += def.sym - ? def.sym->st_value + def.dso->tls_offset + 8 - : self->tls_offset + 8; - break; + return REL_TPOFF; } return 0; } - -#define NO_LEGACY_INITFINI diff --git a/arch/i386/reloc.h b/arch/i386/reloc.h index bc86e96e..12224b79 100644 --- a/arch/i386/reloc.h +++ b/arch/i386/reloc.h @@ -3,48 +3,29 @@ #define LDSO_ARCH "i386" -#define IS_COPY(x) ((x)==R_386_COPY) -#define IS_PLT(x) ((x)==R_386_JMP_SLOT) - -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +static int remap_rel(int type) { switch(type) { case R_386_32: - *reloc_addr += sym_val; - break; + return REL_SYMBOLIC; case R_386_PC32: - *reloc_addr += sym_val - (size_t)reloc_addr; - break; + return REL_OFFSET; case R_386_GLOB_DAT: + return REL_GOT; case R_386_JMP_SLOT: - *reloc_addr = sym_val; - break; + return REL_PLT; case R_386_RELATIVE: - *reloc_addr += (size_t)base_addr; - break; + return REL_RELATIVE; case R_386_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_386_TLS_DTPMOD32: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_386_TLS_DTPOFF32: - *reloc_addr = def.sym->st_value; - break; + return REL_DTPOFF; case R_386_TLS_TPOFF: - *reloc_addr += def.sym - ? def.sym->st_value - def.dso->tls_offset - : 0 - self->tls_offset; - break; + return REL_TPOFF; case R_386_TLS_TPOFF32: - *reloc_addr += def.sym - ? def.dso->tls_offset - def.sym->st_value - : self->tls_offset; - break; + return REL_TPOFF_NEG; } return 0; } diff --git a/arch/microblaze/reloc.h b/arch/microblaze/reloc.h index f2f6c3a0..71a6219c 100644 --- a/arch/microblaze/reloc.h +++ b/arch/microblaze/reloc.h @@ -10,33 +10,25 @@ #define LDSO_ARCH "microblaze" ENDIAN_SUFFIX -#define IS_COPY(x) ((x)==R_MICROBLAZE_COPY) -#define IS_PLT(x) ((x)==R_MICROBLAZE_JUMP_SLOT) +#define TPOFF_K 0 -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +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: - *reloc_addr = sym_val + addend; - break; + return REL_PLT; case R_MICROBLAZE_REL: - *reloc_addr = (size_t)base_addr + addend; - break; + return REL_RELATIVE; case R_MICROBLAZE_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_MICROBLAZE_TLSDTPMOD32: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_MICROBLAZE_TLSDTPREL32: - *reloc_addr = def.sym->st_value + addend; - break; + return REL_DTPOFF; } return 0; } diff --git a/arch/mips/reloc.h b/arch/mips/reloc.h index 08d139da..91fa0977 100644 --- a/arch/mips/reloc.h +++ b/arch/mips/reloc.h @@ -16,37 +16,23 @@ #define LDSO_ARCH "mips" ENDIAN_SUFFIX FP_SUFFIX -#define IS_COPY(x) ((x)==R_MIPS_COPY) -#define IS_PLT(x) 1 +#define TPOFF_K (-0x7000) -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +static int remap_rel(int type) { switch(type) { - case R_MIPS_JUMP_SLOT: - *reloc_addr = sym_val; - break; case R_MIPS_REL32: - if (sym_val) *reloc_addr += sym_val; - else *reloc_addr += (size_t)base_addr; - break; + return REL_SYM_OR_REL; + case R_MIPS_JUMP_SLOT: + return REL_PLT; case R_MIPS_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_MIPS_TLS_DTPMOD32: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_MIPS_TLS_DTPREL32: - *reloc_addr += def.sym->st_value; - break; + return REL_DTPOFF; case R_MIPS_TLS_TPREL32: - *reloc_addr += def.sym - ? def.sym->st_value + def.dso->tls_offset - 0x7000 - : self->tls_offset - 0x7000; - break; + return REL_TPOFF; } return 0; } diff --git a/arch/powerpc/reloc.h b/arch/powerpc/reloc.h index 1563450d..73c583b7 100644 --- a/arch/powerpc/reloc.h +++ b/arch/powerpc/reloc.h @@ -3,39 +3,27 @@ #define LDSO_ARCH "powerpc" -#define IS_COPY(x) ((x)==R_PPC_COPY) -#define IS_PLT(x) ((x)==R_PPC_JMP_SLOT) +#define TPOFF_K (-0x7000) -// see linux' arch/powerpc/include/asm/elf.h -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +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: - case R_PPC_ADDR32: - *reloc_addr = sym_val + addend; - break; - case R_PPC_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_PLT; case R_PPC_RELATIVE: - *reloc_addr = (size_t)base_addr + addend; - break; + return REL_RELATIVE; + case R_PPC_COPY: + return REL_COPY; case R_PPC_DTPMOD32: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_PPC_DTPREL32: - *reloc_addr = def.sym->st_value + addend; - break; + return REL_DTPOFF; case R_PPC_TPREL32: - *reloc_addr = (def.sym - ? def.sym->st_value + def.dso->tls_offset - : self->tls_offset) - 0x7000 + addend; - break; + return REL_TPOFF; } return 0; } diff --git a/arch/sh/reloc.h b/arch/sh/reloc.h index 9090ee3b..aeb02d05 100644 --- a/arch/sh/reloc.h +++ b/arch/sh/reloc.h @@ -6,41 +6,29 @@ #define LDSO_ARCH "sh" ENDIAN_SUFFIX -#define IS_COPY(x) ((x) == R_SH_COPY) -#define IS_PLT(x) ((x) == R_SH_JMP_SLOT) +#define TPOFF_K 8 -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +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: - case R_SH_DIR32: - *reloc_addr = sym_val + addend; - break; + return REL_PLT; case R_SH_RELATIVE: - *reloc_addr = (size_t)base_addr + addend; - break; - case R_SH_REL32: - *reloc_addr = sym_val + addend - (size_t)reloc_addr; - break; + return REL_RELATIVE; case R_SH_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_SH_TLS_DTPMOD32: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_SH_TLS_DTPOFF32: - *reloc_addr = def.sym->st_value + addend; - break; + return REL_DTPOFF; case R_SH_TLS_TPOFF32: - *reloc_addr = (def.sym - ? def.sym->st_value + def.dso->tls_offset - : self->tls_offset) + 8 + addend; - break; + return REL_TPOFF; } return 0; } diff --git a/arch/x32/reloc.h b/arch/x32/reloc.h index 1261fb5d..fcfbf99e 100644 --- a/arch/x32/reloc.h +++ b/arch/x32/reloc.h @@ -4,44 +4,37 @@ #define LDSO_ARCH "x32" -#define IS_COPY(x) ((x)==R_X86_64_COPY) -#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT) +/* FIXME: x32 is very strange in its use of 64-bit relocation types in + * a 32-bit environment. As long as the memory at reloc_addr is + * zero-filled prior to relocations, just treating 64-bit relocations + * as operating on 32-bit slots should be fine, but this should be + * checked. In particular, R_X86_64_64, R_X86_64_DTPOFF64, and + * R_X86_64_TPOFF64 may need checking. */ -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +static int remap_rel(int type) { switch(type) { - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: case R_X86_64_64: - *reloc_addr = sym_val + addend; - break; case R_X86_64_32: - *(uint32_t *)reloc_addr = sym_val + addend; - break; + return REL_SYMBOLIC; case R_X86_64_PC32: - *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr; - break; + 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: - *reloc_addr = (size_t)base_addr + addend; - break; + return REL_RELATIVE; case R_X86_64_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_X86_64_DTPMOD64: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_X86_64_DTPOFF64: - *reloc_addr = def.sym->st_value + addend; - break; + case R_X86_64_DTPOFF32: + return REL_DTPOFF; case R_X86_64_TPOFF64: - *reloc_addr = (def.sym - ? def.sym->st_value - def.dso->tls_offset - : 0 - self->tls_offset) + addend; - break; + case R_X86_64_TPOFF32: + return REL_TPOFF; } return 0; } diff --git a/arch/x86_64/reloc.h b/arch/x86_64/reloc.h index 30f65614..ffab5566 100644 --- a/arch/x86_64/reloc.h +++ b/arch/x86_64/reloc.h @@ -4,44 +4,27 @@ #define LDSO_ARCH "x86_64" -#define IS_COPY(x) ((x)==R_X86_64_COPY) -#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT) - -static inline int do_single_reloc( - struct dso *self, unsigned char *base_addr, - size_t *reloc_addr, int type, size_t addend, - Sym *sym, size_t sym_size, - struct symdef def, size_t sym_val) +static int remap_rel(int type) { switch(type) { - case R_X86_64_GLOB_DAT: - case R_X86_64_JUMP_SLOT: case R_X86_64_64: - *reloc_addr = sym_val + addend; - break; - case R_X86_64_32: - *(uint32_t *)reloc_addr = sym_val + addend; - break; + return REL_SYMBOLIC; case R_X86_64_PC32: - *reloc_addr = sym_val + addend - (size_t)reloc_addr + (size_t)base_addr; - break; + 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: - *reloc_addr = (size_t)base_addr + addend; - break; + return REL_RELATIVE; case R_X86_64_COPY: - memcpy(reloc_addr, (void *)sym_val, sym_size); - break; + return REL_COPY; case R_X86_64_DTPMOD64: - *reloc_addr = def.dso ? def.dso->tls_id : self->tls_id; - break; + return REL_DTPMOD; case R_X86_64_DTPOFF64: - *reloc_addr = def.sym->st_value + addend; - break; + return REL_DTPOFF; case R_X86_64_TPOFF64: - *reloc_addr = (def.sym - ? def.sym->st_value - def.dso->tls_offset - : 0 - self->tls_offset) + addend; - break; + return REL_TPOFF; } return 0; } |