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