Home | History | Annotate | Download | only in unwindstack
      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:
     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 
     73   Memory* memory() { return memory_; }
     74 
     75   const std::unordered_map<uint64_t, LoadInfo>& pt_loads() { return pt_loads_; }
     76 
     77   void SetGnuDebugdataInterface(ElfInterface* interface) { gnu_debugdata_interface_ = interface; }
     78 
     79   uint64_t dynamic_offset() { return dynamic_offset_; }
     80   uint64_t dynamic_vaddr() { return dynamic_vaddr_; }
     81   uint64_t dynamic_size() { return dynamic_size_; }
     82   uint64_t eh_frame_hdr_offset() { return eh_frame_hdr_offset_; }
     83   uint64_t eh_frame_hdr_size() { return eh_frame_hdr_size_; }
     84   uint64_t eh_frame_offset() { return eh_frame_offset_; }
     85   uint64_t eh_frame_size() { return eh_frame_size_; }
     86   uint64_t debug_frame_offset() { return debug_frame_offset_; }
     87   uint64_t debug_frame_size() { return debug_frame_size_; }
     88   uint64_t gnu_debugdata_offset() { return gnu_debugdata_offset_; }
     89   uint64_t gnu_debugdata_size() { return gnu_debugdata_size_; }
     90 
     91   DwarfSection* eh_frame() { return eh_frame_.get(); }
     92   DwarfSection* debug_frame() { return debug_frame_.get(); }
     93 
     94   const ErrorData& last_error() { return last_error_; }
     95   ErrorCode LastErrorCode() { return last_error_.code; }
     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 
    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:
    165   ElfInterface32(Memory* memory) : ElfInterface(memory) {}
    166   virtual ~ElfInterface32() = default;
    167 
    168   bool Init(uint64_t* load_bias) override {
    169     return ElfInterface::ReadAllHeaders<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(load_bias);
    170   }
    171 
    172   void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint32_t>(); }
    173 
    174   bool GetSoname(std::string* soname) override {
    175     return ElfInterface::GetSonameWithTemplate<Elf32_Dyn>(soname);
    176   }
    177 
    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 
    183   bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override {
    184     return ElfInterface::GetGlobalVariableWithTemplate<Elf32_Sym>(name, memory_address);
    185   }
    186 
    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:
    194   ElfInterface64(Memory* memory) : ElfInterface(memory) {}
    195   virtual ~ElfInterface64() = default;
    196 
    197   bool Init(uint64_t* load_bias) override {
    198     return ElfInterface::ReadAllHeaders<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>(load_bias);
    199   }
    200 
    201   void InitHeaders() override { ElfInterface::InitHeadersWithTemplate<uint64_t>(); }
    202 
    203   bool GetSoname(std::string* soname) override {
    204     return ElfInterface::GetSonameWithTemplate<Elf64_Dyn>(soname);
    205   }
    206 
    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 
    212   bool GetGlobalVariable(const std::string& name, uint64_t* memory_address) override {
    213     return ElfInterface::GetGlobalVariableWithTemplate<Elf64_Sym>(name, memory_address);
    214   }
    215 
    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