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 #include <unwindstack/SharedString.h> 31 32 namespace unwindstack { 33 34 // Forward declarations. 35 class Memory; 36 class Regs; 37 class Symbols; 38 39 struct LoadInfo { 40 uint64_t offset; 41 uint64_t table_offset; 42 size_t table_size; 43 }; 44 45 enum : uint8_t { 46 SONAME_UNKNOWN = 0, 47 SONAME_VALID, 48 SONAME_INVALID, 49 }; 50 51 struct ElfTypes32 { 52 using AddressType = uint32_t; 53 using Dyn = Elf32_Dyn; 54 using Ehdr = Elf32_Ehdr; 55 using Nhdr = Elf32_Nhdr; 56 using Phdr = Elf32_Phdr; 57 using Shdr = Elf32_Shdr; 58 using Sym = Elf32_Sym; 59 }; 60 61 struct ElfTypes64 { 62 using AddressType = uint64_t; 63 using Dyn = Elf64_Dyn; 64 using Ehdr = Elf64_Ehdr; 65 using Nhdr = Elf64_Nhdr; 66 using Phdr = Elf64_Phdr; 67 using Shdr = Elf64_Shdr; 68 using Sym = Elf64_Sym; 69 }; 70 71 class ElfInterface { 72 public: ElfInterface(Memory * memory)73 ElfInterface(Memory* memory) : memory_(memory) {} 74 virtual ~ElfInterface(); 75 76 virtual bool Init(int64_t* load_bias) = 0; 77 78 virtual void InitHeaders() = 0; 79 80 virtual std::string GetSoname() = 0; 81 82 virtual bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* offset) = 0; 83 84 virtual bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) = 0; 85 86 virtual std::string GetBuildID() = 0; 87 88 virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished, 89 bool* is_signal_frame); 90 91 virtual bool IsValidPc(uint64_t pc); 92 93 bool GetTextRange(uint64_t* addr, uint64_t* size); 94 95 std::unique_ptr<Memory> CreateGnuDebugdataMemory(); 96 memory()97 Memory* memory() { return memory_; } 98 pt_loads()99 const std::unordered_map<uint64_t, LoadInfo>& pt_loads() { return pt_loads_; } 100 SetGnuDebugdataInterface(ElfInterface * interface)101 void SetGnuDebugdataInterface(ElfInterface* interface) { gnu_debugdata_interface_ = interface; } 102 dynamic_offset()103 uint64_t dynamic_offset() { return dynamic_offset_; } dynamic_vaddr_start()104 uint64_t dynamic_vaddr_start() { return dynamic_vaddr_start_; } dynamic_vaddr_end()105 uint64_t dynamic_vaddr_end() { return dynamic_vaddr_end_; } data_offset()106 uint64_t data_offset() { return data_offset_; } data_vaddr_start()107 uint64_t data_vaddr_start() { return data_vaddr_start_; } data_vaddr_end()108 uint64_t data_vaddr_end() { return data_vaddr_end_; } eh_frame_hdr_offset()109 uint64_t eh_frame_hdr_offset() { return eh_frame_hdr_offset_; } eh_frame_hdr_section_bias()110 int64_t eh_frame_hdr_section_bias() { return eh_frame_hdr_section_bias_; } eh_frame_hdr_size()111 uint64_t eh_frame_hdr_size() { return eh_frame_hdr_size_; } eh_frame_offset()112 uint64_t eh_frame_offset() { return eh_frame_offset_; } eh_frame_section_bias()113 int64_t eh_frame_section_bias() { return eh_frame_section_bias_; } eh_frame_size()114 uint64_t eh_frame_size() { return eh_frame_size_; } debug_frame_offset()115 uint64_t debug_frame_offset() { return debug_frame_offset_; } debug_frame_section_bias()116 int64_t debug_frame_section_bias() { return debug_frame_section_bias_; } debug_frame_size()117 uint64_t debug_frame_size() { return debug_frame_size_; } gnu_debugdata_offset()118 uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; } gnu_debugdata_size()119 uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; } gnu_build_id_offset()120 uint64_t gnu_build_id_offset() { return gnu_build_id_offset_; } gnu_build_id_size()121 uint64_t gnu_build_id_size() { return gnu_build_id_size_; } 122 eh_frame()123 DwarfSection* eh_frame() { return eh_frame_.get(); } debug_frame()124 DwarfSection* debug_frame() { return debug_frame_.get(); } 125 last_error()126 const ErrorData& last_error() { return last_error_; } LastErrorCode()127 ErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()128 uint64_t LastErrorAddress() { return last_error_.address; } 129 130 template <typename EhdrType, typename PhdrType> 131 static int64_t GetLoadBias(Memory* memory); 132 133 template <typename EhdrType, typename ShdrType, typename NhdrType> 134 static std::string ReadBuildIDFromMemory(Memory* memory); 135 136 protected: HandleUnknownType(uint32_t,uint64_t,uint64_t)137 virtual void HandleUnknownType(uint32_t, uint64_t, uint64_t) {} 138 139 Memory* memory_; 140 std::unordered_map<uint64_t, LoadInfo> pt_loads_; 141 142 // Stored elf data. 143 uint64_t dynamic_offset_ = 0; 144 uint64_t dynamic_vaddr_start_ = 0; 145 uint64_t dynamic_vaddr_end_ = 0; 146 147 uint64_t data_offset_ = 0; 148 uint64_t data_vaddr_start_ = 0; 149 uint64_t data_vaddr_end_ = 0; 150 151 uint64_t eh_frame_hdr_offset_ = 0; 152 int64_t eh_frame_hdr_section_bias_ = 0; 153 uint64_t eh_frame_hdr_size_ = 0; 154 155 uint64_t eh_frame_offset_ = 0; 156 int64_t eh_frame_section_bias_ = 0; 157 uint64_t eh_frame_size_ = 0; 158 159 uint64_t debug_frame_offset_ = 0; 160 int64_t debug_frame_section_bias_ = 0; 161 uint64_t debug_frame_size_ = 0; 162 163 uint64_t gnu_debugdata_offset_ = 0; 164 uint64_t gnu_debugdata_size_ = 0; 165 166 uint64_t gnu_build_id_offset_ = 0; 167 uint64_t gnu_build_id_size_ = 0; 168 169 uint64_t text_addr_ = 0; 170 uint64_t text_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 template <typename ElfTypes> 187 class ElfInterfaceImpl : public ElfInterface { 188 public: 189 using AddressType = typename ElfTypes::AddressType; 190 using DynType = typename ElfTypes::Dyn; 191 using EhdrType = typename ElfTypes::Ehdr; 192 using NhdrType = typename ElfTypes::Nhdr; 193 using PhdrType = typename ElfTypes::Phdr; 194 using ShdrType = typename ElfTypes::Shdr; 195 using SymType = typename ElfTypes::Sym; 196 ElfInterfaceImpl(Memory * memory)197 ElfInterfaceImpl(Memory* memory) : ElfInterface(memory) {} 198 virtual ~ElfInterfaceImpl() = default; 199 Init(int64_t * load_bias)200 bool Init(int64_t* load_bias) override { return ReadAllHeaders(load_bias); } 201 202 void InitHeaders() override; 203 204 std::string GetSoname() override; 205 206 bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* func_offset) override; 207 208 bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override; 209 GetBuildID()210 std::string GetBuildID() override { return ReadBuildID(); } 211 212 static void GetMaxSize(Memory* memory, uint64_t* size); 213 214 protected: 215 bool ReadAllHeaders(int64_t* load_bias); 216 217 void ReadProgramHeaders(const EhdrType& ehdr, int64_t* load_bias); 218 219 void ReadSectionHeaders(const EhdrType& ehdr); 220 221 std::string ReadBuildID(); 222 }; 223 224 using ElfInterface32 = ElfInterfaceImpl<ElfTypes32>; 225 using ElfInterface64 = ElfInterfaceImpl<ElfTypes64>; 226 227 } // namespace unwindstack 228 229 #endif // _LIBUNWINDSTACK_ELF_INTERFACE_H 230