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 <unordered_map> 24 25 #include <unwindstack/DwarfLocation.h> 26 #include <unwindstack/DwarfMemory.h> 27 #include <unwindstack/DwarfStructs.h> 28 29 namespace unwindstack { 30 31 // Forward declarations. 32 enum DwarfError : uint8_t; 33 class Memory; 34 class Regs; 35 36 class DwarfSection { 37 public: 38 DwarfSection(Memory* memory); 39 virtual ~DwarfSection() = default; 40 41 class iterator : public std::iterator<std::bidirectional_iterator_tag, DwarfFde*> { 42 public: 43 iterator(DwarfSection* section, size_t index) : section_(section), index_(index) {} 44 45 iterator& operator++() { 46 index_++; 47 return *this; 48 } 49 iterator& operator++(int increment) { 50 index_ += increment; 51 return *this; 52 } 53 iterator& operator--() { 54 index_--; 55 return *this; 56 } 57 iterator& operator--(int decrement) { 58 index_ -= decrement; 59 return *this; 60 } 61 62 bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; } 63 bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; } 64 65 const DwarfFde* operator*() { return section_->GetFdeFromIndex(index_); } 66 67 private: 68 DwarfSection* section_ = nullptr; 69 size_t index_ = 0; 70 }; 71 72 iterator begin() { return iterator(this, 0); } 73 iterator end() { return iterator(this, fde_count_); } 74 75 DwarfError last_error() { return last_error_; } 76 77 virtual bool Init(uint64_t offset, uint64_t size) = 0; 78 79 virtual bool Eval(const DwarfCie*, Memory*, const dwarf_loc_regs_t&, Regs*) = 0; 80 81 virtual bool GetFdeOffsetFromPc(uint64_t pc, uint64_t* fde_offset) = 0; 82 83 virtual bool Log(uint8_t indent, uint64_t pc, uint64_t load_bias, const DwarfFde* fde) = 0; 84 85 virtual const DwarfFde* GetFdeFromIndex(size_t index) = 0; 86 87 const DwarfFde* GetFdeFromPc(uint64_t pc); 88 89 virtual const DwarfFde* GetFdeFromOffset(uint64_t fde_offset) = 0; 90 91 virtual bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) = 0; 92 93 virtual bool IsCie32(uint32_t value32) = 0; 94 95 virtual bool IsCie64(uint64_t value64) = 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); 104 105 protected: 106 DwarfMemory memory_; 107 DwarfError last_error_; 108 109 uint64_t fde_count_; 110 std::unordered_map<uint64_t, DwarfFde> fde_entries_; 111 std::unordered_map<uint64_t, DwarfCie> cie_entries_; 112 std::unordered_map<uint64_t, dwarf_loc_regs_t> cie_loc_regs_; 113 }; 114 115 template <typename AddressType> 116 class DwarfSectionImpl : public DwarfSection { 117 public: 118 DwarfSectionImpl(Memory* memory) : DwarfSection(memory) {} 119 virtual ~DwarfSectionImpl() = default; 120 121 bool Eval(const DwarfCie* cie, Memory* regular_memory, const dwarf_loc_regs_t& loc_regs, 122 Regs* regs) override; 123 124 const DwarfCie* GetCie(uint64_t offset); 125 bool FillInCie(DwarfCie* cie); 126 127 const DwarfFde* GetFdeFromOffset(uint64_t offset) override; 128 bool FillInFde(DwarfFde* fde); 129 130 bool GetCfaLocationInfo(uint64_t pc, const DwarfFde* fde, dwarf_loc_regs_t* loc_regs) override; 131 132 bool Log(uint8_t indent, uint64_t pc, uint64_t load_bias, const DwarfFde* fde) override; 133 134 protected: 135 bool EvalExpression(const DwarfLocation& loc, uint8_t version, Memory* regular_memory, 136 AddressType* value); 137 }; 138 139 } // namespace unwindstack 140 141 #endif // _LIBUNWINDSTACK_DWARF_SECTION_H 142