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