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:
Christopher Haster
2025-08-10 23:39:16 -05:00
parent c9691503bc
commit 3e8f304138
2 changed files with 23 additions and 11 deletions
+13 -3
View File
@@ -422,9 +422,17 @@ def collect_structs(obj_paths, *,
if entry.off in sizeof.cache:
return sizeof.cache[entry.off]
# explicit size?
if 'DW_AT_byte_size' in entry:
# pointer? base type?
if entry.tag in {
'DW_TAG_pointer_type',
'DW_TAG_base_type'}:
size = int(entry['DW_AT_byte_size'])
# struct? union?
elif entry.tag in {
'DW_TAG_structure_type',
'DW_TAG_union_type'}:
# note structs/unions can be incomplete
size = int(entry.get('DW_AT_byte_size', 0))
# array? multiply by size
elif entry.tag == 'DW_TAG_array_type':
type = info[int(entry['DW_AT_type'].strip('<>'), 0)]
@@ -469,7 +477,9 @@ def collect_structs(obj_paths, *,
elif entry.tag in {
'DW_TAG_structure_type',
'DW_TAG_union_type'}:
align = max(alignof(child) for child in entry.children)
align = max(
(alignof(child) for child in entry.children),
default=0)
# indirect type?
elif entry.tag in {
'DW_TAG_typedef',