OSDN Git Service

Make do_rem() safe. From Peter Kjellerstedt.
[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 This file is part of uClibc.
6
7 uClibc is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
11
12 uClibc is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with uClibc; see the file COPYING.LIB.  If not, write to
19 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
20 USA.  */
21
22 /*
23  * Various assembly language/system dependent  hacks that are required
24  * so that we can minimize the amount of platform specific code.
25  */
26
27 /*
28  * Define this if the system uses RELOCA.
29  */
30 #undef ELF_USES_RELOCA
31
32 /* JMPREL relocs are inside the DT_RELA table.  */
33 #define ELF_MACHINE_PLTREL_OVERLAP
34
35 #define DL_NO_COPY_RELOCS
36
37 /*
38  * Initialization sequence for a GOT.  Copy the resolver function
39  * descriptor and the pointer to the elf_resolve/link_map data
40  * structure.  Initialize the got_value in the module while at that.
41  */
42 #define INIT_GOT(GOT_BASE,MODULE) \
43 {                               \
44   (MODULE)->loadaddr.got_value = (GOT_BASE); \
45   GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \
46   GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \
47   GOT_BASE[2] = (unsigned long) MODULE; \
48 }
49
50 /* Here we define the magic numbers that this dynamic loader should accept */
51 #define MAGIC1 EM_CYGNUS_FRV
52 #undef  MAGIC2
53
54 /* Used for error messages */
55 #define ELF_TARGET "FR-V"
56
57 struct elf_resolve;
58
59 struct funcdesc_value
60 {
61   void *entry_point;
62   void *got_value;
63 } __attribute__((__aligned__(8)));
64
65
66 extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
67
68 #define do_rem(result, n, base) ((result) = (n) % (base))
69
70 /* 16KiB page alignment.  Should perhaps be made dynamic using
71    getpagesize(), based on AT_PAGESZ from auxvt?  */
72 #define PAGE_ALIGN 0xffffc000
73 #define ADDR_ALIGN 0x3fff
74 #define OFFS_ALIGN 0x7fffc000
75
76 struct funcdesc_ht;
77
78 /* We must force strings used early in the bootstrap into the data
79    segment, such that they are referenced with GOTOFF instead of
80    GPREL, because GPREL needs the GOT to have already been
81    relocated.  */
82 #undef SEND_EARLY_STDERR
83 #define SEND_EARLY_STDERR(S) \
84   do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
85
86 #define DL_LOADADDR_TYPE struct elf32_fdpic_loadaddr
87
88 #define DL_RELOC_ADDR(ADDR, LOADADDR) \
89   (__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
90
91 #define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) \
92   ((void(*)(void)) _dl_funcdesc_for ((void*)(ADDR), (LOADADDR).got_value))
93
94 #define _dl_stabilize_funcdesc(val) \
95   ({ asm ("" : "+m" (*(val))); (val); })
96
97 #define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \
98   ({ struct funcdesc_value fd = { (void*)(ADDR), (LOADADDR).got_value }; \
99      void (*pf)(void) = (void*) _dl_stabilize_funcdesc (&fd); \
100      (* SIGNATURE pf)(__VA_ARGS__); })
101
102 #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
103   (__dl_init_loadaddr_map (&(LOADADDR), dl_boot_got_pointer, \
104                            dl_boot_ldsomap ?: dl_boot_progmap))
105
106 #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
107   (__dl_init_loadaddr_map (&(LOADADDR), 0, dl_boot_progmap))
108
109 #define DL_INIT_LOADADDR_EXTRA_DECLS \
110   int dl_init_loadaddr_load_count;
111 #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
112   (dl_init_loadaddr_load_count = \
113      __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
114 #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
115   (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
116                            dl_init_loadaddr_load_count))
117 #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
118   (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
119 #define DL_LIB_UNMAP(LIB, LEN) \
120   (__dl_loadaddr_unmap ((LIB)->loadaddr, (LIB)->funcdesc_ht))
121 #define DL_LOADADDR_BASE(LOADADDR) \
122   ((LOADADDR).got_value)
123
124 /* This is called from dladdr(), such that we map a function
125    descriptor's address to the function's entry point before trying to
126    find in which library it's defined.  */
127 #define DL_LOOKUP_ADDRESS(ADDRESS) (_dl_lookup_address (ADDRESS))
128
129 #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
130   (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
131
132 /* We only support loading FDPIC independently-relocatable shared
133    libraries.  It probably wouldn't be too hard to support loading
134    shared libraries that require relocation by the same amount, but we
135    don't know that they exist or would be useful, and the dynamic
136    loader code could leak the whole-library map unless we keeping a
137    bit more state for DL_LOADADDR_UNMAP and DL_LIB_UNMAP, so let's
138    keep things simple for now.  */
139 #define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
140 do \
141 { \
142   if (((epnt)->e_flags & EF_FRV_FDPIC) && ! ((epnt)->e_flags & EF_FRV_PIC)) \
143     (piclib) = 2; \
144   else \
145     { \
146       _dl_internal_error_number = LD_ERROR_NOTDYN; \
147       _dl_dprintf(2, "%s: '%s' is not an FDPIC shared library" \
148                   "\n", (_dl_progname), (libname)); \
149       _dl_close(infile); \
150       return NULL; \
151     } \
152 } \
153 while (0)  
154
155 /* We want want to apply all relocations in the interpreter during
156    bootstrap.  Because of this, we have to skip the interpreter
157    relocations in _dl_parse_relocation_information(), see
158    elfinterp.c.  */
159 #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
160
161 #ifdef __NR_pread
162 #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
163   (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
164 #endif
165
166 /* We want to return to dlsym() a function descriptor if the symbol
167    turns out to be a function.  */
168 #define DL_FIND_HASH_VALUE(TPNT, TYPE_CLASS, SYM) \
169   (((TYPE_CLASS) & ELF_RTYPE_CLASS_DLSYM) \
170    && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \
171    ? _dl_funcdesc_for (DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr),    \
172                        (TPNT)->loadaddr.got_value)                           \
173    : DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr))
174
175 #ifdef __USE_GNU
176 # include <link.h>
177 #else
178 # define __USE_GNU
179 # include <link.h>
180 # undef __USE_GNU
181 #endif