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