OSDN Git Service

use new __always_inline define
[uclinux-h8/uClibc.git] / ldso / include / dl-elf.h
1 #ifndef LINUXELF_H
2 #define LINUXELF_H
3
4 #include <dl-string.h> /* before elf.h to get ELF_USES_RELOCA right */
5 #include <elf.h>
6 #include <link.h>
7
8 /* Forward declarations for stuff defined in ld_hash.h */
9 struct dyn_elf;
10 struct elf_resolve;
11
12 #include <dl-defs.h>
13 #ifdef __LDSO_CACHE_SUPPORT__
14 extern int _dl_map_cache(void);
15 extern int _dl_unmap_cache(void);
16 #else
17 static inline void _dl_map_cache(void) { }
18 static inline void _dl_unmap_cache(void) { }
19 #endif
20
21
22 /* Function prototypes for non-static stuff in readelflib1.c */
23 extern void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
24         unsigned long rel_addr, unsigned long rel_size);
25 extern int _dl_parse_relocation_information(struct dyn_elf *rpnt,
26         unsigned long rel_addr, unsigned long rel_size);
27 extern struct elf_resolve * _dl_load_shared_library(int secure,
28         struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname,
29         int trace_loaded_objects);
30 extern struct elf_resolve * _dl_load_elf_shared_library(int secure,
31         struct dyn_elf **rpnt, char *libname);
32 extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname,
33         int trace_loaded_objects);
34 extern int _dl_linux_resolve(void);
35 extern int _dl_fixup(struct dyn_elf *rpnt, int flag);
36 extern void _dl_protect_relro (struct elf_resolve *l);
37
38 /*
39  * Bitsize related settings for things ElfW()
40  * does not handle already
41  */
42 #if __WORDSIZE == 64
43 # define ELF_ST_BIND(val) ELF64_ST_TYPE(val)
44 # define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
45 # define ELF_R_SYM(i)     ELF64_R_SYM(i)
46 # ifndef ELF_CLASS
47 #  define ELF_CLASS ELFCLASS64
48 # endif
49 #else
50 # define ELF_ST_BIND(val) ELF32_ST_TYPE(val)
51 # define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
52 # define ELF_R_SYM(i)     ELF32_R_SYM(i)
53 # ifndef ELF_CLASS
54 #  define ELF_CLASS ELFCLASS32
55 # endif
56 #endif
57
58 /*
59  * Datatype of a relocation on this platform
60  */
61 #ifdef ELF_USES_RELOCA
62 # define ELF_RELOC      ElfW(Rela)
63 # define DT_RELOC_TABLE_ADDR    DT_RELA
64 # define DT_RELOC_TABLE_SIZE    DT_RELASZ
65 # define DT_RELOCCOUNT          DT_RELACOUNT
66 # define UNSUPPORTED_RELOC_TYPE DT_REL
67 # define UNSUPPORTED_RELOC_STR  "REL"
68 #else
69 # define ELF_RELOC      ElfW(Rel)
70 # define DT_RELOC_TABLE_ADDR    DT_REL
71 # define DT_RELOC_TABLE_SIZE    DT_RELSZ
72 # define DT_RELOCCOUNT          DT_RELCOUNT
73 # define UNSUPPORTED_RELOC_TYPE DT_RELA
74 # define UNSUPPORTED_RELOC_STR  "RELA"
75 #endif
76
77 /* OS and/or GNU dynamic extensions */
78 #define OS_NUM 1
79 #define DT_RELCONT_IDX DT_NUM
80
81 #ifndef ARCH_DYNAMIC_INFO
82   /* define in arch specific code, if needed */
83 # define ARCH_NUM 0
84 #endif
85
86 #define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM)
87
88 extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off);
89
90 static __always_inline
91 void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off)
92 {
93         for (; dpnt->d_tag; dpnt++) {
94                 if (dpnt->d_tag < DT_NUM) {
95                         dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
96 #ifndef __mips__
97                         if (dpnt->d_tag == DT_DEBUG)
98                                 dpnt->d_un.d_val = (unsigned long)debug_addr;
99 #endif
100                         if (dpnt->d_tag == DT_BIND_NOW)
101                                 dynamic_info[DT_BIND_NOW] = 1;
102                         if (dpnt->d_tag == DT_FLAGS &&
103                             (dpnt->d_un.d_val & DF_BIND_NOW))
104                                 dynamic_info[DT_BIND_NOW] = 1;
105                         if (dpnt->d_tag == DT_TEXTREL)
106                                 dynamic_info[DT_TEXTREL] = 1;
107                         if (dpnt->d_tag == DT_RUNPATH)
108                                 dynamic_info[DT_RPATH] = 0;
109                         if (dpnt->d_tag == DT_RPATH && dynamic_info[DT_RUNPATH])
110                                 dynamic_info[DT_RPATH] = 0;
111                 } else if (dpnt->d_tag < DT_LOPROC) {
112                         if (dpnt->d_tag == DT_RELOCCOUNT)
113                                 dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val;
114                         if (dpnt->d_tag == DT_FLAGS_1 &&
115                             (dpnt->d_un.d_val & DF_1_NOW))
116                                 dynamic_info[DT_BIND_NOW] = 1;
117                 }
118 #ifdef ARCH_DYNAMIC_INFO
119                 else {
120                         ARCH_DYNAMIC_INFO(dpnt, dynamic_info, debug_addr);
121                 }
122 #endif
123         }
124 # define ADJUST_DYN_INFO(tag, load_off) \
125         do { \
126                 if (dynamic_info[tag]) \
127                         dynamic_info[tag] += load_off; \
128         } while(0)
129
130       ADJUST_DYN_INFO (DT_HASH, load_off);
131       ADJUST_DYN_INFO (DT_PLTGOT, load_off);
132       ADJUST_DYN_INFO (DT_STRTAB, load_off);
133       ADJUST_DYN_INFO (DT_SYMTAB, load_off);
134       ADJUST_DYN_INFO (DT_RELOC_TABLE_ADDR, load_off);
135       ADJUST_DYN_INFO (DT_JMPREL, load_off);
136 # undef ADJUST_DYN_INFO
137
138                                             }
139
140 /* Reloc type classes as returned by elf_machine_type_class().
141    ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by
142    some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be
143    satisfied by any symbol in the executable.  Some architectures do
144    not support copy relocations.  In this case we define the macro to
145    zero so that the code for handling them gets automatically optimized
146    out.  */
147 #ifdef DL_NO_COPY_RELOCS
148 # define ELF_RTYPE_CLASS_COPY   (0x0)
149 #else
150 # define ELF_RTYPE_CLASS_COPY   (0x2)
151 #endif
152 #define ELF_RTYPE_CLASS_PLT     (0x1)
153
154
155 /* Convert between the Linux flags for page protections and the
156    ones specified in the ELF standard. */
157 #define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \
158                     (((X) & PF_W) ? PROT_WRITE : 0) | \
159                     (((X) & PF_X) ? PROT_EXEC : 0))
160
161
162 #endif  /* LINUXELF_H */