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