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_ELF_FILE_H_ 18 #define ART_RUNTIME_ELF_FILE_H_ 19 20 #include <map> 21 #include <vector> 22 23 #include <llvm/Support/ELF.h> 24 25 #include "base/unix_file/fd_file.h" 26 #include "globals.h" 27 #include "mem_map.h" 28 #include "os.h" 29 #include "UniquePtr.h" 30 31 namespace art { 32 33 // Used for compile time and runtime for ElfFile access. Because of 34 // the need for use at runtime, cannot directly use LLVM classes such as 35 // ELFObjectFile. 36 class ElfFile { 37 public: 38 static ElfFile* Open(File* file, bool writable, bool program_header_only); 39 ~ElfFile(); 40 41 // Load segments into memory based on PT_LOAD program headers 42 GetFile()43 File& GetFile() const { 44 return *file_; 45 } 46 Begin()47 byte* Begin() { 48 return map_->Begin(); 49 } 50 End()51 byte* End() { 52 return map_->End(); 53 } 54 Size()55 size_t Size() const { 56 return map_->Size(); 57 } 58 59 ::llvm::ELF::Elf32_Ehdr& GetHeader(); 60 61 ::llvm::ELF::Elf32_Word GetProgramHeaderNum(); 62 ::llvm::ELF::Elf32_Phdr& GetProgramHeader(::llvm::ELF::Elf32_Word); 63 ::llvm::ELF::Elf32_Phdr* FindProgamHeaderByType(::llvm::ELF::Elf32_Word type); 64 65 ::llvm::ELF::Elf32_Word GetSectionHeaderNum(); 66 ::llvm::ELF::Elf32_Shdr& GetSectionHeader(::llvm::ELF::Elf32_Word); 67 ::llvm::ELF::Elf32_Shdr* FindSectionByType(::llvm::ELF::Elf32_Word type); 68 69 ::llvm::ELF::Elf32_Shdr& GetSectionNameStringSection(); 70 71 // Find .dynsym using .hash for more efficient lookup than FindSymbolAddress. 72 byte* FindDynamicSymbolAddress(const std::string& symbol_name); 73 74 static bool IsSymbolSectionType(::llvm::ELF::Elf32_Word section_type); 75 ::llvm::ELF::Elf32_Word GetSymbolNum(::llvm::ELF::Elf32_Shdr&); 76 ::llvm::ELF::Elf32_Sym& GetSymbol(::llvm::ELF::Elf32_Word section_type, ::llvm::ELF::Elf32_Word i); 77 78 // Find symbol in specified table, returning NULL if it is not found. 79 // 80 // If build_map is true, builds a map to speed repeated access. The 81 // map does not included untyped symbol values (aka STT_NOTYPE) 82 // since they can contain duplicates. If build_map is false, the map 83 // will be used if it was already created. Typically build_map 84 // should be set unless only a small number of symbols will be 85 // looked up. 86 ::llvm::ELF::Elf32_Sym* FindSymbolByName(::llvm::ELF::Elf32_Word section_type, 87 const std::string& symbol_name, 88 bool build_map); 89 90 // Find address of symbol in specified table, returning 0 if it is 91 // not found. See FindSymbolByName for an explanation of build_map. 92 ::llvm::ELF::Elf32_Addr FindSymbolAddress(::llvm::ELF::Elf32_Word section_type, 93 const std::string& symbol_name, 94 bool build_map); 95 96 // Lookup a string given string section and offset. Returns NULL for 97 // special 0 offset. 98 const char* GetString(::llvm::ELF::Elf32_Shdr&, ::llvm::ELF::Elf32_Word); 99 100 // Lookup a string by section type. Returns NULL for special 0 offset. 101 const char* GetString(::llvm::ELF::Elf32_Word section_type, ::llvm::ELF::Elf32_Word); 102 103 ::llvm::ELF::Elf32_Word GetDynamicNum(); 104 ::llvm::ELF::Elf32_Dyn& GetDynamic(::llvm::ELF::Elf32_Word); 105 ::llvm::ELF::Elf32_Word FindDynamicValueByType(::llvm::ELF::Elf32_Sword type); 106 107 ::llvm::ELF::Elf32_Word GetRelNum(::llvm::ELF::Elf32_Shdr&); 108 ::llvm::ELF::Elf32_Rel& GetRel(::llvm::ELF::Elf32_Shdr&, ::llvm::ELF::Elf32_Word); 109 110 ::llvm::ELF::Elf32_Word GetRelaNum(::llvm::ELF::Elf32_Shdr&); 111 ::llvm::ELF::Elf32_Rela& GetRela(::llvm::ELF::Elf32_Shdr&, ::llvm::ELF::Elf32_Word); 112 113 // Returns the expected size when the file is loaded at runtime 114 size_t GetLoadedSize(); 115 116 // Load segments into memory based on PT_LOAD program headers. 117 // executable is true at run time, false at compile time. 118 bool Load(bool executable); 119 120 private: 121 ElfFile(); 122 123 bool Setup(File* file, bool writable, bool program_header_only); 124 125 bool SetMap(MemMap* map); 126 127 byte* GetProgramHeadersStart(); 128 byte* GetSectionHeadersStart(); 129 ::llvm::ELF::Elf32_Phdr& GetDynamicProgramHeader(); 130 ::llvm::ELF::Elf32_Dyn* GetDynamicSectionStart(); 131 ::llvm::ELF::Elf32_Sym* GetSymbolSectionStart(::llvm::ELF::Elf32_Word section_type); 132 const char* GetStringSectionStart(::llvm::ELF::Elf32_Word section_type); 133 ::llvm::ELF::Elf32_Rel* GetRelSectionStart(::llvm::ELF::Elf32_Shdr&); 134 ::llvm::ELF::Elf32_Rela* GetRelaSectionStart(::llvm::ELF::Elf32_Shdr&); 135 ::llvm::ELF::Elf32_Word* GetHashSectionStart(); 136 ::llvm::ELF::Elf32_Word GetHashBucketNum(); 137 ::llvm::ELF::Elf32_Word GetHashChainNum(); 138 ::llvm::ELF::Elf32_Word GetHashBucket(size_t i); 139 ::llvm::ELF::Elf32_Word GetHashChain(size_t i); 140 141 typedef std::map<std::string, ::llvm::ELF::Elf32_Sym*> SymbolTable; 142 SymbolTable** GetSymbolTable(::llvm::ELF::Elf32_Word section_type); 143 144 File* file_; 145 bool writable_; 146 bool program_header_only_; 147 148 // ELF header mapping. If program_header_only_ is false, will actually point to the entire elf file. 149 UniquePtr<MemMap> map_; 150 ::llvm::ELF::Elf32_Ehdr* header_; 151 std::vector<MemMap*> segments_; 152 153 // Pointer to start of first PT_LOAD program segment after Load() when program_header_only_ is true. 154 byte* base_address_; 155 156 // The program header should always available but use GetProgramHeadersStart() to be sure. 157 byte* program_headers_start_; 158 159 // Conditionally available values. Use accessors to ensure they exist if they are required. 160 byte* section_headers_start_; 161 ::llvm::ELF::Elf32_Phdr* dynamic_program_header_; 162 ::llvm::ELF::Elf32_Dyn* dynamic_section_start_; 163 ::llvm::ELF::Elf32_Sym* symtab_section_start_; 164 ::llvm::ELF::Elf32_Sym* dynsym_section_start_; 165 const char* strtab_section_start_; 166 const char* dynstr_section_start_; 167 ::llvm::ELF::Elf32_Word* hash_section_start_; 168 169 SymbolTable* symtab_symbol_table_; 170 SymbolTable* dynsym_symbol_table_; 171 }; 172 173 } // namespace art 174 175 #endif // ART_RUNTIME_ELF_FILE_H_ 176