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