-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResolver.hpp
More file actions
164 lines (127 loc) · 4.33 KB
/
Copy pathResolver.hpp
File metadata and controls
164 lines (127 loc) · 4.33 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "Assembly.hpp"
#include "Loader.hpp"
#include <algorithm>
#include <iostream>
#include <type_traits>
#include <set>
#include <thread>
#include <mutex>
#pragma once
#define GC_TRIGGERED_EXC_CODE 0xC001F00D
inline size_t PadToNextWordx64(size_t size)
{
return ((size+7) >> 3) << 3;
}
namespace ULR::IL { class JITContext; }
namespace ULR::Resolver
{
enum BindingFlags
{
Default,
Instance = 1 << 0,
Static = 1 << 1,
Public = 1 << 2,
NonPublic = 1 << 3
};
struct GCResult
{
public:
size_t size_collected = 0;
size_t num_collected = 0;
};
struct StaticDebugInfo
{
const char* source_filename;
unsigned int source_lineno;
const char* source_line;
unsigned int breakpoint_no;
};
class ULRAPIImpl
{
void (*StaticDebug)(StaticDebugInfo& info);
size_t prev_size_accessible = 0;
std::map<pthread_t, std::pair<char**, char**>> gc_lclsearch_addrs;
std::mutex gc_lock;
std::mutex alloc_lock;
IL::JITContext* jit;
HMODULE debugger;
public:
Loader* loader = new Loader();
GCResult last_gc_result;
std::map<char*, size_t> allocated_objs;
size_t allocated_size = 0;
std::vector<void*> allocated_field_offsets;
ULRAPIImpl(
HMODULE debugger,
bool& debugger_load_successful
);
bool EnsureLoaded(std::string_view assembly_name);
Assembly* LoadNativeAssembly(std::string_view assembly_name);
ULRResult<Assembly*, IL::CompilationError> LoadJITAssembly(std::string jitasm_path);
Assembly* LocateAssembly(std::string_view assembly_name);
void* LocateSymbol(Assembly* assembly, char symbol_name[]);
std::vector<MemberInfo*> GetMember(Type* type, std::string_view name);
ConstructorInfo* GetCtor(Type* type, std::vector<Type*> signature);
DestructorInfo* GetDtor(Type* type);
MethodInfo* GetMethod(Type* type, std::string_view name, std::vector<Type*> argsignature, int bindingflags);
MethodInfo* GetMethod(Type* type, std::string_view name, std::vector<Type*> argsignature);
MethodInfo* GetNonNewMethod(Type* type, std::string_view name, std::vector<Type*> argsignature, int bindingflags); // this is solely for the virtual table loader
FieldInfo* GetField(Type* type, std::string_view name, int bindingflags);
PropertyInfo* GetProperty(Type* type, std::string_view name, int bindingflags);
Type* GetArrayTypePrimarily(std::string_view full_qual_typename);
Type* GetType(std::string_view full_qual_typename);
Type* GetType(std::string_view full_qual_typename, std::string_view assembly_hint);
inline Type* GetTypeOf(char* obj) { return *reinterpret_cast<Type**>(obj); } // special inline decl because this is a highly used small API function (for vcalls, so it has to be fast)
char* AllocateObject(size_t size);
char* AllocateZeroed(size_t size);
char* AllocateObjectNoGC(size_t size);
char* AllocateZeroedNoGC(size_t size);
void* AllocateFieldOffset(size_t size);
template <typename... Args>
char* ConstructObject(
void (*Constructor)(char* obj, Args... args),
Type* typeptr,
Args... args
)
{
char* obj = AllocateObject(typeptr->size);
Type** obj_for_type_place = reinterpret_cast<Type**>(obj);
obj_for_type_place[0] = typeptr;
Constructor(obj, args...);
return obj;
}
std::set<char*> ExamineRoot(char* root);
std::set<char*> ExamineRoots(std::set<char*> roots);
GCResult Collect();
void InitGCLocalVarRoot(char** stackaddr);
void InitGCLocalVarEnd(char** stackaddr);
template <typename ValueType>
char* Box(ValueType& obj, Type* typeptr)
{
constexpr size_t alloc_size = sizeof(Type*)+sizeof(ValueType);
Type** boxed = (Type**) AllocateObject(alloc_size);
boxed[0] = typeptr;
ValueType* obj_for_val_place = (ValueType*) (boxed+1);
obj_for_val_place[0] = obj;
return (char*) boxed;
}
template <typename ValueType>
ValueType UnBox(char* boxed)
{
return *(
(ValueType*) (
((Type**) boxed)+1
)
);
}
void Breakpoint(StaticDebugInfo info);
Assembly* ResolveAddressToAssembly(void* addr);
MemberInfo* ResolveAddressToMember(void* addr);
std::string GetFullyQualifiedNameOf(MemberInfo* type);
std::string GetDisplayNameOf(MemberInfo* member);
std::string GetDisplayNameOf(Type* member);
std::string GetStackTrace(int skipframes);
~ULRAPIImpl();
};
}
extern ULR::Resolver::ULRAPIImpl* internal_api;