• 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 #ifndef _LIBUNWINDSTACK_REGS_H
18 #define _LIBUNWINDSTACK_REGS_H
19 
20 #include <stdint.h>
21 #include <unistd.h>
22 
23 #include <functional>
24 #include <string>
25 #include <vector>
26 
27 #include <unwindstack/Arch.h>
28 
29 namespace unwindstack {
30 
31 // Forward declarations.
32 class Elf;
33 class Memory;
34 
35 class Regs {
36  public:
37   enum LocationEnum : uint8_t {
38     LOCATION_UNKNOWN = 0,
39     LOCATION_REGISTER,
40     LOCATION_SP_OFFSET,
41   };
42 
43   struct Location {
LocationLocation44     Location(LocationEnum type, int16_t value) : type(type), value(value) {}
45 
46     LocationEnum type;
47     int16_t value;
48   };
49 
Regs(uint16_t total_regs,const Location & return_loc)50   Regs(uint16_t total_regs, const Location& return_loc)
51       : total_regs_(total_regs), return_loc_(return_loc) {}
52   virtual ~Regs() = default;
53 
54   virtual ArchEnum Arch() = 0;
55 
Is32Bit()56   bool Is32Bit() { return ArchIs32Bit(Arch()); }
57 
58   virtual void* RawData() = 0;
59   virtual uint64_t pc() = 0;
60   virtual uint64_t sp() = 0;
61 
62   virtual void set_pc(uint64_t pc) = 0;
63   virtual void set_sp(uint64_t sp) = 0;
64 
dex_pc()65   uint64_t dex_pc() { return dex_pc_; }
set_dex_pc(uint64_t dex_pc)66   void set_dex_pc(uint64_t dex_pc) { dex_pc_ = dex_pc; }
67 
fallback_pc()68   virtual void fallback_pc() {}
69 
ResetPseudoRegisters()70   virtual void ResetPseudoRegisters() {}
SetPseudoRegister(uint16_t,uint64_t)71   virtual bool SetPseudoRegister(uint16_t, uint64_t) { return false; }
GetPseudoRegister(uint16_t,uint64_t *)72   virtual bool GetPseudoRegister(uint16_t, uint64_t*) { return false; }
73 
74   virtual bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) = 0;
75 
76   virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0;
77 
78   virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0;
79 
total_regs()80   uint16_t total_regs() { return total_regs_; }
81 
82   virtual Regs* Clone() = 0;
83 
84   static ArchEnum CurrentArch();
85   static Regs* RemoteGet(pid_t pid);
86   static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext);
87   static Regs* CreateFromLocal();
88 
89  protected:
90   uint16_t total_regs_;
91   Location return_loc_;
92   uint64_t dex_pc_ = 0;
93 };
94 
95 template <typename AddressType>
96 class RegsImpl : public Regs {
97  public:
RegsImpl(uint16_t total_regs,Location return_loc)98   RegsImpl(uint16_t total_regs, Location return_loc)
99       : Regs(total_regs, return_loc), regs_(total_regs) {}
100   virtual ~RegsImpl() = default;
101 
102   inline AddressType& operator[](size_t reg) { return regs_[reg]; }
103 
RawData()104   void* RawData() override { return regs_.data(); }
105 
IterateRegisters(std::function<void (const char *,uint64_t)> fn)106   virtual void IterateRegisters(std::function<void(const char*, uint64_t)> fn) override {
107     for (size_t i = 0; i < regs_.size(); ++i) {
108       fn(std::to_string(i).c_str(), regs_[i]);
109     }
110   }
111 
112  protected:
113   std::vector<AddressType> regs_;
114 };
115 
116 uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch);
117 
118 }  // namespace unwindstack
119 
120 #endif  // _LIBUNWINDSTACK_REGS_H
121