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