@@ -234,6 +234,7 @@ def __init__(self):
234
234
self .heap_base_regnum = try_or_else (lambda : int (gdb .parse_and_eval ('(int)__svm_heap_base_regnum' )), 0 , gdb .error )
235
235
self .frame_size_status_mask = try_or_else (lambda : int (gdb .parse_and_eval ('(int)__svm_frame_size_status_mask' )), 0 , gdb .error )
236
236
self .object_type = gdb .lookup_type ("java.lang.Object" )
237
+ self .object_header_type = gdb .lookup_type ("_objhdr" )
237
238
self .stack_type = gdb .lookup_type ("long" )
238
239
self .hub_type = gdb .lookup_type ("java.lang.Class" )
239
240
self .classloader_type = gdb .lookup_type ("java.lang.ClassLoader" )
@@ -372,6 +373,12 @@ def get_java_string(self, obj: gdb.Value, gdb_output_string: bool = False) -> st
372
373
trace (f'<SVMUtil> - get_java_string({ hex (self .get_adr (obj ))} ) = { result } ' )
373
374
return result
374
375
376
+ def get_hub_field (self , obj : gdb .Value ) -> gdb .Value :
377
+ try :
378
+ return obj .cast (self .object_header_type )[self .hub_field_name ]
379
+ except gdb .error :
380
+ return self .null
381
+
375
382
def get_obj_field (self , obj : gdb .Value , field_name : str , default : gdb .Value = None ) -> gdb .Value :
376
383
try :
377
384
return obj [field_name ]
@@ -387,7 +394,7 @@ def get_int_field(self, obj: gdb.Value, field_name: str, default: int = 0) -> in
387
394
388
395
def get_classloader_namespace (self , obj : gdb .Value ) -> str :
389
396
try :
390
- hub = self .get_obj_field (obj , SVMUtil . hub_field_name )
397
+ hub = self .get_hub_field (obj )
391
398
if self .is_null (hub ):
392
399
return ""
393
400
@@ -422,7 +429,7 @@ def get_rtt(self, obj: gdb.Value) -> gdb.Type:
422
429
if self .get_uncompressed_type (SVMUtil .get_basic_type (obj .type )).code == gdb .TYPE_CODE_UNION :
423
430
obj = self .cast_to (obj , self .object_type )
424
431
425
- hub = self .get_obj_field (obj , SVMUtil . hub_field_name )
432
+ hub = self .get_hub_field (obj )
426
433
if self .is_null (hub ):
427
434
return static_type
428
435
@@ -506,15 +513,18 @@ def get_base_class(self, t: gdb.Type) -> gdb.Type:
506
513
507
514
def find_shared_types (self , type_list : list , t : gdb .Type ) -> list : # list[gdb.Type]
508
515
if len (type_list ) == 0 :
516
+ # fill type list -> java.lang.Object will be last element
509
517
while t != self .object_type :
510
518
type_list += [t ]
511
519
t = self .get_base_class (t )
512
520
return type_list
513
521
else :
522
+ # find first type in hierarchy of t that is contained in the type list
514
523
while t != self .object_type :
515
524
if t in type_list :
516
525
return type_list [type_list .index (t ):]
517
526
t = self .get_base_class (t )
527
+ # if nothing matches return the java.lang.Object
518
528
return [self .object_type ]
519
529
520
530
def is_java_type (self , t : gdb .Type ) -> bool :
@@ -847,6 +857,8 @@ def infer_generic_types(self) -> str:
847
857
for i , elem in enumerate (self , 1 ):
848
858
if not self .__svm_util .is_null (elem ): # check for null values
849
859
elem_type = self .__svm_util .find_shared_types (elem_type , self .__svm_util .get_rtt (elem ))
860
+ # java.lang.Object will always be the last element in a type list
861
+ # if it is the only element in the list we cannot infer more than java.lang.Object
850
862
if (len (elem_type ) > 0 and elem_type [0 ] == self .__svm_util .object_type ) or (0 <= svm_infer_generics .value <= i ):
851
863
break
852
864
@@ -924,6 +936,8 @@ def infer_generic_types(self) -> tuple: # (str, str):
924
936
key_type = self .__svm_util .find_shared_types (key_type , self .__svm_util .get_rtt (key ))
925
937
if not self .__svm_util .is_null (value ) and (len (value_type ) == 0 or value_type [0 ] != self .__svm_util .object_type ):
926
938
value_type = self .__svm_util .find_shared_types (value_type , self .__svm_util .get_rtt (value ))
939
+ # java.lang.Object will always be the last element in a type list
940
+ # if it is the only element in the list we cannot infer more than java.lang.Object
927
941
if (0 <= svm_infer_generics .value <= i ) or (len (key_type ) > 0 and key_type [0 ] == self .__svm_util .object_type and
928
942
len (value_type ) > 0 and value_type [0 ] == self .__svm_util .object_type ):
929
943
break
@@ -1010,6 +1024,8 @@ def infer_generic_types(self) -> tuple: # (str, str):
1010
1024
key_type = self .__svm_util .find_shared_types (key_type , self .__svm_util .get_rtt (key ))
1011
1025
if not self .__svm_util .is_null (value ) and (len (value_type ) == 0 or value_type [0 ] != self .__svm_util .object_type ):
1012
1026
value_type = self .__svm_util .find_shared_types (value_type , self .__svm_util .get_rtt (value ))
1027
+ # java.lang.Object will always be the last element in a type list
1028
+ # if it is the only element in the list we cannot infer more than java.lang.Object
1013
1029
if (0 <= svm_infer_generics .value <= i ) or (len (key_type ) > 0 and key_type [0 ] == self .__svm_util .object_type and
1014
1030
len (value_type ) > 0 and value_type [0 ] == self .__svm_util .object_type ):
1015
1031
break
0 commit comments