1 /* 2 * Copyright (C) 2016 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 _LIBUNWINDSTACK_ELF_INTERFACE_H 18 #define _LIBUNWINDSTACK_ELF_INTERFACE_H 19 20 #include <elf.h> 21 #include <stdint.h> 22 23 #include <memory> 24 #include <string> 25 #include <unordered_map> 26 #include <vector> 27 28 #include <unwindstack/DwarfSection.h> 29 #include <unwindstack/Error.h> 30 31 namespace unwindstack { 32 33 // Forward declarations. 34 class Memory; 35 class Regs; 36 class Symbols; 37 38 struct LoadInfo { 39 uint64_t offset; 40 uint64_t table_offset; 41 size_t table_size; 42 }; 43 44 enum : uint8_t { 45 SONAME_UNKNOWN = 0, 46 SONAME_VALID, 47 SONAME_INVALID, 48 }; 49 50 class ElfInterface { 51 public: ElfInterface(Memory * memory)52 ElfInterface(Memory* memory) : memory_(memory) {} 53 virtual ~ElfInterface(); 54 55 virtual bool Init(uint64_t* load_bias) = 0; 56 57 virtual void InitHeaders() = 0; 58 59 virtual bool GetSoname(std::string* name) = 0; 60 61 virtual bool GetFunctionName(uint64_t addr, uint64_t load_bias, std::string* name, 62 uint64_t* offset) = 0; 63 64 virtual bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) = 0; 65 66 virtual bool Step(uint64_t rel_pc, uint64_t load_bias, Regs* regs, Memory* process_memory, 67 bool* finished); 68 69 virtual bool IsValidPc(uint64_t pc); 70 71 Memory* CreateGnuDebugdataMemory(); 72 memory()73 Memory* memory() { return memory_; } 74 pt_loads()75 const std::unordered_map<uint64_t, LoadInfo>& pt_loads() { return pt_loads_; } 76 SetGnuDebugdataInterface(ElfInterface * interface)77 void SetGnuDebugdataInterface(ElfInterface* interface) { gnu_debugdata_interface_ = interface; } 78 dynamic_offset()79 uint64_t dynamic_offset() { return dynamic_offset_; } dynamic_vaddr()80 uint64_t dynamic_vaddr() { return dynamic_vaddr_; } dynamic_size()81 uint64_t dynamic_size() { return dynamic_size_; } eh_frame_hdr_offset()82 uint64_t eh_frame_hdr_offset() { return eh_frame_hdr_offset_; } eh_frame_hdr_size()83 uint64_t eh_frame_hdr_size() { return eh_frame_hdr_size_; } eh_frame_offset()84 uint64_t eh_frame_offset() { return eh_frame_offset_; } eh_frame_size()85 uint64_t eh_frame_size() { return eh_frame_size_; } debug_frame_offset()86 uint64_t debug_frame_offset() { return debug_frame_offset_; } debug_frame_size()87 uint64_t debug_frame_size() { return debug_frame_size_; } gnu_debugdata_offset()88 uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; } gnu_debugdata_size()89 uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; } 90 eh_frame()91 DwarfSection* eh_frame() { return eh_frame_.get(); } debug_frame()92 DwarfSection* debug_frame() { return debug_frame_.get(); } 93 last_error()94 const ErrorData& last_error() { return last_error_; } LastErrorCode()95 ErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()96 uint64_t LastErrorAddress() { return last_error_.address; } 97 98 template <typename EhdrType, typename PhdrType> 99 static uint64_t GetLoadBias(Memory* memory); 100 101 protected: 102 template <typename AddressType> 103 void InitHeadersWithTemplate(); 104 105 template <typename EhdrType, typename PhdrType, typename ShdrType> 106 bool ReadAllHeaders(uint64_t* load_bias); 107 108 template <typename EhdrType, typename PhdrType> 109 bool ReadProgramHeaders(const EhdrType& ehdr, uint64_t* load_bias); 110 111 template <typename EhdrType, typename ShdrType> 112 bool ReadSectionHeaders(const EhdrType& ehdr); 113 114 template <typename DynType> 115 bool GetSonameWithTemplate(std::string* soname); 116 117 template <typename SymType> 118 bool GetFunctionNameWithTemplate(uint64_t addr, uint64_t load_bias, std::string* name, 119 uint64_t* func_offset); 120 121 template <typename SymType> 122 bool GetGlobalVariableWithTemplate(const std::string& name, uint64_t* memory_address); 123 HandleType(uint64_t,uint32_t,uint64_t)124 virtual bool HandleType(uint64_t, uint32_t, uint64_t) { return false; } 125 126 template <typename EhdrType> 127 static void GetMaxSizeWithTemplate(Memory* memory, uint64_t* size); 128 129 Memory* memory_; 130 std::unordered_map<uint64_t, LoadInfo> pt_loads_; 131 132 // Stored elf data. 133 uint64_t dynamic_offset_ = 0; 134 uint64_t dynamic_vaddr_ = 0; 135 uint64_t dynamic_size_ = 0; 136 137 uint64_t eh_frame_hdr_offset_ = 0; 138 uint64_t eh_frame_hdr_size_ = 0; 139 140 uint64_t eh_frame_offset_ = 0; 141 uint64_t eh_frame_size_ = 0; 142 143 uint64_t debug_frame_offset_ = 0; 144 uint64_t debug_frame_size_ = 0; 145 146 uint64_t gnu_debugdata_offset_ = 0; 147 uint64_t gnu_debugdata_size_ = 0; 148 149 uint8_t soname_type_ = SONAME_UNKNOWN; 150 std::string soname_; 151 152 ErrorData last_error_{ERROR_NONE, 0}; 153 154 std::unique_ptr<DwarfSection> eh_frame_; 155 std::unique_ptr<DwarfSection> debug_frame_; 156 // The Elf object owns the gnu_debugdata interface object. 157 ElfInterface* gnu_debugdata_interface_ = nullptr; 158 159 std::vector<Symbols*> symbols_; 160 std::vector<std::pair<uint64_t, uint64_t>> strtabs_; 161 }; 162 163 class ElfInterface32 : public ElfInterface { 164 public: ElfInterface32(Memory * memory)165 ElfInterface32(Memory* memory) : ElfInterface(memory) {} 166 virtual ~ElfInterface32() = default; 167 Init(uint64_t * load_bias)168 bool Init(uint64_t* load_bias) override { 169 return ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(load_bias); 170 } 171 InitHeaders()172 void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint32_t>(); } 173 GetSoname(std::string * soname)174 bool GetSoname(std::string* soname) override { 175 return ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(soname); 176 } 177 GetFunctionName(uint64_t addr,uint64_t load_bias,std::string * name,uint64_t * func_offset)178 bool GetFunctionName(uint64_t addr, uint64_t load_bias, std::string* name, 179 uint64_t* func_offset) override { 180 return ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(addr, load_bias, name, func_offset); 181 } 182 GetGlobalVariable(const std::string & name,uint64_t * memory_address)183 bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override { 184 return ElfInterface::GetGlobalVariableWithTemplate<Elf32_Sym>(name, memory_address); 185 } 186 GetMaxSize(Memory * memory,uint64_t * size)187 static void GetMaxSize(Memory* memory, uint64_t* size) { 188 GetMaxSizeWithTemplate<Elf32_Ehdr>(memory, size); 189 } 190 }; 191 192 class ElfInterface64 : public ElfInterface { 193 public: ElfInterface64(Memory * memory)194 ElfInterface64(Memory* memory) : ElfInterface(memory) {} 195 virtual ~ElfInterface64() = default; 196 Init(uint64_t * load_bias)197 bool Init(uint64_t* load_bias) override { 198 return ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(load_bias); 199 } 200 InitHeaders()201 void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint64_t>(); } 202 GetSoname(std::string * soname)203 bool GetSoname(std::string* soname) override { 204 return ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(soname); 205 } 206 GetFunctionName(uint64_t addr,uint64_t load_bias,std::string * name,uint64_t * func_offset)207 bool GetFunctionName(uint64_t addr, uint64_t load_bias, std::string* name, 208 uint64_t* func_offset) override { 209 return ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(addr, load_bias, name, func_offset); 210 } 211 GetGlobalVariable(const std::string & name,uint64_t * memory_address)212 bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override { 213 return ElfInterface::GetGlobalVariableWithTemplate<Elf64_Sym>(name, memory_address); 214 } 215 GetMaxSize(Memory * memory,uint64_t * size)216 static void GetMaxSize(Memory* memory, uint64_t* size) { 217 GetMaxSizeWithTemplate<Elf64_Ehdr>(memory, size); 218 } 219 }; 220 221 } // namespace unwindstack 222 223 #endif // _LIBUNWINDSTACK_ELF_INTERFACE_H 224