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