1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_OAT_ELF_FILE_IMPL_H_ 18 #define ART_RUNTIME_OAT_ELF_FILE_IMPL_H_ 19 20 #include <type_traits> 21 #include <vector> 22 23 #include "base/macros.h" 24 #include "base/mem_map.h" 25 #include "base/os.h" 26 #include "elf_file.h" 27 28 namespace art HIDDEN { 29 30 template <typename ElfTypes> 31 class ElfFileImpl : public ElfFile { 32 public: 33 using Elf_Addr = typename ElfTypes::Addr; 34 using Elf_Off = typename ElfTypes::Off; 35 using Elf_Half = typename ElfTypes::Half; 36 using Elf_Word = typename ElfTypes::Word; 37 using Elf_Sword = typename ElfTypes::Sword; 38 using Elf_Ehdr = typename ElfTypes::Ehdr; 39 using Elf_Shdr = typename ElfTypes::Shdr; 40 using Elf_Sym = typename ElfTypes::Sym; 41 using Elf_Rel = typename ElfTypes::Rel; 42 using Elf_Rela = typename ElfTypes::Rela; 43 using Elf_Phdr = typename ElfTypes::Phdr; 44 using Elf_Dyn = typename ElfTypes::Dyn; 45 46 static ElfFileImpl* Open(File* file, 47 off_t start, 48 size_t file_length, 49 const std::string& file_location, 50 bool low_4gb, 51 /*out*/ std::string* error_msg); 52 53 Elf_Ehdr& GetHeader() const; 54 55 Elf_Word GetProgramHeaderNum() const; 56 Elf_Phdr* GetProgramHeader(Elf_Word) const; 57 58 Elf_Word GetSectionHeaderNum() const; 59 Elf_Shdr* FindSectionByType(Elf_Word type) const; 60 61 // Find .dynsym using .hash for more efficient lookup than FindSymbolAddress. 62 const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name) const override; 63 64 static bool IsSymbolSectionType(Elf_Word section_type); 65 Elf_Word GetSymbolNum(Elf_Shdr&) const; 66 Elf_Sym* GetSymbol(Elf_Word section_type, Elf_Word i) const; 67 68 Elf_Word GetDynamicNum() const; 69 Elf_Dyn& GetDynamic(Elf_Word) const; 70 71 // Retrieves the expected size when the file is loaded at runtime. Returns true if successful. 72 bool GetLoadedSize(size_t* size, std::string* error_msg) const override; 73 74 // Get the alignment of the first loadable program segment. Return 0 if no loadable segment found. 75 size_t GetElfSegmentAlignmentFromFile() const override; 76 77 // Load segments into memory based on PT_LOAD program headers. 78 // executable is true at run time, false at compile time. 79 bool Load(bool executable, 80 bool low_4gb, 81 /*inout*/ MemMap* reservation, 82 /*out*/ std::string* error_msg) override; 83 Is64Bit()84 bool Is64Bit() const override { return std::is_same_v<ElfTypes, ElfTypes64>; } 85 86 private: ElfFileImpl(File * file,off_t start,size_t file_length,const std::string & file_location)87 ElfFileImpl(File* file, off_t start, size_t file_length, const std::string& file_location) 88 : ElfFile(file, start, file_length, file_location) {} 89 90 bool GetLoadedAddressRange(/*out*/uint8_t** vaddr_begin, 91 /*out*/size_t* vaddr_size, 92 /*out*/std::string* error_msg) const; 93 94 bool Setup(bool low_4gb, std::string* error_msg); 95 96 bool SetMap(MemMap&& map, std::string* error_msg); 97 98 uint8_t* GetProgramHeadersStart() const; 99 Elf_Phdr& GetDynamicProgramHeader() const; 100 Elf_Dyn* GetDynamicSectionStart() const; 101 Elf_Sym* GetSymbolSectionStart(Elf_Word section_type) const; 102 const char* GetStringSectionStart(Elf_Word section_type) const; 103 Elf_Word* GetHashSectionStart() const; 104 Elf_Word GetHashBucketNum() const; 105 Elf_Word GetHashChainNum() const; 106 Elf_Word GetHashBucket(size_t i, bool* ok) const; 107 Elf_Word GetHashChain(size_t i, bool* ok) const; 108 109 bool ValidPointer(const uint8_t* start) const; 110 111 const Elf_Sym* FindDynamicSymbol(const std::string& symbol_name) const; 112 113 // Check that certain sections and their dependencies exist. 114 bool CheckSectionsExist(std::string* error_msg) const; 115 116 Elf_Phdr* FindProgamHeaderByType(Elf_Word type) const; 117 118 // Lookup a string by section type. Returns null for special 0 offset. 119 const char* GetString(Elf_Word section_type, Elf_Word) const; 120 121 Elf_Ehdr* header_ = nullptr; 122 123 // Conditionally available values. Use accessors to ensure they exist if they are required. 124 uint8_t* section_headers_start_ = nullptr; 125 Elf_Phdr* dynamic_program_header_ = nullptr; 126 Elf_Dyn* dynamic_section_start_ = nullptr; 127 Elf_Sym* symtab_section_start_ = nullptr; 128 Elf_Sym* dynsym_section_start_ = nullptr; 129 char* strtab_section_start_ = nullptr; 130 char* dynstr_section_start_ = nullptr; 131 Elf_Word* hash_section_start_ = nullptr; 132 133 DISALLOW_COPY_AND_ASSIGN(ElfFileImpl); 134 }; 135 136 } // namespace art 137 138 #endif // ART_RUNTIME_OAT_ELF_FILE_IMPL_H_ 139