forked from bloomberg/pystack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstructure.h
More file actions
91 lines (77 loc) · 2.34 KB
/
structure.h
File metadata and controls
91 lines (77 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#pragma once
#include <array>
#include <vector>
#include "process.h"
namespace pystack {
template<typename OffsetsStruct>
class Structure
{
public:
// Constructors
Structure(std::shared_ptr<const AbstractProcessManager> manager, remote_addr_t addr);
Structure(const Structure&) = delete;
Structure& operator=(const Structure&) = delete;
// Methods
void copyFromRemote();
template<typename FieldPointer>
remote_addr_t getFieldRemoteAddress(FieldPointer OffsetsStruct::*field) const;
template<typename FieldPointer>
const typename FieldPointer::Type& getField(FieldPointer OffsetsStruct::*field);
private:
// Data members
std::shared_ptr<const AbstractProcessManager> d_manager;
remote_addr_t d_addr;
ssize_t d_size;
std::array<char, 512> d_footprintbuf;
std::vector<char> d_heapbuf;
char* d_buf;
};
template<typename OffsetsStruct>
inline Structure<OffsetsStruct>::Structure(
std::shared_ptr<const AbstractProcessManager> manager,
remote_addr_t addr)
: d_manager(manager)
, d_addr(addr)
, d_size(d_manager->offsets().get<OffsetsStruct>().size)
, d_buf{}
{
}
template<typename OffsetsStruct>
inline void
Structure<OffsetsStruct>::copyFromRemote()
{
if (d_buf) {
return; // already copied
}
if (d_size < 512) {
d_buf = &d_footprintbuf[0];
} else {
d_heapbuf.resize(d_size);
d_buf = &d_heapbuf[0];
}
d_manager->copyMemoryFromProcess(d_addr, d_size, d_buf);
}
template<typename OffsetsStruct>
template<typename FieldPointer>
inline remote_addr_t
Structure<OffsetsStruct>::getFieldRemoteAddress(FieldPointer OffsetsStruct::*field) const
{
offset_t offset = (d_manager->offsets().get<OffsetsStruct>().*field).offset;
return d_addr + offset;
}
template<typename OffsetsStruct>
template<typename FieldPointer>
inline const typename FieldPointer::Type&
Structure<OffsetsStruct>::getField(FieldPointer OffsetsStruct::*field)
{
copyFromRemote();
offset_t offset = (d_manager->offsets().get<OffsetsStruct>().*field).offset;
if (d_size < 0 || (size_t)d_size < sizeof(typename FieldPointer::Type)
|| d_size - sizeof(typename FieldPointer::Type) < offset)
{
abort();
}
auto address = d_buf + offset;
return *reinterpret_cast<const typename FieldPointer::Type*>(address);
}
} // namespace pystack