123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /* Copyright (C) 2010 Texas Instruments Incorporated
- * Contributed by Mark Salter <msalter@redhat.com>
- *
- * Borrowed heavily from frv arch:
- * Copyright (C) 2003, 2004 Red Hat, Inc.
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
- #include <bits/elf-dsbt.h>
- /*
- * Define this if the system uses RELOCA.
- */
- #define ELF_USES_RELOCA 1
- /* JMPREL relocs are inside the DT_RELA table. */
- /* Actually looks like a linker bug sets DT_JMPREL anyway */
- #define ELF_MACHINE_PLTREL_OVERLAP 1
- #undef DL_NO_COPY_RELOCS
- #define HAVE_DL_INLINES_H
- /*
- * Various assembly language/system dependent hacks that are required
- * so that we can minimize the amount of platform specific code.
- */
- /* Initialization sequence for the GOT. */
- #define INIT_GOT(GOT_BASE,MODULE) \
- { \
- GOT_BASE[0] = (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_TI_C6000
- #undef MAGIC2
- /* Used for error messages */
- #define ELF_TARGET "C6000"
- /* Need bootstrap relocations */
- #define ARCH_NEEDS_BOOTSTRAP_RELOCS
- struct elf_resolve;
- extern int _dl_linux_resolve(void) attribute_hidden;
- struct funcdesc_ht;
- struct elf32_dsbt_loadaddr;
- /* We must force strings used early in the bootstrap into the text
- segment (const data), such that they are referenced relative to
- the DP register rather than through the GOT which will not have
- been relocated when these are used. */
- #undef SEND_EARLY_STDERR
- #define SEND_EARLY_STDERR(S) \
- do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
- #define DL_LOADADDR_TYPE struct elf32_dsbt_loadaddr
- #define DL_RELOC_ADDR(LOADADDR, ADDR) \
- ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
- #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
- do { \
- struct elf32_dsbt_loadmap *map; \
- map = dl_boot_ldsomap ?: dl_boot_progmap; \
- if (map->version != 0) { \
- SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
- _dl_exit(-1); \
- } \
- if (map->nsegs < 2) { \
- SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
- _dl_exit(-1); \
- } \
- (LOADADDR).map = map; \
- } while(0)
- #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
- do { \
- if (dl_boot_progmap->version != 0) { \
- SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
- _dl_exit(-1); \
- } \
- if (dl_boot_progmap->nsegs < 2) { \
- SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
- _dl_exit(-1); \
- } \
- (LOADADDR).map = dl_boot_progmap; \
- } while(0)
- #define DL_INIT_LOADADDR_EXTRA_DECLS \
- int dl_init_loadaddr_load_count;
- #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
- (dl_init_loadaddr_load_count = \
- __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
- #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
- dl_init_loadaddr_load_count))
- #define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
- (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
- #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
- (__dl_loadaddr_unmap ((LOADADDR)))
- #define DL_LIB_UNMAP(LIB, LEN) \
- (__dl_loadaddr_unmap ((LIB)->loadaddr))
- #define DL_LOADADDR_BASE(LOADADDR) \
- ((LOADADDR).map->dsbt_table)
- #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
- (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
- /* We only support loading DSBT relocatable shared libraries.
- It probably wouldn't be too hard to support loading statically
- linked executables that require relocation.*/
- #define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
- do \
- { \
- (piclib) = 2; \
- } \
- while (0)
- /* We want want to apply all relocations in the interpreter during
- bootstrap. Because of this, we have to skip the interpreter
- relocations in _dl_parse_relocation_information(), see
- elfinterp.c. */
- #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
- #ifdef __NR_pread64
- #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
- (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
- #endif
- #define DL_GET_READY_TO_RUN_EXTRA_PARMS \
- , struct elf32_dsbt_loadmap *dl_boot_progmap \
- , struct elf32_dsbt_loadmap *dl_boot_ldsomap
- #define DL_GET_READY_TO_RUN_EXTRA_ARGS \
- , dl_boot_progmap \
- , dl_boot_ldsomap
- /*
- * Compute the GOT address.
- * Also setup program and interpreter DSBT table entries.
- */
- #define DL_BOOT_COMPUTE_GOT(GOT) \
- do { \
- unsigned long *ldso_dsbt, *prog_dsbt; \
- ldso_dsbt = dl_boot_ldsomap->dsbt_table; \
- prog_dsbt = dl_boot_progmap->dsbt_table; \
- ldso_dsbt[0] = prog_dsbt[0] = (unsigned long)prog_dsbt; \
- ldso_dsbt[1] = prog_dsbt[1] = (unsigned long)ldso_dsbt; \
- (GOT) = ldso_dsbt + dl_boot_ldsomap->dsbt_size; \
- } while(0)
- #define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
- ((dpnt) = dl_boot_ldso_dyn_pointer)
- #ifdef __USE_GNU
- # include <link.h>
- #else
- # define __USE_GNU
- # include <link.h>
- # undef __USE_GNU
- #endif
- static __always_inline Elf32_Addr
- elf_machine_load_address (void)
- {
- /* this is never an issue on DSBT systems */
- return 0;
- }
- static __always_inline void
- elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
- Elf32_Word relative_count)
- {
- }
- /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
- PLT entries 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_C6000_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
- | (((type) == R_C6000_COPY) * ELF_RTYPE_CLASS_COPY))
- #define ARCH_NUM 3
- #define DT_DSBT_BASE_IDX (DT_NUM + OS_NUM)
- #define DT_DSBT_SIZE_IDX (DT_NUM + OS_NUM + 1)
- #define DT_DSBT_INDEX_IDX (DT_NUM + OS_NUM + 2)
- #define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
- do { \
- if (dpnt->d_tag == DT_C6000_DSBT_BASE) \
- dynamic[DT_DSBT_BASE_IDX] = dpnt->d_un.d_val; \
- else if (dpnt->d_tag == DT_C6000_DSBT_SIZE) \
- dynamic[DT_DSBT_SIZE_IDX] = dpnt->d_un.d_val; \
- else if (dpnt->d_tag == DT_C6000_DSBT_INDEX) \
- dynamic[DT_DSBT_INDEX_IDX] = dpnt->d_un.d_val; \
- } while (0)
|