1 /* Copyright (C) 2010 Texas Instruments Incorporated
2 * Contributed by Mark Salter <msalter@redhat.com>
4 * Borrowed heavily from frv arch:
5 * Copyright (C) 2003, 2004 Red Hat, Inc.
7 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
10 #include <bits/elf-dsbt.h>
13 * Define this if the system uses RELOCA.
15 #define ELF_USES_RELOCA 1
17 /* JMPREL relocs are inside the DT_RELA table. */
18 /* Actually looks like a linker bug sets DT_JMPREL anyway */
19 #define ELF_MACHINE_PLTREL_OVERLAP 1
21 #undef DL_NO_COPY_RELOCS
23 #define HAVE_DL_INLINES_H
27 * Various assembly language/system dependent hacks that are required
28 * so that we can minimize the amount of platform specific code.
31 /* Initialization sequence for the GOT. */
32 #define INIT_GOT(GOT_BASE,MODULE) \
34 GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
35 GOT_BASE[1] = (unsigned long) MODULE; \
38 /* Here we define the magic numbers that this dynamic loader should accept */
39 #define MAGIC1 EM_TI_C6000
42 /* Used for error messages */
43 #define ELF_TARGET "C6000"
45 /* Need bootstrap relocations */
46 #define ARCH_NEEDS_BOOTSTRAP_RELOCS
50 extern int _dl_linux_resolve(void) attribute_hidden;
53 struct elf32_dsbt_loadaddr;
55 /* We must force strings used early in the bootstrap into the text
56 segment (const data), such that they are referenced relative to
57 the DP register rather than through the GOT which will not have
58 been relocated when these are used. */
59 #undef SEND_EARLY_STDERR
60 #define SEND_EARLY_STDERR(S) \
61 do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
63 #define DL_LOADADDR_TYPE struct elf32_dsbt_loadaddr
65 #define DL_RELOC_ADDR(LOADADDR, ADDR) \
66 ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
68 #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
70 struct elf32_dsbt_loadmap *map; \
71 map = dl_boot_ldsomap ?: dl_boot_progmap; \
72 if (map->version != 0) { \
73 SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
76 if (map->nsegs < 2) { \
77 SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
80 (LOADADDR).map = map; \
83 #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
85 if (dl_boot_progmap->version != 0) { \
86 SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
89 if (dl_boot_progmap->nsegs < 2) { \
90 SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
93 (LOADADDR).map = dl_boot_progmap; \
96 #define DL_INIT_LOADADDR_EXTRA_DECLS \
97 int dl_init_loadaddr_load_count;
99 #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
100 (dl_init_loadaddr_load_count = \
101 __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
103 #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
104 (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
105 dl_init_loadaddr_load_count))
107 #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
108 (__dl_loadaddr_unmap ((LOADADDR)))
110 #define DL_LIB_UNMAP(LIB, LEN) \
111 (__dl_loadaddr_unmap ((LIB)->loadaddr))
113 #define DL_LOADADDR_BASE(LOADADDR) \
114 ((LOADADDR).map->dsbt_table)
116 #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
117 (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
120 /* We only support loading DSBT relocatable shared libraries.
121 It probably wouldn't be too hard to support loading statically
122 linked executables that require relocation.*/
123 #define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
130 /* We want want to apply all relocations in the interpreter during
131 bootstrap. Because of this, we have to skip the interpreter
132 relocations in _dl_parse_relocation_information(), see
134 #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
137 #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
138 (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
141 #define DL_GET_READY_TO_RUN_EXTRA_PARMS \
142 , struct elf32_dsbt_loadmap *dl_boot_progmap \
143 , struct elf32_dsbt_loadmap *dl_boot_ldsomap
144 #define DL_GET_READY_TO_RUN_EXTRA_ARGS \
150 * Compute the GOT address.
151 * Also setup program and interpreter DSBT table entries.
153 #define DL_BOOT_COMPUTE_GOT(GOT) \
155 unsigned long *ldso_dsbt, *prog_dsbt; \
156 ldso_dsbt = dl_boot_ldsomap->dsbt_table; \
157 prog_dsbt = dl_boot_progmap->dsbt_table; \
158 ldso_dsbt[0] = prog_dsbt[0] = (unsigned long)prog_dsbt; \
159 ldso_dsbt[1] = prog_dsbt[1] = (unsigned long)ldso_dsbt; \
160 (GOT) = ldso_dsbt + dl_boot_ldsomap->dsbt_size; \
163 #define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
164 ((dpnt) = dl_boot_ldso_dyn_pointer)
175 static __always_inline Elf32_Addr
176 elf_machine_load_address (void)
178 /* this is never an issue on DSBT systems */
182 static __always_inline void
183 elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
184 Elf32_Word relative_count)
188 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
189 PLT entries should not be allowed to define the value.
190 ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
191 of the main executable's symbols, as for a COPY reloc. */
192 #define elf_machine_type_class(type) \
193 ((((type) == R_C6000_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
194 | (((type) == R_C6000_COPY) * ELF_RTYPE_CLASS_COPY))
197 #define DT_DSBT_BASE_IDX (DT_NUM + OS_NUM)
198 #define DT_DSBT_SIZE_IDX (DT_NUM + OS_NUM + 1)
199 #define DT_DSBT_INDEX_IDX (DT_NUM + OS_NUM + 2)
201 #define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
203 if (dpnt->d_tag == DT_C6000_DSBT_BASE) \
204 dynamic[DT_DSBT_BASE_IDX] = dpnt->d_un.d_val; \
205 else if (dpnt->d_tag == DT_C6000_DSBT_SIZE) \
206 dynamic[DT_DSBT_SIZE_IDX] = dpnt->d_un.d_val; \
207 else if (dpnt->d_tag == DT_C6000_DSBT_INDEX) \
208 dynamic[DT_DSBT_INDEX_IDX] = dpnt->d_un.d_val; \