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_DWARF_SECTION_H 18 #define _LIBUNWINDSTACK_DWARF_SECTION_H 19 20 #include <stdint.h> 21 22 #include <iterator> 23 #include <map> 24 #include <unordered_map> 25 26 #include <unwindstack/DwarfError.h> 27 #include <unwindstack/DwarfLocation.h> 28 #include <unwindstack/DwarfMemory.h> 29 #include <unwindstack/DwarfStructs.h> 30 31 namespace unwindstack { 32 33 // Forward declarations. 34 class Memory; 35 class Regs; 36 template <typename AddressType> 37 struct RegsInfo; 38 39 class DwarfSection { 40 public: 41 DwarfSection(Memory* memory); 42 virtual ~DwarfSection() = default; 43 44 class iterator : public std::iterator<std::bidirectional_iterator_tag, DwarfFde*> { 45 public: iterator(DwarfSection * section,size_t index)46 iterator(DwarfSection* section, size_t index) : index_(index) { 47 section->GetFdes(&fdes_); 48 if (index_ == static_cast<size_t>(-1)) { 49 index_ = fdes_.size(); 50 } 51 } 52 53 iterator& operator++() { 54 index_++; 55 return *this; 56 } 57 iterator& operator++(int increment) { 58 index_ += increment; 59 return *this; 60 } 61 iterator& operator--() { 62 index_--; 63 return *this; 64 } 65 iterator& operator--(int decrement) { 66 index_ -= decrement; 67 return *this; 68 } 69 70 bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; } 71 bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; } 72 73 const DwarfFde* operator*() { 74 if (index_ > fdes_.size()) return nullptr; 75 return fdes_[index_]; 76 } 77 78 private: 79 std::vector<const DwarfFde*> fdes_; 80 size_t index_ = 0; 81 }; 82 begin()83 iterator begin() { return iterator(this, 0); } end()84 iterator end() { return iterator(this, static_cast<size_t>(-1)); } 85 LastErrorCode()86 DwarfErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()87 uint64_t LastErrorAddress() { return last_error_.address; } 88 89 virtual bool Init(uint64_t offset, uint64_t size, uint64_t load_bias) = 0; 90 91 virtual bool Eval(const DwarfCie*, Memory*, const dwarf_loc_regs_t&, Regs*, bool*) = 0; 92 93 virtual bool Log(uint8_t indent, uint64_t pc, const DwarfFde* fde) = 0; 94 95 virtual void GetFdes(std::vector<const DwarfFde*>* fdes) = 0; 96 97 virtual const DwarfFde* GetFdeFromPc(uint64_t pc) = 0; 98 99 virtual bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) = 0; 100 101 virtual uint64_t GetCieOffsetFromFde32(uint32_t pointer) = 0; 102 103 virtual uint64_t GetCieOffsetFromFde64(uint64_t pointer) = 0; 104 105 virtual uint64_t AdjustPcFromFde(uint64_t pc) = 0; 106 107 bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished); 108 109 protected: 110 DwarfMemory memory_; 111 DwarfErrorData last_error_{DWARF_ERROR_NONE, 0}; 112 113 uint32_t cie32_value_ = 0; 114 uint64_t cie64_value_ = 0; 115 116 std::unordered_map<uint64_t, DwarfFde> fde_entries_; 117 std::unordered_map<uint64_t, DwarfCie> cie_entries_; 118 std::unordered_map<uint64_t, dwarf_loc_regs_t> cie_loc_regs_; 119 std::map<uint64_t, dwarf_loc_regs_t> loc_regs_; // Single row indexed by pc_end. 120 }; 121 122 template <typename AddressType> 123 class DwarfSectionImpl : public DwarfSection { 124 public: DwarfSectionImpl(Memory * memory)125 DwarfSectionImpl(Memory* memory) : DwarfSection(memory) {} 126 virtual ~DwarfSectionImpl() = default; 127 128 const DwarfCie* GetCieFromOffset(uint64_t offset); 129 130 const DwarfFde* GetFdeFromOffset(uint64_t offset); 131 132 bool EvalRegister(const DwarfLocation* loc, uint32_t reg, AddressType* reg_ptr, void* info); 133 134 bool Eval(const DwarfCie* cie, Memory* regular_memory, const dwarf_loc_regs_t& loc_regs, 135 Regs* regs, bool* finished) override; 136 137 bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) override; 138 139 bool Log(uint8_t indent, uint64_t pc, const DwarfFde* fde) override; 140 141 protected: 142 bool FillInCieHeader(DwarfCie* cie); 143 144 bool FillInCie(DwarfCie* cie); 145 146 bool FillInFdeHeader(DwarfFde* fde); 147 148 bool FillInFde(DwarfFde* fde); 149 150 bool EvalExpression(const DwarfLocation& loc, Memory* regular_memory, AddressType* value, 151 RegsInfo<AddressType>* regs_info, bool* is_dex_pc); 152 153 uint64_t load_bias_ = 0; 154 uint64_t entries_offset_ = 0; 155 uint64_t entries_end_ = 0; 156 uint64_t pc_offset_ = 0; 157 }; 158 159 template <typename AddressType> 160 class DwarfSectionImplNoHdr : public DwarfSectionImpl<AddressType> { 161 public: 162 // Add these so that the protected members of DwarfSectionImpl 163 // can be accessed without needing a this->. 164 using DwarfSectionImpl<AddressType>::memory_; 165 using DwarfSectionImpl<AddressType>::pc_offset_; 166 using DwarfSectionImpl<AddressType>::entries_offset_; 167 using DwarfSectionImpl<AddressType>::entries_end_; 168 using DwarfSectionImpl<AddressType>::last_error_; 169 using DwarfSectionImpl<AddressType>::load_bias_; 170 using DwarfSectionImpl<AddressType>::cie_entries_; 171 using DwarfSectionImpl<AddressType>::fde_entries_; 172 using DwarfSectionImpl<AddressType>::cie32_value_; 173 using DwarfSectionImpl<AddressType>::cie64_value_; 174 DwarfSectionImplNoHdr(Memory * memory)175 DwarfSectionImplNoHdr(Memory* memory) : DwarfSectionImpl<AddressType>(memory) {} 176 virtual ~DwarfSectionImplNoHdr() = default; 177 178 bool Init(uint64_t offset, uint64_t size, uint64_t load_bias) override; 179 180 const DwarfFde* GetFdeFromPc(uint64_t pc) override; 181 182 void GetFdes(std::vector<const DwarfFde*>* fdes) override; 183 184 protected: 185 bool GetNextCieOrFde(DwarfFde** fde_entry); 186 187 void InsertFde(const DwarfFde* fde); 188 189 uint64_t next_entries_offset_ = 0; 190 191 std::map<uint64_t, std::pair<uint64_t, const DwarfFde*>> fdes_; 192 }; 193 194 } // namespace unwindstack 195 196 #endif // _LIBUNWINDSTACK_DWARF_SECTION_H 197