1 /* 2 * Copyright (C) 2012 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 /* Declarations related to the ELF program header table and segments. 32 * 33 * The design goal is to provide an API that is as close as possible 34 * to the ELF spec, and does not depend on linker-specific data 35 * structures (e.g. the exact layout of struct soinfo). 36 */ 37 38 #include "linker.h" 39 #include "linker_mapped_file_fragment.h" 40 41 class ElfReader { 42 public: 43 ElfReader(); 44 45 bool Read(const char* name, int fd, off64_t file_offset, off64_t file_size); 46 bool Load(address_space_params* address_space); 47 name()48 const char* name() const { return name_.c_str(); } phdr_count()49 size_t phdr_count() const { return phdr_num_; } load_start()50 ElfW(Addr) load_start() const { return reinterpret_cast<ElfW(Addr)>(load_start_); } load_size()51 size_t load_size() const { return load_size_; } gap_start()52 ElfW(Addr) gap_start() const { return reinterpret_cast<ElfW(Addr)>(gap_start_); } gap_size()53 size_t gap_size() const { return gap_size_; } load_bias()54 ElfW(Addr) load_bias() const { return load_bias_; } ElfW(Phdr)55 const ElfW(Phdr)* loaded_phdr() const { return loaded_phdr_; } ElfW(Dyn)56 const ElfW(Dyn)* dynamic() const { return dynamic_; } 57 const char* get_string(ElfW(Word) index) const; is_mapped_by_caller()58 bool is_mapped_by_caller() const { return mapped_by_caller_; } entry_point()59 ElfW(Addr) entry_point() const { return header_.e_entry + load_bias_; } 60 61 private: 62 bool ReadElfHeader(); 63 bool VerifyElfHeader(); 64 bool ReadProgramHeaders(); 65 bool ReadSectionHeaders(); 66 bool ReadDynamicSection(); 67 bool ReserveAddressSpace(address_space_params* address_space); 68 bool LoadSegments(); 69 bool FindPhdr(); 70 bool CheckPhdr(ElfW(Addr)); 71 bool CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment); 72 73 bool did_read_; 74 bool did_load_; 75 std::string name_; 76 int fd_; 77 off64_t file_offset_; 78 off64_t file_size_; 79 80 ElfW(Ehdr) header_; 81 size_t phdr_num_; 82 83 MappedFileFragment phdr_fragment_; 84 const ElfW(Phdr)* phdr_table_; 85 86 MappedFileFragment shdr_fragment_; 87 const ElfW(Shdr)* shdr_table_; 88 size_t shdr_num_; 89 90 MappedFileFragment dynamic_fragment_; 91 const ElfW(Dyn)* dynamic_; 92 93 MappedFileFragment strtab_fragment_; 94 const char* strtab_; 95 size_t strtab_size_; 96 97 // First page of reserved address space. 98 void* load_start_; 99 // Size in bytes of reserved address space. 100 size_t load_size_; 101 // First page of inaccessible gap mapping reserved for this DSO. 102 void* gap_start_; 103 // Size in bytes of the gap mapping. 104 size_t gap_size_; 105 // Load bias. 106 ElfW(Addr) load_bias_; 107 108 // Loaded phdr. 109 const ElfW(Phdr)* loaded_phdr_; 110 111 // Is map owned by the caller 112 bool mapped_by_caller_; 113 }; 114 115 size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count, 116 ElfW(Addr)* min_vaddr = nullptr, ElfW(Addr)* max_vaddr = nullptr); 117 118 int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, 119 size_t phdr_count, ElfW(Addr) load_bias); 120 121 int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count, 122 ElfW(Addr) load_bias); 123 124 int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count, 125 ElfW(Addr) load_bias); 126 127 int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count, 128 ElfW(Addr) load_bias, int fd, size_t* file_offset); 129 130 int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count, 131 ElfW(Addr) load_bias, int fd, size_t* file_offset); 132 133 #if defined(__arm__) 134 int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count, ElfW(Addr) load_bias, 135 ElfW(Addr)** arm_exidx, size_t* arm_exidix_count); 136 #endif 137 138 void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count, 139 ElfW(Addr) load_bias, ElfW(Dyn)** dynamic, 140 ElfW(Word)* dynamic_flags); 141 142 const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count, 143 ElfW(Addr) load_bias); 144