Commit | Line | Data |
---|---|---|
d42e7319 JB |
1 | /* |
2 | * Copyright (C) 2008 The Android Open Source Project | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * * Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * * Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in | |
12 | * the documentation and/or other materials provided with the | |
13 | * distribution. | |
14 | * | |
15 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
16 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
17 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
18 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
19 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | |
22 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |
25 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
26 | * SUCH DAMAGE. | |
27 | */ | |
28 | ||
29 | #ifndef _LINKER_H_ | |
30 | #define _LINKER_H_ | |
31 | ||
32 | #include <unistd.h> | |
33 | #include <sys/types.h> | |
34 | #include <elf.h> | |
35 | ||
36 | #undef PAGE_MASK | |
37 | #undef PAGE_SIZE | |
38 | #define PAGE_SIZE 4096 | |
39 | #define PAGE_MASK 4095 | |
40 | ||
41 | void debugger_init(); | |
42 | const char *addr_to_name(unsigned addr); | |
43 | ||
44 | /* magic shared structures that GDB knows about */ | |
45 | ||
46 | struct link_map | |
47 | { | |
48 | uintptr_t l_addr; | |
49 | char * l_name; | |
50 | uintptr_t l_ld; | |
51 | struct link_map * l_next; | |
52 | struct link_map * l_prev; | |
53 | }; | |
54 | ||
55 | /* needed for dl_iterate_phdr to be passed to the callbacks provided */ | |
56 | struct dl_phdr_info | |
57 | { | |
58 | Elf32_Addr dlpi_addr; | |
59 | const char *dlpi_name; | |
60 | const Elf32_Phdr *dlpi_phdr; | |
61 | Elf32_Half dlpi_phnum; | |
62 | }; | |
63 | ||
64 | ||
65 | // Values for r_debug->state | |
66 | enum { | |
67 | RT_CONSISTENT, | |
68 | RT_ADD, | |
69 | RT_DELETE | |
70 | }; | |
71 | ||
72 | struct r_debug | |
73 | { | |
74 | int32_t r_version; | |
75 | struct link_map * r_map; | |
76 | void (*r_brk)(void); | |
77 | int32_t r_state; | |
78 | uintptr_t r_ldbase; | |
79 | }; | |
80 | ||
81 | typedef struct soinfo soinfo; | |
82 | ||
83 | #define FLAG_LINKED 0x00000001 | |
84 | #define FLAG_ERROR 0x00000002 | |
85 | #define FLAG_EXE 0x00000004 // The main executable | |
86 | ||
87 | #define SOINFO_NAME_LEN 128 | |
88 | ||
89 | struct soinfo | |
90 | { | |
91 | const char name[SOINFO_NAME_LEN]; | |
92 | Elf32_Phdr *phdr; | |
93 | int phnum; | |
94 | unsigned entry; | |
95 | unsigned base; | |
96 | unsigned size; | |
97 | ||
98 | int unused; // DO NOT USE, maintained for compatibility. | |
99 | ||
100 | unsigned *dynamic; | |
101 | ||
102 | unsigned wrprotect_start; | |
103 | unsigned wrprotect_end; | |
104 | ||
105 | soinfo *next; | |
106 | unsigned flags; | |
107 | ||
108 | const char *strtab; | |
109 | Elf32_Sym *symtab; | |
110 | ||
111 | unsigned nbucket; | |
112 | unsigned nchain; | |
113 | unsigned *bucket; | |
114 | unsigned *chain; | |
115 | ||
116 | unsigned *plt_got; | |
117 | ||
118 | Elf32_Rel *plt_rel; | |
119 | unsigned plt_rel_count; | |
120 | ||
121 | Elf32_Rel *rel; | |
122 | unsigned rel_count; | |
123 | ||
124 | #ifdef ANDROID_SH_LINKER | |
125 | Elf32_Rela *plt_rela; | |
126 | unsigned plt_rela_count; | |
127 | ||
128 | Elf32_Rela *rela; | |
129 | unsigned rela_count; | |
130 | #endif /* ANDROID_SH_LINKER */ | |
131 | ||
132 | unsigned *preinit_array; | |
133 | unsigned preinit_array_count; | |
134 | ||
135 | unsigned *init_array; | |
136 | unsigned init_array_count; | |
137 | unsigned *fini_array; | |
138 | unsigned fini_array_count; | |
139 | ||
140 | void (*init_func)(void); | |
141 | void (*fini_func)(void); | |
142 | ||
143 | #ifdef ANDROID_ARM_LINKER | |
144 | /* ARM EABI section used for stack unwinding. */ | |
145 | unsigned *ARM_exidx; | |
146 | unsigned ARM_exidx_count; | |
147 | #endif | |
148 | ||
149 | unsigned refcount; | |
150 | struct link_map linkmap; | |
151 | }; | |
152 | ||
153 | ||
154 | extern soinfo libdl_info; | |
155 | ||
156 | #ifdef ANDROID_ARM_LINKER | |
157 | ||
158 | #define R_ARM_COPY 20 | |
159 | #define R_ARM_GLOB_DAT 21 | |
160 | #define R_ARM_JUMP_SLOT 22 | |
161 | #define R_ARM_RELATIVE 23 | |
162 | ||
163 | /* According to the AAPCS specification, we only | |
164 | * need the above relocations. However, in practice, | |
165 | * the following ones turn up from time to time. | |
166 | */ | |
167 | #define R_ARM_ABS32 2 | |
168 | #define R_ARM_REL32 3 | |
169 | ||
170 | #elif defined(ANDROID_X86_LINKER) | |
171 | ||
172 | #define R_386_32 1 | |
173 | #define R_386_PC32 2 | |
174 | #define R_386_GLOB_DAT 6 | |
175 | #define R_386_JUMP_SLOT 7 | |
176 | #define R_386_RELATIVE 8 | |
177 | ||
178 | #elif defined(ANDROID_SH_LINKER) | |
179 | ||
180 | #define R_SH_DIR32 1 | |
181 | #define R_SH_GLOB_DAT 163 | |
182 | #define R_SH_JUMP_SLOT 164 | |
183 | #define R_SH_RELATIVE 165 | |
184 | ||
185 | #endif /* ANDROID_*_LINKER */ | |
186 | ||
187 | ||
188 | #ifndef DT_INIT_ARRAY | |
189 | #define DT_INIT_ARRAY 25 | |
190 | #endif | |
191 | ||
192 | #ifndef DT_FINI_ARRAY | |
193 | #define DT_FINI_ARRAY 26 | |
194 | #endif | |
195 | ||
196 | #ifndef DT_INIT_ARRAYSZ | |
197 | #define DT_INIT_ARRAYSZ 27 | |
198 | #endif | |
199 | ||
200 | #ifndef DT_FINI_ARRAYSZ | |
201 | #define DT_FINI_ARRAYSZ 28 | |
202 | #endif | |
203 | ||
204 | #ifndef DT_PREINIT_ARRAY | |
205 | #define DT_PREINIT_ARRAY 32 | |
206 | #endif | |
207 | ||
208 | #ifndef DT_PREINIT_ARRAYSZ | |
209 | #define DT_PREINIT_ARRAYSZ 33 | |
210 | #endif | |
211 | ||
212 | soinfo *find_library(const char *name); | |
213 | unsigned unload_library(soinfo *si); | |
214 | Elf32_Sym *lookup_in_library(soinfo *si, const char *name); | |
215 | Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start); | |
216 | soinfo *find_containing_library(const void *addr); | |
217 | Elf32_Sym *find_containing_symbol(const void *addr, soinfo *si); | |
218 | const char *linker_get_error(void); | |
219 | ||
220 | #ifdef ANDROID_ARM_LINKER | |
221 | typedef long unsigned int *_Unwind_Ptr; | |
222 | _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount); | |
223 | #elif defined(ANDROID_X86_LINKER) || defined(ANDROID_SH_LINKER) | |
224 | int dl_iterate_phdr(int (*cb)(struct dl_phdr_info *, size_t, void *), void *); | |
225 | #endif | |
226 | ||
227 | #endif |