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(int64_t* load_bias) = 0; 56 57 virtual void InitHeaders() = 0; 58 59 virtual std::string GetSoname() = 0; 60 61 virtual bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* offset) = 0; 62 63 virtual bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) = 0; 64 65 virtual std::string GetBuildID() = 0; 66 67 virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, 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_start()80 uint64_t dynamic_vaddr_start() { return dynamic_vaddr_start_; } dynamic_vaddr_end()81 uint64_t dynamic_vaddr_end() { return dynamic_vaddr_end_; } data_offset()82 uint64_t data_offset() { return data_offset_; } data_vaddr_start()83 uint64_t data_vaddr_start() { return data_vaddr_start_; } data_vaddr_end()84 uint64_t data_vaddr_end() { return data_vaddr_end_; } eh_frame_hdr_offset()85 uint64_t eh_frame_hdr_offset() { return eh_frame_hdr_offset_; } eh_frame_hdr_section_bias()86 int64_t eh_frame_hdr_section_bias() { return eh_frame_hdr_section_bias_; } eh_frame_hdr_size()87 uint64_t eh_frame_hdr_size() { return eh_frame_hdr_size_; } eh_frame_offset()88 uint64_t eh_frame_offset() { return eh_frame_offset_; } eh_frame_section_bias()89 int64_t eh_frame_section_bias() { return eh_frame_section_bias_; } eh_frame_size()90 uint64_t eh_frame_size() { return eh_frame_size_; } debug_frame_offset()91 uint64_t debug_frame_offset() { return debug_frame_offset_; } debug_frame_section_bias()92 int64_t debug_frame_section_bias() { return debug_frame_section_bias_; } debug_frame_size()93 uint64_t debug_frame_size() { return debug_frame_size_; } gnu_debugdata_offset()94 uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; } gnu_debugdata_size()95 uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; } gnu_build_id_offset()96 uint64_t gnu_build_id_offset() { return gnu_build_id_offset_; } gnu_build_id_size()97 uint64_t gnu_build_id_size() { return gnu_build_id_size_; } 98 eh_frame()99 DwarfSection* eh_frame() { return eh_frame_.get(); } debug_frame()100 DwarfSection* debug_frame() { return debug_frame_.get(); } 101 last_error()102 const ErrorData& last_error() { return last_error_; } LastErrorCode()103 ErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()104 uint64_t LastErrorAddress() { return last_error_.address; } 105 106 template <typename EhdrType, typename PhdrType> 107 static int64_t GetLoadBias(Memory* memory); 108 109 template <typename EhdrType, typename ShdrType, typename NhdrType> 110 static std::string ReadBuildIDFromMemory(Memory* memory); 111 112 protected: 113 template <typename AddressType> 114 void InitHeadersWithTemplate(); 115 116 template <typename EhdrType, typename PhdrType, typename ShdrType> 117 bool ReadAllHeaders(int64_t* load_bias); 118 119 template <typename EhdrType, typename PhdrType> 120 void ReadProgramHeaders(const EhdrType& ehdr, int64_t* load_bias); 121 122 template <typename EhdrType, typename ShdrType> 123 void ReadSectionHeaders(const EhdrType& ehdr); 124 125 template <typename DynType> 126 std::string GetSonameWithTemplate(); 127 128 template <typename SymType> 129 bool GetFunctionNameWithTemplate(uint64_t addr, std::string* name, uint64_t* func_offset); 130 131 template <typename SymType> 132 bool GetGlobalVariableWithTemplate(const std::string& name, uint64_t* memory_address); 133 HandleUnknownType(uint32_t,uint64_t,uint64_t)134 virtual void HandleUnknownType(uint32_t, uint64_t, uint64_t) {} 135 136 template <typename EhdrType> 137 static void GetMaxSizeWithTemplate(Memory* memory, uint64_t* size); 138 139 template <typename NhdrType> 140 std::string ReadBuildID(); 141 142 Memory* memory_; 143 std::unordered_map<uint64_t, LoadInfo> pt_loads_; 144 145 // Stored elf data. 146 uint64_t dynamic_offset_ = 0; 147 uint64_t dynamic_vaddr_start_ = 0; 148 uint64_t dynamic_vaddr_end_ = 0; 149 150 uint64_t data_offset_ = 0; 151 uint64_t data_vaddr_start_ = 0; 152 uint64_t data_vaddr_end_ = 0; 153 154 uint64_t eh_frame_hdr_offset_ = 0; 155 int64_t eh_frame_hdr_section_bias_ = 0; 156 uint64_t eh_frame_hdr_size_ = 0; 157 158 uint64_t eh_frame_offset_ = 0; 159 int64_t eh_frame_section_bias_ = 0; 160 uint64_t eh_frame_size_ = 0; 161 162 uint64_t debug_frame_offset_ = 0; 163 int64_t debug_frame_section_bias_ = 0; 164 uint64_t debug_frame_size_ = 0; 165 166 uint64_t gnu_debugdata_offset_ = 0; 167 uint64_t gnu_debugdata_size_ = 0; 168 169 uint64_t gnu_build_id_offset_ = 0; 170 uint64_t gnu_build_id_size_ = 0; 171 172 uint8_t soname_type_ = SONAME_UNKNOWN; 173 std::string soname_; 174 175 ErrorData last_error_{ERROR_NONE, 0}; 176 177 std::unique_ptr<DwarfSection> eh_frame_; 178 std::unique_ptr<DwarfSection> debug_frame_; 179 // The Elf object owns the gnu_debugdata interface object. 180 ElfInterface* gnu_debugdata_interface_ = nullptr; 181 182 std::vector<Symbols*> symbols_; 183 std::vector<std::pair<uint64_t, uint64_t>> strtabs_; 184 }; 185 186 class ElfInterface32 : public ElfInterface { 187 public: ElfInterface32(Memory * memory)188 ElfInterface32(Memory* memory) : ElfInterface(memory) {} 189 virtual ~ElfInterface32() = default; 190 Init(int64_t * load_bias)191 bool Init(int64_t* load_bias) override { 192 return ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(load_bias); 193 } 194 InitHeaders()195 void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint32_t>(); } 196 GetSoname()197 std::string GetSoname() override { return ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(); } 198 GetFunctionName(uint64_t addr,std::string * name,uint64_t * func_offset)199 bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) override { 200 return ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(addr, name, func_offset); 201 } 202 GetGlobalVariable(const std::string & name,uint64_t * memory_address)203 bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override { 204 return ElfInterface::GetGlobalVariableWithTemplate<Elf32_Sym>(name, memory_address); 205 } 206 GetBuildID()207 std::string GetBuildID() override { return ElfInterface::ReadBuildID<Elf32_Nhdr>(); } 208 GetMaxSize(Memory * memory,uint64_t * size)209 static void GetMaxSize(Memory* memory, uint64_t* size) { 210 GetMaxSizeWithTemplate<Elf32_Ehdr>(memory, size); 211 } 212 }; 213 214 class ElfInterface64 : public ElfInterface { 215 public: ElfInterface64(Memory * memory)216 ElfInterface64(Memory* memory) : ElfInterface(memory) {} 217 virtual ~ElfInterface64() = default; 218 Init(int64_t * load_bias)219 bool Init(int64_t* load_bias) override { 220 return ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(load_bias); 221 } 222 InitHeaders()223 void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint64_t>(); } 224 GetSoname()225 std::string GetSoname() override { return ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(); } 226 GetFunctionName(uint64_t addr,std::string * name,uint64_t * func_offset)227 bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) override { 228 return ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(addr, name, func_offset); 229 } 230 GetGlobalVariable(const std::string & name,uint64_t * memory_address)231 bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override { 232 return ElfInterface::GetGlobalVariableWithTemplate<Elf64_Sym>(name, memory_address); 233 } 234 GetBuildID()235 std::string GetBuildID() override { return ElfInterface::ReadBuildID<Elf64_Nhdr>(); } 236 GetMaxSize(Memory * memory,uint64_t * size)237 static void GetMaxSize(Memory* memory, uint64_t* size) { 238 GetMaxSizeWithTemplate<Elf64_Ehdr>(memory, size); 239 } 240 }; 241 242 } // namespace unwindstack 243 244 #endif // _LIBUNWINDSTACK_ELF_INTERFACE_H 245