• 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 <stdint.h>
20 #include <unistd.h>
21 
22 #include <functional>
23 #include <string>
24 #include <vector>
25 
26 #include <unwindstack/Arch.h>
27 
28 namespace unwindstack {
29 
30 // Forward declarations.
31 class Elf;
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 
Is32Bit()55   bool Is32Bit() { return ArchIs32Bit(Arch()); }
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 
fallback_pc()67   virtual void fallback_pc() {}
68 
ResetPseudoRegisters()69   virtual void ResetPseudoRegisters() {}
SetPseudoRegister(uint16_t,uint64_t)70   virtual bool SetPseudoRegister(uint16_t, uint64_t) { return false; }
GetPseudoRegister(uint16_t,uint64_t *)71   virtual bool GetPseudoRegister(uint16_t, uint64_t*) { return false; }
72 
73   virtual bool StepIfSignalHandler(uint64_t elf_offset, Elf* elf, Memory* process_memory) = 0;
74 
75   virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0;
76 
77   virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0;
78 
total_regs()79   uint16_t total_regs() { return total_regs_; }
80 
81   virtual Regs* Clone() = 0;
82 
83   static ArchEnum CurrentArch();
84   static ArchEnum RemoteGetArch(pid_t pid);
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