Skip to content

Commit 332fa68

Browse files
committed
feat(rtti): better vtable typing
1 parent 9dd5d64 commit 332fa68

1 file changed

Lines changed: 36 additions & 21 deletions

File tree

compilers/rtti/msvc/msvc.c

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -168,45 +168,60 @@ static bool _rtti_msvc_check_completeobjectlocator_v1(
168168
}
169169

170170
static void _rtti_msvc_process_vtable(RDContext* ctx, RDReader* r,
171-
RDAddress vftable_addr,
172-
const char* classtag, usize stride) {
173-
RDAddress slot = vftable_addr;
171+
RDAddress vtable_addr,
172+
const char* classtag, usize stride,
173+
const char* objlocator_type) {
174+
RDAddress slot = vtable_addr;
174175
u32 index = 0;
175176

176177
char* classtag_ptr = rd_strdup(classtag);
177178

178179
while(true) {
179180
rd_reader_seek(r, slot);
180-
RDAddress funcaddr;
181+
RDAddress vtable_addr = (RDAddress)rd_reader_tell(r);
182+
RDAddress vtable_entryaddr;
181183

182184
if(stride == sizeof(u32)) {
183185
u32 addr;
184186
if(!rd_reader_read_le32(r, &addr)) break;
185-
funcaddr = (RDAddress)addr;
187+
vtable_entryaddr = (RDAddress)addr;
186188
}
187189
else {
188190
u64 addr;
189191
if(!rd_reader_read_le64(r, &addr)) break;
190-
funcaddr = (RDAddress)addr;
192+
vtable_entryaddr = (RDAddress)addr;
191193
}
192194

193-
const RDSegment* seg = rd_find_segment(ctx, funcaddr);
194-
if(!seg || !(seg->perm & RD_SP_X)) break;
195+
const RDSegment* seg = rd_find_segment(ctx, vtable_entryaddr);
196+
if(!seg) break;
195197

196-
const char* name =
197-
rd_format("%s::vfunc_%" PRIx64, classtag_ptr, funcaddr);
198+
const char* name = NULL;
198199

199-
rd_auto_function(ctx, funcaddr, name);
200+
if(!(seg->perm & RD_SP_X)) {
201+
RDType t;
200202

201-
slot += stride;
202-
index++;
203-
}
203+
if(rd_get_type(ctx, vtable_entryaddr, &t) &&
204+
!strcmp(t.name, objlocator_type)) {
205+
name = rd_format("%s::obj_locator", classtag_ptr);
206+
rd_library_name(ctx, vtable_addr, name);
207+
rd_library_type(ctx, vtable_addr, rd_integral_from_size(stride),
208+
0, RD_TYPE_NONE);
209+
}
210+
211+
break;
212+
}
213+
214+
name = rd_format("%s::vfunc_%" PRIx64, classtag_ptr, vtable_entryaddr);
215+
rd_auto_function(ctx, vtable_entryaddr, name);
204216

205-
if(index > 0) {
206-
const char* name = rd_format("%s::vftable", classtag_ptr);
207-
rd_library_name(ctx, vftable_addr, name);
208-
rd_library_type(ctx, vftable_addr, rd_integral_from_size(stride), 0,
217+
// vtable entry
218+
name = rd_format("%s::vtable_%" PRId32, classtag_ptr, index);
219+
rd_library_name(ctx, vtable_addr, name);
220+
rd_library_type(ctx, vtable_addr, rd_integral_from_size(stride), 0,
209221
RD_TYPE_NONE);
222+
223+
slot += stride;
224+
index++;
210225
}
211226

212227
rd_free(classtag_ptr);
@@ -289,7 +304,7 @@ static void _rtti_msvc_find_vtables(RDContext* ctx, RDReader* r,
289304

290305
if(ok && _rtti_msvc_addressvect_contains(locators, value)) {
291306

292-
RDAddress vftable_addr = slot + stride;
307+
RDAddress vtable_addr = slot + stride;
293308

294309
// re-read the locator to recover its TypeDescriptor/classtag
295310
rd_reader_seek(r, value);
@@ -299,8 +314,8 @@ static void _rtti_msvc_find_vtables(RDContext* ctx, RDReader* r,
299314
_rtti_msvc_extract_classtag(r, value, &objlocator);
300315

301316
if(classtag) {
302-
_rtti_msvc_process_vtable(ctx, r, vftable_addr,
303-
classtag, stride);
317+
_rtti_msvc_process_vtable(ctx, r, vtable_addr, classtag,
318+
stride, objlocator_type);
304319
}
305320
}
306321
}

0 commit comments

Comments
 (0)