From 19cd428a3cfbf88618d8e910b5b243119460ee6e Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 5 Dec 2024 15:50:09 -0600 Subject: [PATCH] scripts: Added DwarfEntry.info to help find recursive tags Long story short: DW_TAG_lexical_blocks are annoying. In order to search the full tree of children of a given dwarf entry, we need a recursive function somewhere. We might as well make this function a part of the DwarfEntry class so we can share it with other scripts. Note this is roughly the same as collect_dwarf_info, but limited to the children of a given dwarf entry. This is useful for ongoing stack.py rework. --- scripts/code.py | 15 ++++++++++++++- scripts/ctx.py | 15 ++++++++++++++- scripts/data.py | 15 ++++++++++++++- scripts/structs.py | 17 +++++++++++++++-- 4 files changed, 57 insertions(+), 5 deletions(-) diff --git a/scripts/code.py b/scripts/code.py index cd402dab..8049e388 100755 --- a/scripts/code.py +++ b/scripts/code.py @@ -393,6 +393,19 @@ class DwarfEntry: else: return None + def info(self, tags=None): + # recursively flatten children + def flatten(entry): + for child in entry.children: + # filter if requested + if tags is None or child.tag in tags: + yield child + + yield from flatten(child) + + return DwarfInfo(co.OrderedDict( + (child.off, child) for child in flatten(self))) + # a collection of dwarf entries class DwarfInfo: def __init__(self, entries): @@ -443,7 +456,7 @@ class DwarfInfo: return len(self.entries) def __iter__(self): - return (v for k, v in self.entries.items()) + return iter(self.entries.values()) def collect_dwarf_info(obj_path, tags=None, *, objdump_path=OBJDUMP_PATH, diff --git a/scripts/ctx.py b/scripts/ctx.py index ebb7cc2c..9f52ba31 100755 --- a/scripts/ctx.py +++ b/scripts/ctx.py @@ -402,6 +402,19 @@ class DwarfEntry: else: return None + def info(self, tags=None): + # recursively flatten children + def flatten(entry): + for child in entry.children: + # filter if requested + if tags is None or child.tag in tags: + yield child + + yield from flatten(child) + + return DwarfInfo(co.OrderedDict( + (child.off, child) for child in flatten(self))) + # a collection of dwarf entries class DwarfInfo: def __init__(self, entries): @@ -452,7 +465,7 @@ class DwarfInfo: return len(self.entries) def __iter__(self): - return (v for k, v in self.entries.items()) + return iter(self.entries.values()) def collect_dwarf_info(obj_path, tags=None, *, objdump_path=OBJDUMP_PATH, diff --git a/scripts/data.py b/scripts/data.py index 7f0f835d..b9e0129c 100755 --- a/scripts/data.py +++ b/scripts/data.py @@ -393,6 +393,19 @@ class DwarfEntry: else: return None + def info(self, tags=None): + # recursively flatten children + def flatten(entry): + for child in entry.children: + # filter if requested + if tags is None or child.tag in tags: + yield child + + yield from flatten(child) + + return DwarfInfo(co.OrderedDict( + (child.off, child) for child in flatten(self))) + # a collection of dwarf entries class DwarfInfo: def __init__(self, entries): @@ -443,7 +456,7 @@ class DwarfInfo: return len(self.entries) def __iter__(self): - return (v for k, v in self.entries.items()) + return iter(self.entries.values()) def collect_dwarf_info(obj_path, tags=None, *, objdump_path=OBJDUMP_PATH, diff --git a/scripts/structs.py b/scripts/structs.py index 411fd1d2..c30ff233 100755 --- a/scripts/structs.py +++ b/scripts/structs.py @@ -253,7 +253,7 @@ class DwarfEntry: def name(self): if 'DW_AT_name' in self: name = self['DW_AT_name'].split(':')[-1].strip() - # prefix with struct/union + # prefix with struct/union/enum if self.tag == 'DW_TAG_structure_type': name = 'struct ' + name elif self.tag == 'DW_TAG_union_type': @@ -264,6 +264,19 @@ class DwarfEntry: else: return None + def info(self, tags=None): + # recursively flatten children + def flatten(entry): + for child in entry.children: + # filter if requested + if tags is None or child.tag in tags: + yield child + + yield from flatten(child) + + return DwarfInfo(co.OrderedDict( + (child.off, child) for child in flatten(self))) + # a collection of dwarf entries class DwarfInfo: def __init__(self, entries): @@ -314,7 +327,7 @@ class DwarfInfo: return len(self.entries) def __iter__(self): - return (v for k, v in self.entries.items()) + return iter(self.entries.values()) def collect_dwarf_info(obj_path, tags=None, *, objdump_path=OBJDUMP_PATH,