Skip to content

Commit a1d7bf8

Browse files
committed
Templatize the "setDwarf" method
This allows more generic support for restoring registers from memory in dwarf expressions
1 parent e7003e3 commit a1d7bf8

File tree

7 files changed

+69
-44
lines changed

7 files changed

+69
-44
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ add_library(dwelf ${LIBTYPE}
114114
)
115115

116116
add_library(procman ${LIBTYPE} dead.cc self.cc live.cc process.cc proc_service.cc
117-
dwarfproc.cc procdump.cc arch.cc ${stubsrc} ${pysrc})
117+
dwarfproc.cc procdump.cc ${stubsrc} ${pysrc})
118118

119119
add_executable(canal canal.cc)
120120

arch.cc

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,5 @@
44
#include <cstdint>
55
#include "libpstack/arch.h"
66

7-
#ifdef __x86_64__
8-
#include "x86_64.cc"
9-
#endif
10-
#ifdef __aarch64__
11-
#include "aarch64.cc"
12-
#endif
13-
#ifdef __i386__
14-
#include "i386.cc"
15-
#endif
16-
177
namespace pstack::Procman {
18-
void CoreRegisters::setDwarf(int regId, const RegisterValue &value) {
19-
opReg(*this, Set{}, regId, value );
20-
};
21-
22-
RegisterValue CoreRegisters::getDwarf(int regId) const {
23-
RegisterValue value;
24-
opReg(*this, Get{}, regId, value);
25-
return value;
26-
};
278
}

dwarfproc.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ extern std::ostream & operator << (std::ostream &os, const pstack::Dwarf::DIE &)
99

1010
namespace pstack::Procman {
1111

12+
struct RegisterFromReader {
13+
const Reader &reader;
14+
off_t offset;
15+
public:
16+
explicit RegisterFromReader(const Reader &reader, off_t offset) : reader(reader), offset(offset) { }
17+
};
18+
19+
template <typename T>
20+
auto get( const RegisterFromReader &rfr ) -> T {
21+
T t = rfr.reader.readObj<T>(rfr.offset);
22+
return t;
23+
}
24+
1225
gpreg
1326
StackFrame::rawIP() const
1427
{
@@ -556,17 +569,20 @@ std::optional<CoreRegisters> StackFrame::unwind(Process &p) {
556569
}
557570
auto rarInfo = dcf.registers.find(cie->rar);
558571

572+
559573
out = regs;
560574
#ifdef CFA_RESTORE_REGNO
561575
// "The CFA is defined to be the stack pointer in the calling frame."
562-
out.setDwarf(CFA_RESTORE_REGNO, cfa );
576+
out.setDwarf(CFA_RESTORE_REGNO, RegisterValue{cfa} );
563577
#endif
564578
for (const auto &[regno, unwind] : dcf.registers) {
565579
try {
566580
switch (unwind.type) {
567-
case OFFSET: // XXX: assume addrLen = sizeof (general purpos reg)
568-
out.setDwarf(regno, p.io->readObj<gpreg>(cfa + unwind.u.offset));
581+
case OFFSET: {
582+
RegisterFromReader rfr(*p.io, cfa + unwind.u.offset);
583+
out.setDwarf(regno, rfr);
569584
break;
585+
}
570586

571587
case REG:
572588
out.setDwarf(regno, regs.getDwarf(unwind.u.reg));
@@ -582,7 +598,7 @@ std::optional<CoreRegisters> StackFrame::unwind(Process &p) {
582598
// EXPRESSIONs give an address, VAL_EXPRESSION gives a literal.
583599
if (unwind.type == EXPRESSION)
584600
p.io->readObj(val, &val);
585-
out.setDwarf(regno, val);
601+
out.setDwarf(regno, RegisterValue{val});
586602
break;
587603
}
588604

File renamed without changes.
File renamed without changes.

x86_64.cc renamed to libpstack/arch-x86_64.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <cstdint>
55
#include <type_traits>
6-
#include "libpstack/elf.h"
6+
#include "libpstack/stringify.h"
77
namespace pstack::Procman {
88

99
// see https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf

libpstack/arch.h

Lines changed: 47 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ using gpreg = long;
2525

2626
using gpreg = unsigned long long;
2727

28-
2928
#elif defined( __ARM_ARCH )
3029
#ifdef __aarch64__
3130
using gpreg = unsigned long long;
@@ -110,8 +109,8 @@ struct CoreRegisters {
110109
#elif defined(__i386__)
111110
user_fpxregs_struct fpx;
112111
#endif
113-
RegisterValue getDwarf(int reg) const;
114-
void setDwarf(int reg, const RegisterValue &val);
112+
inline RegisterValue getDwarf(int reg) const;
113+
template <typename RV> void setDwarf(int reg, const RV &val);
115114
};
116115

117116
// Maps a name to its dwarf register index.
@@ -120,7 +119,6 @@ using DwarfNames = std::vector<std::pair<int, std::string_view>>;
120119
// Sets of registers for an architecture. Each architecture supports at least
121120
// "general" registers.
122121
using ArchRegs = std::unordered_map<std::string_view, DwarfNames>;
123-
extern const ArchRegs registers;
124122

125123
#ifndef __aarch64__
126124
void gregset2user(user_regs_struct &core, const gregset_t greg);
@@ -141,45 +139,75 @@ inline void regop(Set, T &reg, const T &val) { reg = val; }
141139
template <typename T>
142140
inline void regop(Get, const T &reg, T &val) { val = reg; }
143141

144-
template <typename T> void regop(Set, T &reg, const RegisterValue &val) {
145-
regop(Set{}, reg, std::get<T>(val));
142+
template <typename T, typename RV> void regop(Set, T &reg, const RV &rv) {
143+
const T branch = get<T>(rv);
144+
regop(Set{}, reg, branch);
146145
}
147-
template <typename T> void regop(Get, const T &reg, RegisterValue &val) {
146+
template <typename T, typename RV> void regop(Get, const T &reg, RV &val) {
148147
T newval;
149148
regop(Get{}, reg, newval);
150149
val = newval;
151150
}
152151

153-
inline void regop(Set, Simd128 &simd, const RegisterValue &v) {
154-
std::memcpy((void *)&simd, (void *)&std::get<Simd128>(v), sizeof simd);
152+
template <typename RV>
153+
inline void regop(Set, Simd128 &simd, const RV &v) {
154+
Simd128 value = get<Simd128>(v);
155+
std::memcpy((void *)&simd, (void *)&value, sizeof simd);
155156
}
156157

157-
inline void regop(Get, const Simd128 &simd, RegisterValue &v) {
158+
template <typename RV>
159+
inline void regop(Get, const Simd128 &simd, RV &v) {
158160
v = Simd128{};
159-
std::memcpy((void *)&std::get<Simd128>(v), (void *)&simd, sizeof simd);
161+
std::memcpy((void *)&get<Simd128>(v), (void *)&simd, sizeof simd);
160162
}
161163

162-
inline void regop(Set, i387Float &simd, const RegisterValue &v) {
163-
std::memcpy((void *)&simd, (void *)&std::get<i387Float>(v), sizeof simd);
164+
template <typename RV>
165+
inline void regop(Set, i387Float &simd, const RV &v) {
166+
auto fp = get<i387Float>( v );
167+
std::memcpy((void *)&simd, (void *)&fp, sizeof simd);
164168
}
165169

166-
inline void regop(Get, const i387Float &simd, RegisterValue &v) {
170+
template <typename RV>
171+
inline void regop(Get, const i387Float &simd, RV &v) {
167172
v = i387Float{};
168-
std::memcpy((void *)&std::get<i387Float>(v), (void *)&simd, sizeof simd);
173+
std::memcpy((void *)&get<i387Float>(v), (void *)&simd, sizeof simd);
169174
}
170175

171176

172-
inline void regop(Set, Simd64 &simd, const RegisterValue &v) {
173-
std::memcpy((void *)&simd, (void *)&std::get<Simd64>(v), sizeof simd);
177+
template <typename RV>
178+
inline void regop(Set, Simd64 &simd, const RV &v) {
179+
auto branch = get<Simd64>(v);
180+
std::memcpy((void *)&simd, (void *)&branch, sizeof simd);
174181
}
175182

176-
inline void regop(Get, const Simd64 &simd, RegisterValue &v) {
183+
template <typename RV>
184+
inline void regop(Get, const Simd64 &simd, RV &v) {
177185
v = Simd64{};
178-
std::memcpy((void *)&std::get<Simd64>(v), (void *)&simd, sizeof simd);
186+
std::memcpy((void *)&get<Simd64>(v), (void *)&simd, sizeof simd);
187+
}
188+
179189
}
180190

191+
#ifdef __x86_64__
192+
#include "libpstack/arch-x86_64.h"
193+
#endif
194+
#ifdef __aarch64__
195+
#include "libpstack/arch-aarch64.h"
196+
#endif
197+
#ifdef __i386__
198+
#include "libpstack/arch-i386.h"
199+
#endif
181200

201+
namespace pstack::Procman {
202+
template <typename RV> void CoreRegisters::setDwarf(int regId, const RV &value) {
203+
opReg(*this, Set{}, regId, value );
204+
};
182205

206+
RegisterValue CoreRegisters::getDwarf(int regId) const {
207+
RegisterValue value;
208+
opReg(*this, Get{}, regId, value);
209+
return value;
210+
};
183211

184212
}
185213
#endif

0 commit comments

Comments
 (0)