diff options
Diffstat (limited to 'toolchain/uClibc/patches-0.9.30.1/440-backport_mips_nonpic.patch')
-rw-r--r-- | toolchain/uClibc/patches-0.9.30.1/440-backport_mips_nonpic.patch | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/toolchain/uClibc/patches-0.9.30.1/440-backport_mips_nonpic.patch b/toolchain/uClibc/patches-0.9.30.1/440-backport_mips_nonpic.patch deleted file mode 100644 index abcd6ec636..0000000000 --- a/toolchain/uClibc/patches-0.9.30.1/440-backport_mips_nonpic.patch +++ /dev/null @@ -1,289 +0,0 @@ ---- a/include/elf.h -+++ b/include/elf.h -@@ -1547,6 +1547,7 @@ typedef struct - #define STO_MIPS_INTERNAL 0x1 - #define STO_MIPS_HIDDEN 0x2 - #define STO_MIPS_PROTECTED 0x3 -+#define STO_MIPS_PLT 0x8 - #define STO_MIPS_SC_ALIGN_UNUSED 0xff - - /* MIPS specific values for `st_info'. */ -@@ -1692,8 +1693,11 @@ typedef struct - #define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ - #define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ - #define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ -+#define R_MIPS_GLOB_DAT 51 -+#define R_MIPS_COPY 126 -+#define R_MIPS_JUMP_SLOT 127 - /* Keep this the last entry. */ --#define R_MIPS_NUM 51 -+#define R_MIPS_NUM 128 - - /* Legal values for p_type field of Elf32_Phdr. */ - -@@ -1759,7 +1763,13 @@ typedef struct - #define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ - #define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ - #define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ --#define DT_MIPS_NUM 0x32 -+/* The address of .got.plt in an executable using the new non-PIC ABI. */ -+#define DT_MIPS_PLTGOT 0x70000032 -+/* The base of the PLT in an executable using the new non-PIC ABI if that -+ PLT is writable. For a non-writable PLT, this is omitted or has a zero -+ value. */ -+#define DT_MIPS_RWPLT 0x70000034 -+#define DT_MIPS_NUM 0x35 - - /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ - ---- a/ldso/ldso/dl-hash.c -+++ b/ldso/ldso/dl-hash.c -@@ -160,6 +160,11 @@ check_match (const ElfW(Sym) *sym, char - /* undefined symbol itself */ - return NULL; - -+#ifdef __mips__ -+ if (sym->st_shndx == SHN_UNDEF && !(sym->st_other & STO_MIPS_PLT)) -+ return NULL; -+#endif -+ - if (sym->st_value == 0) - /* No value */ - return NULL; ---- a/ldso/ldso/mips/dl-sysdep.h -+++ b/ldso/ldso/mips/dl-sysdep.h -@@ -93,10 +93,11 @@ typedef struct - - #include <link.h> - --#define ARCH_NUM 3 -+#define ARCH_NUM 4 - #define DT_MIPS_GOTSYM_IDX (DT_NUM + OS_NUM) - #define DT_MIPS_LOCAL_GOTNO_IDX (DT_NUM + OS_NUM +1) - #define DT_MIPS_SYMTABNO_IDX (DT_NUM + OS_NUM +2) -+#define DT_MIPS_PLTGOT_IDX (DT_NUM + OS_NUM +3) - - #define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \ - do { \ -@@ -106,6 +107,8 @@ else if (dpnt->d_tag == DT_MIPS_LOCAL_GO - dynamic[DT_MIPS_LOCAL_GOTNO_IDX] = dpnt->d_un.d_val; \ - else if (dpnt->d_tag == DT_MIPS_SYMTABNO) \ - dynamic[DT_MIPS_SYMTABNO_IDX] = dpnt->d_un.d_val; \ -+else if (dpnt->d_tag == DT_MIPS_PLTGOT) \ -+ dynamic[DT_MIPS_PLTGOT_IDX] = dpnt->d_un.d_val; \ - else if (dpnt->d_tag == DT_MIPS_RLD_MAP) \ - *(ElfW(Addr) *)(dpnt->d_un.d_ptr) = (ElfW(Addr)) debug_addr; \ - } while (0) -@@ -114,6 +117,7 @@ else if (dpnt->d_tag == DT_MIPS_RLD_MAP) - #define INIT_GOT(GOT_BASE,MODULE) \ - do { \ - unsigned long idx; \ -+ unsigned long *pltgot; \ - \ - /* Check if this is the dynamic linker itself */ \ - if (MODULE->libtype == program_interpreter) \ -@@ -123,6 +127,12 @@ do { \ - GOT_BASE[0] = (unsigned long) _dl_runtime_resolve; \ - GOT_BASE[1] = (unsigned long) MODULE; \ - \ -+ pltgot = MODULE->dynamic_info[DT_MIPS_PLTGOT_IDX]; \ -+ if (pltgot) { \ -+ pltgot[0] = (unsigned long) _dl_runtime_pltresolve; \ -+ pltgot[1] = (unsigned long) MODULE; \ -+ } \ -+ \ - /* Add load address displacement to all local GOT entries */ \ - idx = 2; \ - while (idx < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \ -@@ -157,9 +167,9 @@ void _dl_perform_mips_global_got_relocat - #define OFFS_ALIGN 0x7ffff000 - #endif /* O32 || N32 */ - --#define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT --/* MIPS does not have COPY relocs */ --#define DL_NO_COPY_RELOCS -+#define elf_machine_type_class(type) \ -+ ((((type) == R_MIPS_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ -+ | (((type) == R_MIPS_COPY) * ELF_RTYPE_CLASS_COPY)) - - #define OFFSET_GP_GOT 0x7ff0 - ---- a/ldso/ldso/mips/elfinterp.c -+++ b/ldso/ldso/mips/elfinterp.c -@@ -30,6 +30,7 @@ - #include "ldso.h" - - extern int _dl_runtime_resolve(void); -+extern int _dl_runtime_pltresolve(void); - - #define OFFSET_GP_GOT 0x7ff0 - -@@ -83,6 +84,61 @@ unsigned long __dl_runtime_resolve(unsig - return new_addr; - } - -+unsigned long -+__dl_runtime_pltresolve(struct elf_resolve *tpnt, int reloc_entry) -+{ -+ int reloc_type; -+ ELF_RELOC *this_reloc; -+ char *strtab; -+ Elf32_Sym *symtab; -+ int symtab_index; -+ char *rel_addr; -+ char *new_addr; -+ char **got_addr; -+ unsigned long instr_addr; -+ char *symname; -+ -+ rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; -+ this_reloc = (ELF_RELOC *)(intptr_t)(rel_addr + reloc_entry); -+ reloc_type = ELF32_R_TYPE(this_reloc->r_info); -+ symtab_index = ELF32_R_SYM(this_reloc->r_info); -+ -+ symtab = (Elf32_Sym *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB]; -+ strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; -+ symname = strtab + symtab[symtab_index].st_name; -+ -+ /* Address of the jump instruction to fix up. */ -+ instr_addr = ((unsigned long)this_reloc->r_offset + -+ (unsigned long)tpnt->loadaddr); -+ got_addr = (char **)instr_addr; -+ -+ /* Get the address of the GOT entry. */ -+ new_addr = _dl_find_hash(symname, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT); -+ if (unlikely(!new_addr)) { -+ _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); -+ _dl_exit(1); -+ } -+ -+#if defined (__SUPPORT_LD_DEBUG__) -+ if ((unsigned long)got_addr < 0x40000000) { -+ if (_dl_debug_bindings) { -+ _dl_dprintf(_dl_debug_file, "\nresolve function: %s", symname); -+ if (_dl_debug_detail) -+ _dl_dprintf(_dl_debug_file, -+ "\n\tpatched: %x ==> %x @ %x", -+ *got_addr, new_addr, got_addr); -+ } -+ } -+ if (!_dl_debug_nofixups) { -+ *got_addr = new_addr; -+ } -+#else -+ *got_addr = new_addr; -+#endif -+ -+ return (unsigned long)new_addr; -+} -+ - void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size) - { -@@ -115,6 +171,7 @@ int _dl_parse_relocation_information(str - got = (unsigned long *) tpnt->dynamic_info[DT_PLTGOT]; - - for (i = 0; i < rel_size; i++, rpnt++) { -+ char *symname = NULL; - reloc_addr = (unsigned long *) (tpnt->loadaddr + - (unsigned long) rpnt->r_offset); - reloc_type = ELF_R_TYPE(rpnt->r_info); -@@ -128,6 +185,16 @@ int _dl_parse_relocation_information(str - old_val = *reloc_addr; - #endif - -+ if (reloc_type == R_MIPS_JUMP_SLOT || reloc_type == R_MIPS_COPY) { -+ symname = strtab + symtab[symtab_index].st_name; -+ symbol_addr = (unsigned long)_dl_find_hash(symname, -+ tpnt->symbol_scope, -+ tpnt, -+ elf_machine_type_class(reloc_type)); -+ if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) -+ return 1; -+ } -+ - switch (reloc_type) { - #if _MIPS_SIM == _MIPS_SIM_ABI64 - case (R_MIPS_64 << 8) | R_MIPS_REL32: -@@ -148,6 +215,24 @@ int _dl_parse_relocation_information(str - *reloc_addr += (unsigned long) tpnt->loadaddr; - } - break; -+ case R_MIPS_JUMP_SLOT: -+ *reloc_addr = symbol_addr; -+ break; -+ case R_MIPS_COPY: -+ if (symbol_addr) { -+#if defined (__SUPPORT_LD_DEBUG__) -+ if (_dl_debug_move) -+ _dl_dprintf(_dl_debug_file, -+ "\n%s move %d bytes from %x to %x", -+ symname, symtab[symtab_index].st_size, -+ symbol_addr, reloc_addr); -+#endif -+ -+ _dl_memcpy((char *)reloc_addr, -+ (char *)symbol_addr, -+ symtab[symtab_index].st_size); -+ } -+ break; - case R_MIPS_NONE: - break; - default: ---- a/ldso/ldso/mips/resolve.S -+++ b/ldso/ldso/mips/resolve.S -@@ -112,3 +112,54 @@ _dl_runtime_resolve: - .end _dl_runtime_resolve - .previous - -+/* Assembler veneer called from the PLT header code when using the -+ non-PIC ABI. -+ -+ Code in each PLT entry puts the caller's return address into t7 ($15), -+ the PLT entry index into t8 ($24), the address of _dl_runtime_pltresolve -+ into t9 ($25) and the address of .got.plt into gp ($28). __dl_runtime_pltresolve -+ needs a0 ($4) to hold the link map and a1 ($5) to hold the index into -+ .rel.plt (== PLT entry index * 4). */ -+ -+ .text -+ .align 2 -+ .globl _dl_runtime_pltresolve -+ .type _dl_runtime_pltresolve,@function -+ .ent _dl_runtime_pltresolve -+_dl_runtime_pltresolve: -+ .frame $29, 40, $31 -+ .set noreorder -+ # Save arguments and sp value in stack. -+ subu $29, 40 -+ lw $10, 4($28) -+ # Modify t9 ($25) so as to point .cpload instruction. -+ addiu $25, 12 -+ # Compute GP. -+ .cpload $25 -+ .set reorder -+ -+ /* Store function arguments from registers to stack */ -+ sw $15, 36($29) -+ sw $4, 16($29) -+ sw $5, 20($29) -+ sw $6, 24($29) -+ sw $7, 28($29) -+ -+ /* Setup functions args and call __dl_runtime_pltresolve. */ -+ move $4, $10 -+ sll $5, $24, 3 -+ jal __dl_runtime_pltresolve -+ -+ /* Restore function arguments from stack to registers */ -+ lw $31, 36($29) -+ lw $4, 16($29) -+ lw $5, 20($29) -+ lw $6, 24($29) -+ lw $7, 28($29) -+ -+ /* Do a tail call to the original function */ -+ addiu $29, 40 -+ move $25, $2 -+ jr $25 -+ .end _dl_runtime_pltresolve -+ .previous |