Home | History | Annotate | Download | only in linker
      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 <inttypes.h>
     34 #include <link.h>
     35 #include <unistd.h>
     36 #include <android/dlext.h>
     37 #include <sys/stat.h>
     38 
     39 #include "private/libc_logging.h"
     40 #include "linked_list.h"
     41 
     42 #include <string>
     43 #include <vector>
     44 
     45 #define DL_ERR(fmt, x...) \
     46     do { \
     47       __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \
     48       /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \
     49       DEBUG("%s\n", linker_get_error_buffer()); \
     50     } while (false)
     51 
     52 #define DL_WARN(fmt, x...) \
     53     do { \
     54       __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \
     55       __libc_format_fd(2, "WARNING: linker: "); \
     56       __libc_format_fd(2, fmt, ##x); \
     57       __libc_format_fd(2, "\n"); \
     58     } while (false)
     59 
     60 #if defined(__LP64__)
     61 #define ELFW(what) ELF64_ ## what
     62 #else
     63 #define ELFW(what) ELF32_ ## what
     64 #endif
     65 
     66 // mips64 interprets Elf64_Rel structures' r_info field differently.
     67 // bionic (like other C libraries) has macros that assume regular ELF files,
     68 // but the dynamic linker needs to be able to load mips64 ELF files.
     69 #if defined(__mips__) && defined(__LP64__)
     70 #undef ELF64_R_SYM
     71 #undef ELF64_R_TYPE
     72 #undef ELF64_R_INFO
     73 #define ELF64_R_SYM(info)   (((info) >> 0) & 0xffffffff)
     74 #define ELF64_R_SSYM(info)  (((info) >> 32) & 0xff)
     75 #define ELF64_R_TYPE3(info) (((info) >> 40) & 0xff)
     76 #define ELF64_R_TYPE2(info) (((info) >> 48) & 0xff)
     77 #define ELF64_R_TYPE(info)  (((info) >> 56) & 0xff)
     78 #endif
     79 
     80 // Returns the address of the page containing address 'x'.
     81 #define PAGE_START(x)  ((x) & PAGE_MASK)
     82 
     83 // Returns the offset of address 'x' in its page.
     84 #define PAGE_OFFSET(x) ((x) & ~PAGE_MASK)
     85 
     86 // Returns the address of the next page after address 'x', unless 'x' is
     87 // itself at the start of a page.
     88 #define PAGE_END(x)    PAGE_START((x) + (PAGE_SIZE-1))
     89 
     90 #define FLAG_LINKED     0x00000001
     91 #define FLAG_EXE        0x00000004 // The main executable
     92 #define FLAG_LINKER     0x00000010 // The linker itself
     93 #define FLAG_GNU_HASH   0x00000040 // uses gnu hash
     94 #define FLAG_NEW_SOINFO 0x40000000 // new soinfo format
     95 
     96 #define SUPPORTED_DT_FLAGS_1 (DF_1_NOW | DF_1_GLOBAL | DF_1_NODELETE)
     97 
     98 #define SOINFO_VERSION 2
     99 
    100 #if defined(__work_around_b_19059885__)
    101 #define SOINFO_NAME_LEN 128
    102 #endif
    103 
    104 typedef void (*linker_function_t)();
    105 
    106 // Android uses RELA for aarch64 and x86_64. mips64 still uses REL.
    107 #if defined(__aarch64__) || defined(__x86_64__)
    108 #define USE_RELA 1
    109 #endif
    110 
    111 struct soinfo;
    112 
    113 class SoinfoListAllocator {
    114  public:
    115   static LinkedListEntry<soinfo>* alloc();
    116   static void free(LinkedListEntry<soinfo>* entry);
    117 
    118  private:
    119   // unconstructable
    120   DISALLOW_IMPLICIT_CONSTRUCTORS(SoinfoListAllocator);
    121 };
    122 
    123 class SymbolName {
    124  public:
    125   explicit SymbolName(const char* name)
    126       : name_(name), has_elf_hash_(false), has_gnu_hash_(false),
    127         elf_hash_(0), gnu_hash_(0) { }
    128 
    129   const char* get_name() {
    130     return name_;
    131   }
    132 
    133   uint32_t elf_hash();
    134   uint32_t gnu_hash();
    135 
    136  private:
    137   const char* name_;
    138   bool has_elf_hash_;
    139   bool has_gnu_hash_;
    140   uint32_t elf_hash_;
    141   uint32_t gnu_hash_;
    142 
    143   DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName);
    144 };
    145 
    146 struct version_info {
    147   version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {}
    148 
    149   uint32_t elf_hash;
    150   const char* name;
    151   const soinfo* target_si;
    152 };
    153 
    154 // Class used construct version dependency graph.
    155 class VersionTracker {
    156  public:
    157   VersionTracker() = default;
    158   bool init(const soinfo* si_from);
    159 
    160   const version_info* get_version_info(ElfW(Versym) source_symver) const;
    161  private:
    162   bool init_verneed(const soinfo* si_from);
    163   bool init_verdef(const soinfo* si_from);
    164   void add_version_info(size_t source_index, ElfW(Word) elf_hash,
    165       const char* ver_name, const soinfo* target_si);
    166 
    167   std::vector<version_info> version_infos;
    168 
    169   DISALLOW_COPY_AND_ASSIGN(VersionTracker);
    170 };
    171 
    172 struct soinfo {
    173  public:
    174   typedef LinkedList<soinfo, SoinfoListAllocator> soinfo_list_t;
    175 #if defined(__work_around_b_19059885__)
    176  private:
    177   char old_name_[SOINFO_NAME_LEN];
    178 #endif
    179  public:
    180   const ElfW(Phdr)* phdr;
    181   size_t phnum;
    182   ElfW(Addr) entry;
    183   ElfW(Addr) base;
    184   size_t size;
    185 
    186 #if defined(__work_around_b_19059885__)
    187   uint32_t unused1;  // DO NOT USE, maintained for compatibility.
    188 #endif
    189 
    190   ElfW(Dyn)* dynamic;
    191 
    192 #if defined(__work_around_b_19059885__)
    193   uint32_t unused2; // DO NOT USE, maintained for compatibility
    194   uint32_t unused3; // DO NOT USE, maintained for compatibility
    195 #endif
    196 
    197   soinfo* next;
    198  private:
    199   uint32_t flags_;
    200 
    201   const char* strtab_;
    202   ElfW(Sym)* symtab_;
    203 
    204   size_t nbucket_;
    205   size_t nchain_;
    206   uint32_t* bucket_;
    207   uint32_t* chain_;
    208 
    209 #if defined(__mips__) || !defined(__LP64__)
    210   // This is only used by mips and mips64, but needs to be here for
    211   // all 32-bit architectures to preserve binary compatibility.
    212   ElfW(Addr)** plt_got_;
    213 #endif
    214 
    215 #if defined(USE_RELA)
    216   ElfW(Rela)* plt_rela_;
    217   size_t plt_rela_count_;
    218 
    219   ElfW(Rela)* rela_;
    220   size_t rela_count_;
    221 #else
    222   ElfW(Rel)* plt_rel_;
    223   size_t plt_rel_count_;
    224 
    225   ElfW(Rel)* rel_;
    226   size_t rel_count_;
    227 #endif
    228 
    229   linker_function_t* preinit_array_;
    230   size_t preinit_array_count_;
    231 
    232   linker_function_t* init_array_;
    233   size_t init_array_count_;
    234   linker_function_t* fini_array_;
    235   size_t fini_array_count_;
    236 
    237   linker_function_t init_func_;
    238   linker_function_t fini_func_;
    239 
    240 #if defined(__arm__)
    241  public:
    242   // ARM EABI section used for stack unwinding.
    243   uint32_t* ARM_exidx;
    244   size_t ARM_exidx_count;
    245  private:
    246 #elif defined(__mips__)
    247   uint32_t mips_symtabno_;
    248   uint32_t mips_local_gotno_;
    249   uint32_t mips_gotsym_;
    250   bool mips_relocate_got(const VersionTracker& version_tracker,
    251                          const soinfo_list_t& global_group,
    252                          const soinfo_list_t& local_group);
    253 
    254 #endif
    255   size_t ref_count_;
    256  public:
    257   link_map link_map_head;
    258 
    259   bool constructors_called;
    260 
    261   // When you read a virtual address from the ELF file, add this
    262   // value to get the corresponding address in the process' address space.
    263   ElfW(Addr) load_bias;
    264 
    265 #if !defined(__LP64__)
    266   bool has_text_relocations;
    267 #endif
    268   bool has_DT_SYMBOLIC;
    269 
    270  public:
    271   soinfo(const char* name, const struct stat* file_stat, off64_t file_offset, int rtld_flags);
    272 
    273   void call_constructors();
    274   void call_destructors();
    275   void call_pre_init_constructors();
    276   bool prelink_image();
    277   bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group,
    278                   const android_dlextinfo* extinfo);
    279 
    280   void add_child(soinfo* child);
    281   void remove_all_links();
    282 
    283   ino_t get_st_ino() const;
    284   dev_t get_st_dev() const;
    285   off64_t get_file_offset() const;
    286 
    287   uint32_t get_rtld_flags() const;
    288   uint32_t get_dt_flags_1() const;
    289   void set_dt_flags_1(uint32_t dt_flags_1);
    290 
    291   soinfo_list_t& get_children();
    292   const soinfo_list_t& get_children() const;
    293 
    294   soinfo_list_t& get_parents();
    295 
    296   bool find_symbol_by_name(SymbolName& symbol_name,
    297                            const version_info* vi,
    298                            const ElfW(Sym)** symbol) const;
    299 
    300   ElfW(Sym)* find_symbol_by_address(const void* addr);
    301   ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const;
    302 
    303   const char* get_string(ElfW(Word) index) const;
    304   bool can_unload() const;
    305   bool is_gnu_hash() const;
    306 
    307   bool inline has_min_version(uint32_t min_version __unused) const {
    308 #if defined(__work_around_b_19059885__)
    309     return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version;
    310 #else
    311     return true;
    312 #endif
    313   }
    314 
    315   bool is_linked() const;
    316   bool is_main_executable() const;
    317 
    318   void set_linked();
    319   void set_linker_flag();
    320   void set_main_executable();
    321 
    322   void increment_ref_count();
    323   size_t decrement_ref_count();
    324 
    325   soinfo* get_local_group_root() const;
    326 
    327   const char* get_soname() const;
    328   const char* get_realpath() const;
    329   const ElfW(Versym)* get_versym(size_t n) const;
    330   ElfW(Addr) get_verneed_ptr() const;
    331   size_t get_verneed_cnt() const;
    332   ElfW(Addr) get_verdef_ptr() const;
    333   size_t get_verdef_cnt() const;
    334 
    335   bool find_verdef_version_index(const version_info* vi, ElfW(Versym)* versym) const;
    336 
    337   uint32_t get_target_sdk_version() const;
    338 
    339  private:
    340   bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
    341   ElfW(Sym)* elf_addr_lookup(const void* addr);
    342   bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const;
    343   ElfW(Sym)* gnu_addr_lookup(const void* addr);
    344 
    345   bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym,
    346                            const char* sym_name, const version_info** vi);
    347 
    348   void call_array(const char* array_name, linker_function_t* functions, size_t count, bool reverse);
    349   void call_function(const char* function_name, linker_function_t function);
    350   template<typename ElfRelIteratorT>
    351   bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator,
    352                 const soinfo_list_t& global_group, const soinfo_list_t& local_group);
    353 
    354  private:
    355   // This part of the structure is only available
    356   // when FLAG_NEW_SOINFO is set in this->flags.
    357   uint32_t version_;
    358 
    359   // version >= 0
    360   dev_t st_dev_;
    361   ino_t st_ino_;
    362 
    363   // dependency graph
    364   soinfo_list_t children_;
    365   soinfo_list_t parents_;
    366 
    367   // version >= 1
    368   off64_t file_offset_;
    369   uint32_t rtld_flags_;
    370   uint32_t dt_flags_1_;
    371   size_t strtab_size_;
    372 
    373   // version >= 2
    374 
    375   size_t gnu_nbucket_;
    376   uint32_t* gnu_bucket_;
    377   uint32_t* gnu_chain_;
    378   uint32_t gnu_maskwords_;
    379   uint32_t gnu_shift2_;
    380   ElfW(Addr)* gnu_bloom_filter_;
    381 
    382   soinfo* local_group_root_;
    383 
    384   uint8_t* android_relocs_;
    385   size_t android_relocs_size_;
    386 
    387   const char* soname_;
    388   std::string realpath_;
    389 
    390   const ElfW(Versym)* versym_;
    391 
    392   ElfW(Addr) verdef_ptr_;
    393   size_t verdef_cnt_;
    394 
    395   ElfW(Addr) verneed_ptr_;
    396   size_t verneed_cnt_;
    397 
    398   uint32_t target_sdk_version_;
    399 
    400   friend soinfo* get_libdl_info();
    401 };
    402 
    403 bool soinfo_do_lookup(soinfo* si_from, const char* name, const version_info* vi,
    404                       soinfo** si_found_in, const soinfo::soinfo_list_t& global_group,
    405                       const soinfo::soinfo_list_t& local_group, const ElfW(Sym)** symbol);
    406 
    407 enum RelocationKind {
    408   kRelocAbsolute = 0,
    409   kRelocRelative,
    410   kRelocCopy,
    411   kRelocSymbol,
    412   kRelocMax
    413 };
    414 
    415 void count_relocation(RelocationKind kind);
    416 
    417 soinfo* get_libdl_info();
    418 
    419 void do_android_get_LD_LIBRARY_PATH(char*, size_t);
    420 void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
    421 soinfo* do_dlopen(const char* name, int flags, const android_dlextinfo* extinfo);
    422 void do_dlclose(soinfo* si);
    423 
    424 int do_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data);
    425 
    426 const ElfW(Sym)* dlsym_linear_lookup(const char* name, soinfo** found, soinfo* caller, void* handle);
    427 soinfo* find_containing_library(const void* addr);
    428 
    429 const ElfW(Sym)* dlsym_handle_lookup(soinfo* si, soinfo** found, const char* name);
    430 
    431 void debuggerd_init();
    432 extern "C" abort_msg_t* g_abort_message;
    433 extern "C" void notify_gdb_of_libraries();
    434 
    435 char* linker_get_error_buffer();
    436 size_t linker_get_error_buffer_size();
    437 
    438 void set_application_target_sdk_version(uint32_t target);
    439 uint32_t get_application_target_sdk_version();
    440 
    441 #endif
    442