Windows: Add basic C++ support (skip C++ types)

This commit is contained in:
Mike Auty
2021-07-29 00:06:06 +01:00
parent fda1512273
commit 796cf69b20
2 changed files with 170 additions and 5 deletions
@@ -812,6 +812,33 @@
"kind": "struct",
"size": 10
},
"LF_BCLASS": {
"fields": {
"field_attributes": {
"offset": 0,
"type": {
"kind": "base",
"name": "unsigned short"
}
},
"type_index": {
"offset": 2,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"bases": {
"offset": 6,
"type": {
"kind": "base",
"name": "unsigned long"
}
}
},
"kind": "struct",
"size": 10
},
"LF_BITFIELD": {
"fields": {
"underlying_type": {
@@ -992,6 +1019,112 @@
"kind": "struct",
"size": 8
},
"LF_METHOD": {
"fields": {
"count": {
"offset": 0,
"type": {
"kind": "base",
"name": "unsigned short"
}
},
"method_list": {
"offset": 2,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"name": {
"offset": 6,
"type": {
"kind": "base",
"name": "string"
}
}
},
"kind": "struct",
"size": 7
},
"LF_METHODLIST": {
"fields": {
"mlist": {
"offset": 0,
"type": {
"kind": "array",
"count": 1,
"subtype": {
"kind": "base",
"name": "unsigned long"
}
}
}
},
"kind": "struct",
"size": 4
},
"LF_MFUNCTION": {
"fields": {
"return_type": {
"offset": 0,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"class_type": {
"offset": 4,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"this_type": {
"offset": 8,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"calling_convention": {
"offset": 12,
"type": {
"kind": "base",
"name": "unsigned char"
}
},
"attributes": {
"offset": 13,
"type": {
"kind": "base",
"name": "unsigned short"
}
},
"num_params": {
"offset": 15,
"type": {
"kind": "base",
"name": "unsigned short"
}
},
"arglist": {
"offset": 17,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"adjuster": {
"offset": 21,
"type": {
"kind": "base",
"name": "unsigned long"
}
}
},
"kind": "struct",
"size": 25
},
"LF_MODIFIER": {
"fields": {
"subtype_index": {
@@ -1041,6 +1174,26 @@
"kind": "struct",
"size": 6
},
"LF_NESTTYPE": {
"fields": {
"subtype_index": {
"offset": 2,
"type": {
"kind": "base",
"name": "unsigned long"
}
},
"name": {
"offset": 6,
"type": {
"kind": "base",
"name": "string"
}
}
},
"kind": "struct",
"size": 10
},
"LF_POINTER": {
"fields": {
"subtype_index": {
@@ -363,6 +363,7 @@ class PdbReader:
except ValueError:
return None
def _read_info_stream(self, stream_number, stream_name, info_list):
vollog.debug(f"Reading {stream_name}")
info_layer = self._context.layers.get(self._layer_name + "_stream" + str(stream_number), None)
@@ -656,7 +657,7 @@ class PdbReader:
result = value.size
elif leaf_type in [leaf_type.LF_ARRAY, leaf_type.LF_ARRAY_ST, leaf_type.LF_STRIDED_ARRAY]:
result = value.size
elif leaf_type in [leaf_type.LF_MODIFIER, leaf_type.LF_ENUM, leaf_type.LF_ARGLIST]:
elif leaf_type in [leaf_type.LF_MODIFIER, leaf_type.LF_ENUM, leaf_type.LF_ARGLIST, leaf_type.LF_NESTTYPE]:
result = self.get_size_from_index(value.subtype_index)
elif leaf_type in [leaf_type.LF_MEMBER]:
result = self.get_size_from_index(value.field_type)
@@ -755,7 +756,12 @@ class PdbReader:
'LF_BITFIELD': ('LF_BITFIELD', False, None),
'LF_UDT_SRC_LINE': ('LF_UDT_SRC_LINE', False, None),
'LF_UDT_MOD_SRC_LINE': ('LF_UDT_MOD_SRC_LINE', False, None),
'LF_BUILDINFO': ('LF_BUILDINFO', False, None)
'LF_BUILDINFO': ('LF_BUILDINFO', False, None),
'LF_NESTTYPE': ('LF_NESTTYPE', True, None),
'LF_BCLASS': ('LF_BCLASS', False, None),
'LF_METHOD': ('LF_METHOD', True, None),
'LF_METHODLIST': ('LF_METHODLIST', False, None),
'LF_MFUNCTION': ('LF_MFUNCTION', False, None),
}
def consume_type(
@@ -829,6 +835,12 @@ class PdbReader:
return result
for field in fields_struct:
_, name, member = field
skip = False
for skip_type in ['LF_NESTTYPE', 'LF_METHOD', 'LF_BCLASS']:
if member.vol.type_name.endswith(skip_type):
skip = True
if skip:
continue
result[name] = {"offset": member.offset, "type": self.get_type_from_index(member.field_type)}
return result
@@ -852,9 +864,9 @@ class PdbReader:
if element_type > 0x1000:
_, name, toplevel_type = self.types[element_type - 0x1000]
# If there's no name, the original size is probably fine as long as we're not indirect (LF_MODIFIER)
if not name and isinstance(
toplevel_type,
interfaces.objects.ObjectInterface) and toplevel_type.vol.type_name.endswith('LF_MODIFIER'):
if not name and isinstance(toplevel_type, interfaces.objects.ObjectInterface) and \
(toplevel_type.vol.type_name.endswith('LF_MODIFIER') or
toplevel_type.vol.type_name.endswith('LF_NESTTYPE')):
# We have check they don't point to a forward reference, so we go round again with the subtype
element_type = toplevel_type.subtype_index
loop = True