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 <stdint.h>
20 #include <unistd.h>
21 
22 #include <functional>
23 #include <string>
24 #include <vector>
25 
26 #include <unwindstack/Arch.h>
27 #include <unwindstack/Error.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 
Convert(uint16_t reg)84   virtual uint16_t Convert(uint16_t reg) { return reg; }
85 
86   static ArchEnum CurrentArch();
87   static ArchEnum RemoteGetArch(pid_t pid, ErrorCode* error_code = nullptr);
88   static Regs* RemoteGet(pid_t pid, ErrorCode* error_code = nullptr);
89   static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext);
90   static Regs* CreateFromLocal();
91 
92  protected:
93   uint16_t total_regs_;
94   Location return_loc_;
95   uint64_t dex_pc_ = 0;
96 };
97 
98 template <typename AddressType>
99 class RegsImpl : public Regs {
100  public:
RegsImpl(uint16_t total_regs,Location return_loc)101   RegsImpl(uint16_t total_regs, Location return_loc)
102       : Regs(total_regs, return_loc), regs_(total_regs) {}
103   virtual ~RegsImpl() = default;
104 
105   inline AddressType& operator[](size_t reg) { return regs_[reg]; }
106 
RawData()107   void* RawData() override { return regs_.data(); }
108 
IterateRegisters(std::function<void (const char *,uint64_t)> fn)109   virtual void IterateRegisters(std::function<void(const char*, uint64_t)> fn) override {
110     for (size_t i = 0; i < regs_.size(); ++i) {
111       fn(std::to_string(i).c_str(), regs_[i]);
112     }
113   }
114 
115  protected:
116   std::vector<AddressType> regs_;
117 };
118 
119 uint64_t GetPcAdjustment(uint64_t rel_pc, Elf* elf, ArchEnum arch);
120 
121 }  // namespace unwindstack
122