linker.h revision 1272dbd1d76c979358fff3beae9de0c1462345af
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 <elf.h>
33#include <link.h>
34#include <unistd.h>
35
36#include "private/libc_logging.h"
37
38#define DL_ERR(fmt, x...) \
39    do { \
40      __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
41      /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
42      DEBUG("%s\n", linker_get_error_buffer()); \
43    } while (false)
44
45#define DL_WARN(fmt, x...) \
46    do { \
47      __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \
48      __libc_format_fd(2, "WARNING: linker: "); \
49      __libc_format_fd(2, fmt, ##x); \
50      __libc_format_fd(2, "\n"); \
51    } while (false)
52
53
54// Returns the address of the page containing address 'x'.
55#define PAGE_START(x)  ((x) & PAGE_MASK)
56
57// Returns the offset of address 'x' in its page.
58#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
59
60// Returns the address of the next page after address 'x', unless 'x' is
61// itself at the start of a page.
62#define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
63
64// Magic shared structures that GDB knows about.
65
66struct link_map_t {
67  uintptr_t l_addr;
68  char*  l_name;
69  uintptr_t l_ld;
70  link_map_t* l_next;
71  link_map_t* l_prev;
72};
73
74// Values for r_debug->state
75enum {
76  RT_CONSISTENT,
77  RT_ADD,
78  RT_DELETE
79};
80
81struct r_debug {
82  int32_t r_version;
83  link_map_t* r_map;
84  void (*r_brk)(void);
85  int32_t r_state;
86  uintptr_t r_ldbase;
87};
88
89#define FLAG_LINKED     0x00000001
90#define FLAG_EXE        0x00000004 // The main executable
91#define FLAG_LINKER     0x00000010 // The linker itself
92
93#define SOINFO_NAME_LEN 128
94
95typedef void (*linker_function_t)();
96
97// Android uses REL for 32-bit but only uses RELA for 64-bit.
98#if defined(__LP64__)
99#define USE_RELA 1
100#endif
101
102struct soinfo {
103 public:
104  char name[SOINFO_NAME_LEN];
105  const Elf_Phdr* phdr;
106  size_t phnum;
107  Elf_Addr entry;
108  Elf_Addr base;
109  unsigned size;
110
111#ifndef __LP64__
112  uint32_t unused1;  // DO NOT USE, maintained for compatibility.
113#endif
114
115  Elf_Dyn* dynamic;
116
117#ifndef __LP64__
118  uint32_t unused2; // DO NOT USE, maintained for compatibility
119  uint32_t unused3; // DO NOT USE, maintained for compatibility
120#endif
121
122  soinfo* next;
123  unsigned flags;
124
125  const char* strtab;
126  Elf_Sym* symtab;
127
128  size_t nbucket;
129  size_t nchain;
130  unsigned* bucket;
131  unsigned* chain;
132
133#if !defined(__LP64__)
134  // This is only used by 32-bit MIPS, but needs to be here for
135  // all 32-bit architectures to preserve binary compatibility.
136  unsigned* plt_got;
137#endif
138
139#if defined(USE_RELA)
140  Elf_Rela* plt_rela;
141  size_t plt_rela_count;
142
143  Elf_Rela* rela;
144  size_t rela_count;
145#else
146  Elf_Rel* plt_rel;
147  size_t plt_rel_count;
148
149  Elf_Rel* rel;
150  size_t rel_count;
151#endif
152
153  linker_function_t* preinit_array;
154  size_t preinit_array_count;
155
156  linker_function_t* init_array;
157  size_t init_array_count;
158  linker_function_t* fini_array;
159  size_t fini_array_count;
160
161  linker_function_t init_func;
162  linker_function_t fini_func;
163
164#if defined(__arm__)
165  // ARM EABI section used for stack unwinding.
166  unsigned* ARM_exidx;
167  size_t ARM_exidx_count;
168#elif defined(__mips__)
169  unsigned mips_symtabno;
170  unsigned mips_local_gotno;
171  unsigned mips_gotsym;
172#endif
173
174  size_t ref_count;
175  link_map_t link_map;
176
177  bool constructors_called;
178
179  // When you read a virtual address from the ELF file, add this
180  // value to get the corresponding address in the process' address space.
181  Elf_Addr load_bias;
182
183#if !defined(__LP64__)
184  bool has_text_relocations;
185#endif
186  bool has_DT_SYMBOLIC;
187
188  void CallConstructors();
189  void CallDestructors();
190  void CallPreInitConstructors();
191
192 private:
193  void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
194  void CallFunction(const char* function_name, linker_function_t function);
195};
196
197extern soinfo libdl_info;
198
199void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
200soinfo* do_dlopen(const char* name, int flags);
201int do_dlclose(soinfo* si);
202
203Elf_Sym* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* start);
204soinfo* find_containing_library(const void* addr);
205
206Elf_Sym* dladdr_find_symbol(soinfo* si, const void* addr);
207Elf_Sym* dlsym_handle_lookup(soinfo* si, const char* name);
208
209void debuggerd_init();
210extern "C" abort_msg_t* gAbortMessage;
211extern "C" void notify_gdb_of_libraries();
212
213char* linker_get_error_buffer();
214size_t linker_get_error_buffer_size();
215
216#endif
217