linker.h revision 422106a24d620af4be58e8d92a2e9b7b6167b72d
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#include <android/dlext.h>
36#include <sys/stat.h>
37
38#include "private/libc_logging.h"
39#include "linked_list.h"
40
41#define DL_ERR(fmt, x...) \
42    do { \
43      __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
44      /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
45      DEBUG("%s\n", linker_get_error_buffer()); \
46    } while (false)
47
48#define DL_WARN(fmt, x...) \
49    do { \
50      __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \
51      __libc_format_fd(2, "WARNING: linker: "); \
52      __libc_format_fd(2, fmt, ##x); \
53      __libc_format_fd(2, "\n"); \
54    } while (false)
55
56#if defined(__LP64__)
57#define ELFW(what) ELF64_ ## what
58#else
59#define ELFW(what) ELF32_ ## what
60#endif
61
62// mips64 interprets Elf64_Rel structures' r_info field differently.
63// bionic (like other C libraries) has macros that assume regular ELF files,
64// but the dynamic linker needs to be able to load mips64 ELF files.
65#if defined(__mips__) && defined(__LP64__)
66#undef ELF64_R_SYM
67#undef ELF64_R_TYPE
68#undef ELF64_R_INFO
69#define ELF64_R_SYM(info)   (((info) >> 0) & 0xffffffff)
70#define ELF64_R_SSYM(info)  (((info) >> 32) & 0xff)
71#define ELF64_R_TYPE3(info) (((info) >> 40) & 0xff)
72#define ELF64_R_TYPE2(info) (((info) >> 48) & 0xff)
73#define ELF64_R_TYPE(info)  (((info) >> 56) & 0xff)
74#endif
75
76// Returns the address of the page containing address 'x'.
77#define PAGE_START(x)  ((x) & PAGE_MASK)
78
79// Returns the offset of address 'x' in its page.
80#define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
81
82// Returns the address of the next page after address 'x', unless 'x' is
83// itself at the start of a page.
84#define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
85
86#define FLAG_LINKED     0x00000001
87#define FLAG_EXE        0x00000004 // The main executable
88#define FLAG_LINKER     0x00000010 // The linker itself
89#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
90
91#define SOINFO_NAME_LEN 128
92
93typedef void (*linker_function_t)();
94
95// Android uses RELA for aarch64 and x86_64. mips64 still uses REL.
96#if defined(__aarch64__) || defined(__x86_64__)
97#define USE_RELA 1
98#endif
99
100struct soinfo;
101
102class SoinfoListAllocator {
103public:
104  static LinkedListEntry<soinfo>* alloc();
105  static void free(LinkedListEntry<soinfo>* entry);
106private:
107  // unconstructable
108  DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
109};
110
111struct soinfo {
112 public:
113  typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
114 public:
115  char name[SOINFO_NAME_LEN];
116  const ElfW(Phdr)* phdr;
117  size_t phnum;
118  ElfW(Addr) entry;
119  ElfW(Addr) base;
120  size_t size;
121
122#ifndef __LP64__
123  uint32_t unused1;  // DO NOT USE, maintained for compatibility.
124#endif
125
126  ElfW(Dyn)* dynamic;
127
128#ifndef __LP64__
129  uint32_t unused2; // DO NOT USE, maintained for compatibility
130  uint32_t unused3; // DO NOT USE, maintained for compatibility
131#endif
132
133  soinfo* next;
134  unsigned flags;
135
136  const char* strtab;
137  ElfW(Sym)* symtab;
138
139  size_t nbucket;
140  size_t nchain;
141  unsigned* bucket;
142  unsigned* chain;
143
144#if defined(__mips__) || !defined(__LP64__)
145  // This is only used by mips and mips64, but needs to be here for
146  // all 32-bit architectures to preserve binary compatibility.
147  ElfW(Addr)** plt_got;
148#endif
149
150#if defined(USE_RELA)
151  ElfW(Rela)* plt_rela;
152  size_t plt_rela_count;
153
154  ElfW(Rela)* rela;
155  size_t rela_count;
156#else
157  ElfW(Rel)* plt_rel;
158  size_t plt_rel_count;
159
160  ElfW(Rel)* rel;
161  size_t rel_count;
162#endif
163
164  linker_function_t* preinit_array;
165  size_t preinit_array_count;
166
167  linker_function_t* init_array;
168  size_t init_array_count;
169  linker_function_t* fini_array;
170  size_t fini_array_count;
171
172  linker_function_t init_func;
173  linker_function_t fini_func;
174
175#if defined(__arm__)
176  // ARM EABI section used for stack unwinding.
177  unsigned* ARM_exidx;
178  size_t ARM_exidx_count;
179#elif defined(__mips__)
180  unsigned mips_symtabno;
181  unsigned mips_local_gotno;
182  unsigned mips_gotsym;
183#endif
184
185  size_t ref_count;
186  link_map link_map_head;
187
188  bool constructors_called;
189
190  // When you read a virtual address from the ELF file, add this
191  // value to get the corresponding address in the process' address space.
192  ElfW(Addr) load_bias;
193
194#if !defined(__LP64__)
195  bool has_text_relocations;
196#endif
197  bool has_DT_SYMBOLIC;
198  void CallConstructors();
199  void CallDestructors();
200  void CallPreInitConstructors();
201
202  void add_child(soinfo* child);
203  void remove_all_links();
204
205  void set_st_dev(dev_t st_dev);
206  void set_st_ino(ino_t st_ino);
207  ino_t get_st_ino();
208  dev_t get_st_dev();
209
210  soinfo_list_t& get_children();
211
212 private:
213  void CallArray(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
214  void CallFunction(const char* function_name, linker_function_t function);
215
216 private:
217  // This part of the structure is only available
218  // when FLAG_NEW_SOINFO is set in this->flags.
219  unsigned int version;
220
221  dev_t st_dev;
222  ino_t st_ino;
223
224  // dependency graph
225  soinfo_list_t children;
226  soinfo_list_t parents;
227
228};
229
230extern soinfo* get_libdl_info();
231
232void do_android_get_LD_LIBRARY_PATH(char*, size_t);
233void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
234soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
235void do_dlclose(soinfo* si);
236
237ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* start, soinfo* caller_si);
238soinfo* find_containing_library(const void* addr);
239
240ElfW(Sym)* dladdr_find_symbol(soinfo* si, const void* addr);
241ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name, soinfo* caller_si);
242
243void debuggerd_init();
244extern "C" abort_msg_t* g_abort_message;
245extern "C" void notify_gdb_of_libraries();
246
247char* linker_get_error_buffer();
248size_t linker_get_error_buffer_size();
249
250#endif
251