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