Home | History | Annotate | Download | only in linker
      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:
     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 
     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 {
     75   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 
    229   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>
    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