blob: a7567d83acbd8b1c21f748a03db3397ca7c78e9c [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
22#include <vector>
23
Christopher Ferris3958f802017-02-01 15:44:40 -080024// Forward declarations.
25class Elf;
26struct MapInfo;
27
Christopher Ferris723cf9b2017-01-19 20:08:48 -080028class Regs {
29 public:
Christopher Ferris3958f802017-02-01 15:44:40 -080030 enum LocationEnum : uint8_t {
31 LOCATION_UNKNOWN = 0,
32 LOCATION_REGISTER,
33 LOCATION_SP_OFFSET,
34 };
35
36 struct Location {
37 Location(LocationEnum type, int16_t value) : type(type), value(value) {}
38
39 LocationEnum type;
40 int16_t value;
41 };
42
43 Regs(uint16_t total_regs, uint16_t sp_reg, const Location& return_loc)
44 : total_regs_(total_regs), sp_reg_(sp_reg), return_loc_(return_loc) {}
Christopher Ferris723cf9b2017-01-19 20:08:48 -080045 virtual ~Regs() = default;
46
Christopher Ferris3958f802017-02-01 15:44:40 -080047 virtual void* RawData() = 0;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080048 virtual uint64_t pc() = 0;
49 virtual uint64_t sp() = 0;
50
Christopher Ferris3958f802017-02-01 15:44:40 -080051 virtual bool GetReturnAddressFromDefault(Memory* memory, uint64_t* value) = 0;
52
53 virtual uint64_t GetRelPc(Elf* elf, const MapInfo* map_info) = 0;
54
55 virtual uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) = 0;
56
Christopher Ferris2a25c4a2017-07-07 16:35:48 -070057 virtual void SetFromRaw() = 0;
58
Christopher Ferris3958f802017-02-01 15:44:40 -080059 uint16_t sp_reg() { return sp_reg_; }
60 uint16_t total_regs() { return total_regs_; }
61
Christopher Ferris2a25c4a2017-07-07 16:35:48 -070062 static uint32_t GetMachineType();
Christopher Ferris3958f802017-02-01 15:44:40 -080063 static Regs* RemoteGet(pid_t pid, uint32_t* machine_type);
Christopher Ferris2a25c4a2017-07-07 16:35:48 -070064 static Regs* CreateFromUcontext(uint32_t machine_type, void* ucontext);
65 static Regs* CreateFromLocal();
Christopher Ferris3958f802017-02-01 15:44:40 -080066
Christopher Ferris723cf9b2017-01-19 20:08:48 -080067 protected:
Christopher Ferris723cf9b2017-01-19 20:08:48 -080068 uint16_t total_regs_;
Christopher Ferris3958f802017-02-01 15:44:40 -080069 uint16_t sp_reg_;
70 Location return_loc_;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080071};
72
73template <typename AddressType>
Christopher Ferris7b8e4672017-06-01 17:55:25 -070074class RegsImpl : public Regs {
Christopher Ferris723cf9b2017-01-19 20:08:48 -080075 public:
Christopher Ferris7b8e4672017-06-01 17:55:25 -070076 RegsImpl(uint16_t total_regs, uint16_t sp_reg, Location return_loc)
Christopher Ferris3958f802017-02-01 15:44:40 -080077 : Regs(total_regs, sp_reg, return_loc), regs_(total_regs) {}
Christopher Ferris7b8e4672017-06-01 17:55:25 -070078 virtual ~RegsImpl() = default;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080079
Christopher Ferris3958f802017-02-01 15:44:40 -080080 uint64_t GetRelPc(Elf* elf, const MapInfo* map_info) override;
81
82 bool GetReturnAddressFromDefault(Memory* memory, uint64_t* value) override;
83
84 uint64_t pc() override { return pc_; }
85 uint64_t sp() override { return sp_; }
86
87 void set_pc(AddressType pc) { pc_ = pc; }
88 void set_sp(AddressType sp) { sp_ = sp; }
Christopher Ferris723cf9b2017-01-19 20:08:48 -080089
90 inline AddressType& operator[](size_t reg) { return regs_[reg]; }
91
Christopher Ferris3958f802017-02-01 15:44:40 -080092 void* RawData() override { return regs_.data(); }
Christopher Ferris723cf9b2017-01-19 20:08:48 -080093
Christopher Ferris3958f802017-02-01 15:44:40 -080094 protected:
95 AddressType pc_;
96 AddressType sp_;
Christopher Ferris723cf9b2017-01-19 20:08:48 -080097 std::vector<AddressType> regs_;
98};
99
Christopher Ferris7b8e4672017-06-01 17:55:25 -0700100class RegsArm : public RegsImpl<uint32_t> {
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800101 public:
Christopher Ferris3958f802017-02-01 15:44:40 -0800102 RegsArm();
103 virtual ~RegsArm() = default;
104
105 uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
Christopher Ferris2a25c4a2017-07-07 16:35:48 -0700106
107 void SetFromRaw() override;
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800108};
109
Christopher Ferris7b8e4672017-06-01 17:55:25 -0700110class RegsArm64 : public RegsImpl<uint64_t> {
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800111 public:
Christopher Ferris3958f802017-02-01 15:44:40 -0800112 RegsArm64();
113 virtual ~RegsArm64() = default;
114
115 uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
Christopher Ferris2a25c4a2017-07-07 16:35:48 -0700116
117 void SetFromRaw() override;
Christopher Ferris3958f802017-02-01 15:44:40 -0800118};
119
Christopher Ferris7b8e4672017-06-01 17:55:25 -0700120class RegsX86 : public RegsImpl<uint32_t> {
Christopher Ferris3958f802017-02-01 15:44:40 -0800121 public:
122 RegsX86();
123 virtual ~RegsX86() = default;
124
125 uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
Christopher Ferris2a25c4a2017-07-07 16:35:48 -0700126
127 void SetFromRaw() override;
Christopher Ferris3958f802017-02-01 15:44:40 -0800128};
129
Christopher Ferris7b8e4672017-06-01 17:55:25 -0700130class RegsX86_64 : public RegsImpl<uint64_t> {
Christopher Ferris3958f802017-02-01 15:44:40 -0800131 public:
132 RegsX86_64();
133 virtual ~RegsX86_64() = default;
134
135 uint64_t GetAdjustedPc(uint64_t rel_pc, Elf* elf) override;
Christopher Ferris2a25c4a2017-07-07 16:35:48 -0700136
137 void SetFromRaw() override;
Christopher Ferris723cf9b2017-01-19 20:08:48 -0800138};
139
140#endif // _LIBUNWINDSTACK_REGS_H