]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/ldso/ldso/c6x/dl-sysdep.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / ldso / ldso / c6x / dl-sysdep.h
1 /* Copyright (C) 2010 Texas Instruments Incorporated
2  * Contributed by Mark Salter <msalter@redhat.com>
3  *
4  * Borrowed heavily from frv arch:
5  * Copyright (C) 2003, 2004 Red Hat, Inc.
6  *
7  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
8  */
9
10 #include <bits/elf-dsbt.h>
11
12 /*
13  * Define this if the system uses RELOCA.
14  */
15 #define ELF_USES_RELOCA 1
16
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
20
21 #undef DL_NO_COPY_RELOCS
22
23 #define HAVE_DL_INLINES_H
24
25
26 /*
27  * Various assembly language/system dependent  hacks that are required
28  * so that we can minimize the amount of platform specific code.
29  */
30
31 /* Initialization sequence for the GOT.  */
32 #define INIT_GOT(GOT_BASE,MODULE) \
33 { \
34   GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
35   GOT_BASE[1] = (unsigned long) MODULE; \
36 }
37
38 /* Here we define the magic numbers that this dynamic loader should accept */
39 #define MAGIC1 EM_TI_C6000
40 #undef  MAGIC2
41
42 /* Used for error messages */
43 #define ELF_TARGET "C6000"
44
45 /* Need bootstrap relocations */
46 #define ARCH_NEEDS_BOOTSTRAP_RELOCS
47
48 struct elf_resolve;
49
50 extern int _dl_linux_resolve(void) attribute_hidden;
51
52 struct funcdesc_ht;
53 struct elf32_dsbt_loadaddr;
54
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)
62
63 #define DL_LOADADDR_TYPE struct elf32_dsbt_loadaddr
64
65 #define DL_RELOC_ADDR(LOADADDR, ADDR) \
66   ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
67
68 #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
69         do {                                                            \
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"); \
74                 _dl_exit(-1);                                           \
75             }                                                           \
76             if (map->nsegs < 2) {                                       \
77                 SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
78                 _dl_exit(-1);                                           \
79             }                                                           \
80             (LOADADDR).map = map;                                       \
81         } while(0)
82
83 #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
84         do {                                                            \
85             if (dl_boot_progmap->version != 0) {                        \
86                 SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
87                 _dl_exit(-1);                                           \
88             }                                                           \
89             if (dl_boot_progmap->nsegs < 2) {                           \
90                 SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
91                 _dl_exit(-1);                                           \
92             }                                                           \
93             (LOADADDR).map = dl_boot_progmap;                           \
94         } while(0)
95
96 #define DL_INIT_LOADADDR_EXTRA_DECLS \
97   int dl_init_loadaddr_load_count;
98
99 #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
100   (dl_init_loadaddr_load_count = \
101      __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
102
103 #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
104   (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
105                            dl_init_loadaddr_load_count))
106
107 #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
108   (__dl_loadaddr_unmap ((LOADADDR)))
109
110 #define DL_LIB_UNMAP(LIB, LEN) \
111   (__dl_loadaddr_unmap ((LIB)->loadaddr))
112
113 #define DL_LOADADDR_BASE(LOADADDR) \
114   ((LOADADDR).map->dsbt_table)
115
116 #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
117   (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
118
119
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) \
124 do \
125 { \
126     (piclib) = 2; \
127 } \
128 while (0)
129
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
133    elfinterp.c.  */
134 #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
135
136 #ifdef __NR_pread64
137 #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
138   (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
139 #endif
140
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 \
145   , dl_boot_progmap \
146   , dl_boot_ldsomap
147
148
149 /*
150  * Compute the GOT address.
151  * Also setup program and interpreter DSBT table entries.
152  */
153 #define DL_BOOT_COMPUTE_GOT(GOT) \
154   do {                                                          \
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;             \
161   } while(0)
162
163 #define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
164   ((dpnt) = dl_boot_ldso_dyn_pointer)
165
166
167 #ifdef __USE_GNU
168 # include <link.h>
169 #else
170 # define __USE_GNU
171 # include <link.h>
172 # undef __USE_GNU
173 #endif
174
175 static __always_inline Elf32_Addr
176 elf_machine_load_address (void)
177 {
178         /* this is never an issue on DSBT systems */
179         return 0;
180 }
181
182 static __always_inline void
183 elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
184                       Elf32_Word relative_count)
185 {
186 }
187
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))
195
196 #define ARCH_NUM 3
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)
200
201 #define ARCH_DYNAMIC_INFO(dpnt,  dynamic, debug_addr) \
202 do { \
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; \
209 } while (0)