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 30 namespace unwindstack { 31 32 // Forward declarations. 33 class Memory; 34 class Regs; 35 class Symbols; 36 37 struct LoadInfo { 38 uint64_t offset; 39 uint64_t table_offset; 40 size_t table_size; 41 }; 42 43 enum : uint8_t { 44 SONAME_UNKNOWN = 0, 45 SONAME_VALID, 46 SONAME_INVALID, 47 }; 48 49 class ElfInterface { 50 public: ElfInterface(Memory * memory)51 ElfInterface(Memory* memory) : memory_(memory) {} 52 virtual ~ElfInterface(); 53 54 virtual bool Init() = 0; 55 56 virtual void InitHeaders() = 0; 57 58 virtual bool GetSoname(std::string* name) = 0; 59 60 virtual bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* offset) = 0; 61 62 virtual bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory); 63 64 Memory* CreateGnuDebugdataMemory(); 65 memory()66 Memory* memory() { return memory_; } 67 pt_loads()68 const std::unordered_map<uint64_t, LoadInfo>& pt_loads() { return pt_loads_; } load_bias()69 uint64_t load_bias() { return load_bias_; } set_load_bias(uint64_t load_bias)70 void set_load_bias(uint64_t load_bias) { load_bias_ = load_bias; } 71 dynamic_offset()72 uint64_t dynamic_offset() { return dynamic_offset_; } dynamic_size()73 uint64_t dynamic_size() { return dynamic_size_; } eh_frame_offset()74 uint64_t eh_frame_offset() { return eh_frame_offset_; } eh_frame_size()75 uint64_t eh_frame_size() { return eh_frame_size_; } debug_frame_offset()76 uint64_t debug_frame_offset() { return debug_frame_offset_; } debug_frame_size()77 uint64_t debug_frame_size() { return debug_frame_size_; } gnu_debugdata_offset()78 uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; } gnu_debugdata_size()79 uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; } 80 eh_frame()81 DwarfSection* eh_frame() { return eh_frame_.get(); } debug_frame()82 DwarfSection* debug_frame() { return debug_frame_.get(); } 83 84 protected: 85 template <typename AddressType> 86 void InitHeadersWithTemplate(); 87 88 template <typename EhdrType, typename PhdrType, typename ShdrType> 89 bool ReadAllHeaders(); 90 91 template <typename EhdrType, typename PhdrType> 92 bool ReadProgramHeaders(const EhdrType& ehdr); 93 94 template <typename EhdrType, typename ShdrType> 95 bool ReadSectionHeaders(const EhdrType& ehdr); 96 97 template <typename DynType> 98 bool GetSonameWithTemplate(std::string* soname); 99 100 template <typename SymType> 101 bool GetFunctionNameWithTemplate(uint64_t addr, std::string* name, uint64_t* func_offset); 102 HandleType(uint64_t,uint32_t)103 virtual bool HandleType(uint64_t, uint32_t) { return false; } 104 105 Memory* memory_; 106 std::unordered_map<uint64_t, LoadInfo> pt_loads_; 107 uint64_t load_bias_ = 0; 108 109 // Stored elf data. 110 uint64_t dynamic_offset_ = 0; 111 uint64_t dynamic_size_ = 0; 112 113 uint64_t eh_frame_offset_ = 0; 114 uint64_t eh_frame_size_ = 0; 115 116 uint64_t debug_frame_offset_ = 0; 117 uint64_t debug_frame_size_ = 0; 118 119 uint64_t gnu_debugdata_offset_ = 0; 120 uint64_t gnu_debugdata_size_ = 0; 121 122 uint8_t soname_type_ = SONAME_UNKNOWN; 123 std::string soname_; 124 125 std::unique_ptr<DwarfSection> eh_frame_; 126 std::unique_ptr<DwarfSection> debug_frame_; 127 128 std::vector<Symbols*> symbols_; 129 }; 130 131 class ElfInterface32 : public ElfInterface { 132 public: ElfInterface32(Memory * memory)133 ElfInterface32(Memory* memory) : ElfInterface(memory) {} 134 virtual ~ElfInterface32() = default; 135 Init()136 bool Init() override { 137 return ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(); 138 } 139 InitHeaders()140 void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint32_t>(); } 141 GetSoname(std::string * soname)142 bool GetSoname(std::string* soname) override { 143 return ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(soname); 144 } 145 GetFunctionName(uint64_t addr,std::string * name,uint64_t * func_offset)146 bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) override { 147 return ElfInterface::GetFunctionNameWithTemplate<Elf32_Sym>(addr, name, func_offset); 148 } 149 }; 150 151 class ElfInterface64 : public ElfInterface { 152 public: ElfInterface64(Memory * memory)153 ElfInterface64(Memory* memory) : ElfInterface(memory) {} 154 virtual ~ElfInterface64() = default; 155 Init()156 bool Init() override { 157 return ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(); 158 } 159 InitHeaders()160 void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint64_t>(); } 161 GetSoname(std::string * soname)162 bool GetSoname(std::string* soname) override { 163 return ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(soname); 164 } 165 GetFunctionName(uint64_t addr,std::string * name,uint64_t * func_offset)166 bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) override { 167 return ElfInterface::GetFunctionNameWithTemplate<Elf64_Sym>(addr, name, func_offset); 168 } 169 }; 170 171 } // namespace unwindstack 172 173 #endif // _LIBUNWINDSTACK_ELF_INTERFACE_H 174