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