• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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