[binutils-gdb] Emit DWARF expressions from dwarf-to-dwarf-assembler.py
Tom Tromey via Gdb-cvs <[email protected]> Fri, 5 Jun 2026 21:11:56 +0000 (GMT)
| Newsgroups | gmane.comp.gdb.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=18ad8c1a54d5d0e3fe3ff6c13f217e0dc840f991 commit 18ad8c1a54d5d0e3fe3ff6c13f217e0dc840f991 Author: Tom Tromey <[email protected]> Date: Fri May 22 11:17:17 2026 -0600 Emit DWARF expressions from dwarf-to-dwarf-assembler.py This changes dwarf-to-dwarf-assembler.py to attempt to emit DWARF expressions. It is not close to perfect, since it relies on the elftools formatting to some extent, but it does at least eliminate the need to do a separate "readelf" step to try to work on the expression by hand. Diff: --- gdb/contrib/dwarf-to-dwarf-assembler.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/gdb/contrib/dwarf-to-dwarf-assembler.py b/gdb/contrib/dwarf-to-dwarf-assembler.py index 58342274fb1..314a9e9587b 100755 --- a/gdb/contrib/dwarf-to-dwarf-assembler.py +++ b/gdb/contrib/dwarf-to-dwarf-assembler.py @@ -52,6 +52,7 @@ from elftools.construct.lib.container import ListContainer from elftools.dwarf.compileunit import CompileUnit as RawCompileUnit from elftools.dwarf.die import DIE as RawDIE from elftools.dwarf.die import AttributeValue +from elftools.dwarf.dwarf_expr import DWARFExprParser from elftools.dwarf.enums import ENUM_DW_ATE, ENUM_DW_LANG from elftools.elf.elffile import ELFFile @@ -118,19 +119,27 @@ class DWARFAttribute: def __init__( self, + cu, die_offset: int, name: str, value: str | bytes | int | bool, form=None, ): + self.cu = cu self.die_offset = die_offset self.name = name self.value = value self.form = form - def _format_expr_value(self) -> str: - self.form = "SPECIAL_expr" - return "{ MANUAL: Fill expr list }" + def _format_expr_value(self, intro, indent_count: int) -> str: + result = indent(intro, indent_count) + "{\n" + parser = DWARFExprParser(self.cu.structs) + for op in parser.parse_expr(self.value): + result += indent(f"{op.op_name} 0x{op.op:02x}", indent_count + 1) + if op.args: + result += f" {op.args}" + result += "\n" + return result + indent("} SPECIAL_expr", indent_count) def _needs_escaping(self, str_value: str) -> bool: charset = set(str_value) @@ -151,9 +160,7 @@ class DWARFAttribute: def _format_value( self, offset_die_lookup: dict[int, "DWARFDIE"], indent_count: int = 0 ) -> str: - if self.form in EXPR_ATTRIBUTE_FORMS: - return self._format_expr_value() - elif isinstance(self.value, bool): + if isinstance(self.value, bool): return str(int(self.value)) elif isinstance(self.value, int): if self.form == "DW_FORM_ref4": @@ -218,6 +225,10 @@ class DWARFAttribute: s += "@" + LANG_NAME[self.value] elif self.name == "DW_AT_encoding" and isinstance(self.value, int): s += "@" + ATE_NAME[self.value] + elif self.form in EXPR_ATTRIBUTE_FORMS: + # This returns a complete description that is already + # indented. + return self._format_expr_value(s, indent_count) else: s += self._format_value(offset_die_lookup) @@ -491,7 +502,7 @@ class DWARFParser: self.referenced_offsets.add(referenced_die.offset) processed_attrs[attr_name] = DWARFAttribute( - raw_die.offset, attr_name, actual_value, attr_value.form + die_cu, raw_die.offset, attr_name, actual_value, attr_value.form ) if raw_die.tag == DWARFCompileUnit.compile_unit_tag: