1*eb293b8fSAndroid Build Coastguard Worker /* 2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*eb293b8fSAndroid Build Coastguard Worker * 4*eb293b8fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*eb293b8fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*eb293b8fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*eb293b8fSAndroid Build Coastguard Worker * 8*eb293b8fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*eb293b8fSAndroid Build Coastguard Worker * 10*eb293b8fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*eb293b8fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*eb293b8fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*eb293b8fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*eb293b8fSAndroid Build Coastguard Worker * limitations under the License. 15*eb293b8fSAndroid Build Coastguard Worker */ 16*eb293b8fSAndroid Build Coastguard Worker 17*eb293b8fSAndroid Build Coastguard Worker #pragma once 18*eb293b8fSAndroid Build Coastguard Worker 19*eb293b8fSAndroid Build Coastguard Worker #include <elf.h> 20*eb293b8fSAndroid Build Coastguard Worker #include <stddef.h> 21*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h> 22*eb293b8fSAndroid Build Coastguard Worker 23*eb293b8fSAndroid Build Coastguard Worker #include <iterator> 24*eb293b8fSAndroid Build Coastguard Worker #include <memory> 25*eb293b8fSAndroid Build Coastguard Worker #include <unordered_map> 26*eb293b8fSAndroid Build Coastguard Worker 27*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/ElfInterface.h> 28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/Memory.h> 29*eb293b8fSAndroid Build Coastguard Worker 30*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack { 31*eb293b8fSAndroid Build Coastguard Worker 32*eb293b8fSAndroid Build Coastguard Worker class ElfInterfaceArm : public ElfInterface32 { 33*eb293b8fSAndroid Build Coastguard Worker public: ElfInterfaceArm(std::shared_ptr<Memory> & memory)34*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceArm(std::shared_ptr<Memory>& memory) : ElfInterface32(memory) {} 35*eb293b8fSAndroid Build Coastguard Worker virtual ~ElfInterfaceArm() = default; 36*eb293b8fSAndroid Build Coastguard Worker 37*eb293b8fSAndroid Build Coastguard Worker class iterator { 38*eb293b8fSAndroid Build Coastguard Worker public: 39*eb293b8fSAndroid Build Coastguard Worker using iterator_category = std::bidirectional_iterator_tag; 40*eb293b8fSAndroid Build Coastguard Worker using value_type = uint32_t; 41*eb293b8fSAndroid Build Coastguard Worker using difference_type = ptrdiff_t; 42*eb293b8fSAndroid Build Coastguard Worker using pointer = uint32_t*; 43*eb293b8fSAndroid Build Coastguard Worker using reference = uint32_t&; 44*eb293b8fSAndroid Build Coastguard Worker iterator(ElfInterfaceArm * interface,size_t index)45*eb293b8fSAndroid Build Coastguard Worker iterator(ElfInterfaceArm* interface, size_t index) : interface_(interface), index_(index) { } 46*eb293b8fSAndroid Build Coastguard Worker 47*eb293b8fSAndroid Build Coastguard Worker iterator& operator++() { index_++; return *this; } 48*eb293b8fSAndroid Build Coastguard Worker iterator& operator++(int increment) { index_ += increment; return *this; } 49*eb293b8fSAndroid Build Coastguard Worker iterator& operator--() { index_--; return *this; } 50*eb293b8fSAndroid Build Coastguard Worker iterator& operator--(int decrement) { index_ -= decrement; return *this; } 51*eb293b8fSAndroid Build Coastguard Worker 52*eb293b8fSAndroid Build Coastguard Worker bool operator==(const iterator& rhs) const { return this->index_ == rhs.index_; } 53*eb293b8fSAndroid Build Coastguard Worker bool operator!=(const iterator& rhs) const { return this->index_ != rhs.index_; } 54*eb293b8fSAndroid Build Coastguard Worker 55*eb293b8fSAndroid Build Coastguard Worker uint32_t operator*() { 56*eb293b8fSAndroid Build Coastguard Worker uint32_t addr = interface_->addrs_[index_]; 57*eb293b8fSAndroid Build Coastguard Worker if (addr == 0) { 58*eb293b8fSAndroid Build Coastguard Worker if (!interface_->GetPrel31Addr(interface_->start_offset_ + index_ * 8, &addr)) { 59*eb293b8fSAndroid Build Coastguard Worker return 0; 60*eb293b8fSAndroid Build Coastguard Worker } 61*eb293b8fSAndroid Build Coastguard Worker interface_->addrs_[index_] = addr; 62*eb293b8fSAndroid Build Coastguard Worker } 63*eb293b8fSAndroid Build Coastguard Worker return addr; 64*eb293b8fSAndroid Build Coastguard Worker } 65*eb293b8fSAndroid Build Coastguard Worker 66*eb293b8fSAndroid Build Coastguard Worker private: 67*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceArm* interface_ = nullptr; 68*eb293b8fSAndroid Build Coastguard Worker size_t index_ = 0; 69*eb293b8fSAndroid Build Coastguard Worker }; 70*eb293b8fSAndroid Build Coastguard Worker begin()71*eb293b8fSAndroid Build Coastguard Worker iterator begin() { return iterator(this, 0); } end()72*eb293b8fSAndroid Build Coastguard Worker iterator end() { return iterator(this, total_entries_); } 73*eb293b8fSAndroid Build Coastguard Worker 74*eb293b8fSAndroid Build Coastguard Worker bool Init(int64_t* section_bias) override; 75*eb293b8fSAndroid Build Coastguard Worker 76*eb293b8fSAndroid Build Coastguard Worker bool GetPrel31Addr(uint32_t offset, uint32_t* addr); 77*eb293b8fSAndroid Build Coastguard Worker 78*eb293b8fSAndroid Build Coastguard Worker bool FindEntry(uint32_t pc, uint64_t* entry_offset); 79*eb293b8fSAndroid Build Coastguard Worker 80*eb293b8fSAndroid Build Coastguard Worker void HandleUnknownType(uint32_t type, uint64_t ph_offset, uint64_t ph_filesz) override; 81*eb293b8fSAndroid Build Coastguard Worker 82*eb293b8fSAndroid Build Coastguard Worker bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished, 83*eb293b8fSAndroid Build Coastguard Worker bool* is_signal_frame) override; 84*eb293b8fSAndroid Build Coastguard Worker 85*eb293b8fSAndroid Build Coastguard Worker bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished); 86*eb293b8fSAndroid Build Coastguard Worker 87*eb293b8fSAndroid Build Coastguard Worker bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* offset) override; 88*eb293b8fSAndroid Build Coastguard Worker start_offset()89*eb293b8fSAndroid Build Coastguard Worker uint64_t start_offset() { return start_offset_; } 90*eb293b8fSAndroid Build Coastguard Worker total_entries()91*eb293b8fSAndroid Build Coastguard Worker size_t total_entries() { return total_entries_; } 92*eb293b8fSAndroid Build Coastguard Worker set_load_bias(uint64_t load_bias)93*eb293b8fSAndroid Build Coastguard Worker void set_load_bias(uint64_t load_bias) { load_bias_ = load_bias; } 94*eb293b8fSAndroid Build Coastguard Worker 95*eb293b8fSAndroid Build Coastguard Worker protected: 96*eb293b8fSAndroid Build Coastguard Worker uint64_t start_offset_ = 0; 97*eb293b8fSAndroid Build Coastguard Worker size_t total_entries_ = 0; 98*eb293b8fSAndroid Build Coastguard Worker uint64_t load_bias_ = 0; 99*eb293b8fSAndroid Build Coastguard Worker 100*eb293b8fSAndroid Build Coastguard Worker std::unordered_map<size_t, uint32_t> addrs_; 101*eb293b8fSAndroid Build Coastguard Worker }; 102*eb293b8fSAndroid Build Coastguard Worker 103*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack 104