Emit DWARF expressions from dwarf-to-dwarf-assembler.py
Checks
| Context |
Check |
Description |
| linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
Commit Message
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.
---
gdb/contrib/dwarf-to-dwarf-assembler.py | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
base-commit: 1678d7d3d2e4cf83cda5a96334a0326573ad0f7c
Comments
>>>>> "Tom" == Tom Tromey <tromey@adacore.com> writes:
Tom> This changes dwarf-to-dwarf-assembler.py to attempt to emit DWARF
Tom> expressions. It is not close to perfect, since it relies on the
Tom> elftools formatting to some extent, but it does at least eliminate the
Tom> need to do a separate "readelf" step to try to work on the expression
Tom> by hand.
I'm going to check this in.
Tom
@@ -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: