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 <utility> 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 struct SectionInfo { 46 uint64_t offset; 47 uint64_t size; 48 uint64_t flags; 49 int64_t bias; 50 }; 51 52 enum : uint8_t { 53 SONAME_UNKNOWN = 0, 54 SONAME_VALID, 55 SONAME_INVALID, 56 }; 57 58 struct ElfTypes32 { 59 using AddressType = uint32_t; 60 using Chdr = Elf32_Chdr; 61 using Dyn = Elf32_Dyn; 62 using Ehdr = Elf32_Ehdr; 63 using Nhdr = Elf32_Nhdr; 64 using Phdr = Elf32_Phdr; 65 using Shdr = Elf32_Shdr; 66 using Sym = Elf32_Sym; 67 }; 68 69 struct ElfTypes64 { 70 using AddressType = uint64_t; 71 using Chdr = Elf64_Chdr; 72 using Dyn = Elf64_Dyn; 73 using Ehdr = Elf64_Ehdr; 74 using Nhdr = Elf64_Nhdr; 75 using Phdr = Elf64_Phdr; 76 using Shdr = Elf64_Shdr; 77 using Sym = Elf64_Sym; 78 }; 79 80 class ElfInterface { 81 public: ElfInterface(std::shared_ptr<Memory> & memory)82 ElfInterface(std::shared_ptr<Memory>& memory) : memory_(memory) {} 83 virtual ~ElfInterface(); 84 85 virtual bool Init(int64_t* load_bias) = 0; 86 87 virtual void InitHeaders() = 0; 88 89 virtual std::string GetSoname() = 0; 90 91 virtual bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* offset) = 0; 92 93 virtual bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) = 0; 94 95 virtual std::string GetBuildID() = 0; 96 97 virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished, 98 bool* is_signal_frame); 99 100 virtual bool IsValidPc(uint64_t pc); 101 102 bool GetTextRange(uint64_t* addr, uint64_t* size); 103 104 std::shared_ptr<Memory> CreateGnuDebugdataMemory(); 105 memory()106 std::shared_ptr<Memory> memory() { return memory_; } 107 pt_loads()108 const std::unordered_map<uint64_t, LoadInfo>& pt_loads() { return pt_loads_; } 109 SetGnuDebugdataInterface(ElfInterface * interface)110 void SetGnuDebugdataInterface(ElfInterface* interface) { gnu_debugdata_interface_ = interface; } 111 dynamic_offset()112 uint64_t dynamic_offset() { return dynamic_offset_; } dynamic_vaddr_start()113 uint64_t dynamic_vaddr_start() { return dynamic_vaddr_start_; } dynamic_vaddr_end()114 uint64_t dynamic_vaddr_end() { return dynamic_vaddr_end_; } 115 data_offset()116 uint64_t data_offset() { return data_offset_; } data_vaddr_start()117 uint64_t data_vaddr_start() { return data_vaddr_start_; } data_vaddr_end()118 uint64_t data_vaddr_end() { return data_vaddr_end_; } 119 eh_frame_hdr_info()120 const SectionInfo& eh_frame_hdr_info() { return eh_frame_hdr_info_; } eh_frame_info()121 const SectionInfo& eh_frame_info() { return eh_frame_info_; } debug_frame_info()122 const SectionInfo& debug_frame_info() { return debug_frame_info_; } 123 gnu_debugdata_offset()124 uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; } gnu_debugdata_size()125 uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; } 126 gnu_build_id_offset()127 uint64_t gnu_build_id_offset() { return gnu_build_id_offset_; } gnu_build_id_size()128 uint64_t gnu_build_id_size() { return gnu_build_id_size_; } 129 eh_frame()130 DwarfSection* eh_frame() { return eh_frame_.get(); } debug_frame()131 DwarfSection* debug_frame() { return debug_frame_.get(); } 132 last_error()133 const ErrorData& last_error() { return last_error_; } LastErrorCode()134 ErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()135 uint64_t LastErrorAddress() { return last_error_.address; } 136 137 template <typename EhdrType, typename PhdrType> 138 static int64_t GetLoadBias(Memory* memory); 139 140 template <typename EhdrType, typename ShdrType, typename NhdrType> 141 static std::string ReadBuildIDFromMemory(Memory* memory); 142 143 protected: HandleUnknownType(uint32_t,uint64_t,uint64_t)144 virtual void HandleUnknownType(uint32_t, uint64_t, uint64_t) {} 145 146 std::shared_ptr<Memory> memory_; 147 std::unordered_map<uint64_t, LoadInfo> pt_loads_; 148 149 // Stored elf data. 150 uint64_t dynamic_offset_ = 0; 151 uint64_t dynamic_vaddr_start_ = 0; 152 uint64_t dynamic_vaddr_end_ = 0; 153 154 uint64_t data_offset_ = 0; 155 uint64_t data_vaddr_start_ = 0; 156 uint64_t data_vaddr_end_ = 0; 157 158 SectionInfo eh_frame_hdr_info_ = {}; 159 SectionInfo eh_frame_info_ = {}; 160 SectionInfo debug_frame_info_ = {}; 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 ChdrType = typename ElfTypes::Chdr; 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(std::shared_ptr<Memory> & memory)197 ElfInterfaceImpl(std::shared_ptr<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