@@ -168,45 +168,60 @@ static bool _rtti_msvc_check_completeobjectlocator_v1(
168168}
169169
170170static 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