blob: 613682ffdaa01edb8a0986721a07b81d7ca326c0 [file] [log] [blame]
Christopher Ferris723cf9b2017-01-19 20:08:48 -08001/*
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
Josh Gao6f580d82017-09-22 12:57:15 -070022#include <functional>
23#include <string>
Christopher Ferris723cf9b2017-01-19 20:08:48 -080024#include <vector>
25
Christopher Ferrisd226a512017-07-14 10:37:19 -070026namespace unwindstack {
27
Christopher Ferris3958f802017-02-01 15:44:40 -080028// Forward declarations.
29class Elf;
Christopher Ferrisd06001d2017-11-30 18:56:01 -080030enum ArchEnum : uint8_t;
Christopher Ferrisd226a512017-07-14 10:37:19 -070031class Memory;
Christopher Ferris3958f802017-02-01 15:44:40 -080032
Christopher Ferris723cf9b2017-01-19 20:08:48 -080033class Regs {
34 public:
Christopher Ferris3958f802017-02-01 15:44:40 -080035 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, uint16_t sp_reg, const Location& return_loc)
49 : total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {}
Christopher Ferris723cf9b2017-01-19 20:08:48 -080050 virtual ~Regs() = default;
51
Christopher Ferrisd06001d2017-11-30 18:56:01 -080052 virtual ArchEnum Arch() = 0;
Josh Gao0953ecd2017-08-25 13:55:06 -070053
Christopher Ferris02fdb562017-12-08 15:04:49 -080054 virtual bool Format32Bit() = 0;
55
Christopher Ferris3958f802017-02-01 15:44:40 -080056 virtual void* RawData() = 0;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080057 virtual uint64_t pc() = 0;
58 virtual uint64_t sp() = 0;
59
Christopher Ferris3958f802017-02-01 15:44:40 -080060 virtual uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) = 0;
61
Christopher Ferriseb4a6db2017-07-19 12:37:45 -070062 virtual bool StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_memory) = 0;
Christopher Ferrisa0196652017-07-18 16:09:20 -070063
Christopher Ferris2a25c4a2017-07-07 16:35:48 -070064 virtual void SetFromRaw() = 0;
65
Christopher Ferrisb9de87f2017-09-20 13:37:24 -070066 virtual bool SetPcFromReturnAddress(Memory* process_memory) = 0;
67
Josh Gao6f580d82017-09-22 12:57:15 -070068 virtual void IterateRegisters(std::function<void(const char*, uint64_t)>) = 0;
69
Christopher Ferris3958f802017-02-01 15:44:40 -080070 uint16_t sp_reg() { return sp_reg_; }
71 uint16_t total_regs() { return total_regs_; }
72
Christopher Ferrisd06001d2017-11-30 18:56:01 -080073 static ArchEnum CurrentArch();
Josh Gao0953ecd2017-08-25 13:55:06 -070074 static Regs* RemoteGet(pid_t pid);
Christopher Ferrisd06001d2017-11-30 18:56:01 -080075 static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext);
Christopher Ferris2a25c4a2017-07-07 16:35:48 -070076 static Regs* CreateFromLocal();
Christopher Ferris3958f802017-02-01 15:44:40 -080077
Christopher Ferris723cf9b2017-01-19 20:08:48 -080078 protected:
Christopher Ferris723cf9b2017-01-19 20:08:48 -080079 uint16_t total_regs_;
Christopher Ferris3958f802017-02-01 15:44:40 -080080 uint16_t sp_reg_;
81 Location return_loc_;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080082};
83
84template <typename AddressType>
Christopher Ferris7b8e4672017-06-01 17:55:25 -070085class RegsImpl : public Regs {
Christopher Ferris723cf9b2017-01-19 20:08:48 -080086 public:
Christopher Ferris7b8e4672017-06-01 17:55:25 -070087 RegsImpl(uint16_t total_regs, uint16_t sp_reg, Location return_loc)
Christopher Ferris3958f802017-02-01 15:44:40 -080088 : Regs(total_regs, sp_reg, return_loc), regs_(total_regs) {}
Christopher Ferris7b8e4672017-06-01 17:55:25 -070089 virtual ~RegsImpl() = default;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080090
Christopher Ferris3958f802017-02-01 15:44:40 -080091 uint64_t pc() override { return pc_; }
92 uint64_t sp() override { return sp_; }
93
94 void set_pc(AddressType pc) { pc_ = pc; }
95 void set_sp(AddressType sp) { sp_ = sp; }
Christopher Ferris723cf9b2017-01-19 20:08:48 -080096
Christopher Ferris02fdb562017-12-08 15:04:49 -080097 bool Format32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); }
98
Christopher Ferris723cf9b2017-01-19 20:08:48 -080099 inline AddressType& operator[](size_t reg) { return regs_[reg]; }
100
Christopher Ferris3958f802017-02-01 15:44:40 -0800101 void* RawData() override { return regs_.data(); }
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800102
Josh Gao6f580d82017-09-22 12:57:15 -0700103 virtual void IterateRegisters(std::function<void(const char*, uint64_t)> fn) override {
104 for (size_t i = 0; i < regs_.size(); ++i) {
105 fn(std::to_string(i).c_str(), regs_[i]);
106 }
107 }
108
Christopher Ferris3958f802017-02-01 15:44:40 -0800109 protected:
110 AddressType pc_;
111 AddressType sp_;
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800112 std::vector<AddressType> regs_;
113};
114
Christopher Ferrisd226a512017-07-14 10:37:19 -0700115} // namespace unwindstack
116
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800117#endif // _LIBUNWINDSTACK_REGS_H