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