diff options
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/sh64/dl-debug.h | 79 | ||||
-rw-r--r-- | ldso/ldso/sh64/dl-startup.h | 118 | ||||
-rw-r--r-- | ldso/ldso/sh64/dl-syscalls.h | 18 | ||||
-rw-r--r-- | ldso/ldso/sh64/dl-sysdep.h | 168 | ||||
-rw-r--r-- | ldso/ldso/sh64/elfinterp.c | 345 | ||||
-rw-r--r-- | ldso/ldso/sh64/resolve.S | 95 |
6 files changed, 0 insertions, 823 deletions
diff --git a/ldso/ldso/sh64/dl-debug.h b/ldso/ldso/sh64/dl-debug.h deleted file mode 100644 index 6d861e5b4..000000000 --- a/ldso/ldso/sh64/dl-debug.h +++ /dev/null @@ -1,79 +0,0 @@ -/* vi: set sw=8 ts=8: */ -/* - * ldso/ldso/sh64/elfinterp.c - * - * SuperH (sh64) ELF shared library loader suppport - * - * Copyright (C) 2003, 2004, 2005 Paul Mundt <lethal@linux-sh.org> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the above contributors may not be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -static const char * const _dl_reltypes_tab[] = { - /* SHcompact relocs */ - [0] = "R_SH_NONE", "R_SH_DIR32", - "R_SH_REL32", "R_SH_DIR8WPN", - [4] = "R_SH_IND12W", "R_SH_DIR8WPL", - "R_SH_DIR8WPZ", "R_SH_DIR8BP", - [8] = "R_SH_DIR8W", "R_SH_DIR8L", - [25] = "R_SH_SWITCH16", "R_SH_SWITCH32", - "R_SH_USES", "R_SH_COUNT", - [29] = "R_SH_ALIGN", "R_SH_CODE", - "R_SH_DATA", "R_SH_LABEL", - [33] = "R_SH_SWITCH8", "R_SH_GNU_VTINHERIT", - "R_SH_GNU_VTENTRY", - [160] = "R_SH_GOT32", "R_SH_PLT32", - "R_SH_COPY", "R_SH_GLOB_DAT", - [164] = "R_SH_JMP_SLOT", "R_SH_RELATIVE", - "R_SH_GOTOFF", "R_SH_GOTPC", - - /* SHmedia relocs */ - [45] = "R_SH_DIR5U", "R_SH_DIR6U", - "R_SH_DIR6S", "R_SH_DIR10S", - [49] = "R_SH_DIR10SW", "R_SH_DIR10SL", - "R_SH_DIR10SQ", - [169] = "R_SH_GOT_LOW16", "R_SH_GOT_MEDLOW16", - "R_SH_GOT_MEDHI16", "R_SH_GOT_HI16", - [173] = "R_SH_GOTPLT_LOW16", "R_SH_GOTPLT_MEDLOW16", - "R_SH_GOTPLT_MEDHI16", "R_SH_GOTPLT_HI16", - [177] = "R_SH_PLT_LOW16", "R_SH_PLT_MEDLOW16", - "R_SH_PLT_MEDHI16", "R_SH_PLT_HI16", - [181] = "R_SH_GOTOFF_LOW16", "R_SH_GOTOFF_MEDLOW16", - "R_SH_GOTOFF_MEDHI16", "R_SH_GOTOFF_HI16", - [185] = "R_SH_GOTPC_LOW16", "R_SH_GOTPC_MEDLOW16", - "R_SH_GOTPC_MEDHI16", "R_SH_GOTPC_HI16", - [189] = "R_SH_GOT10BY4", "R_SH_GOTPLT10BY4", - "R_SH_GOT10BY8", "R_SH_GOTPLT10BY8", - [193] = "R_SH_COPY64", "R_SH_GLOB_DAT64", - "R_SH_JMP_SLOT64", "R_SH_RELATIVE64", - [197] = "R_SH_RELATIVE_LOW16", "R_SH_RELATIVE_MEDLOW16", - "R_SH_RELATIVE_MEDHI16","R_SH_RELATIVE_HI16", - [242] = "R_SH_SHMEDIA_CODE", "R_SH_PT_16", - "R_SH_IMMS16", "R_SH_IMMU16", - [246] = "R_SH_IMM_LOW16", "R_SH_IMM_LOW16_PCREL", - "R_SH_IMM_MEDLOW16", "R_SH_IMM_MEDLOW16_PCREL", - [250] = "R_SH_IMM_MEDHI16", "R_SH_IMM_MEDHI16_PCREL", - "R_SH_IMM_HI16", "R_SH_IMM_HI16_PCREL", - [254] = "R_SH_64", "R_SH_64_PCREL", -}; diff --git a/ldso/ldso/sh64/dl-startup.h b/ldso/ldso/sh64/dl-startup.h deleted file mode 100644 index 9dac5ef2c..000000000 --- a/ldso/ldso/sh64/dl-startup.h +++ /dev/null @@ -1,118 +0,0 @@ -/* Any assembly language/system dependent hacks needed to setup boot1.c so it - * will work as expected and cope with whatever platform specific wierdness is - * needed for this architecture. - */ - -__asm__("" \ -" .section .text..SHmedia32,\"ax\"\n" \ -" .globl _start\n" \ -" .type _start, @function\n" \ -" .hidden _start\n" \ -" .align 5\n" \ -"_start:\n" \ -" ! Set r12 to point to GOT\n" \ -" movi (((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ3-.)) >> 16) & 0xffff), r12\n" \ -" shori ((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ3-.)) & 0xffff), r12\n" \ -".LZZZ3:\n" \ -" ptrel/u r12, tr0\n" \ -" gettr tr0, r12 ! GOT address\n" \ -" add r18, r63, r11 ! save return address - needed?\n" \ -" add r15, r63, r2 ! arg = stack pointer\n" \ -" pt _dl_start, tr0 ! should work even if PIC\n" \ -" blink tr0, r18 ! call _dl_start - user EP is in r2\n" \ -" add r2, r63, r28\n" \ -" movi (((_dl_fini@GOT) >> 16) & 0xffff), r1\n" \ -" shori ((_dl_fini@GOT) & 0xffff), r1\n" \ -" ldx.l r1, r12, r2\n" \ -" add r11, r63, r18\n" \ -" ptabs/l r28, tr0\n" \ -" blink tr0, r63\n" \ -" .size _start,.-_start\n" -" .previous\n" -); - -/* - * Get a pointer to the argv array. On many platforms this can be just - * the address of the first argument, on other platforms we need to - * do something a little more subtle here. - */ -#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *)ARGS)+1) - -/* - * Here is a macro to perform a relocation. This is only used when - * bootstrapping the dynamic loader. RELP is the relocation that we - * are performing, REL is the pointer to the address we are relocating. - * SYMBOL is the symbol involved in the relocation, and LOAD is the - * load address. - */ - -#include <elf.h> - -#define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \ - const unsigned int r_type = ELF_R_TYPE((RELP)->r_info); \ - int lsb = !!((SYMTAB)->st_other & STO_SH5_ISA32); \ - \ - switch (r_type) { \ - case R_SH_REL32: \ - *(REL) = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - break; \ - case R_SH_DIR32: \ - case R_SH_GLOB_DAT: \ - case R_SH_JMP_SLOT: \ - *(REL) = ((SYMBOL) + (RELP)->r_addend) | lsb; \ - break; \ - case R_SH_RELATIVE: \ - *(REL) = (LOAD) + (RELP)->r_addend; \ - break; \ - case R_SH_RELATIVE_LOW16: \ - case R_SH_RELATIVE_MEDLOW16: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = (LOAD) + (RELP)->r_addend; \ - \ - if (r_type == R_SH_RELATIVE_MEDLOW16) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_IMM_LOW16: \ - case R_SH_IMM_MEDLOW16: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = ((SYMBOL) + (RELP)->r_addend) | lsb; \ - \ - if (r_type == R_SH_IMM_MEDLOW16) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_IMM_LOW16_PCREL: \ - case R_SH_IMM_MEDLOW16_PCREL: \ - { \ - unsigned long word, value; \ - \ - word = (unsigned long)(REL) & ~0x3fffc00; \ - value = (SYMBOL) + (RELP)->r_addend \ - - (unsigned long)(REL); \ - \ - if (r_type == R_SH_IMM_MEDLOW16_PCREL) \ - value >>= 16; \ - \ - word |= (value & 0xffff) << 10; \ - *(REL) = word; \ - break; \ - } \ - case R_SH_NONE: \ - break; \ - default: \ - _dl_exit(1); \ - } diff --git a/ldso/ldso/sh64/dl-syscalls.h b/ldso/ldso/sh64/dl-syscalls.h deleted file mode 100644 index 2ea4bb7d0..000000000 --- a/ldso/ldso/sh64/dl-syscalls.h +++ /dev/null @@ -1,18 +0,0 @@ -#undef __syscall_return -#define __syscall_return(type, res) \ -do { \ - /* \ - * Note: when returning from kernel the return value is in r9 \ - * \ - * This prevents conflicts between return value and arg1 \ - * when dispatching signal handler, in other words makes \ - * life easier in the system call epilogue (see entry.S) \ - */ \ - register unsigned long __sr2 __asm__ ("r2") = res; \ - if ((unsigned long)(res) >= (unsigned long)(-125)) { \ - _dl_errno = -(res); \ - __sr2 = -1; \ - } \ - return (type)(__sr2); \ -} while (0) - diff --git a/ldso/ldso/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h deleted file mode 100644 index 043413931..000000000 --- a/ldso/ldso/sh64/dl-sysdep.h +++ /dev/null @@ -1,168 +0,0 @@ -/* vi: set sw=8 ts=8: */ -/* - * Various assembly language/system dependent hacks that are required - * so that we can minimize the amount of platform specific code. - */ - -/* Define this if the system uses RELOCA. */ -#define ELF_USES_RELOCA -#include <elf.h> -/* - * Initialization sequence for a GOT. - */ -#define INIT_GOT(GOT_BASE,MODULE) \ -{ \ - GOT_BASE[2] = (unsigned long)_dl_linux_resolve; \ - GOT_BASE[1] = (unsigned long)(MODULE); \ -} - -/* Here we define the magic numbers that this dynamic loader should accept */ -#define MAGIC1 EM_SH -#undef MAGIC2 - -/* Used for error messages */ -#define ELF_TARGET "sh64" - -/* Need bootstrap relocations */ -#define ARCH_NEEDS_BOOTSTRAP_RELOCS - -struct elf_resolve; -extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); - -/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or - TLS variable, so undefined references should not be allowed to - define the value. - ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one - of the main executable's symbols, as for a COPY reloc. */ -#define elf_machine_type_class(type) \ - ((((type) == R_SH_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ - | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY)) - -/* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ -static __always_inline Elf32_Addr elf_machine_dynamic(void) -{ - register Elf32_Addr *got; - - /* - * The toolchain adds 32768 to the GOT address, we compensate for - * that in the movi/sub pair. - * - * XXX: If this is cleaned up in the toolchain, we can end up - * saving 2 instructions and subsequently free up r1 from the - * clobber list.. - */ - __asm__ ( - "movi\t(((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ1-.)) >> 16) & 0xffff), r2\n\t" - "shori\t((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ1-.)) & 0xffff), r2\n\t" - ".LZZZ1:\tptrel/u r2, tr0\n\t" - "movi\t32768, r1\n\t" - "gettr\ttr0, r2\n\t" - "sub\tr2, r1, %0\n\t" - : "=r" (got) - : /* no inputs */ - : "r1", "r2", "tr0" - ); - - return *got; -} - -/* Return the run-time load address of the shared object. */ -static __always_inline Elf32_Addr elf_machine_load_address(void) -{ - Elf32_Addr addr; - - __asm__ ( - "movi\t(((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ2-.)) >> 16) & 0xffff), r0\n\t" - "shori\t((datalabel _GLOBAL_OFFSET_TABLE_-(.LZZZ2-.)) & 0xffff), r0\n\t" - ".LZZZ2:\tptrel/u r0, tr0\n\t" - "movi\t(((_dl_start@GOTOFF) >> 16) & 0xffff), r2\n\t" - "shori\t((_dl_start@GOTOFF) & 0xffff), r2\n\t" - "gettr\ttr0, r0\n\t" - "add\tr2, r0, r2\n\t" - "movi\t(((_dl_start@GOT) >> 16) & 0xffff), r1\n\t" - "shori\t((_dl_start@GOT) & 0xffff), r1\n\t" - "ldx.l\tr1, r0, r1\n\t" - "sub\tr2, r1, %0\n\t" - : "=r" (addr) - : /* no inputs */ - : "r0", "r1", "r2", "tr0" - ); - - return addr; -} - -/* - * XXX: As we don't need to worry about r25 clobbering, we could probably - * get away with inlining {st,ld}{x,}.l and friends here instead and - * forego gcc's idea of code generation. - */ -#define COPY_UNALIGNED_WORD(swp, twp, align) \ -{ \ - void *__s = (swp), *__t = (twp); \ - unsigned char *__s1 = __s, *__t1 = __t; \ - unsigned short *__s2 = __s, *__t2 = __t; \ - unsigned long *__s4 = __s, *__t4 = __t; \ - \ - switch ((align)) { \ - case 0: \ - *__t4 = *__s4; \ - break; \ - case 2: \ - *__t2++ = *__s2++; \ - *__t2 = *__s2; \ - break; \ - default: \ - *__t1++ = *__s1++; \ - *__t1++ = *__s1++; \ - *__t1++ = *__s1++; \ - *__t1 = *__s1; \ - break; \ - } \ -} - -static __always_inline void -elf_machine_relative(Elf32_Addr load_off, const Elf32_Addr rel_addr, - Elf32_Word relative_count) -{ - Elf32_Addr value, word; - Elf32_Rela *rpnt = (void *)rel_addr; - int reloc_type = ELF_R_TYPE(rpnt->r_info); - - do { - Elf32_Addr *const reloc_addr = - (void *)(load_off + rpnt->r_offset); - int align = (int)reloc_addr & 3; - - switch (reloc_type) { - case R_SH_RELATIVE_LOW16: - COPY_UNALIGNED_WORD(reloc_addr, &word, align); - word &= ~0x3fffc00; - value = (rpnt->r_addend + load_off); - word |= (value & 0xffff) << 10; - COPY_UNALIGNED_WORD(&word, reloc_addr, align); - break; - case R_SH_RELATIVE_MEDLOW16: - COPY_UNALIGNED_WORD(reloc_addr, &word, align); - word &= ~0x3fffc00; - value = (rpnt->r_addend + load_off) >> 16; - word |= (value & 0xffff) << 10; - COPY_UNALIGNED_WORD(&word, reloc_addr, align); - break; - default: - if (rpnt->r_addend) { - value = load_off + rpnt->r_addend; - } else { - COPY_UNALIGNED_WORD(reloc_addr, &value, align); - value += load_off; - } - - COPY_UNALIGNED_WORD(&value, reloc_addr, align); - break; - } - - rpnt++; - } while (--relative_count); -#undef COPY_UNALIGNED_WORD -} diff --git a/ldso/ldso/sh64/elfinterp.c b/ldso/ldso/sh64/elfinterp.c deleted file mode 100644 index 3a59bc4be..000000000 --- a/ldso/ldso/sh64/elfinterp.c +++ /dev/null @@ -1,345 +0,0 @@ -/* vi: set sw=8 ts=8: */ -/* - * ldso/ldso/sh64/elfinterp.c - * - * SuperH (sh64) ELF shared library loader suppport - * - * Copyright (C) 2003, 2004, 2005 Paul Mundt <lethal@linux-sh.org> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the above contributors may not be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* Program to load an ELF binary on a linux system, and run it. - References to symbols in sharable libraries can be resolved by either - an ELF sharable library or a linux style of shared library. */ - -/* Disclaimer: I have never seen any AT&T source code for SVr4, nor have - I ever taken any courses on internals. This program was developed using - information available through the book "UNIX SYSTEM V RELEASE 4, - Programmers guide: Ansi C and Programming Support Tools", which did - a more than adequate job of explaining everything required to get this - working. */ - -#include "ldso.h" - -extern int _dl_linux_resolve(void); - -unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) -{ - ELF_RELOC *this_reloc; - char *strtab; - ElfW(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); - symtab_index = ELF_R_SYM(this_reloc->r_info); - - symtab = (ElfW(Sym) *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB]; - strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; - symname = strtab + symtab[symtab_index].st_name; - - /* Address of 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, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); - if (unlikely(!new_addr)) { - _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", - _dl_progname, symname); - _dl_exit(1); - } - -#ifdef __SUPPORT_LD_DEBUG__ - if ((unsigned long)got_addr < 0x20000000) { - 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\n", - *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; -} - -static int _dl_parse(struct elf_resolve *tpnt, struct r_scope_elem *scope, - unsigned long rel_addr, unsigned long rel_size, - int (*reloc_fnc)(struct elf_resolve *tpnt, - struct r_scope_elem *scope, - ELF_RELOC *rpnt, ElfW(Sym) *symtab, - char *strtab)) -{ - unsigned int i; - char *strtab; - ElfW(Sym) *symtab; - ELF_RELOC *rpnt; - int symtab_index; - - /* Now parse the relocation information */ - rpnt = (ELF_RELOC *)(intptr_t)rel_addr; - rel_size = rel_size / sizeof(ELF_RELOC); - - symtab = (ElfW(Sym) *)(intptr_t)tpnt->dynamic_info[DT_SYMTAB]; - strtab = (char *)tpnt->dynamic_info[DT_STRTAB]; - - for (i = 0; i < rel_size; i++, rpnt++) { - int res; - - symtab_index = ELF_R_SYM(rpnt->r_info); - debug_sym(symtab,strtab,symtab_index); - debug_reloc(symtab,strtab,rpnt); - - res = reloc_fnc (tpnt, scope, rpnt, symtab, strtab); - if (res == 0) - continue; - - _dl_dprintf(2, "\n%s: ",_dl_progname); - - if (symtab_index) - _dl_dprintf(2, "symbol '%s': ", - strtab + symtab[symtab_index].st_name); - - if (unlikely(res < 0)) { - int reloc_type = ELF_R_TYPE(rpnt->r_info); - - _dl_dprintf(2, "can't handle reloc type " -#ifdef __SUPPORT_LD_DEBUG__ - "%s\n", _dl_reltypes(reloc_type) -#else - "%x\n", reloc_type -#endif - ); - - _dl_exit(-res); - } - if (unlikely(res > 0)) { - _dl_dprintf(2, "can't resolve symbol\n"); - - return res; - } - } - - return 0; -} - -static int _dl_do_reloc(struct elf_resolve *tpnt,struct r_scope_elem *scope, - ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) -{ - int reloc_type; - int symtab_index, lsb; - char *symname; - unsigned long *reloc_addr; - unsigned long symbol_addr; -#ifdef __SUPPORT_LD_DEBUG__ - unsigned long old_val; -#endif - struct symbol_ref sym_ref; - - reloc_type = ELF_R_TYPE(rpnt->r_info); - symtab_index = ELF_R_SYM(rpnt->r_info); - symbol_addr = 0; - lsb = !!(symtab[symtab_index].st_other & STO_SH5_ISA32); - sym_ref.sym = &symtab[symtab_index]; - sym_ref.tpnt = NULL; - symname = strtab + symtab[symtab_index].st_name; - reloc_addr = (unsigned long *)(intptr_t) - (tpnt->loadaddr + (unsigned long)rpnt->r_offset); - - if (symtab_index) { - int stb; - - symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt, - elf_machine_type_class(reloc_type), &sym_ref); - - /* - * We want to allow undefined references to weak symbols - this - * might have been intentional. We should not be linking local - * symbols here, so all bases should be covered. - */ - stb = ELF_ST_BIND(symtab[symtab_index].st_info); - - if (stb != STB_WEAK && !symbol_addr) { - _dl_dprintf (2, "%s: can't resolve symbol '%s'\n", - _dl_progname, symname); - _dl_exit (1); - } - if (_dl_trace_prelink) { - _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - &sym_ref, elf_machine_type_class(reloc_type)); - } - } - -#ifdef __SUPPORT_LD_DEBUG__ - old_val = *reloc_addr; -#endif - - switch (reloc_type) { - case R_SH_NONE: - break; - case R_SH_COPY: - _dl_memcpy((char *)reloc_addr, - (char *)symbol_addr, symtab[symtab_index].st_size); - break; - case R_SH_DIR32: - case R_SH_GLOB_DAT: - case R_SH_JMP_SLOT: - *reloc_addr = (symbol_addr + rpnt->r_addend) | lsb; - break; - case R_SH_REL32: - *reloc_addr = symbol_addr + rpnt->r_addend - - (unsigned long)reloc_addr; - break; - case R_SH_RELATIVE: - *reloc_addr = (unsigned long)tpnt->loadaddr + rpnt->r_addend; - break; - case R_SH_RELATIVE_LOW16: - case R_SH_RELATIVE_MEDLOW16: - { - unsigned long word, value; - - word = (unsigned long)reloc_addr & ~0x3fffc00; - value = (unsigned long)tpnt->loadaddr + rpnt->r_addend; - - if (reloc_type == R_SH_RELATIVE_MEDLOW16) - value >>= 16; - - word |= (value & 0xffff) << 10; - *reloc_addr = word; - - break; - } - case R_SH_IMM_LOW16: - case R_SH_IMM_MEDLOW16: - { - unsigned long word, value; - - word = (unsigned long)reloc_addr & ~0x3fffc00; - value = (symbol_addr + rpnt->r_addend) | lsb; - - if (reloc_type == R_SH_IMM_MEDLOW16) - value >>= 16; - - word |= (value & 0xffff) << 10; - *reloc_addr = word; - - break; - } - case R_SH_IMM_LOW16_PCREL: - case R_SH_IMM_MEDLOW16_PCREL: - { - unsigned long word, value; - - word = (unsigned long)reloc_addr & ~0x3fffc00; - value = symbol_addr + rpnt->r_addend - - (unsigned long)reloc_addr; - - if (reloc_type == R_SH_IMM_MEDLOW16_PCREL) - value >>= 16; - - word |= (value & 0xffff) << 10; - *reloc_addr = word; - - break; - } - default: - return -1; /*call _dl_exit(1) */ - } - -#ifdef __SUPPORT_LD_DEBUG__ - if (_dl_debug_reloc && _dl_debug_detail) - _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", - old_val, *reloc_addr, reloc_addr); -#endif - - return 0; -} - -static int _dl_do_lazy_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, - ELF_RELOC *rpnt, ElfW(Sym) *symtab, char *strtab) -{ - int reloc_type, symtab_index, lsb; - unsigned long *reloc_addr; -#ifdef __SUPPORT_LD_DEBUG__ - unsigned long old_val; -#endif - - reloc_type = ELF_R_TYPE(rpnt->r_info); - symtab_index = ELF_R_SYM(rpnt->r_info); - lsb = !!(symtab[symtab_index].st_other & STO_SH5_ISA32); - reloc_addr = (unsigned long *)(intptr_t) - (tpnt->loadaddr + (unsigned long)rpnt->r_offset); - -#ifdef __SUPPORT_LD_DEBUG__ - old_val = *reloc_addr; -#endif - - switch (reloc_type) { - case R_SH_NONE: - break; - case R_SH_JMP_SLOT: - *reloc_addr += (unsigned long)tpnt->loadaddr | lsb; - break; - default: - return -1; /*call _dl_exit(1) */ - } - -#ifdef __SUPPORT_LD_DEBUG__ - if (_dl_debug_reloc && _dl_debug_detail) - _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n", - old_val, *reloc_addr, reloc_addr); -#endif - - return 0; -} - -void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt, - unsigned long rel_addr, unsigned long rel_size) -{ - (void)_dl_parse(rpnt->dyn, NULL, rel_addr, rel_size, _dl_do_lazy_reloc); -} - -int _dl_parse_relocation_information(struct dyn_elf *rpnt, - struct r_scope_elem *scope, unsigned long rel_addr, unsigned long rel_size) -{ - return _dl_parse(rpnt->dyn, scope, rel_addr, rel_size, _dl_do_reloc); -} diff --git a/ldso/ldso/sh64/resolve.S b/ldso/ldso/sh64/resolve.S deleted file mode 100644 index ca915d2ef..000000000 --- a/ldso/ldso/sh64/resolve.S +++ /dev/null @@ -1,95 +0,0 @@ -/* vi: set sw=8 ts=8: */ -/* - * ldso/ldso/sh64/resolve.S - * - * SuperH (sh64) dynamic resolver support - * - * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the above contributors may not be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - .section .text..SHmedia32,"ax" - .globl _dl_linux_resolver - .globl _dl_linux_resolve - .type _dl_linux_resolve, @function - - .balign 16 -_dl_linux_resolve: - addi r15, -72, r15 ! make room on the stack - pt _dl_linux_resolver, tr0 - st.q r15, 0, r2 ! save regs - st.q r15, 8, r3 - st.q r15, 16, r4 - st.q r15, 24, r5 - st.q r15, 32, r6 - st.q r15, 40, r7 - st.q r15, 48, r8 - st.q r15, 56, r9 - st.q r15, 64, r18 - -#ifdef HAVE_FPU - addi r15, -48, r15 ! make room for FP regs - fst.d r15, 0, dr0 ! save FP regs - fst.d r15, 8, dr2 - fst.d r15, 16, dr4 - fst.d r15, 24, dr6 - fst.d r15, 32, dr8 - fst.d r15, 40, dr10 -#endif - - /* - * Args for _dl_linux_resolver(), set in r17/r21 by PLT code - */ - - add r17, r63, r2 ! link map address - add r21, r63, r3 ! GOT offset - blink tr0, r18 ! call _dl_linux_resolver() - ptabs/l r2, tr0 ! save result = addr of function called - -#ifdef HAVE_FPU - fld.d r15, 0, dr0 ! restore FP regs - fld.d r15, 8, dr2 - fld.d r15, 16, dr4 - fld.d r15, 24, dr6 - fld.d r15, 32, dr8 - fld.d r15, 40, dr10 - addi r15, 48, r15 -#endif - - ld.q r15, 0, r2 ! restore regs - ld.q r15, 8, r3 - ld.q r15, 16, r4 - ld.q r15, 24, r5 - ld.q r15, 32, r6 - ld.q r15, 40, r7 - ld.q r15, 48, r8 - ld.q r15, 56, r9 - ld.q r15, 64, r18 - - addi r15, 72, r15 - blink tr0, r63 ! jump to function address - - .size _dl_linux_resolve, . - _dl_linux_resolve - |