• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <sys/exec_elf.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 #include <link.h>
41 
42 #undef PAGE_MASK
43 #undef PAGE_SIZE
44 #define PAGE_SIZE 4096
45 #define PAGE_MASK (PAGE_SIZE-1)
46 
47 /* Convenience macros to make page address/offset computations more explicit */
48 
49 /* Returns the address of the page starting at address 'x' */
50 #define PAGE_START(x)  ((x) & ~PAGE_MASK)
51 
52 /* Returns the offset of address 'x' in its memory page, i.e. this is the
53  * same than 'x' - PAGE_START(x) */
54 #define PAGE_OFFSET(x) ((x) & PAGE_MASK)
55 
56 /* Returns the address of the next page after address 'x', unless 'x' is
57  * itself at the start of a page. Equivalent to:
58  *
59  *  (x == PAGE_START(x)) ? x : PAGE_START(x)+PAGE_SIZE
60  */
61 #define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
62 
63 void debugger_init();
64 
65 /* magic shared structures that GDB knows about */
66 
67 struct link_map
68 {
69     uintptr_t l_addr;
70     char * l_name;
71     uintptr_t l_ld;
72     struct link_map * l_next;
73     struct link_map * l_prev;
74 };
75 
76 // Values for r_debug->state
77 enum {
78     RT_CONSISTENT,
79     RT_ADD,
80     RT_DELETE
81 };
82 
83 struct r_debug
84 {
85     int32_t r_version;
86     struct link_map * r_map;
87     void (*r_brk)(void);
88     int32_t r_state;
89     uintptr_t r_ldbase;
90 };
91 
92 typedef struct soinfo soinfo;
93 
94 #define FLAG_LINKED     0x00000001
95 #define FLAG_ERROR      0x00000002
96 #define FLAG_EXE        0x00000004 // The main executable
97 #define FLAG_LINKER     0x00000010 // The linker itself
98 
99 #define SOINFO_NAME_LEN 128
100 
101 struct soinfo
102 {
103     char name[SOINFO_NAME_LEN];
104     const Elf32_Phdr *phdr;
105     int phnum;
106     unsigned entry;
107     unsigned base;
108     unsigned size;
109 
110     int unused;  // DO NOT USE, maintained for compatibility.
111 
112     unsigned *dynamic;
113 
114     unsigned unused2; // DO NOT USE, maintained for compatibility
115     unsigned unused3; // DO NOT USE, maintained for compatibility
116 
117     soinfo *next;
118     unsigned flags;
119 
120     const char *strtab;
121     Elf32_Sym *symtab;
122 
123     unsigned nbucket;
124     unsigned nchain;
125     unsigned *bucket;
126     unsigned *chain;
127 
128     unsigned *plt_got;
129 
130     Elf32_Rel *plt_rel;
131     unsigned plt_rel_count;
132 
133     Elf32_Rel *rel;
134     unsigned rel_count;
135 
136     unsigned *preinit_array;
137     unsigned preinit_array_count;
138 
139     unsigned *init_array;
140     unsigned init_array_count;
141     unsigned *fini_array;
142     unsigned fini_array_count;
143 
144     void (*init_func)(void);
145     void (*fini_func)(void);
146 
147 #if defined(ANDROID_ARM_LINKER)
148     /* ARM EABI section used for stack unwinding. */
149     unsigned *ARM_exidx;
150     unsigned ARM_exidx_count;
151 #elif defined(ANDROID_MIPS_LINKER)
152 #if 0
153      /* not yet */
154      unsigned *mips_pltgot
155 #endif
156      unsigned mips_symtabno;
157      unsigned mips_local_gotno;
158      unsigned mips_gotsym;
159 #endif /* ANDROID_*_LINKER */
160 
161     unsigned refcount;
162     struct link_map linkmap;
163 
164     int constructors_called;
165 
166     /* When you read a virtual address from the ELF file, add this
167      * value to get the corresponding address in the process' address space */
168     Elf32_Addr load_bias;
169     int has_text_relocations;
170 };
171 
172 
173 extern soinfo libdl_info;
174 
175 
176 #include <asm/elf.h>
177 
178 #if defined(ANDROID_ARM_LINKER)
179 
180 // These aren't defined in <arch-arm/asm/elf.h>.
181 #define R_ARM_REL32      3
182 #define R_ARM_COPY       20
183 #define R_ARM_GLOB_DAT   21
184 #define R_ARM_JUMP_SLOT  22
185 #define R_ARM_RELATIVE   23
186 
187 #elif defined(ANDROID_MIPS_LINKER)
188 
189 // These aren't defined in <arch-arm/mips/elf.h>.
190 #define R_MIPS_JUMP_SLOT       127
191 
192 #define DT_MIPS_PLTGOT         0x70000032
193 #define DT_MIPS_RWPLT          0x70000034
194 
195 #elif defined(ANDROID_X86_LINKER)
196 
197 // x86 has everything it needs in <arch-arm/x86/elf.h>.
198 
199 #endif /* ANDROID_*_LINKER */
200 
201 #ifndef DT_INIT_ARRAY
202 #define DT_INIT_ARRAY      25
203 #endif
204 
205 #ifndef DT_FINI_ARRAY
206 #define DT_FINI_ARRAY      26
207 #endif
208 
209 #ifndef DT_INIT_ARRAYSZ
210 #define DT_INIT_ARRAYSZ    27
211 #endif
212 
213 #ifndef DT_FINI_ARRAYSZ
214 #define DT_FINI_ARRAYSZ    28
215 #endif
216 
217 #ifndef DT_PREINIT_ARRAY
218 #define DT_PREINIT_ARRAY   32
219 #endif
220 
221 #ifndef DT_PREINIT_ARRAYSZ
222 #define DT_PREINIT_ARRAYSZ 33
223 #endif
224 
225 soinfo *find_library(const char *name);
226 Elf32_Sym *lookup(const char *name, soinfo **found, soinfo *start);
227 soinfo *find_containing_library(const void *addr);
228 const char *linker_get_error(void);
229 
230 int soinfo_unload(soinfo* si);
231 Elf32_Sym *soinfo_find_symbol(soinfo* si, const void *addr);
232 Elf32_Sym *soinfo_lookup(soinfo *si, const char *name);
233 void soinfo_call_constructors(soinfo *si);
234 
235 #ifdef __cplusplus
236 };
237 #endif
238 
239 #endif
240