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 | #define FLAG_LINKER 0x00000010 // The linker itself | |
87 | ||
88 | #define SOINFO_NAME_LEN 128 | |
89 | ||
90 | struct soinfo | |
91 | { | |
92 | const char name[SOINFO_NAME_LEN]; | |
93 | Elf32_Phdr *phdr; | |
94 | int phnum; | |
95 | unsigned entry; | |
96 | unsigned base; | |
97 | unsigned size; | |
98 | ||
99 | int unused; // DO NOT USE, maintained for compatibility. | |
100 | ||
101 | unsigned *dynamic; | |
102 | ||
103 | unsigned wrprotect_start; | |
104 | unsigned wrprotect_end; | |
105 | ||
106 | soinfo *next; | |
107 | unsigned flags; | |
108 | ||
109 | const char *strtab; | |
110 | Elf32_Sym *symtab; | |
111 | ||
112 | unsigned nbucket; | |
113 | unsigned nchain; | |
114 | unsigned *bucket; | |
115 | unsigned *chain; | |
116 | ||
117 | unsigned *plt_got; | |
118 | ||
119 | Elf32_Rel *plt_rel; | |
120 | unsigned plt_rel_count; | |
121 | ||
122 | Elf32_Rel *rel; | |
123 | unsigned rel_count; | |
124 | ||
125 | unsigned *preinit_array; | |
126 | unsigned preinit_array_count; | |
127 | ||
128 | unsigned *init_array; | |
129 | unsigned init_array_count; | |
130 | unsigned *fini_array; | |
131 | unsigned fini_array_count; | |
132 | ||
133 | void (*init_func)(void); | |
134 | void (*fini_func)(void); | |
135 | ||
136 | #ifdef ANDROID_ARM_LINKER | |
137 | /* ARM EABI section used for stack unwinding. */ | |
138 | unsigned *ARM_exidx; | |
139 | unsigned ARM_exidx_count; | |
140 | #endif | |
141 | ||
142 | unsigned refcount; | |
143 | struct link_map linkmap; | |
144 | ||
145 | int constructors_called; | |
146 | ||
147 | Elf32_Addr gnu_relro_start; | |
148 | unsigned gnu_relro_len; | |
149 | ||
150 | }; | |
151 | ||
152 | ||
153 | extern soinfo libdl_info; | |
154 | ||
155 | #ifdef ANDROID_ARM_LINKER | |
156 | ||
157 | #define R_ARM_COPY 20 | |
158 | #define R_ARM_GLOB_DAT 21 | |
159 | #define R_ARM_JUMP_SLOT 22 | |
160 | #define R_ARM_RELATIVE 23 | |
161 | ||
162 | /* According to the AAPCS specification, we only | |
163 | * need the above relocations. However, in practice, | |
164 | * the following ones turn up from time to time. | |
165 | */ | |
166 | #define R_ARM_ABS32 2 | |
167 | #define R_ARM_REL32 3 | |
168 | ||
169 | #elif defined(ANDROID_X86_LINKER) | |
170 | ||
171 | #define R_386_32 1 | |
172 | #define R_386_PC32 2 | |
173 | #define R_386_GLOB_DAT 6 | |
174 | #define R_386_JUMP_SLOT 7 | |
175 | #define R_386_RELATIVE 8 | |
176 | ||
177 | #endif | |
178 | ||
179 | #ifndef DT_INIT_ARRAY | |
180 | #define DT_INIT_ARRAY 25 | |
181 | #endif | |
182 | ||
183 | #ifndef DT_FINI_ARRAY | |
184 | #define DT_FINI_ARRAY 26 | |
185 | #endif | |
186 | ||
187 | #ifndef DT_INIT_ARRAYSZ | |
188 | #define DT_INIT_ARRAYSZ 27 | |
189 | #endif | |
190 | ||
191 | #ifndef DT_FINI_ARRAYSZ | |
192 | #define DT_FINI_ARRAYSZ 28 | |
193 | #endif | |
194 | ||
195 | #ifndef DT_PREINIT_ARRAY | |
196 | #define DT_PREINIT_ARRAY 32 | |
197 | #endif | |
198 | ||
199 | #ifndef DT_PREINIT_ARRAYSZ | |
200 | #define DT_PREINIT_ARRAYSZ 33 | |
201 | #endif | |
202 | ||
203 | soinfo *find_library(const char *name); | |
204 | unsigned unload_library(soinfo *si); | |
205 | Elf32_Sym *lookup_in_library(soinfo *si, const char *name); | |
206 | Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start); | |
207 | soinfo *find_containing_library(const void *addr); | |
208 | Elf32_Sym *find_containing_symbol(const void *addr, soinfo *si); | |
209 | const char *linker_get_error(void); | |
210 | void call_constructors_recursive(soinfo *si); | |
211 | ||
212 | #ifdef ANDROID_ARM_LINKER | |
213 | typedef long unsigned int *_Unwind_Ptr; | |
214 | _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr pc, int *pcount); | |
215 | #elif defined(ANDROID_X86_LINKER) | |
216 | int dl_iterate_phdr(int (*cb)(struct dl_phdr_info *, size_t, void *), void *); | |
217 | #endif | |
218 | ||
219 | #endif |