scripts: ctx.py/structs.py: Worked around incomplete structs/unions
Found when trying to measure ctx of yaffs2, which relies on incomplete structs to hide some internal state (yaffs_summary_tags, yaffs_DIR). This is less common in microcontroller filesystems since almost all structs end up statically/stack allocated, and you can't statically allocate incomplete structs. It's not too surprising, but incomplete structs have no associated DW_AT_byte_size in the relevant dwarf info, which broke ctx.py and structs.py... As a workaround, I'm now defaulting to size=0 if DW_AT_byte_size is missing. --- With this fix, at least structs.py is able to pick up the later internal definition of yaffs_summary_tags. ctx.py doesn't because it only looks at the unique dwarf offset referenced by the function definition, but I'm hesitant to try anything more clever here. yaffs_DIR is noteworthy in that there is simply no complete definition. Internally, yaffs_DIR pointers alias yaffsfs_DirSearchContext structs. In this case I think returning size=0 is the only reasonable option.
This commit is contained in:
+10
-8
@@ -522,9 +522,16 @@ def collect_ctx(obj_paths, *,
|
||||
if 'DW_AT_type' in entry:
|
||||
type = info[int(entry['DW_AT_type'].strip('<>'), 0)]
|
||||
size += sizeof(type, seen | {entry.off})
|
||||
# base type?
|
||||
elif entry.tag == 'DW_TAG_base_type':
|
||||
size = int(entry['DW_AT_byte_size'])
|
||||
# function pointer?
|
||||
elif entry.tag == 'DW_TAG_subroutine_type':
|
||||
size = 0
|
||||
# struct? include any nested pointers
|
||||
elif entry.tag == 'DW_TAG_structure_type':
|
||||
size = int(entry['DW_AT_byte_size'])
|
||||
# note structs/unions can be incomplete
|
||||
size = int(entry.get('DW_AT_byte_size', 0))
|
||||
for child in entry.children:
|
||||
if child.tag != 'DW_TAG_member':
|
||||
continue
|
||||
@@ -536,7 +543,8 @@ def collect_ctx(obj_paths, *,
|
||||
size += sizeof(type__, seen | {entry.off})
|
||||
# union? include any nested pointers
|
||||
elif entry.tag == 'DW_TAG_union_type':
|
||||
size = int(entry['DW_AT_byte_size'])
|
||||
# note structs/unions can be incomplete
|
||||
size = int(entry.get('DW_AT_byte_size', 0))
|
||||
size_ = 0
|
||||
for child in entry.children:
|
||||
if child.tag != 'DW_TAG_member':
|
||||
@@ -555,12 +563,6 @@ def collect_ctx(obj_paths, *,
|
||||
for child in entry.children:
|
||||
if child.tag == 'DW_TAG_subrange_type':
|
||||
size *= int(child['DW_AT_upper_bound']) + 1
|
||||
# base type?
|
||||
elif entry.tag == 'DW_TAG_base_type':
|
||||
size = int(entry['DW_AT_byte_size'])
|
||||
# function pointer?
|
||||
elif entry.tag == 'DW_TAG_subroutine_type':
|
||||
size = 0
|
||||
# a modifier?
|
||||
elif (entry.tag in {
|
||||
'DW_TAG_typedef',
|
||||
|
||||
Reference in New Issue
Block a user