• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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_SOINFO_H
30 #define __LINKER_SOINFO_H
31 
32 #include <link.h>
33 
34 #include <string>
35 
36 #include "linker_namespaces.h"
37 
38 #define FLAG_LINKED           0x00000001
39 #define FLAG_EXE              0x00000004 // The main executable
40 #define FLAG_LINKER           0x00000010 // The linker itself
41 #define FLAG_GNU_HASH         0x00000040 // uses gnu hash
42 #define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller
43                                          // and should not be unmapped
44 #define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
45 
46 #define SOINFO_VERSION 3
47 
48 typedef void (*linker_dtor_function_t)();
49 typedef void (*linker_ctor_function_t)(int, char**, char**);
50 
51 class SymbolName {
52  public:
SymbolName(const char * name)53   explicit SymbolName(const char* name)
54       : name_(name), has_elf_hash_(false), has_gnu_hash_(false),
55         elf_hash_(0), gnu_hash_(0) { }
56 
get_name()57   const char* get_name() {
58     return name_;
59   }
60 
61   uint32_t elf_hash();
62   uint32_t gnu_hash();
63 
64  private:
65   const char* name_;
66   bool has_elf_hash_;
67   bool has_gnu_hash_;
68   uint32_t elf_hash_;
69   uint32_t gnu_hash_;
70 
71   DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName);
72 };
73 
74 struct version_info {
version_infoversion_info75   constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
76 
77   uint32_t elf_hash;
78   const char* name;
79   const soinfo* target_si;
80 };
81 
82 // TODO(dimitry): remove reference from soinfo member functions to this class.
83 class VersionTracker;
84 
85 #if defined(__work_around_b_24465209__)
86 #define SOINFO_NAME_LEN 128
87 #endif
88 
89 struct soinfo {
90 #if defined(__work_around_b_24465209__)
91  private:
92   char old_name_[SOINFO_NAME_LEN];
93 #endif
94  public:
95   const ElfW(Phdr)* phdr;
96   size_t phnum;
97 #if defined(__work_around_b_24465209__)
98   ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility.
99 #endif
100   ElfW(Addr) base;
101   size_t size;
102 
103 #if defined(__work_around_b_24465209__)
104   uint32_t unused1;  // DO NOT USE, maintained for compatibility.
105 #endif
106 
107   ElfW(Dyn)* dynamic;
108 
109 #if defined(__work_around_b_24465209__)
110   uint32_t unused2; // DO NOT USE, maintained for compatibility
111   uint32_t unused3; // DO NOT USE, maintained for compatibility
112 #endif
113 
114   soinfo* next;
115  private:
116   uint32_t flags_;
117 
118   const char* strtab_;
119   ElfW(Sym)* symtab_;
120 
121   size_t nbucket_;
122   size_t nchain_;
123   uint32_t* bucket_;
124   uint32_t* chain_;
125 
126 #if defined(__mips__) || !defined(__LP64__)
127   // This is only used by mips and mips64, but needs to be here for
128   // all 32-bit architectures to preserve binary compatibility.
129   ElfW(Addr)** plt_got_;
130 #endif
131 
132 #if defined(USE_RELA)
133   ElfW(Rela)* plt_rela_;
134   size_t plt_rela_count_;
135 
136   ElfW(Rela)* rela_;
137   size_t rela_count_;
138 #else
139   ElfW(Rel)* plt_rel_;
140   size_t plt_rel_count_;
141 
142   ElfW(Rel)* rel_;
143   size_t rel_count_;
144 #endif
145 
146   linker_ctor_function_t* preinit_array_;
147   size_t preinit_array_count_;
148 
149   linker_ctor_function_t* init_array_;
150   size_t init_array_count_;
151   linker_dtor_function_t* fini_array_;
152   size_t fini_array_count_;
153 
154   linker_ctor_function_t init_func_;
155   linker_dtor_function_t fini_func_;
156 
157 #if defined(__arm__)
158  public:
159   // ARM EABI section used for stack unwinding.
160   uint32_t* ARM_exidx;
161   size_t ARM_exidx_count;
162  private:
163 #elif defined(__mips__)
164   uint32_t mips_symtabno_;
165   uint32_t mips_local_gotno_;
166   uint32_t mips_gotsym_;
167   bool mips_relocate_got(const VersionTracker& version_tracker,
168                          const soinfo_list_t& global_group,
169                          const soinfo_list_t& local_group);
170 #if !defined(__LP64__)
171   bool mips_check_and_adjust_fp_modes();
172 #endif
173 #endif
174   size_t ref_count_;
175  public:
176   link_map link_map_head;
177 
178   bool constructors_called;
179 
180   // When you read a virtual address from the ELF file, add this
181   // value to get the corresponding address in the process' address space.
182   ElfW(Addr) load_bias;
183 
184 #if !defined(__LP64__)
185   bool has_text_relocations;
186 #endif
187   bool has_DT_SYMBOLIC;
188 
189  public:
190   soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,
191          off64_t file_offset, int rtld_flags);
192   ~soinfo();
193 
194   void call_constructors();
195   void call_destructors();
196   void call_pre_init_constructors();
197   bool prelink_image();
198   bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
199                   const android_dlextinfo* extinfo);
200   bool protect_relro();
201 
202   void add_child(soinfo* child);
203   void remove_all_links();
204 
205   ino_t get_st_ino() const;
206   dev_t get_st_dev() const;
207   off64_t get_file_offset() const;
208 
209   uint32_t get_rtld_flags() const;
210   uint32_t get_dt_flags_1() const;
211   void set_dt_flags_1(uint32_t dt_flags_1);
212 
213   soinfo_list_t& get_children();
214   const soinfo_list_t& get_children() const;
215 
216   soinfo_list_t& get_parents();
217 
218   bool find_symbol_by_name(SymbolName& symbol_name,
219                            const version_info* vi,
220                            const ElfW(Sym)** symbol) const;
221 
222   ElfW(Sym)* find_symbol_by_address(const void* addr);
223   ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const;
224 
225   const char* get_string(ElfW(Word) index) const;
226   bool can_unload() const;
227   bool is_gnu_hash() const;
228 
has_min_versionsoinfo229   bool inline has_min_version(uint32_t min_version __unused) const {
230 #if defined(__work_around_b_24465209__)
231     return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
232 #else
233     return true;
234 #endif
235   }
236 
237   bool is_linked() const;
238   bool is_linker() const;
239   bool is_main_executable() const;
240 
241   void set_linked();
242   void set_linker_flag();
243   void set_main_executable();
244   void set_nodelete();
245 
246   void increment_ref_count();
247   size_t decrement_ref_count();
248 
249   soinfo* get_local_group_root() const;
250 
251   void set_soname(const char* soname);
252   const char* get_soname() const;
253   const char* get_realpath() const;
254   const ElfW(Versym)* get_versym(size_t n) const;
255   ElfW(Addr) get_verneed_ptr() const;
256   size_t get_verneed_cnt() const;
257   ElfW(Addr) get_verdef_ptr() const;
258   size_t get_verdef_cnt() const;
259 
260   uint32_t get_target_sdk_version() const;
261 
262   void set_dt_runpath(const char *);
263   const std::vector<std::string>& get_dt_runpath() const;
264   android_namespace_t* get_primary_namespace();
265   void add_secondary_namespace(android_namespace_t* secondary_ns);
266   android_namespace_list_t& get_secondary_namespaces();
267 
268   void set_mapped_by_caller(bool reserved_map);
269   bool is_mapped_by_caller() const;
270 
271   uintptr_t get_handle() const;
272   void generate_handle();
273   void* to_handle();
274 
275  private:
276   bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
277   ElfW(Sym)* elf_addr_lookup(const void* addr);
278   bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
279   ElfW(Sym)* gnu_addr_lookup(const void* addr);
280 
281   bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
282                            const char* sym_name, const version_info** vi);
283 
284   template<typename ElfRelIteratorT>
285   bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
286                 const soinfo_list_t& global_group, const soinfo_list_t& local_group);
287 
288  private:
289   // This part of the structure is only available
290   // when FLAG_NEW_SOINFO is set in this->flags.
291   uint32_t version_;
292 
293   // version >= 0
294   dev_t st_dev_;
295   ino_t st_ino_;
296 
297   // dependency graph
298   soinfo_list_t children_;
299   soinfo_list_t parents_;
300 
301   // version >= 1
302   off64_t file_offset_;
303   uint32_t rtld_flags_;
304   uint32_t dt_flags_1_;
305   size_t strtab_size_;
306 
307   // version >= 2
308 
309   size_t gnu_nbucket_;
310   uint32_t* gnu_bucket_;
311   uint32_t* gnu_chain_;
312   uint32_t gnu_maskwords_;
313   uint32_t gnu_shift2_;
314   ElfW(Addr)* gnu_bloom_filter_;
315 
316   soinfo* local_group_root_;
317 
318   uint8_t* android_relocs_;
319   size_t android_relocs_size_;
320 
321   const char* soname_;
322   std::string realpath_;
323 
324   const ElfW(Versym)* versym_;
325 
326   ElfW(Addr) verdef_ptr_;
327   size_t verdef_cnt_;
328 
329   ElfW(Addr) verneed_ptr_;
330   size_t verneed_cnt_;
331 
332   uint32_t target_sdk_version_;
333 
334   // version >= 3
335   std::vector<std::string> dt_runpath_;
336   android_namespace_t* primary_namespace_;
337   android_namespace_list_t secondary_namespaces_;
338   uintptr_t handle_;
339 
340   friend soinfo* get_libdl_info(const char* linker_path);
341 };
342 
343 // This function is used by dlvsym() to calculate hash of sym_ver
344 uint32_t calculate_elf_hash(const char* name);
345 
346 const char* fix_dt_needed(const char* dt_needed, const char* sopath);
347 
348 template<typename F>
for_each_dt_needed(const soinfo * si,F action)349 void for_each_dt_needed(const soinfo* si, F action) {
350   for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
351     if (d->d_tag == DT_NEEDED) {
352       action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath()));
353     }
354   }
355 }
356 
357 #endif  /* __LINKER_SOINFO_H */
358