• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <elf.h>
20 #include <stdint.h>
21 
22 #include <unordered_map>
23 
24 #include <unwindstack/ElfInterface.h>
25 #include <unwindstack/Memory.h>
26 
27 namespace unwindstack {
28 
29 class ElfInterfaceArm : public ElfInterface32 {
30  public:
ElfInterfaceArm(Memory * memory)31   ElfInterfaceArm(Memory* memory) : ElfInterface32(memory) {}
32   virtual ~ElfInterfaceArm() = default;
33 
34   class iterator {
35    public:
36     using iterator_category = std::bidirectional_iterator_tag;
37     using value_type = uint32_t;
38     using difference_type = std::ptrdiff_t;
39     using pointer = uint32_t*;
40     using reference = uint32_t&;
41 
iterator(ElfInterfaceArm * interface,size_t index)42     iterator(ElfInterfaceArm* interface, size_t index) : interface_(interface), index_(index) { }
43 
44     iterator& operator++() { index_++; return *this; }
45     iterator& operator++(int increment) { index_ += increment; return *this; }
46     iterator& operator--() { index_--; return *this; }
47     iterator& operator--(int decrement) { index_ -= decrement; return *this; }
48 
49     bool operator==(const iterator& rhs) { return this->index_ == rhs.index_; }
50     bool operator!=(const iterator& rhs) { return this->index_ != rhs.index_; }
51 
52     uint32_t operator*() {
53       uint32_t addr = interface_->addrs_[index_];
54       if (addr == 0) {
55         if (!interface_->GetPrel31Addr(interface_->start_offset_ + index_ * 8, &addr)) {
56           return 0;
57         }
58         interface_->addrs_[index_] = addr;
59       }
60       return addr;
61     }
62 
63    private:
64     ElfInterfaceArm* interface_ = nullptr;
65     size_t index_ = 0;
66   };
67 
begin()68   iterator begin() { return iterator(this, 0); }
end()69   iterator end() { return iterator(this, total_entries_); }
70 
71   bool Init(int64_t* section_bias) override;
72 
73   bool GetPrel31Addr(uint32_t offset, uint32_t* addr);
74 
75   bool FindEntry(uint32_t pc, uint64_t* entry_offset);
76 
77   void HandleUnknownType(uint32_t type, uint64_t ph_offset, uint64_t ph_filesz) override;
78 
79   bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished,
80             bool* is_signal_frame) override;
81 
82   bool StepExidx(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished);
83 
84   bool GetFunctionName(uint64_t addr, SharedString* name, uint64_t* offset) override;
85 
start_offset()86   uint64_t start_offset() { return start_offset_; }
87 
total_entries()88   size_t total_entries() { return total_entries_; }
89 
set_load_bias(uint64_t load_bias)90   void set_load_bias(uint64_t load_bias) { load_bias_ = load_bias; }
91 
92  protected:
93   uint64_t start_offset_ = 0;
94   size_t total_entries_ = 0;
95   uint64_t load_bias_ = 0;
96 
97   std::unordered_map<size_t, uint32_t> addrs_;
98 };
99 
100 }  // namespace unwindstack
101