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