OSDN Git Service

206a66247e986b4b1abb5c45b586120cf1781034
[uclinux-h8/uClibc.git] / ldso / ldso / frv / dl-sysdep.h
1 /* Copyright (C) 2003, 2004 Red Hat, Inc.
2  * Contributed by Alexandre Oliva <aoliva@redhat.com>
3  * Based on ../i386/dl-sysdep.h
4  *
5  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
6  */
7
8 /*
9  * Various assembly language/system dependent  hacks that are required
10  * so that we can minimize the amount of platform specific code.
11  */
12
13 /*
14  * Define this if the system uses RELOCA.
15  */
16 #undef ELF_USES_RELOCA
17
18 /* JMPREL relocs are inside the DT_RELA table.  */
19 #define ELF_MACHINE_PLTREL_OVERLAP
20
21 #define DL_NO_COPY_RELOCS
22
23 /*
24  * Initialization sequence for a GOT.  Copy the resolver function
25  * descriptor and the pointer to the elf_resolve/link_map data
26  * structure.  Initialize the got_value in the module while at that.
27  */
28 #define INIT_GOT(GOT_BASE,MODULE) \
29 {                               \
30   (MODULE)->loadaddr.got_value = (GOT_BASE); \
31   GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \
32   GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \
33   GOT_BASE[2] = (unsigned long) MODULE; \
34 }
35
36 /* Here we define the magic numbers that this dynamic loader should accept */
37 #define MAGIC1 EM_CYGNUS_FRV
38 #undef  MAGIC2
39
40 /* Used for error messages */
41 #define ELF_TARGET "FR-V"
42
43 /* Need bootstrap relocations */
44 #define ARCH_NEEDS_BOOTSTRAP_RELOCS
45
46 struct elf_resolve;
47
48 struct funcdesc_value
49 {
50   void *entry_point;
51   void *got_value;
52 } __attribute__((__aligned__(8)));
53
54
55 extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
56
57 struct funcdesc_ht;
58
59 /* We must force strings used early in the bootstrap into the data
60    segment, such that they are referenced with GOTOFF instead of
61    GPREL, because GPREL needs the GOT to have already been
62    relocated.  */
63 #undef SEND_EARLY_STDERR
64 #define SEND_EARLY_STDERR(S) \
65   do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
66
67 #define DL_LOADADDR_TYPE struct elf32_fdpic_loadaddr
68
69 #define DL_RELOC_ADDR(ADDR, LOADADDR) \
70   (__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
71
72 #define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) \
73   ((void(*)(void)) _dl_funcdesc_for ((void*)(ADDR), (LOADADDR).got_value))
74
75 #define _dl_stabilize_funcdesc(val) \
76   ({ __asm__ ("" : "+m" (*(val))); (val); })
77
78 #define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \
79   ({ struct funcdesc_value fd = { (void*)(ADDR), (LOADADDR).got_value }; \
80      void (*pf)(void) = (void*) _dl_stabilize_funcdesc (&fd); \
81      (* SIGNATURE pf)(__VA_ARGS__); })
82
83 #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
84   (__dl_init_loadaddr_map (&(LOADADDR), dl_boot_got_pointer, \
85                            dl_boot_ldsomap ?: dl_boot_progmap))
86
87 #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
88   (__dl_init_loadaddr_map (&(LOADADDR), 0, dl_boot_progmap))
89
90 #define DL_INIT_LOADADDR_EXTRA_DECLS \
91   int dl_init_loadaddr_load_count;
92 #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
93   (dl_init_loadaddr_load_count = \
94      __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
95 #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
96   (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
97                            dl_init_loadaddr_load_count))
98 #define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
99   (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
100 #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
101   (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
102 #define DL_LIB_UNMAP(LIB, LEN) \
103   (__dl_loadaddr_unmap ((LIB)->loadaddr, (LIB)->funcdesc_ht))
104 #define DL_LOADADDR_BASE(LOADADDR) \
105   ((LOADADDR).got_value)
106
107 /* This is called from dladdr(), such that we map a function
108    descriptor's address to the function's entry point before trying to
109    find in which library it's defined.  */
110 #define DL_LOOKUP_ADDRESS(ADDRESS) (_dl_lookup_address (ADDRESS))
111
112 #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
113   (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
114
115 /* Make sure we only load libraries that use the same number of
116    general-purpose and floating-point registers the dynamic loader was
117    compiled for.  */
118 #define DL_CHECK_REG_COUNT(flags) \
119   (((flags & EF_FRV_GPR_MASK) == EF_FRV_GPR_32 ? __FRV_GPR__ == 32 : 1) \
120    && ((flags & EF_FRV_GPR_MASK) == EF_FRV_GPR_64 ? __FRV_GPR__ == 64 : 1) \
121    && ((flags & EF_FRV_FPR_MASK) == EF_FRV_FPR_32 ? __FRV_FPR__ == 32 : 1) \
122    && ((flags & EF_FRV_FPR_MASK) == EF_FRV_FPR_64 ? __FRV_FPR__ == 64 : 1) \
123    && ((flags & EF_FRV_FPR_MASK) == EF_FRV_FPR_NONE ? __FRV_FPR__ == 0 : 1))
124
125 /* We only support loading FDPIC independently-relocatable shared
126    libraries.  It probably wouldn't be too hard to support loading
127    shared libraries that require relocation by the same amount, but we
128    don't know that they exist or would be useful, and the dynamic
129    loader code could leak the whole-library map unless we keeping a
130    bit more state for DL_LOADADDR_UNMAP and DL_LIB_UNMAP, so let's
131    keep things simple for now.  */
132 #define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
133 do \
134 { \
135   if (((epnt)->e_flags & EF_FRV_FDPIC) && ! ((epnt)->e_flags & EF_FRV_PIC)) \
136     (piclib) = 2; \
137   else \
138     { \
139       _dl_internal_error_number = LD_ERROR_NOTDYN; \
140       _dl_dprintf(2, "%s: '%s' is not an FDPIC shared library" \
141                   "\n", (_dl_progname), (libname)); \
142       _dl_close(infile); \
143       return NULL; \
144     } \
145 \
146   if (! DL_CHECK_REG_COUNT ((epnt)->e_flags)) \
147     { \
148       _dl_internal_error_number = LD_ERROR_NOTDYN; \
149       _dl_dprintf(2, "%s: '%s' assumes different register counts" \
150                   "\n", (_dl_progname), (libname)); \
151       _dl_close(infile); \
152     } \
153 } \
154 while (0)
155
156 /* We want want to apply all relocations in the interpreter during
157    bootstrap.  Because of this, we have to skip the interpreter
158    relocations in _dl_parse_relocation_information(), see
159    elfinterp.c.  */
160 #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
161
162 #ifdef __NR_pread
163 #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
164   (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
165 #endif
166
167 /* We want to return to dlsym() a function descriptor if the symbol
168    turns out to be a function.  */
169 #define DL_FIND_HASH_VALUE(TPNT, TYPE_CLASS, SYM) \
170   (((TYPE_CLASS) & ELF_RTYPE_CLASS_DLSYM) \
171    && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \
172    ? _dl_funcdesc_for (DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr),    \
173                        (TPNT)->loadaddr.got_value)                           \
174    : DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr))
175
176 #define DL_GET_READY_TO_RUN_EXTRA_PARMS \
177   , struct elf32_fdpic_loadmap *dl_boot_progmap
178 #define DL_GET_READY_TO_RUN_EXTRA_ARGS \
179   , dl_boot_progmap
180
181
182
183
184 #ifdef __USE_GNU
185 # include <link.h>
186 #else
187 # define __USE_GNU
188 # include <link.h>
189 # undef __USE_GNU
190 #endif