CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
108 lines
4.8 KiB
Python
108 lines
4.8 KiB
Python
#!/usr/bin/python3
|
|
|
|
# Parsing dwarfdump's output to determine whether the location list for the
|
|
# parameter "b" covers all of the function. The script searches for information
|
|
# in the input file to determine the [prologue, epilogue) range for the
|
|
# function, the location list range for "b", and checks that the latter covers
|
|
# the entirety of the former.
|
|
import re
|
|
import sys
|
|
|
|
DebugInfoPattern = r"\.debug_info contents:"
|
|
DebugLinePattern = r"\.debug_line contents:"
|
|
ProloguePattern = r"^\s*0x([0-9a-f]+)\s.+prologue_end"
|
|
EpiloguePattern = r"^\s*0x([0-9a-f]+)\s.+epilogue_begin"
|
|
FormalPattern = r"^0x[0-9a-f]+:\s+DW_TAG_formal_parameter"
|
|
LocationPattern = r"DW_AT_location\s+\[DW_FORM_([a-z_]+)\](?:.*0x([a-f0-9]+))"
|
|
DebugLocPattern = r'\[0x([a-f0-9]+),\s+0x([a-f0-9]+)\) ".text": (.+)$'
|
|
|
|
SeenDebugInfo = False
|
|
SeenDebugLine = False
|
|
LocationRanges = None
|
|
PrologueEnd = None
|
|
EpilogueBegin = None
|
|
|
|
# The dwarfdump output should contain the DW_AT_location for "b" first, then the
|
|
# line table which should contain prologue_end and epilogue_begin entries.
|
|
with open(sys.argv[1], "r") as dwarf_dump_file:
|
|
dwarf_iter = iter(dwarf_dump_file)
|
|
for line in dwarf_iter:
|
|
if not SeenDebugInfo and re.match(DebugInfoPattern, line):
|
|
SeenDebugInfo = True
|
|
if not SeenDebugLine and re.match(DebugLinePattern, line):
|
|
SeenDebugLine = True
|
|
# Get the range of DW_AT_location for "b".
|
|
if LocationRanges is None:
|
|
if match := re.match(FormalPattern, line):
|
|
# Go until we either find DW_AT_location or reach the end of this entry.
|
|
location_match = None
|
|
while location_match is None:
|
|
if (line := next(dwarf_iter, "")) == "\n":
|
|
raise RuntimeError(
|
|
".debug_info output is missing DW_AT_location for 'b'"
|
|
)
|
|
location_match = re.search(LocationPattern, line)
|
|
# Variable has whole-scope location, represented by an empty tuple.
|
|
if location_match.group(1) == "exprloc":
|
|
LocationRanges = ()
|
|
continue
|
|
if location_match.group(1) != "sec_offset":
|
|
raise RuntimeError(
|
|
f"Unhandled form for DW_AT_location: DW_FORM_{location_match.group(1)}"
|
|
)
|
|
# Variable has location range list.
|
|
if (
|
|
debug_loc_match := re.search(DebugLocPattern, next(dwarf_iter, ""))
|
|
) is None:
|
|
raise RuntimeError(f"Invalid location range list for 'b'")
|
|
LocationRanges = (
|
|
int(debug_loc_match.group(1), 16),
|
|
int(debug_loc_match.group(2), 16),
|
|
)
|
|
while (
|
|
debug_loc_match := re.search(DebugLocPattern, next(dwarf_iter, ""))
|
|
) is not None:
|
|
match_loc_start = int(debug_loc_match.group(1), 16)
|
|
match_loc_end = int(debug_loc_match.group(2), 16)
|
|
match_expr = debug_loc_match.group(3)
|
|
if match_loc_start != LocationRanges[1]:
|
|
raise RuntimeError(
|
|
f"Location list for 'b' is discontinuous from [0x{LocationRanges[1]:x}, 0x{match_loc_start:x})"
|
|
)
|
|
if "stack_value" in match_expr:
|
|
raise RuntimeError(
|
|
f"Location list for 'b' contains a stack_value expression: {match_expr}"
|
|
)
|
|
LocationRanges = (LocationRanges[0], match_loc_end)
|
|
# Get the prologue_end address.
|
|
elif PrologueEnd is None:
|
|
if match := re.match(ProloguePattern, line):
|
|
PrologueEnd = int(match.group(1), 16)
|
|
# Get the epilogue_begin address.
|
|
elif EpilogueBegin is None:
|
|
if match := re.match(EpiloguePattern, line):
|
|
EpilogueBegin = int(match.group(1), 16)
|
|
break
|
|
|
|
if not SeenDebugInfo:
|
|
raise RuntimeError(".debug_info section not found.")
|
|
if not SeenDebugLine:
|
|
raise RuntimeError(".debug_line section not found.")
|
|
|
|
if LocationRanges is None:
|
|
raise RuntimeError(".debug_info output is missing parameter 'b'")
|
|
if PrologueEnd is None:
|
|
raise RuntimeError(".debug_line output is missing prologue_end")
|
|
if EpilogueBegin is None:
|
|
raise RuntimeError(".debug_line output is missing epilogue_begin")
|
|
|
|
if len(LocationRanges) == 2 and (
|
|
LocationRanges[0] > PrologueEnd or LocationRanges[1] < EpilogueBegin
|
|
):
|
|
raise RuntimeError(
|
|
f"""Location list for 'b' does not cover the whole function:")
|
|
Prologue to Epilogue = [0x{PrologueEnd:x}, 0x{EpilogueBegin:x})
|
|
Location range = [0x{LocationRanges[0]:x}, 0x{LocationRanges[1]:x})
|
|
"""
|
|
)
|