• 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 #pragma once
30 
31 #include <link.h>
32 
33 #include <memory>
34 #include <string>
35 #include <vector>
36 
37 #include "async_safe/CHECK.h"
38 #include "linker_namespaces.h"
39 #include "linker_tls.h"
40 #include "private/bionic_elf_tls.h"
41 #include "private/bionic_globals.h"
42 
43 #define FLAG_LINKED           0x00000001
44 #define FLAG_EXE              0x00000004 // The main executable
45 #define FLAG_LINKER           0x00000010 // The linker itself
46 #define FLAG_GNU_HASH         0x00000040 // uses gnu hash
47 #define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller
48                                          // and should not be unmapped
49 #define FLAG_IMAGE_LINKED     0x00000100 // Is image linked - this is a guard on link_image.
50                                          // The difference between this flag and
51                                          // FLAG_LINKED is that FLAG_LINKED
52                                          // means is set when load_group is
53                                          // successfully loaded whereas this
54                                          // flag is set to avoid linking image
55                                          // when link_image called for the
56                                          // second time. This situation happens
57                                          // when load group is crossing
58                                          // namespace boundary twice and second
59                                          // local group depends on the same libraries.
60 #define FLAG_RESERVED         0x00000200 // This flag was set when there is at least one
61                                          // outstanding thread_local dtor
62                                          // registered with this soinfo. In such
63                                          // a case the actual unload is
64                                          // postponed until the last thread_local
65                                          // destructor associated with this
66                                          // soinfo is executed and this flag is
67                                          // unset.
68 #define FLAG_PRELINKED        0x00000400 // prelink_image has successfully processed this soinfo
69 #define FLAG_NEW_SOINFO       0x40000000 // new soinfo format
70 
71 #define SOINFO_VERSION 6
72 
73 ElfW(Addr) call_ifunc_resolver(ElfW(Addr) resolver_addr);
74 
75 typedef void (*linker_dtor_function_t)();
76 typedef void (*linker_ctor_function_t)(int, char**, char**);
77 
78 // An entry within a SymbolLookupList.
79 struct SymbolLookupLib {
80   uint32_t gnu_maskwords_ = 0;
81   uint32_t gnu_shift2_ = 0;
82   ElfW(Addr)* gnu_bloom_filter_ = nullptr;
83 
84   const char* strtab_;
85   size_t strtab_size_;
86   const ElfW(Sym)* symtab_;
87   const ElfW(Versym)* versym_;
88 
89   const uint32_t* gnu_chain_;
90   size_t gnu_nbucket_;
91   uint32_t* gnu_bucket_;
92 
93   soinfo* si_ = nullptr;
94 
needs_sysv_lookupSymbolLookupLib95   bool needs_sysv_lookup() const { return si_ != nullptr && gnu_bloom_filter_ == nullptr; }
96 };
97 
98 // A list of libraries to search for a symbol.
99 class SymbolLookupList {
100   std::vector<SymbolLookupLib> libs_;
101   SymbolLookupLib sole_lib_;
102   const SymbolLookupLib* begin_;
103   const SymbolLookupLib* end_;
104   size_t slow_path_count_ = 0;
105 
106  public:
107   explicit SymbolLookupList(soinfo* si);
108   SymbolLookupList(const soinfo_list_t& global_group, const soinfo_list_t& local_group);
109   void set_dt_symbolic_lib(soinfo* symbolic_lib);
110 
begin()111   const SymbolLookupLib* begin() const { return begin_; }
end()112   const SymbolLookupLib* end() const { return end_; }
needs_slow_path()113   bool needs_slow_path() const { return slow_path_count_ > 0; }
114 };
115 
116 class SymbolName {
117  public:
SymbolName(const char * name)118   explicit SymbolName(const char* name)
119       : name_(name), has_elf_hash_(false), has_gnu_hash_(false),
120         elf_hash_(0), gnu_hash_(0) { }
121 
get_name()122   const char* get_name() {
123     return name_;
124   }
125 
126   uint32_t elf_hash();
127   uint32_t gnu_hash();
128 
129  private:
130   const char* name_;
131   bool has_elf_hash_;
132   bool has_gnu_hash_;
133   uint32_t elf_hash_;
134   uint32_t gnu_hash_;
135 
136   DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName);
137 };
138 
139 struct version_info {
version_infoversion_info140   constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
141 
142   uint32_t elf_hash;
143   const char* name;
144   const soinfo* target_si;
145 };
146 
147 // TODO(dimitry): remove reference from soinfo member functions to this class.
148 class VersionTracker;
149 
150 struct soinfo_tls {
151   TlsSegment segment;
152   size_t module_id = kTlsUninitializedModuleId;
153 };
154 
155 #if defined(__work_around_b_24465209__)
156 #define SOINFO_NAME_LEN 128
157 #endif
158 
159 struct soinfo {
160 #if defined(__work_around_b_24465209__)
161  private:
162   char old_name_[SOINFO_NAME_LEN];
163 #endif
164  public:
165   const ElfW(Phdr)* phdr;
166   size_t phnum;
167 #if defined(__work_around_b_24465209__)
168   ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility.
169 #endif
170   ElfW(Addr) base;
171   size_t size;
172 
173 #if defined(__work_around_b_24465209__)
174   uint32_t unused1;  // DO NOT USE, maintained for compatibility.
175 #endif
176 
177   ElfW(Dyn)* dynamic;
178 
179 #if defined(__work_around_b_24465209__)
180   uint32_t unused2; // DO NOT USE, maintained for compatibility
181   uint32_t unused3; // DO NOT USE, maintained for compatibility
182 #endif
183 
184   soinfo* next;
185  private:
186   uint32_t flags_;
187 
188   const char* strtab_;
189   ElfW(Sym)* symtab_;
190 
191   size_t nbucket_;
192   size_t nchain_;
193   uint32_t* bucket_;
194   uint32_t* chain_;
195 
196 #if !defined(__LP64__)
197   ElfW(Addr)** unused4; // DO NOT USE, maintained for compatibility
198 #endif
199 
200 #if defined(USE_RELA)
201   ElfW(Rela)* plt_rela_;
202   size_t plt_rela_count_;
203 
204   ElfW(Rela)* rela_;
205   size_t rela_count_;
206 #else
207   ElfW(Rel)* plt_rel_;
208   size_t plt_rel_count_;
209 
210   ElfW(Rel)* rel_;
211   size_t rel_count_;
212 #endif
213 
214   linker_ctor_function_t* preinit_array_;
215   size_t preinit_array_count_;
216 
217   linker_ctor_function_t* init_array_;
218   size_t init_array_count_;
219   linker_dtor_function_t* fini_array_;
220   size_t fini_array_count_;
221 
222   linker_ctor_function_t init_func_;
223   linker_dtor_function_t fini_func_;
224 
225 #if defined(__arm__)
226  public:
227   // ARM EABI section used for stack unwinding.
228   uint32_t* ARM_exidx;
229   size_t ARM_exidx_count;
230  private:
231 #endif
232   size_t ref_count_;
233  public:
234   link_map link_map_head;
235 
236   bool constructors_called;
237 
238   // When you read a virtual address from the ELF file, add this
239   // value to get the corresponding address in the process' address space.
240   ElfW(Addr) load_bias;
241 
242 #if !defined(__LP64__)
243   bool has_text_relocations;
244 #endif
245   bool has_DT_SYMBOLIC;
246 
247  public:
248   soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat,
249          off64_t file_offset, int rtld_flags);
250   ~soinfo();
251 
252   void call_constructors();
253   void call_destructors();
254   void call_pre_init_constructors();
255   bool prelink_image();
256   bool link_image(const SymbolLookupList& lookup_list, soinfo* local_group_root,
257                   const android_dlextinfo* extinfo, size_t* relro_fd_offset);
258   bool protect_relro();
259 
260   void add_child(soinfo* child);
261   void remove_all_links();
262 
263   ino_t get_st_ino() const;
264   dev_t get_st_dev() const;
265   off64_t get_file_offset() const;
266 
267   uint32_t get_rtld_flags() const;
268   uint32_t get_dt_flags_1() const;
269   void set_dt_flags_1(uint32_t dt_flags_1);
270 
271   soinfo_list_t& get_children();
272   const soinfo_list_t& get_children() const;
273 
274   soinfo_list_t& get_parents();
275 
276   const ElfW(Sym)* find_symbol_by_name(SymbolName& symbol_name, const version_info* vi) const;
277 
278   ElfW(Sym)* find_symbol_by_address(const void* addr);
279 
resolve_symbol_addresssoinfo280   ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const {
281     if (ELF_ST_TYPE(s->st_info) == STT_GNU_IFUNC) {
282       return call_ifunc_resolver(s->st_value + load_bias);
283     }
284 
285     return static_cast<ElfW(Addr)>(s->st_value + load_bias);
286   }
287 
288   const char* get_string(ElfW(Word) index) const;
289   bool can_unload() const;
290   bool is_gnu_hash() const;
291 
has_min_versionsoinfo292   bool inline has_min_version(uint32_t min_version __unused) const {
293 #if defined(__work_around_b_24465209__)
294     return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
295 #else
296     return true;
297 #endif
298   }
299 
ElfWsoinfo300   const ElfW(Versym)* get_versym_table() const {
301     return has_min_version(2) ? versym_ : nullptr;
302   }
303 
304   bool is_linked() const;
305   bool is_linker() const;
306   bool is_main_executable() const;
307 
308   void set_linked();
309   void set_linker_flag();
310   void set_main_executable();
311   void set_nodelete();
312 
313   size_t increment_ref_count();
314   size_t decrement_ref_count();
315   size_t get_ref_count() const;
316 
317   soinfo* get_local_group_root() const;
318 
319   void set_soname(const char* soname);
320   const char* get_soname() const;
321   void set_realpath(const char* path);
322   const char* get_realpath() const;
323   const ElfW(Versym)* get_versym(size_t n) const;
324   ElfW(Addr) get_verneed_ptr() const;
325   size_t get_verneed_cnt() const;
326   ElfW(Addr) get_verdef_ptr() const;
327   size_t get_verdef_cnt() const;
328 
329   int get_target_sdk_version() const;
330 
331   void set_dt_runpath(const char *);
332   const std::vector<std::string>& get_dt_runpath() const;
333   android_namespace_t* get_primary_namespace();
334   void add_secondary_namespace(android_namespace_t* secondary_ns);
335   android_namespace_list_t& get_secondary_namespaces();
336 
get_tlssoinfo337   soinfo_tls* get_tls() const {
338     return has_min_version(5) ? tls_.get() : nullptr;
339   }
340 
341   void set_mapped_by_caller(bool reserved_map);
342   bool is_mapped_by_caller() const;
343 
344   uintptr_t get_handle() const;
345   void generate_handle();
346   void* to_handle();
347 
348   SymbolLookupLib get_lookup_lib();
349 
350   void set_gap_start(ElfW(Addr) gap_start);
351   ElfW(Addr) get_gap_start() const;
352 
353   void set_gap_size(size_t gap_size);
354   size_t get_gap_size() const;
355 
memtag_dynamic_entriessoinfo356   const memtag_dynamic_entries_t* memtag_dynamic_entries() const {
357     CHECK(has_min_version(7));
358     return &memtag_dynamic_entries_;
359   }
memtag_globalssoinfo360   void* memtag_globals() const { return memtag_dynamic_entries()->memtag_globals; }
memtag_globalsszsoinfo361   size_t memtag_globalssz() const { return memtag_dynamic_entries()->memtag_globalssz; }
has_memtag_modesoinfo362   bool has_memtag_mode() const { return memtag_dynamic_entries()->has_memtag_mode; }
memtag_modesoinfo363   unsigned memtag_mode() const { return memtag_dynamic_entries()->memtag_mode; }
memtag_heapsoinfo364   bool memtag_heap() const { return memtag_dynamic_entries()->memtag_heap; }
memtag_stacksoinfo365   bool memtag_stack() const { return memtag_dynamic_entries()->memtag_stack; }
366 
set_should_pad_segmentssoinfo367   void set_should_pad_segments(bool should_pad_segments) {
368    should_pad_segments_ = should_pad_segments;
369   }
should_pad_segmentssoinfo370   bool should_pad_segments() const { return should_pad_segments_; }
371 
372  private:
373   bool is_image_linked() const;
374   void set_image_linked();
375 
376   const ElfW(Sym)* gnu_lookup(SymbolName& symbol_name, const version_info* vi) const;
377   const ElfW(Sym)* elf_lookup(SymbolName& symbol_name, const version_info* vi) const;
378   ElfW(Sym)* gnu_addr_lookup(const void* addr);
379   ElfW(Sym)* elf_addr_lookup(const void* addr);
380 
381  public:
382   bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
383                            const char* sym_name, const version_info** vi);
384 
385  private:
386   bool relocate(const SymbolLookupList& lookup_list);
387 
388   // This part of the structure is only available
389   // when FLAG_NEW_SOINFO is set in this->flags.
390   uint32_t version_;
391 
392   // version >= 0
393   dev_t st_dev_;
394   ino_t st_ino_;
395 
396   // dependency graph
397   soinfo_list_t children_;
398   soinfo_list_t parents_;
399 
400   // version >= 1
401   off64_t file_offset_;
402   uint32_t rtld_flags_;
403   uint32_t dt_flags_1_;
404   size_t strtab_size_;
405 
406   // version >= 2
407 
408   size_t gnu_nbucket_;
409   uint32_t* gnu_bucket_;
410   uint32_t* gnu_chain_;
411   uint32_t gnu_maskwords_;
412   uint32_t gnu_shift2_;
413   ElfW(Addr)* gnu_bloom_filter_;
414 
415   soinfo* local_group_root_;
416 
417   uint8_t* android_relocs_;
418   size_t android_relocs_size_;
419 
420   std::string soname_;
421   std::string realpath_;
422 
423   const ElfW(Versym)* versym_;
424 
425   ElfW(Addr) verdef_ptr_;
426   size_t verdef_cnt_;
427 
428   ElfW(Addr) verneed_ptr_;
429   size_t verneed_cnt_;
430 
431   int target_sdk_version_;
432 
433   // version >= 3
434   std::vector<std::string> dt_runpath_;
435   android_namespace_t* primary_namespace_;
436   android_namespace_list_t secondary_namespaces_;
437   uintptr_t handle_;
438 
439   friend soinfo* get_libdl_info(const soinfo& linker_si);
440 
441   // version >= 4
442   ElfW(Relr)* relr_;
443   size_t relr_count_;
444 
445   // version >= 5
446   std::unique_ptr<soinfo_tls> tls_;
447   std::vector<TlsDynamicResolverArg> tlsdesc_args_;
448 
449   // version >= 6
450   ElfW(Addr) gap_start_;
451   size_t gap_size_;
452 
453   // version >= 7
454   memtag_dynamic_entries_t memtag_dynamic_entries_;
455 
456   // Pad gaps between segments when memory mapping?
457   bool should_pad_segments_ = false;
458 };
459 
460 // This function is used by dlvsym() to calculate hash of sym_ver
461 uint32_t calculate_elf_hash(const char* name);
462 
463 const char* fix_dt_needed(const char* dt_needed, const char* sopath);
464 
465 template<typename F>
for_each_dt_needed(const soinfo * si,F action)466 void for_each_dt_needed(const soinfo* si, F action) {
467   for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) {
468     if (d->d_tag == DT_NEEDED) {
469       action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath()));
470     }
471   }
472 }
473 
474 const ElfW(Sym)* soinfo_do_lookup(const char* name, const version_info* vi,
475                                   soinfo** si_found_in, const SymbolLookupList& lookup_list);
476