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) : section_(section), index_(index) {} 47 48 iterator& operator++() { 49 index_++; 50 return *this; 51 } 52 iterator& operator++(int increment) { 53 index_ += increment; 54 return *this; 55 } 56 iterator& operator--() { 57 index_--; 58 return *this; 59 } 60 iterator& operator--(int decrement) { 61 index_ -= decrement; 62 return *this; 63 } 64 65 bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; } 66 bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; } 67 68 const DwarfFde* operator*() { return section_->GetFdeFromIndex(index_); } 69 70 private: 71 DwarfSection* section_ = nullptr; 72 size_t index_ = 0; 73 }; 74 begin()75 iterator begin() { return iterator(this, 0); } end()76 iterator end() { return iterator(this, fde_count_); } 77 LastErrorCode()78 DwarfErrorCode LastErrorCode() { return last_error_.code; } LastErrorAddress()79 uint64_t LastErrorAddress() { return last_error_.address; } 80 81 virtual bool Init(uint64_t offset, uint64_t size) = 0; 82 83 virtual bool Eval(const DwarfCie*, Memory*, const dwarf_loc_regs_t&, Regs*, bool*) = 0; 84 85 virtual bool GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) = 0; 86 87 virtual bool Log(uint8_t indent, uint64_t pc, uint64_t load_bias, const DwarfFde* fde) = 0; 88 89 virtual const DwarfFde* GetFdeFromIndex(size_t index) = 0; 90 91 const DwarfFde* GetFdeFromPc(uint64_t pc); 92 93 virtual const DwarfFde* GetFdeFromOffset(uint64_t fde_offset) = 0; 94 95 virtual bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) = 0; 96 97 virtual uint64_t GetCieOffsetFromFde32(uint32_t pointer) = 0; 98 99 virtual uint64_t GetCieOffsetFromFde64(uint64_t pointer) = 0; 100 101 virtual uint64_t AdjustPcFromFde(uint64_t pc) = 0; 102 103 bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished); 104 105 protected: 106 DwarfMemory memory_; 107 DwarfErrorData last_error_{DWARF_ERROR_NONE, 0}; 108 109 uint32_t cie32_value_ = 0; 110 uint64_t cie64_value_ = 0; 111 112 uint64_t fde_count_ = 0; 113 std::unordered_map<uint64_t, DwarfFde> fde_entries_; 114 std::unordered_map<uint64_t, DwarfCie> cie_entries_; 115 std::unordered_map<uint64_t, dwarf_loc_regs_t> cie_loc_regs_; 116 std::map<uint64_t, dwarf_loc_regs_t> loc_regs_; // Single row indexed by pc_end. 117 }; 118 119 template <typename AddressType> 120 class DwarfSectionImpl : public DwarfSection { 121 public: 122 struct FdeInfo { FdeInfoFdeInfo123 FdeInfo(uint64_t offset, uint64_t start, uint64_t length) 124 : offset(offset), start(start), end(start + length) {} 125 126 uint64_t offset; 127 AddressType start; 128 AddressType end; 129 }; 130 DwarfSectionImpl(Memory * memory)131 DwarfSectionImpl(Memory* memory) : DwarfSection(memory) {} 132 virtual ~DwarfSectionImpl() = default; 133 134 bool Init(uint64_t offset, uint64_t size) override; 135 136 bool GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) override; 137 138 const DwarfFde* GetFdeFromIndex(size_t index) 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 const DwarfCie* GetCie(uint64_t offset); 146 bool FillInCie(DwarfCie* cie); 147 148 const DwarfFde* GetFdeFromOffset(uint64_t offset) override; 149 bool FillInFde(DwarfFde* fde); 150 151 bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) override; 152 153 bool Log(uint8_t indent, uint64_t pc, uint64_t load_bias, const DwarfFde* fde) override; 154 155 protected: 156 bool EvalExpression(const DwarfLocation& loc, Memory* regular_memory, AddressType* value, 157 RegsInfo<AddressType>* regs_info, bool* is_dex_pc); 158 159 bool GetCieInfo(uint8_t* segment_size, uint8_t* encoding); 160 161 bool AddFdeInfo(uint64_t entry_offset, uint8_t segment_size, uint8_t encoding); 162 163 bool CreateSortedFdeList(); 164 165 std::vector<FdeInfo> fdes_; 166 uint64_t entries_offset_; 167 uint64_t entries_end_; 168 }; 169 170 } // namespace unwindstack 171 172 #endif // _LIBUNWINDSTACK_DWARF_SECTION_H 173