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