mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-22 17:23:06 +00:00
tests: test DWARF 5
Pick a few tests where the version difference matters rather than running every test twice. Signed-off-by: Omar Sandoval <osandov@osandov.com>
This commit is contained in:
parent
4eb0a8fa85
commit
69a99dde0d
@ -1,18 +1,19 @@
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
from collections import OrderedDict
|
||||
import os.path
|
||||
from typing import Any, NamedTuple, Optional, Sequence, Union
|
||||
import zlib
|
||||
|
||||
from tests.assembler import _append_sleb128, _append_uleb128
|
||||
from tests.dwarf import DW_AT, DW_FORM, DW_TAG
|
||||
from tests.dwarf import DW_AT, DW_FORM, DW_LNCT, DW_TAG, DW_UT
|
||||
from tests.elf import ET, SHT
|
||||
from tests.elfwriter import ElfSection, create_elf_file
|
||||
|
||||
|
||||
class DwarfAttrib(NamedTuple):
|
||||
name: str
|
||||
name: DW_AT
|
||||
form: DW_FORM
|
||||
value: Any
|
||||
|
||||
@ -25,11 +26,16 @@ class DwarfDie(NamedTuple):
|
||||
tag: DW_TAG
|
||||
attribs: Sequence[DwarfAttrib]
|
||||
children: Sequence[Union["DwarfDie", DwarfLabel]] = ()
|
||||
|
||||
|
||||
class DwarfUnit(NamedTuple):
|
||||
type: DW_UT
|
||||
die: DwarfDie
|
||||
type_signature: Optional[int] = None
|
||||
type_offset: Optional[str] = None
|
||||
|
||||
|
||||
def _compile_debug_abbrev(unit_dies, use_dw_form_indirect):
|
||||
def _compile_debug_abbrev(units, use_dw_form_indirect):
|
||||
buf = bytearray()
|
||||
code = 1
|
||||
|
||||
@ -52,13 +58,13 @@ def _compile_debug_abbrev(unit_dies, use_dw_form_indirect):
|
||||
for child in die.children:
|
||||
aux(child)
|
||||
|
||||
for die in unit_dies:
|
||||
aux(die)
|
||||
for unit in units:
|
||||
aux(unit.die)
|
||||
buf.append(0)
|
||||
return buf
|
||||
|
||||
|
||||
def _compile_debug_info(unit_dies, little_endian, bits, use_dw_form_indirect):
|
||||
def _compile_debug_info(units, little_endian, bits, version, use_dw_form_indirect):
|
||||
byteorder = "little" if little_endian else "big"
|
||||
all_labels = set()
|
||||
labels = {}
|
||||
@ -131,25 +137,33 @@ def _compile_debug_info(unit_dies, little_endian, bits, use_dw_form_indirect):
|
||||
|
||||
debug_info = bytearray()
|
||||
debug_types = bytearray()
|
||||
for die in unit_dies:
|
||||
for unit in units:
|
||||
labels.clear()
|
||||
relocations.clear()
|
||||
buf = debug_info if die.tag == DW_TAG.compile_unit else debug_types
|
||||
decl_file = 1
|
||||
if version == 4 and unit.type in (DW_UT.type, DW_UT.split_type):
|
||||
buf = debug_types
|
||||
else:
|
||||
buf = debug_info
|
||||
orig_len = len(buf)
|
||||
buf.extend(b"\0\0\0\0") # unit_length
|
||||
buf.extend((4).to_bytes(2, byteorder)) # version
|
||||
buf.extend(version.to_bytes(2, byteorder)) # version
|
||||
if version >= 5:
|
||||
buf.append(unit.type) # unit_type
|
||||
buf.append(bits // 8) # address_size
|
||||
buf.extend((0).to_bytes(4, byteorder)) # debug_abbrev_offset
|
||||
buf.append(bits // 8) # address_size
|
||||
if version < 5:
|
||||
buf.append(bits // 8) # address_size
|
||||
|
||||
if die.tag == DW_TAG.type_unit:
|
||||
buf.extend(die.type_signature.to_bytes(8, byteorder))
|
||||
relocations.append((len(buf), die.type_offset))
|
||||
if unit.type in (DW_UT.type, DW_UT.split_type):
|
||||
buf.extend(unit.type_signature.to_bytes(8, byteorder)) # type_signature
|
||||
relocations.append((len(buf), unit.type_offset))
|
||||
buf.extend(b"\0\0\0\0") # type_offset
|
||||
else:
|
||||
assert die.type_signature is None
|
||||
assert die.type_offset is None
|
||||
assert unit.type_signature is None
|
||||
assert unit.type_offset is None
|
||||
|
||||
aux(buf, die, 0)
|
||||
aux(buf, unit.die, 0)
|
||||
|
||||
unit_length = len(buf) - orig_len - 4
|
||||
buf[orig_len : orig_len + 4] = unit_length.to_bytes(4, byteorder)
|
||||
@ -160,72 +174,119 @@ def _compile_debug_info(unit_dies, little_endian, bits, use_dw_form_indirect):
|
||||
return debug_info, debug_types
|
||||
|
||||
|
||||
def _compile_debug_line(unit_dies, little_endian):
|
||||
buf = bytearray()
|
||||
def _compile_debug_line(units, little_endian, bits, version):
|
||||
byteorder = "little" if little_endian else "big"
|
||||
|
||||
buf.extend(b"\0\0\0\0") # unit_length
|
||||
buf.extend((4).to_bytes(2, byteorder)) # version
|
||||
buf.extend(b"\0\0\0\0") # header_length
|
||||
buf.append(1) # minimum_instruction_length
|
||||
buf.append(1) # maximum_operations_per_instruction
|
||||
buf.append(1) # default_is_stmt
|
||||
buf.append(1) # line_base
|
||||
buf.append(1) # line_range
|
||||
buf.append(1) # opcode_base
|
||||
# Don't need standard_opcode_length
|
||||
if not units:
|
||||
units = [DwarfUnit(DW_UT.compile, DwarfDie(DW_TAG.compile_unit, []))]
|
||||
|
||||
def compile_include_directories(die):
|
||||
if isinstance(die, DwarfLabel):
|
||||
return
|
||||
for attrib in die.attribs:
|
||||
if attrib.name != DW_AT.decl_file:
|
||||
continue
|
||||
dirname = os.path.dirname(attrib.value)
|
||||
if dirname:
|
||||
buf.extend(dirname.encode("ascii"))
|
||||
buf = bytearray()
|
||||
for unit in units:
|
||||
unit.die.attribs.append(
|
||||
DwarfAttrib(DW_AT.stmt_list, DW_FORM.sec_offset, len(buf))
|
||||
)
|
||||
if unit.type in (DW_UT.compile, DW_UT.partial, DW_UT.skeleton):
|
||||
unit.die.attribs.append(DwarfAttrib(DW_AT.name, DW_FORM.string, "main.c"))
|
||||
unit.die.attribs.append(
|
||||
DwarfAttrib(DW_AT.comp_dir, DW_FORM.string, "/usr/src")
|
||||
)
|
||||
|
||||
unit_length_start = len(buf)
|
||||
buf.extend(b"\0\0\0\0") # unit_length
|
||||
unit_length_end = len(buf)
|
||||
buf.extend(version.to_bytes(2, byteorder)) # version
|
||||
if version >= 5:
|
||||
buf.append(bits // 8) # address_size
|
||||
buf.append(0) # segment_selector_size
|
||||
header_length_start = len(buf)
|
||||
buf.extend(b"\0\0\0\0") # header_length
|
||||
header_length_end = len(buf)
|
||||
buf.append(1) # minimum_instruction_length
|
||||
buf.append(1) # maximum_operations_per_instruction
|
||||
buf.append(1) # default_is_stmt
|
||||
buf.append(1) # line_base
|
||||
buf.append(1) # line_range
|
||||
buf.append(1) # opcode_base
|
||||
# Don't need standard_opcode_lengths
|
||||
if version >= 5:
|
||||
buf.append(1) # directory_entry_format_count
|
||||
# directory_entry_format
|
||||
_append_uleb128(buf, DW_LNCT.path)
|
||||
_append_uleb128(buf, DW_FORM.string)
|
||||
|
||||
directories = OrderedDict([("/usr/src", 0)])
|
||||
|
||||
def collect_directories(die):
|
||||
if isinstance(die, DwarfLabel):
|
||||
return
|
||||
for attrib in die.attribs:
|
||||
if attrib.name != DW_AT.decl_file:
|
||||
continue
|
||||
dirname = os.path.dirname(attrib.value)
|
||||
if dirname:
|
||||
directories.setdefault(dirname, len(directories))
|
||||
for child in die.children:
|
||||
collect_directories(child)
|
||||
|
||||
collect_directories(unit.die)
|
||||
|
||||
if version >= 5:
|
||||
_append_uleb128(buf, len(directories)) # directories_count
|
||||
|
||||
# directories (or include_directories in version <= 4)
|
||||
for directory, index in directories.items():
|
||||
if index > 0 or version >= 5:
|
||||
buf.extend(directory.encode("ascii"))
|
||||
buf.append(0)
|
||||
if die.children:
|
||||
for child in die.children:
|
||||
compile_include_directories(child)
|
||||
|
||||
for die in unit_dies:
|
||||
compile_include_directories(die)
|
||||
buf.append(0)
|
||||
|
||||
decl_file = 1
|
||||
directory = 1
|
||||
|
||||
def compile_file_names(die):
|
||||
if isinstance(die, DwarfLabel):
|
||||
return
|
||||
nonlocal decl_file, directory
|
||||
for attrib in die.attribs:
|
||||
if attrib.name != DW_AT.decl_file:
|
||||
continue
|
||||
dirname, basename = os.path.split(attrib.value)
|
||||
buf.extend(basename.encode("ascii"))
|
||||
if version < 5:
|
||||
buf.append(0)
|
||||
# directory index
|
||||
if dirname:
|
||||
_append_uleb128(buf, directory)
|
||||
directory += 1
|
||||
else:
|
||||
_append_uleb128(buf, 0)
|
||||
_append_uleb128(buf, 0) # mtime
|
||||
_append_uleb128(buf, 0) # size
|
||||
if die.children:
|
||||
|
||||
if version >= 5:
|
||||
buf.append(2) # file_name_entry_format_count
|
||||
# file_name_entry_format
|
||||
_append_uleb128(buf, DW_LNCT.path)
|
||||
_append_uleb128(buf, DW_FORM.string)
|
||||
_append_uleb128(buf, DW_LNCT.directory_index)
|
||||
_append_uleb128(buf, DW_FORM.udata)
|
||||
|
||||
file_names = [("main.c", 0)]
|
||||
|
||||
def collect_file_names(die):
|
||||
if isinstance(die, DwarfLabel):
|
||||
return
|
||||
for attrib in die.attribs:
|
||||
if attrib.name != DW_AT.decl_file:
|
||||
continue
|
||||
dirname, basename = os.path.split(attrib.value)
|
||||
directory_index = directories[dirname] if dirname else 0
|
||||
file_names.append((basename, directory_index))
|
||||
for child in die.children:
|
||||
compile_file_names(child)
|
||||
collect_file_names(child)
|
||||
|
||||
for die in unit_dies:
|
||||
compile_file_names(die)
|
||||
buf.append(0)
|
||||
collect_file_names(unit.die)
|
||||
|
||||
unit_length = len(buf) - 4
|
||||
buf[:4] = unit_length.to_bytes(4, byteorder)
|
||||
header_length = unit_length - 6
|
||||
buf[6:10] = header_length.to_bytes(4, byteorder)
|
||||
if version >= 5:
|
||||
_append_uleb128(buf, len(file_names)) # file_names_count
|
||||
|
||||
# file_names
|
||||
for path, directory_index in file_names[0 if version >= 5 else 1 :]:
|
||||
# path
|
||||
buf.extend(path.encode("ascii"))
|
||||
buf.append(0)
|
||||
_append_uleb128(buf, directory_index) # directory_index
|
||||
if version < 5:
|
||||
_append_uleb128(buf, 0) # mtime
|
||||
_append_uleb128(buf, 0) # size
|
||||
|
||||
if version < 5:
|
||||
buf.append(0)
|
||||
|
||||
buf[unit_length_start:unit_length_end] = (len(buf) - unit_length_end).to_bytes(
|
||||
unit_length_end - unit_length_start, byteorder
|
||||
)
|
||||
buf[header_length_start:header_length_end] = (
|
||||
len(buf) - header_length_end
|
||||
).to_bytes(header_length_end - header_length_start, byteorder)
|
||||
return buf
|
||||
|
||||
|
||||
@ -233,69 +294,72 @@ _UNIT_TAGS = frozenset({DW_TAG.type_unit, DW_TAG.compile_unit})
|
||||
|
||||
|
||||
def dwarf_sections(
|
||||
dies,
|
||||
units_or_dies,
|
||||
little_endian=True,
|
||||
bits=64,
|
||||
*,
|
||||
version=4,
|
||||
lang=None,
|
||||
use_dw_form_indirect=False,
|
||||
compress=None,
|
||||
):
|
||||
if isinstance(dies, DwarfDie):
|
||||
dies = (dies,)
|
||||
assert all(isinstance(die, (DwarfDie, DwarfLabel)) for die in dies)
|
||||
assert compress in (None, "zlib-gnu", "zlib-gabi")
|
||||
|
||||
if any(isinstance(die, DwarfDie) and die.tag in _UNIT_TAGS for die in dies):
|
||||
assert all(isinstance(die, DwarfLabel) or die.tag in _UNIT_TAGS for die in dies)
|
||||
unit_dies = dies
|
||||
if isinstance(units_or_dies, (DwarfDie, DwarfUnit)):
|
||||
units_or_dies = (units_or_dies,)
|
||||
if not units_or_dies or isinstance(units_or_dies[0], DwarfUnit):
|
||||
units = units_or_dies
|
||||
else:
|
||||
unit_dies = (DwarfDie(DW_TAG.compile_unit, (), dies),)
|
||||
assert all(isinstance(die, (DwarfDie, DwarfLabel)) for die in units_or_dies)
|
||||
assert all(
|
||||
not isinstance(die, DwarfDie) or die.tag not in _UNIT_TAGS
|
||||
for die in units_or_dies
|
||||
)
|
||||
units = (
|
||||
DwarfUnit(DW_UT.compile, DwarfDie(DW_TAG.compile_unit, (), units_or_dies)),
|
||||
)
|
||||
assert all(isinstance(unit, DwarfUnit) for unit in units)
|
||||
assert all(unit.die.tag in _UNIT_TAGS for unit in units)
|
||||
|
||||
unit_attribs = [DwarfAttrib(DW_AT.stmt_list, DW_FORM.sec_offset, 0)]
|
||||
unit_attribs = []
|
||||
if lang is not None:
|
||||
unit_attribs.append(DwarfAttrib(DW_AT.language, DW_FORM.data1, lang))
|
||||
cu_attribs = unit_attribs + [
|
||||
DwarfAttrib(DW_AT.comp_dir, DW_FORM.string, "/usr/src")
|
||||
|
||||
units = [
|
||||
unit._replace(
|
||||
die=unit.die._replace(attribs=list(unit.die.attribs) + unit_attribs)
|
||||
)
|
||||
for unit in units
|
||||
]
|
||||
|
||||
unit_dies = [
|
||||
die._replace(
|
||||
attribs=list(die.attribs)
|
||||
+ (cu_attribs if die.tag == DW_TAG.compile_unit else unit_attribs)
|
||||
)
|
||||
for die in unit_dies
|
||||
]
|
||||
debug_line = _compile_debug_line(units, little_endian, bits, version)
|
||||
|
||||
debug_info, debug_types = _compile_debug_info(
|
||||
unit_dies, little_endian, bits, use_dw_form_indirect
|
||||
units, little_endian, bits, version, use_dw_form_indirect
|
||||
)
|
||||
|
||||
if compress == "zlib-gnu":
|
||||
|
||||
def debug_section(name, data):
|
||||
assert name.startswith(".debug")
|
||||
def debug_section(name, data):
|
||||
assert name.startswith(".debug")
|
||||
if compress == "zlib-gnu":
|
||||
name = ".z" + name[1:]
|
||||
compressed_data = bytearray(b"ZLIB")
|
||||
compressed_data.extend(len(data).to_bytes(8, "big"))
|
||||
compressed_data.extend(zlib.compress(data))
|
||||
return ElfSection(
|
||||
name=".z" + name[1:], sh_type=SHT.PROGBITS, data=compressed_data
|
||||
)
|
||||
|
||||
else:
|
||||
assert compress is None or compress == "zlib-gabi", compress
|
||||
compressed = compress is not None
|
||||
|
||||
def debug_section(name, data):
|
||||
return ElfSection(
|
||||
name=name, sh_type=SHT.PROGBITS, data=data, compressed=compressed
|
||||
)
|
||||
data = compressed_data
|
||||
return ElfSection(
|
||||
name=name,
|
||||
sh_type=SHT.PROGBITS,
|
||||
data=data,
|
||||
compressed=(compress == "zlib-gabi"),
|
||||
)
|
||||
return name
|
||||
|
||||
sections = [
|
||||
debug_section(
|
||||
".debug_abbrev", _compile_debug_abbrev(unit_dies, use_dw_form_indirect)
|
||||
".debug_abbrev", _compile_debug_abbrev(units, use_dw_form_indirect)
|
||||
),
|
||||
debug_section(".debug_info", data=debug_info),
|
||||
debug_section(".debug_line", _compile_debug_line(unit_dies, little_endian)),
|
||||
debug_section(".debug_info", debug_info),
|
||||
debug_section(".debug_line", debug_line),
|
||||
debug_section(".debug_str", b"\0"),
|
||||
]
|
||||
if debug_types:
|
||||
@ -308,6 +372,7 @@ def compile_dwarf(
|
||||
little_endian=True,
|
||||
bits=64,
|
||||
*,
|
||||
version=4,
|
||||
lang=None,
|
||||
use_dw_form_indirect=False,
|
||||
compress=None,
|
||||
@ -318,6 +383,7 @@ def compile_dwarf(
|
||||
dies,
|
||||
little_endian=little_endian,
|
||||
bits=bits,
|
||||
version=version,
|
||||
lang=lang,
|
||||
use_dw_form_indirect=use_dw_form_indirect,
|
||||
compress=compress,
|
||||
|
@ -29,8 +29,14 @@ from tests import (
|
||||
identical,
|
||||
)
|
||||
import tests.assembler as assembler
|
||||
from tests.dwarf import DW_AT, DW_ATE, DW_END, DW_FORM, DW_LANG, DW_OP, DW_TAG
|
||||
from tests.dwarfwriter import DwarfAttrib, DwarfDie, DwarfLabel, compile_dwarf
|
||||
from tests.dwarf import DW_AT, DW_ATE, DW_END, DW_FORM, DW_LANG, DW_OP, DW_TAG, DW_UT
|
||||
from tests.dwarfwriter import (
|
||||
DwarfAttrib,
|
||||
DwarfDie,
|
||||
DwarfLabel,
|
||||
DwarfUnit,
|
||||
compile_dwarf,
|
||||
)
|
||||
|
||||
bool_die = DwarfDie(
|
||||
DW_TAG.base_type,
|
||||
@ -725,84 +731,19 @@ class TestTypes(TestCase):
|
||||
)
|
||||
|
||||
def test_incomplete_to_complete(self):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"),
|
||||
),
|
||||
),
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.declaration, DW_FORM.flag_present, True),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "foo.c"),
|
||||
),
|
||||
(
|
||||
for version in (4, 5):
|
||||
with self.subTest(version=version):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
)
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.pointer_type(
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(prog.int_type("int", 4, True), "x"),
|
||||
TypeMember(prog.int_type("int", 4, True), "y", 32),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
def test_incomplete_to_complete_namespace(self):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.namespace,
|
||||
(DwarfAttrib(DW_AT.name, DW_FORM.string, "Math"),),
|
||||
(
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
@ -813,12 +754,6 @@ class TestTypes(TestCase):
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.namespace,
|
||||
(DwarfAttrib(DW_AT.name, DW_FORM.string, "Math"),),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
@ -832,9 +767,7 @@ class TestTypes(TestCase):
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location,
|
||||
DW_FORM.data1,
|
||||
0,
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
@ -846,9 +779,245 @@ class TestTypes(TestCase):
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location,
|
||||
DW_FORM.data1,
|
||||
4,
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
),
|
||||
version=version,
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.pointer_type(
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(prog.int_type("int", 4, True), "x"),
|
||||
TypeMember(prog.int_type("int", 4, True), "y", 32),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
def test_incomplete_to_complete_namespace(self):
|
||||
for version in (4, 5):
|
||||
with self.subTest(version=version):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.namespace,
|
||||
(DwarfAttrib(DW_AT.name, DW_FORM.string, "Math"),),
|
||||
(
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "point"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.declaration,
|
||||
DW_FORM.flag_present,
|
||||
True,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.namespace,
|
||||
(DwarfAttrib(DW_AT.name, DW_FORM.string, "Math"),),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "point"
|
||||
),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(
|
||||
DW_AT.decl_file, DW_FORM.udata, "foo.c"
|
||||
),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "x"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location,
|
||||
DW_FORM.data1,
|
||||
0,
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "y"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location,
|
||||
DW_FORM.data1,
|
||||
4,
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
# Incorrect structure we should not access
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "wrong.c"),
|
||||
),
|
||||
),
|
||||
),
|
||||
lang=DW_LANG.C_plus_plus,
|
||||
version=version,
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.pointer_type(
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(
|
||||
prog.int_type(
|
||||
"int", 4, True, language=Language.CPP
|
||||
),
|
||||
"x",
|
||||
),
|
||||
TypeMember(
|
||||
prog.int_type(
|
||||
"int", 4, True, language=Language.CPP
|
||||
),
|
||||
"y",
|
||||
32,
|
||||
),
|
||||
),
|
||||
language=Language.CPP,
|
||||
),
|
||||
language=Language.CPP,
|
||||
),
|
||||
)
|
||||
|
||||
def test_incomplete_to_complete_ambiguous(self):
|
||||
for version in (4, 5):
|
||||
with self.subTest(version=version):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(
|
||||
DW_AT.declaration, DW_FORM.flag_present, True
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "foo.c"),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "bar.c"),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "a"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "b"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
@ -858,192 +1027,90 @@ class TestTypes(TestCase):
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
# Incorrect structure we should not access
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "wrong.c"),
|
||||
),
|
||||
),
|
||||
),
|
||||
lang=DW_LANG.C_plus_plus,
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.pointer_type(
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(
|
||||
prog.int_type("int", 4, True, language=Language.CPP), "x"
|
||||
),
|
||||
TypeMember(
|
||||
prog.int_type("int", 4, True, language=Language.CPP),
|
||||
"y",
|
||||
32,
|
||||
),
|
||||
),
|
||||
language=Language.CPP,
|
||||
),
|
||||
language=Language.CPP,
|
||||
),
|
||||
)
|
||||
|
||||
def test_incomplete_to_complete_ambiguous(self):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"),
|
||||
),
|
||||
),
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.declaration, DW_FORM.flag_present, True),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "foo.c"),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.decl_file, DW_FORM.udata, "bar.c"),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "a"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "b"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type, prog.pointer_type(prog.struct_type("point"))
|
||||
)
|
||||
version=version,
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type, prog.pointer_type(prog.struct_type("point"))
|
||||
)
|
||||
|
||||
def test_incomplete_to_complete_specification(self):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"),
|
||||
),
|
||||
),
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.declaration, DW_FORM.flag_present, True),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.specification, DW_FORM.ref4, "incomplete_struct_die"
|
||||
),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
),
|
||||
(
|
||||
for version in (4, 5):
|
||||
with self.subTest(version=version):
|
||||
prog = dwarf_program(
|
||||
wrap_test_type_dies(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
DW_TAG.pointer_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
DW_AT.type, DW_FORM.ref4, "incomplete_struct_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfLabel("incomplete_struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(
|
||||
DW_AT.declaration, DW_FORM.flag_present, True
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
DW_AT.specification,
|
||||
DW_FORM.ref4,
|
||||
"incomplete_struct_die",
|
||||
),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "int_die"),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
)
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.pointer_type(
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(prog.int_type("int", 4, True), "x"),
|
||||
TypeMember(prog.int_type("int", 4, True), "y", 32),
|
||||
version=version,
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.pointer_type(
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(prog.int_type("int", 4, True), "x"),
|
||||
TypeMember(prog.int_type("int", 4, True), "y", 32),
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
def test_filename(self):
|
||||
dies = (
|
||||
@ -3718,125 +3785,177 @@ class TestTypes(TestCase):
|
||||
)
|
||||
|
||||
def test_base_type_unit(self):
|
||||
prog = dwarf_program(
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.compile_unit,
|
||||
(),
|
||||
for version in (4, 5):
|
||||
with self.subTest(version=version):
|
||||
prog = dwarf_program(
|
||||
(
|
||||
DwarfLabel("signature_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.base_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.signature, DW_FORM.ref_sig8, 0xDEADBEEF
|
||||
DwarfUnit(
|
||||
DW_UT.compile,
|
||||
DwarfDie(
|
||||
DW_TAG.compile_unit,
|
||||
(),
|
||||
(
|
||||
DwarfLabel("signature_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.base_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.signature,
|
||||
DW_FORM.ref_sig8,
|
||||
0xDEADBEEF,
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.typedef,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "TEST"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type,
|
||||
DW_FORM.ref4,
|
||||
"signature_die",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.typedef,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "TEST"),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "signature_die"),
|
||||
DwarfUnit(
|
||||
DW_UT.type,
|
||||
DwarfDie(
|
||||
DW_TAG.type_unit,
|
||||
(),
|
||||
labeled_int_die,
|
||||
),
|
||||
type_signature=0xDEADBEEF,
|
||||
type_offset="int_die",
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.type_unit,
|
||||
(),
|
||||
labeled_int_die,
|
||||
type_signature=0xDEADBEEF,
|
||||
type_offset="int_die",
|
||||
),
|
||||
)
|
||||
)
|
||||
self.assertIdentical(prog.type("TEST").type, prog.int_type("int", 4, True))
|
||||
self.assertIdentical(prog.type("int"), prog.type("TEST").type)
|
||||
version=version,
|
||||
)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type, prog.int_type("int", 4, True)
|
||||
)
|
||||
self.assertIdentical(prog.type("int"), prog.type("TEST").type)
|
||||
|
||||
def test_struct_type_unit(self):
|
||||
prog = dwarf_program(
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.compile_unit,
|
||||
(),
|
||||
for version in (4, 5):
|
||||
with self.subTest(version=version):
|
||||
prog = dwarf_program(
|
||||
(
|
||||
DwarfLabel("signature_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.signature, DW_FORM.ref_sig8, 0xDEADBEEF
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.typedef,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "TEST"),
|
||||
DwarfAttrib(DW_AT.type, DW_FORM.ref4, "signature_die"),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.type_unit,
|
||||
(),
|
||||
(
|
||||
DwarfLabel("struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "point"),
|
||||
DwarfAttrib(DW_AT.byte_size, DW_FORM.data1, 8),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "x"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 0
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
DwarfUnit(
|
||||
DW_UT.compile,
|
||||
DwarfDie(
|
||||
DW_TAG.compile_unit,
|
||||
(),
|
||||
(
|
||||
DwarfLabel("signature_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.signature,
|
||||
DW_FORM.ref_sig8,
|
||||
0xDEADBEEF,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(DW_AT.name, DW_FORM.string, "y"),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location, DW_FORM.data1, 4
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type, DW_FORM.ref4, "int_die"
|
||||
DwarfDie(
|
||||
DW_TAG.typedef,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "TEST"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type,
|
||||
DW_FORM.ref4,
|
||||
"signature_die",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
DwarfUnit(
|
||||
DW_UT.type,
|
||||
DwarfDie(
|
||||
DW_TAG.type_unit,
|
||||
(),
|
||||
(
|
||||
DwarfLabel("struct_die"),
|
||||
DwarfDie(
|
||||
DW_TAG.structure_type,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "point"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.byte_size, DW_FORM.data1, 8
|
||||
),
|
||||
),
|
||||
(
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "x"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location,
|
||||
DW_FORM.data1,
|
||||
0,
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type,
|
||||
DW_FORM.ref4,
|
||||
"int_die",
|
||||
),
|
||||
),
|
||||
),
|
||||
DwarfDie(
|
||||
DW_TAG.member,
|
||||
(
|
||||
DwarfAttrib(
|
||||
DW_AT.name, DW_FORM.string, "y"
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.data_member_location,
|
||||
DW_FORM.data1,
|
||||
4,
|
||||
),
|
||||
DwarfAttrib(
|
||||
DW_AT.type,
|
||||
DW_FORM.ref4,
|
||||
"int_die",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
*labeled_int_die,
|
||||
),
|
||||
),
|
||||
type_signature=0xDEADBEEF,
|
||||
type_offset="struct_die",
|
||||
),
|
||||
),
|
||||
type_signature=0xDEADBEEF,
|
||||
type_offset="struct_die",
|
||||
),
|
||||
)
|
||||
)
|
||||
version=version,
|
||||
)
|
||||
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(prog.int_type("int", 4, True), "x", 0),
|
||||
TypeMember(prog.int_type("int", 4, True), "y", 32),
|
||||
),
|
||||
),
|
||||
)
|
||||
self.assertIdentical(prog.type("struct point"), prog.type("TEST").type)
|
||||
self.assertIdentical(
|
||||
prog.type("TEST").type,
|
||||
prog.struct_type(
|
||||
"point",
|
||||
8,
|
||||
(
|
||||
TypeMember(prog.int_type("int", 4, True), "x", 0),
|
||||
TypeMember(prog.int_type("int", 4, True), "y", 32),
|
||||
),
|
||||
),
|
||||
)
|
||||
self.assertIdentical(prog.type("struct point"), prog.type("TEST").type)
|
||||
|
||||
def test_namespaces(self):
|
||||
def make_composite_die(tag: DW_TAG, name: str) -> DwarfDie:
|
||||
|
Loading…
Reference in New Issue
Block a user