148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov/* 248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * Copyright (C) 2016 The Android Open Source Project 348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * All rights reserved. 448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * 548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * Redistribution and use in source and binary forms, with or without 648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * modification, are permitted provided that the following conditions 748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * are met: 848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * * Redistributions of source code must retain the above copyright 948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * notice, this list of conditions and the following disclaimer. 1048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * * Redistributions in binary form must reproduce the above copyright 1148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * notice, this list of conditions and the following disclaimer in 1248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * the documentation and/or other materials provided with the 1348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * distribution. 1448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * 1548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov * SUCH DAMAGE. 2748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov */ 2848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 2948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#ifndef __LINKER_SOINFO_H 3048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define __LINKER_SOINFO_H 3148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 3248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#include <link.h> 3348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 3448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#include <string> 3548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 3648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#include "linker_namespaces.h" 3748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 3848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define FLAG_LINKED 0x00000001 3948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define FLAG_EXE 0x00000004 // The main executable 4048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define FLAG_LINKER 0x00000010 // The linker itself 4148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define FLAG_GNU_HASH 0x00000040 // uses gnu hash 4248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define FLAG_MAPPED_BY_CALLER 0x00000080 // the map is reserved by the caller 4348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // and should not be unmapped 4448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define FLAG_NEW_SOINFO 0x40000000 // new soinfo format 4548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 4648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define SOINFO_VERSION 3 4748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 4848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovtypedef void (*linker_dtor_function_t)(); 4948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovtypedef void (*linker_ctor_function_t)(int, char**, char**); 5048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 5148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovclass SymbolName { 5248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov public: 5348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov explicit SymbolName(const char* name) 5448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov : name_(name), has_elf_hash_(false), has_gnu_hash_(false), 5548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov elf_hash_(0), gnu_hash_(0) { } 5648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 5748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* get_name() { 5848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov return name_; 5948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov } 6048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 6148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t elf_hash(); 6248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t gnu_hash(); 6348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 6448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov private: 6548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* name_; 6648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool has_elf_hash_; 6748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool has_gnu_hash_; 6848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t elf_hash_; 6948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t gnu_hash_; 7048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 7148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolName); 7248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov}; 7348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 7448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovstruct version_info { 7548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov constexpr version_info() : elf_hash(0), name(nullptr), target_si(nullptr) {} 7648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 7748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t elf_hash; 7848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* name; 7948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const soinfo* target_si; 8048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov}; 8148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 8248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov// TODO(dimitry): remove reference from soinfo member functions to this class. 8348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovclass VersionTracker; 8448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 8548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__work_around_b_24465209__) 8648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#define SOINFO_NAME_LEN 128 8748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 8848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 8948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovstruct soinfo { 9048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__work_around_b_24465209__) 9148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov private: 9248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov char old_name_[SOINFO_NAME_LEN]; 9348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 9448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov public: 9548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const ElfW(Phdr)* phdr; 9648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t phnum; 9748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__work_around_b_24465209__) 9848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) unused0; // DO NOT USE, maintained for compatibility. 9948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 10048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) base; 10148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t size; 10248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 10348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__work_around_b_24465209__) 10448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t unused1; // DO NOT USE, maintained for compatibility. 10548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 10648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 10748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Dyn)* dynamic; 10848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 10948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__work_around_b_24465209__) 11048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t unused2; // DO NOT USE, maintained for compatibility 11148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t unused3; // DO NOT USE, maintained for compatibility 11248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 11348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 11448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo* next; 11548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov private: 11648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t flags_; 11748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 11848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* strtab_; 11948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Sym)* symtab_; 12048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 12148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t nbucket_; 12248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t nchain_; 12348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t* bucket_; 12448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t* chain_; 12548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 12648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__mips__) || !defined(__LP64__) 12748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // This is only used by mips and mips64, but needs to be here for 12848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // all 32-bit architectures to preserve binary compatibility. 12948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr)** plt_got_; 13048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 13148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 13248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(USE_RELA) 13348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Rela)* plt_rela_; 13448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t plt_rela_count_; 13548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 13648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Rela)* rela_; 13748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t rela_count_; 13848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#else 13948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Rel)* plt_rel_; 14048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t plt_rel_count_; 14148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 14248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Rel)* rel_; 14348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t rel_count_; 14448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 14548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 14648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov linker_ctor_function_t* preinit_array_; 14748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t preinit_array_count_; 14848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 14948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov linker_ctor_function_t* init_array_; 15048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t init_array_count_; 15148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov linker_dtor_function_t* fini_array_; 15248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t fini_array_count_; 15348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 15448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov linker_ctor_function_t init_func_; 15548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov linker_dtor_function_t fini_func_; 15648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 15748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__arm__) 15848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov public: 15948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // ARM EABI section used for stack unwinding. 16048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t* ARM_exidx; 16148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t ARM_exidx_count; 16248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov private: 16348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#elif defined(__mips__) 16448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t mips_symtabno_; 16548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t mips_local_gotno_; 16648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t mips_gotsym_; 16748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool mips_relocate_got(const VersionTracker& version_tracker, 16848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const soinfo_list_t& global_group, 16948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const soinfo_list_t& local_group); 17048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if !defined(__LP64__) 17148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool mips_check_and_adjust_fp_modes(); 17248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 17348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 17448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t ref_count_; 17548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov public: 17648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov link_map link_map_head; 17748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 17848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool constructors_called; 17948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 18048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // When you read a virtual address from the ELF file, add this 18148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // value to get the corresponding address in the process' address space. 18248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) load_bias; 18348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 18448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if !defined(__LP64__) 18548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool has_text_relocations; 18648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 18748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool has_DT_SYMBOLIC; 18848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 18948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov public: 19048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo(android_namespace_t* ns, const char* name, const struct stat* file_stat, 19148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov off64_t file_offset, int rtld_flags); 19248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ~soinfo(); 19348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 19448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void call_constructors(); 19548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void call_destructors(); 19648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void call_pre_init_constructors(); 19748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool prelink_image(); 19848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool link_image(const soinfo_list_t& global_group, const soinfo_list_t& local_group, 19948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const android_dlextinfo* extinfo); 20048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool protect_relro(); 20148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 20248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void add_child(soinfo* child); 20348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void remove_all_links(); 20448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 20548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ino_t get_st_ino() const; 20648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov dev_t get_st_dev() const; 20748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov off64_t get_file_offset() const; 20848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 20948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t get_rtld_flags() const; 21048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t get_dt_flags_1() const; 21148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_dt_flags_1(uint32_t dt_flags_1); 21248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 21348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo_list_t& get_children(); 21448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const soinfo_list_t& get_children() const; 21548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 21648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo_list_t& get_parents(); 21748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 21848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool find_symbol_by_name(SymbolName& symbol_name, 21948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const version_info* vi, 22048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const ElfW(Sym)** symbol) const; 22148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 22248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Sym)* find_symbol_by_address(const void* addr); 22348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) resolve_symbol_address(const ElfW(Sym)* s) const; 22448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 22548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* get_string(ElfW(Word) index) const; 22648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool can_unload() const; 22748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool is_gnu_hash() const; 22848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 22948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool inline has_min_version(uint32_t min_version __unused) const { 23048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#if defined(__work_around_b_24465209__) 23148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov return (flags_ & FLAG_NEW_SOINFO) != 0 && version_ >= min_version; 23248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#else 23348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov return true; 23448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif 23548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov } 23648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 23748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool is_linked() const; 23848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool is_linker() const; 23948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool is_main_executable() const; 24048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 24148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_linked(); 24248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_linker_flag(); 24348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_main_executable(); 24448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_nodelete(); 24548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 24648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void increment_ref_count(); 24748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t decrement_ref_count(); 24848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 24948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo* get_local_group_root() const; 25048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 25148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_soname(const char* soname); 25248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* get_soname() const; 25348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* get_realpath() const; 25448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const ElfW(Versym)* get_versym(size_t n) const; 25548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) get_verneed_ptr() const; 25648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t get_verneed_cnt() const; 25748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) get_verdef_ptr() const; 25848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t get_verdef_cnt() const; 25948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 26048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t get_target_sdk_version() const; 26148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 26248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_dt_runpath(const char *); 26348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const std::vector<std::string>& get_dt_runpath() const; 26448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov android_namespace_t* get_primary_namespace(); 26548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void add_secondary_namespace(android_namespace_t* secondary_ns); 2667a34b9d57a762ca7cd6b8d6b9f9fb45c2b991da7Dimitry Ivanov android_namespace_list_t& get_secondary_namespaces(); 26748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 26848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void set_mapped_by_caller(bool reserved_map); 26948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool is_mapped_by_caller() const; 27048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 27148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uintptr_t get_handle() const; 27248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void generate_handle(); 27348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov void* to_handle(); 27448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 27548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov private: 27648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool elf_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const; 27748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Sym)* elf_addr_lookup(const void* addr); 27848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool gnu_lookup(SymbolName& symbol_name, const version_info* vi, uint32_t* symbol_index) const; 27948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Sym)* gnu_addr_lookup(const void* addr); 28048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 28148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool lookup_version_info(const VersionTracker& version_tracker, ElfW(Word) sym, 28248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* sym_name, const version_info** vi); 28348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 28448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov template<typename ElfRelIteratorT> 28548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov bool relocate(const VersionTracker& version_tracker, ElfRelIteratorT&& rel_iterator, 28648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const soinfo_list_t& global_group, const soinfo_list_t& local_group); 28748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 28848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov private: 28948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // This part of the structure is only available 29048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // when FLAG_NEW_SOINFO is set in this->flags. 29148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t version_; 29248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 29348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // version >= 0 29448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov dev_t st_dev_; 29548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ino_t st_ino_; 29648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 29748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // dependency graph 29848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo_list_t children_; 29948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo_list_t parents_; 30048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 30148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // version >= 1 30248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov off64_t file_offset_; 30348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t rtld_flags_; 30448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t dt_flags_1_; 30548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t strtab_size_; 30648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 30748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // version >= 2 30848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 30948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t gnu_nbucket_; 31048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t* gnu_bucket_; 31148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t* gnu_chain_; 31248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t gnu_maskwords_; 31348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t gnu_shift2_; 31448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr)* gnu_bloom_filter_; 31548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 31648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov soinfo* local_group_root_; 31748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 31848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint8_t* android_relocs_; 31948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t android_relocs_size_; 32048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 32148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const char* soname_; 32248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov std::string realpath_; 32348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 32448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov const ElfW(Versym)* versym_; 32548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 32648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) verdef_ptr_; 32748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t verdef_cnt_; 32848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 32948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov ElfW(Addr) verneed_ptr_; 33048ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov size_t verneed_cnt_; 33148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 33248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uint32_t target_sdk_version_; 33348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 33448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov // version >= 3 33548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov std::vector<std::string> dt_runpath_; 33648ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov android_namespace_t* primary_namespace_; 33748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov android_namespace_list_t secondary_namespaces_; 33848ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov uintptr_t handle_; 33948ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 340d9e427cf41893377dcdd0650ba20ff7cf7d72209Dimitry Ivanov friend soinfo* get_libdl_info(const char* linker_path); 34148ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov}; 34248ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 34348ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov// This function is used by dlvsym() to calculate hash of sym_ver 34448ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanovuint32_t calculate_elf_hash(const char* name); 34548ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov 3463f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovconst char* fix_dt_needed(const char* dt_needed, const char* sopath); 3473f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov 3483f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovtemplate<typename F> 3493f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanovvoid for_each_dt_needed(const soinfo* si, F action) { 3503f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov for (const ElfW(Dyn)* d = si->dynamic; d->d_tag != DT_NULL; ++d) { 3513f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov if (d->d_tag == DT_NEEDED) { 3523f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov action(fix_dt_needed(si->get_string(d->d_un.d_val), si->get_realpath())); 3533f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov } 3543f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov } 3553f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov} 3563f6605754464c0856862c4d66ed03227a60a6f4dDimitry Ivanov 35748ec288d40d272e6fe5e68c4c0a9778b55e24f8aDimitry Ivanov#endif /* __LINKER_SOINFO_H */ 358