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_; } load_bias()52 ElfW(Addr) load_bias() const { return load_bias_; } ElfW(Phdr)53 const ElfW(Phdr)* loaded_phdr() const { return loaded_phdr_; } ElfW(Dyn)54 const ElfW(Dyn)* dynamic() const { return dynamic_; } 55 const char* get_string(ElfW(Word) index) const; is_mapped_by_caller()56 bool is_mapped_by_caller() const { return mapped_by_caller_; } entry_point()57 ElfW(Addr) entry_point() const { return header_.e_entry + load_bias_; } 58 59 private: 60 bool ReadElfHeader(); 61 bool VerifyElfHeader(); 62 bool ReadProgramHeaders(); 63 bool ReadSectionHeaders(); 64 bool ReadDynamicSection(); 65 bool ReserveAddressSpace(address_space_params* address_space); 66 bool LoadSegments(); 67 bool FindPhdr(); 68 bool CheckPhdr(ElfW(Addr)); 69 bool CheckFileRange(ElfW(Addr) offset, size_t size, size_t alignment); 70 71 bool did_read_; 72 bool did_load_; 73 std::string name_; 74 int fd_; 75 off64_t file_offset_; 76 off64_t file_size_; 77 78 ElfW(Ehdr) header_; 79 size_t phdr_num_; 80 81 MappedFileFragment phdr_fragment_; 82 const ElfW(Phdr)* phdr_table_; 83 84 MappedFileFragment shdr_fragment_; 85 const ElfW(Shdr)* shdr_table_; 86 size_t shdr_num_; 87 88 MappedFileFragment dynamic_fragment_; 89 const ElfW(Dyn)* dynamic_; 90 91 MappedFileFragment strtab_fragment_; 92 const char* strtab_; 93 size_t strtab_size_; 94 95 // First page of reserved address space. 96 void* load_start_; 97 // Size in bytes of reserved address space. 98 size_t load_size_; 99 // Load bias. 100 ElfW(Addr) load_bias_; 101 102 // Loaded phdr. 103 const ElfW(Phdr)* loaded_phdr_; 104 105 // Is map owned by the caller 106 bool mapped_by_caller_; 107 }; 108 109 size_t phdr_table_get_load_size(const ElfW(Phdr)* phdr_table, size_t phdr_count, 110 ElfW(Addr)* min_vaddr = nullptr, ElfW(Addr)* max_vaddr = nullptr); 111 112 int phdr_table_protect_segments(const ElfW(Phdr)* phdr_table, 113 size_t phdr_count, ElfW(Addr) load_bias); 114 115 int phdr_table_unprotect_segments(const ElfW(Phdr)* phdr_table, size_t phdr_count, 116 ElfW(Addr) load_bias); 117 118 int phdr_table_protect_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count, 119 ElfW(Addr) load_bias); 120 121 int phdr_table_serialize_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count, 122 ElfW(Addr) load_bias, int fd, size_t* file_offset); 123 124 int phdr_table_map_gnu_relro(const ElfW(Phdr)* phdr_table, size_t phdr_count, 125 ElfW(Addr) load_bias, int fd, size_t* file_offset); 126 127 #if defined(__arm__) 128 int phdr_table_get_arm_exidx(const ElfW(Phdr)* phdr_table, size_t phdr_count, ElfW(Addr) load_bias, 129 ElfW(Addr)** arm_exidx, size_t* arm_exidix_count); 130 #endif 131 132 void phdr_table_get_dynamic_section(const ElfW(Phdr)* phdr_table, size_t phdr_count, 133 ElfW(Addr) load_bias, ElfW(Dyn)** dynamic, 134 ElfW(Word)* dynamic_flags); 135 136 const char* phdr_table_get_interpreter_name(const ElfW(Phdr) * phdr_table, size_t phdr_count, 137 ElfW(Addr) load_bias); 138