Home | History | Annotate | Download | only in unwindstack
      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:
     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 
     75   iterator begin() { return iterator(this, 0); }
     76   iterator end() { return iterator(this, fde_count_); }
     77 
     78   DwarfErrorCode LastErrorCode() { return last_error_.code; }
     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 {
    123     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 
    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