Skip to content

Commit 3be61b4

Browse files
committed
feat(rtti): deeper class detail propagation
1 parent 332fa68 commit 3be61b4

1 file changed

Lines changed: 73 additions & 10 deletions

File tree

compilers/rtti/msvc/msvc.c

Lines changed: 73 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,14 @@ static bool _rtti_msvc_is_typedescriptor_valid(const char* s, usize n) {
3434
return true;
3535
}
3636

37+
static const char*
38+
_rtti_msvc_extract_classtag(RDReader* r, RDAddress locator_addr,
39+
const RTTICompleteObjectLocator* objlocator);
40+
3741
static bool _rtti_msvc_walk_baseclassarray(
3842
RDContext* ctx, RDReader* r,
39-
const RTTIClassHierarchyDescriptor* classdescriptor, RDAddress imagebase) {
43+
const RTTIClassHierarchyDescriptor* classdescriptor, RDAddress imagebase,
44+
const char* classtag) {
4045
RDAddress baseclassarray_va = imagebase + classdescriptor->pBaseClassArray;
4146

4247
for(u32 i = 0; i < classdescriptor->numBaseClasses; i++) {
@@ -49,6 +54,8 @@ static bool _rtti_msvc_walk_baseclassarray(
4954
RDAddress bcd_va = imagebase + bcd_addr_val;
5055
if(!_rtti_msvc_segment_ok(ctx, bcd_va)) return false;
5156

57+
rd_library_type(ctx, entry_addr, "u32", 0, RD_TYPE_PTR);
58+
5259
rd_reader_seek(r, bcd_va);
5360
RTTIBaseClassDescriptor basedescriptor;
5461
if(!rtti_msvc_read_baseclassdescriptor(r, &basedescriptor))
@@ -71,6 +78,11 @@ static bool _rtti_msvc_walk_baseclassarray(
7178

7279
rd_library_type(ctx, bcd_va, "RTTI_BaseClassDescriptor", 0,
7380
RD_TYPE_NONE);
81+
82+
if(classtag) {
83+
rd_library_name(ctx, bcd_va,
84+
rd_format("%s::__base_class", classtag));
85+
}
7486
}
7587

7688
return true;
@@ -107,8 +119,12 @@ static bool _rtti_msvc_check_completeobjectlocator_v0(
107119
sizeof(u32)))
108120
return false;
109121

110-
if(!_rtti_msvc_walk_baseclassarray(ctx, r, &classdescriptor, 0))
122+
char* classtag = rd_strdup(_rtti_msvc_extract_classtag(r, 0, objlocator));
123+
124+
if(!_rtti_msvc_walk_baseclassarray(ctx, r, &classdescriptor, 0, classtag)) {
125+
rd_free(classtag);
111126
return false;
127+
}
112128

113129
rd_library_type(ctx, typedescriptor_name, "char", n + 1, RD_TYPE_NONE);
114130

@@ -118,7 +134,20 @@ static bool _rtti_msvc_check_completeobjectlocator_v0(
118134
rd_library_type(ctx, objlocator->pTypeDescriptor, "RTTI_TypeDescriptor", 0,
119135
RD_TYPE_NONE);
120136

121-
return !rd_reader_has_error(r);
137+
if(rd_reader_has_error(r)) {
138+
rd_free(classtag);
139+
return false;
140+
}
141+
142+
if(classtag) {
143+
rd_library_name(ctx, objlocator->pClassDescriptor,
144+
rd_format("%s::__rtti_class_hierarchy", classtag));
145+
rd_library_name(ctx, objlocator->pTypeDescriptor,
146+
rd_format("%s::__rtti_type_descriptor", classtag));
147+
}
148+
149+
rd_free(classtag);
150+
return true;
122151
}
123152

124153
static bool _rtti_msvc_check_completeobjectlocator_v1(
@@ -156,15 +185,34 @@ static bool _rtti_msvc_check_completeobjectlocator_v1(
156185
ctx, bca_va, (usize)classdescriptor.numBaseClasses * sizeof(u32)))
157186
return false;
158187

159-
if(!_rtti_msvc_walk_baseclassarray(ctx, r, &classdescriptor, imagebase))
188+
char* classtag =
189+
rd_strdup(_rtti_msvc_extract_classtag(r, locator_addr, objlocator));
190+
191+
if(!_rtti_msvc_walk_baseclassarray(ctx, r, &classdescriptor, imagebase,
192+
classtag)) {
193+
rd_free(classtag);
160194
return false;
195+
}
161196

162197
rd_library_type(ctx, typedescriptor_name, "char", n + 1, RD_TYPE_NONE);
163198
rd_library_type(ctx, cd_va, "RTTI_ClassHierarchyDescriptor", 0,
164199
RD_TYPE_NONE);
165200
rd_library_type(ctx, td_va, "RTTI_TypeDescriptor64", 0, RD_TYPE_NONE);
166201

167-
return !rd_reader_has_error(r);
202+
if(rd_reader_has_error(r)) {
203+
rd_free(classtag);
204+
return false;
205+
}
206+
207+
if(classtag) {
208+
rd_library_name(ctx, cd_va,
209+
rd_format("%s::__rtti_class_hierarchy", classtag));
210+
rd_library_name(ctx, td_va,
211+
rd_format("%s::__rtti_type_descriptor", classtag));
212+
}
213+
214+
rd_free(classtag);
215+
return true;
168216
}
169217

170218
static void _rtti_msvc_process_vtable(RDContext* ctx, RDReader* r,
@@ -202,10 +250,12 @@ static void _rtti_msvc_process_vtable(RDContext* ctx, RDReader* r,
202250

203251
if(rd_get_type(ctx, vtable_entryaddr, &t) &&
204252
!strcmp(t.name, objlocator_type)) {
205-
name = rd_format("%s::obj_locator", classtag_ptr);
253+
name = rd_format("%s::__obj_locator", classtag_ptr);
206254
rd_library_name(ctx, vtable_addr, name);
207255
rd_library_type(ctx, vtable_addr, rd_integral_from_size(stride),
208-
0, RD_TYPE_NONE);
256+
0, RD_TYPE_PTR);
257+
258+
rd_add_xref(ctx, vtable_addr, vtable_entryaddr, RD_DR_ADDRESS);
209259
}
210260

211261
break;
@@ -215,10 +265,11 @@ static void _rtti_msvc_process_vtable(RDContext* ctx, RDReader* r,
215265
rd_auto_function(ctx, vtable_entryaddr, name);
216266

217267
// vtable entry
218-
name = rd_format("%s::vtable_%" PRId32, classtag_ptr, index);
268+
name = rd_format("%s::__vtable_%" PRId32, classtag_ptr, index);
219269
rd_library_name(ctx, vtable_addr, name);
220270
rd_library_type(ctx, vtable_addr, rd_integral_from_size(stride), 0,
221-
RD_TYPE_NONE);
271+
RD_TYPE_PTR);
272+
rd_add_xref(ctx, vtable_addr, vtable_entryaddr, RD_DR_ADDRESS);
222273

223274
slot += stride;
224275
index++;
@@ -367,8 +418,20 @@ static void _rtti_msvc_find_objlocators(RDContext* ctx, RDReader* r) {
367418
}
368419
}
369420

370-
if(ok)
421+
if(ok) {
422+
char* classtag = rd_strdup(
423+
_rtti_msvc_extract_classtag(r, addr, &objlocator));
424+
425+
if(classtag) {
426+
rd_library_name(
427+
ctx, addr,
428+
rd_format("%s::__rtti_obj_locator", classtag));
429+
}
430+
431+
rd_free(classtag);
432+
371433
addr = next;
434+
}
372435
else
373436
addr += sizeof(u32);
374437
}

0 commit comments

Comments
 (0)