[llvm] [BOLT][DWARF] Add support for cross-cu references for debug-names (PR #86015)
Alexander Yermolovich via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 20 14:36:23 PDT 2024
https://github.com/ayermolo created https://github.com/llvm/llvm-project/pull/86015
The DW_AT_abstract_origin can be a cross-cu reference as a by-product of LTO. On IR level for absolute references an address is stored, vs a DIE for relative references. Added a map to keep track of cross-cu referenced DIEs to use when we add an Entry.
>From 8f3d210458f42c1d5ddcd0c8cb0e9ee31f738c80 Mon Sep 17 00:00:00 2001
From: Alexander Yermolovich <ayermolo at meta.com>
Date: Wed, 20 Mar 2024 14:08:04 -0700
Subject: [PATCH] [BOLT][DWARF] Add support for cross-cu references for
debug-names
The DW_AT_abstract_origin can be a cross-cu reference as a by-product of LTO. On
IR level for absolute references an address is stored, vs a DIE for relative
references. Added a map to keep track of cross-cu referenced DIEs to use when we
add an Entry.
---
bolt/include/bolt/Core/DebugNames.h | 11 +
bolt/lib/Core/DIEBuilder.cpp | 6 +-
bolt/lib/Core/DebugNames.cpp | 109 +--
bolt/test/X86/dwarf5-debug-names-cross-cu.s | 712 ++++++++++++++++++++
4 files changed, 796 insertions(+), 42 deletions(-)
create mode 100644 bolt/test/X86/dwarf5-debug-names-cross-cu.s
diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h
index 1f17f1ae4d139b..327404caf8feeb 100644
--- a/bolt/include/bolt/Core/DebugNames.h
+++ b/bolt/include/bolt/Core/DebugNames.h
@@ -16,6 +16,7 @@
#include "DebugData.h"
#include "llvm/CodeGen/AccelTable.h"
+#include <cstdint>
namespace llvm {
namespace bolt {
@@ -68,6 +69,15 @@ class DWARF5AcceleratorTable {
std::unique_ptr<DebugBufferVector> releaseBuffer() {
return std::move(FullTableBuffer);
}
+ /// Adds a DIE that is referenced across CUs.
+ void addCrossCUDie(const DIE *Die) {
+ CrossCUDies.insert({Die->getOffset(), Die});
+ }
+ /// Returns true if the DIE will generate an entry for a cross cu reference.
+ /// This only checks TAGs of a DIE because when this is invoked DIE might not
+ /// be fully constructed.
+ bool isIncluded(const DWARFUnit &Unit, const DIE &Die,
+ const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec);
private:
BinaryContext &BC;
@@ -128,6 +138,7 @@ class DWARF5AcceleratorTable {
llvm::DenseMap<uint64_t, uint32_t> CUOffsetsToPatch;
// Contains a map of Entry ID to Entry relative offset.
llvm::DenseMap<uint64_t, uint32_t> EntryRelativeOffsets;
+ llvm::DenseMap<uint64_t, const DIE *> CrossCUDies;
/// Adds Unit to either CUList, LocalTUList or ForeignTUList.
/// Input Unit being processed, and DWO ID if Unit is being processed comes
/// from a DWO section.
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index 0cf8a5e8c2c3db..4be8801c7cb580 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -545,6 +545,10 @@ void DIEBuilder::cloneDieReferenceAttribute(
NewRefDie = DieInfo.Die;
if (AttrSpec.Form == dwarf::DW_FORM_ref_addr) {
+ // Adding referenced DIE to DebugNames to be used when entries are created
+ // that contain cross cu references.
+ if (DebugNamesTable.isIncluded(U, Die, AttrSpec))
+ DebugNamesTable.addCrossCUDie(DieInfo.Die);
// no matter forward reference or backward reference, we are supposed
// to calculate them in `finish` due to the possible modification of
// the DIE.
@@ -554,7 +558,7 @@ void DIEBuilder::cloneDieReferenceAttribute(
std::make_pair(CurDieInfo, AddrReferenceInfo(&DieInfo, AttrSpec)));
Die.addValue(getState().DIEAlloc, AttrSpec.Attr, dwarf::DW_FORM_ref_addr,
- DIEInteger(0xDEADBEEF));
+ DIEInteger(DieInfo.Die->getOffset()));
return;
}
diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp
index 23a29f52513c04..dca3347a97483f 100644
--- a/bolt/lib/Core/DebugNames.cpp
+++ b/bolt/lib/Core/DebugNames.cpp
@@ -146,6 +146,55 @@ static bool shouldIncludeVariable(const DWARFUnit &Unit, const DIE &Die) {
return false;
}
+bool static canProcess(const DWARFUnit &Unit, const DIE &Die,
+ std::string &NameToUse, const bool TagsOnly) {
+ switch (Die.getTag()) {
+ case dwarf::DW_TAG_base_type:
+ case dwarf::DW_TAG_class_type:
+ case dwarf::DW_TAG_enumeration_type:
+ case dwarf::DW_TAG_imported_declaration:
+ case dwarf::DW_TAG_pointer_type:
+ case dwarf::DW_TAG_structure_type:
+ case dwarf::DW_TAG_typedef:
+ case dwarf::DW_TAG_unspecified_type:
+ if (TagsOnly || Die.findAttribute(dwarf::Attribute::DW_AT_name))
+ return true;
+ return false;
+ case dwarf::DW_TAG_namespace:
+ // According to DWARF5 spec namespaces without DW_AT_name needs to have
+ // "(anonymous namespace)"
+ if (!Die.findAttribute(dwarf::Attribute::DW_AT_name))
+ NameToUse = "(anonymous namespace)";
+ return true;
+ case dwarf::DW_TAG_inlined_subroutine:
+ case dwarf::DW_TAG_label:
+ case dwarf::DW_TAG_subprogram:
+ if (TagsOnly || Die.findAttribute(dwarf::Attribute::DW_AT_low_pc) ||
+ Die.findAttribute(dwarf::Attribute::DW_AT_high_pc) ||
+ Die.findAttribute(dwarf::Attribute::DW_AT_ranges) ||
+ Die.findAttribute(dwarf::Attribute::DW_AT_entry_pc))
+ return true;
+ return false;
+ case dwarf::DW_TAG_variable:
+ return TagsOnly || shouldIncludeVariable(Unit, Die);
+ default:
+ break;
+ }
+ return false;
+}
+
+bool DWARF5AcceleratorTable::isIncluded(
+ const DWARFUnit &Unit, const DIE &Die,
+ const DWARFAbbreviationDeclaration::AttributeSpec &AttrSpec) {
+ if (!isCreated())
+ return false;
+ std::string NameToUse = "";
+ if (!canProcess(Unit, Die, NameToUse, true))
+ return false;
+ return (AttrSpec.Attr == dwarf::Attribute::DW_AT_abstract_origin ||
+ AttrSpec.Attr == dwarf::Attribute::DW_AT_specification) &&
+ AttrSpec.Form == dwarf::DW_FORM_ref_addr;
+}
/// Returns name offset in String Offset section.
static uint64_t getNameOffset(BinaryContext &BC, DWARFUnit &Unit,
const uint64_t Index) {
@@ -175,41 +224,6 @@ DWARF5AcceleratorTable::addAccelTableEntry(
if (Unit.getVersion() < 5 || !NeedToCreate)
return std::nullopt;
std::string NameToUse = "";
- auto canProcess = [&](const DIE &Die) -> bool {
- switch (Die.getTag()) {
- case dwarf::DW_TAG_base_type:
- case dwarf::DW_TAG_class_type:
- case dwarf::DW_TAG_enumeration_type:
- case dwarf::DW_TAG_imported_declaration:
- case dwarf::DW_TAG_pointer_type:
- case dwarf::DW_TAG_structure_type:
- case dwarf::DW_TAG_typedef:
- case dwarf::DW_TAG_unspecified_type:
- if (Die.findAttribute(dwarf::Attribute::DW_AT_name))
- return true;
- return false;
- case dwarf::DW_TAG_namespace:
- // According to DWARF5 spec namespaces without DW_AT_name needs to have
- // "(anonymous namespace)"
- if (!Die.findAttribute(dwarf::Attribute::DW_AT_name))
- NameToUse = "(anonymous namespace)";
- return true;
- case dwarf::DW_TAG_inlined_subroutine:
- case dwarf::DW_TAG_label:
- case dwarf::DW_TAG_subprogram:
- if (Die.findAttribute(dwarf::Attribute::DW_AT_low_pc) ||
- Die.findAttribute(dwarf::Attribute::DW_AT_high_pc) ||
- Die.findAttribute(dwarf::Attribute::DW_AT_ranges) ||
- Die.findAttribute(dwarf::Attribute::DW_AT_entry_pc))
- return true;
- return false;
- case dwarf::DW_TAG_variable:
- return shouldIncludeVariable(Unit, Die);
- default:
- break;
- }
- return false;
- };
auto getUnitID = [&](const DWARFUnit &Unit, bool &IsTU,
uint32_t &DieTag) -> uint32_t {
@@ -223,7 +237,7 @@ DWARF5AcceleratorTable::addAccelTableEntry(
return CUList.size() - 1;
};
- if (!canProcess(Die))
+ if (!canProcess(Unit, Die, NameToUse, false))
return std::nullopt;
// Addes a Unit to either CU, LocalTU or ForeignTU list the first time we
@@ -318,10 +332,24 @@ DWARF5AcceleratorTable::addAccelTableEntry(
const DIEValue Value = Die.findAttribute(Attr);
if (!Value)
return std::nullopt;
- const DIEEntry &DIEENtry = Value.getDIEEntry();
- DIE &EntryDie = DIEENtry.getEntry();
- addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
- return addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_name));
+ const DIE *EntryDie = nullptr;
+ if (Value.getForm() == dwarf::DW_FORM_ref_addr) {
+ auto Iter = CrossCUDies.find(Value.getDIEInteger().getValue());
+ if (Iter == CrossCUDies.end()) {
+ BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find "
+ "referenced DIE in CrossCUDies for "
+ << Twine::utohexstr(Value.getDIEInteger().getValue())
+ << ".\n";
+ return std::nullopt;
+ }
+ EntryDie = Iter->second;
+ } else {
+ const DIEEntry &DIEENtry = Value.getDIEEntry();
+ EntryDie = &DIEENtry.getEntry();
+ }
+
+ addEntry(EntryDie->findAttribute(dwarf::Attribute::DW_AT_linkage_name));
+ return addEntry(EntryDie->findAttribute(dwarf::Attribute::DW_AT_name));
};
if (std::optional<BOLTDWARF5AccelTableData *> Entry =
@@ -332,7 +360,6 @@ DWARF5AcceleratorTable::addAccelTableEntry(
return *Entry;
return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
- ;
}
/// Algorithm from llvm implementation.
diff --git a/bolt/test/X86/dwarf5-debug-names-cross-cu.s b/bolt/test/X86/dwarf5-debug-names-cross-cu.s
new file mode 100644
index 00000000000000..73c50d6d41db09
--- /dev/null
+++ b/bolt/test/X86/dwarf5-debug-names-cross-cu.s
@@ -0,0 +1,712 @@
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o
+# RUN: %clang %cflags -dwarf-5 %tmain.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.bolt --update-debug-sections
+# RUN: llvm-dwarfdump --debug-info -r 0 --debug-names %t.bolt > %t.txt
+# RUN: cat %t.txt | FileCheck --check-prefix=CHECK %s
+
+## This test checks that BOLT generates Entries for DW_AT_abstract_origin when it has cross cu reference.
+
+# CHECK: [[OFFSET1:0x[0-9a-f]*]]: Compile Unit
+# CHECK: [[OFFSET2:0x[0-9a-f]*]]: Compile Unit
+# CHECK: Name Index @ 0x0 {
+# CHECK-NEXT: Header {
+# CHECK-NEXT: Length: 0xD2
+# CHECK-NEXT: Format: DWARF32
+# CHECK-NEXT: Version: 5
+# CHECK-NEXT: CU count: 2
+# CHECK-NEXT: Local TU count: 0
+# CHECK-NEXT: Foreign TU count: 0
+# CHECK-NEXT: Bucket count: 5
+# CHECK-NEXT: Name count: 5
+# CHECK-NEXT: Abbreviations table size: 0x1F
+# CHECK-NEXT: Augmentation: 'BOLT'
+# CHECK-NEXT: }
+# CHECK-NEXT: Compilation Unit offsets [
+# CHECK-NEXT: CU[0]: [[OFFSET1]]
+# CHECK-NEXT: CU[1]: [[OFFSET2]]
+# CHECK-NEXT: ]
+# CHECK-NEXT: Abbreviations [
+# CHECK-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+# CHECK-NEXT: Tag: DW_TAG_subprogram
+# CHECK-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+# CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+# CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
+# CHECK-NEXT: }
+# CHECK-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
+# CHECK-NEXT: Tag: DW_TAG_inlined_subroutine
+# CHECK-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+# CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+# CHECK-NEXT: DW_IDX_parent: DW_FORM_ref4
+# CHECK-NEXT: }
+# CHECK-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+# CHECK-NEXT: Tag: DW_TAG_base_type
+# CHECK-NEXT: DW_IDX_compile_unit: DW_FORM_data1
+# CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+# CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Bucket 0 [
+# CHECK-NEXT: EMPTY
+# CHECK-NEXT: ]
+# CHECK-NEXT: Bucket 1 [
+# CHECK-NEXT: Name 1 {
+# CHECK-NEXT: Hash: 0x7C9A7F6A
+# CHECK-NEXT: String: {{.+}} "main"
+# CHECK-NEXT: Entry @ [[ENTRY:0x[0-9a-f]*]] {
+# CHECK-NEXT: Abbrev: [[ABBREV1]]
+# CHECK-NEXT: Tag: DW_TAG_subprogram
+# CHECK-NEXT: DW_IDX_compile_unit: 0x00
+# CHECK-NEXT: DW_IDX_die_offset: 0x00000024
+# CHECK-NEXT: DW_IDX_parent: <parent not indexed>
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: Name 2 {
+# CHECK-NEXT: Hash: 0xB5063CFE
+# CHECK-NEXT: String: {{.+}} "_Z3fooi"
+# CHECK-NEXT: Entry @ {{.+}} {
+# CHECK-NEXT: Abbrev: [[ABBREV1]]
+# CHECK-NEXT: Tag: DW_TAG_subprogram
+# CHECK-NEXT: DW_IDX_compile_unit: 0x01
+# CHECK-NEXT: DW_IDX_die_offset: 0x0000003a
+# CHECK-NEXT: DW_IDX_parent: <parent not indexed>
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry @ {{.+}} {
+# CHECK-NEXT: Abbrev: [[ABBREV2]]
+# CHECK-NEXT: Tag: DW_TAG_inlined_subroutine
+# CHECK-NEXT: DW_IDX_compile_unit: 0x00
+# CHECK-NEXT: DW_IDX_die_offset: 0x00000054
+# CHECK-NEXT: DW_IDX_parent: Entry @ [[ENTRY]]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Bucket 2 [
+# CHECK-NEXT: EMPTY
+# CHECK-NEXT: ]
+# CHECK-NEXT: Bucket 3 [
+# CHECK-NEXT: Name 3 {
+# CHECK-NEXT: Hash: 0xB888030
+# CHECK-NEXT: String: {{.+}} "int"
+# CHECK-NEXT: Entry @ {{.+}} {
+# CHECK-NEXT: Abbrev: [[ABBREV3]]
+# CHECK-NEXT: Tag: DW_TAG_base_type
+# CHECK-NEXT: DW_IDX_compile_unit: 0x01
+# CHECK-NEXT: DW_IDX_die_offset: 0x00000036
+# CHECK-NEXT: DW_IDX_parent: <parent not indexed>
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Bucket 4 [
+# CHECK-NEXT: Name 4 {
+# CHECK-NEXT: Hash: 0xB887389
+# CHECK-NEXT: String: {{.+}} "foo"
+# CHECK-NEXT: Entry @ {{.+}} {
+# CHECK-NEXT: Abbrev: [[ABBREV1]]
+# CHECK-NEXT: Tag: DW_TAG_subprogram
+# CHECK-NEXT: DW_IDX_compile_unit: 0x01
+# CHECK-NEXT: DW_IDX_die_offset: 0x0000003a
+# CHECK-NEXT: DW_IDX_parent: <parent not indexed>
+# CHECK-NEXT: }
+# CHECK-NEXT: Entry @ 0xc4 {
+# CHECK-NEXT: Abbrev: [[ABBREV2]]
+# CHECK-NEXT: Tag: DW_TAG_inlined_subroutine
+# CHECK-NEXT: DW_IDX_compile_unit: 0x00
+# CHECK-NEXT: DW_IDX_die_offset: 0x00000054
+# CHECK-NEXT: DW_IDX_parent: Entry @ [[ENTRY]]
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: Name 5 {
+# CHECK-NEXT: Hash: 0x7C952063
+# CHECK-NEXT: String: {{.+}} "char"
+# CHECK-NEXT: Entry @ {{.+}} {
+# CHECK-NEXT: Abbrev: [[ABBREV3]]
+# CHECK-NEXT: Tag: DW_TAG_base_type
+# CHECK-NEXT: DW_IDX_compile_unit: 0x00
+# CHECK-NEXT: DW_IDX_die_offset: 0x00000075
+# CHECK-NEXT: DW_IDX_parent: <parent not indexed>
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: }
+
+## clang++ -g2 -gpubnames -S -emit-llvm main.cpp -o main.ll
+## clang++ -g2 -gpubnames -S -emit-llvm helper.cpp -o helper.ll
+## llvm-link main.ll helper.ll -o combined.ll
+## clang++ -g2 -gpubnames combined.ll -emit-llvm -S -o combined.opt.ll
+## llc -dwarf-version=5 -filetype=asm -mtriple x86_64-unknown-linux combined.opt.ll -o combined.s
+## main.cpp
+## extern int foo(int);
+## int main(int argc, char* argv[]) {
+## int i = 0;
+## [[clang::always_inline]] i = foo(argc);
+## return i;
+## }
+## helper.cpp
+## int foo(int i) {
+## return i ++;
+## }
+
+ .text
+ .file "llvm-link"
+ .globl main # -- Begin function main
+ .p2align 4, 0x90
+ .type main, at function
+main: # @main
+.Lfunc_begin0:
+ .file 1 "/home" "main.cpp" md5 0x24fb0b4c3900e91fece1ac87ed73ff3b
+ .loc 1 2 0 # main.cpp:2:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl $0, -16(%rbp)
+ movl %edi, -12(%rbp)
+ movq %rsi, -24(%rbp)
+.Ltmp0:
+ .loc 1 3 7 prologue_end # main.cpp:3:7
+ movl $0, -4(%rbp)
+ .loc 1 4 36 # main.cpp:4:36
+ movl -12(%rbp), %eax
+ movl %eax, -8(%rbp)
+.Ltmp1:
+ .file 2 "/home" "helper.cpp" md5 0x7d4429e24d8c74d7ee22c1889ad46d6b
+ .loc 2 2 12 # helper.cpp:2:12
+ movl -8(%rbp), %eax
+ movl %eax, %ecx
+ addl $1, %ecx
+ movl %ecx, -8(%rbp)
+.Ltmp2:
+ .loc 1 4 30 # main.cpp:4:30
+ movl %eax, -4(%rbp)
+ .loc 1 5 10 # main.cpp:5:10
+ movl -4(%rbp), %eax
+ .loc 1 5 3 epilogue_begin is_stmt 0 # main.cpp:5:3
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp3:
+.Lfunc_end0:
+ .size main, .Lfunc_end0-main
+ .cfi_endproc
+ # -- End function
+ .globl _Z3fooi # -- Begin function _Z3fooi
+ .p2align 4, 0x90
+ .type _Z3fooi, at function
+_Z3fooi: # @_Z3fooi
+.Lfunc_begin1:
+ .loc 2 1 0 is_stmt 1 # helper.cpp:1:0
+ .cfi_startproc
+# %bb.0: # %entry
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ movl %edi, -4(%rbp)
+.Ltmp4:
+ .loc 2 2 12 prologue_end # helper.cpp:2:12
+ movl -4(%rbp), %eax
+ movl %eax, %ecx
+ addl $1, %ecx
+ movl %ecx, -4(%rbp)
+ .loc 2 2 3 epilogue_begin is_stmt 0 # helper.cpp:2:3
+ popq %rbp
+ .cfi_def_cfa %rsp, 8
+ retq
+.Ltmp5:
+.Lfunc_end1:
+ .size _Z3fooi, .Lfunc_end1-_Z3fooi
+ .cfi_endproc
+ # -- End function
+ .section .debug_abbrev,"", at progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 37 # DW_FORM_strx1
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 114 # DW_AT_str_offsets_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .byte 27 # DW_AT_comp_dir
+ .byte 37 # DW_FORM_strx1
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 115 # DW_AT_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 16 # DW_FORM_ref_addr
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 16 # DW_FORM_ref_addr
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 4 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 5 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 16 # DW_FORM_ref_addr
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 6 # Abbreviation Code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 1 # DW_CHILDREN_yes
+ .byte 49 # DW_AT_abstract_origin
+ .byte 16 # DW_FORM_ref_addr
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 88 # DW_AT_call_file
+ .byte 11 # DW_FORM_data1
+ .byte 89 # DW_AT_call_line
+ .byte 11 # DW_FORM_data1
+ .byte 87 # DW_AT_call_column
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 7 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 49 # DW_AT_abstract_origin
+ .byte 16 # DW_FORM_ref_addr
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 8 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 9 # Abbreviation Code
+ .byte 36 # DW_TAG_base_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 62 # DW_AT_encoding
+ .byte 11 # DW_FORM_data1
+ .byte 11 # DW_AT_byte_size
+ .byte 11 # DW_FORM_data1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 10 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 110 # DW_AT_linkage_name
+ .byte 37 # DW_FORM_strx1
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 32 # DW_AT_inline
+ .byte 33 # DW_FORM_implicit_const
+ .byte 1
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 11 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 37 # DW_FORM_strx1
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 12 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_CHILDREN_yes
+ .byte 17 # DW_AT_low_pc
+ .byte 27 # DW_FORM_addrx
+ .byte 18 # DW_AT_high_pc
+ .byte 6 # DW_FORM_data4
+ .byte 64 # DW_AT_frame_base
+ .byte 24 # DW_FORM_exprloc
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 13 # Abbreviation Code
+ .byte 5 # DW_TAG_formal_parameter
+ .byte 0 # DW_CHILDREN_no
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 49 # DW_AT_abstract_origin
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"", at progbits
+.Lcu_begin0:
+ .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x6d DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 1 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 2 # Abbrev [2] 0x23:0x47 DW_TAG_subprogram
+ .byte 0 # DW_AT_low_pc
+ .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .byte 8 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .long .debug_info+174 # DW_AT_type
+ # DW_AT_external
+ .byte 3 # Abbrev [3] 0x32:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 116
+ .byte 9 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .long .debug_info+174 # DW_AT_type
+ .byte 4 # Abbrev [4] 0x3d:0xb DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 104
+ .byte 10 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 2 # DW_AT_decl_line
+ .long 106 # DW_AT_type
+ .byte 5 # Abbrev [5] 0x48:0xb DW_TAG_variable
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 124
+ .byte 7 # DW_AT_name
+ .byte 1 # DW_AT_decl_file
+ .byte 3 # DW_AT_decl_line
+ .long .debug_info+174 # DW_AT_type
+ .byte 6 # Abbrev [6] 0x53:0x16 DW_TAG_inlined_subroutine
+ .long .debug_info+156 # DW_AT_abstract_origin
+ .byte 1 # DW_AT_low_pc
+ .long .Ltmp2-.Ltmp1 # DW_AT_high_pc
+ .byte 1 # DW_AT_call_file
+ .byte 4 # DW_AT_call_line
+ .byte 32 # DW_AT_call_column
+ .byte 7 # Abbrev [7] 0x60:0x8 DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 120
+ .long .debug_info+165 # DW_AT_abstract_origin
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+ .byte 8 # Abbrev [8] 0x6a:0x5 DW_TAG_pointer_type
+ .long 111 # DW_AT_type
+ .byte 8 # Abbrev [8] 0x6f:0x5 DW_TAG_pointer_type
+ .long 116 # DW_AT_type
+ .byte 9 # Abbrev [9] 0x74:0x4 DW_TAG_base_type
+ .byte 11 # DW_AT_name
+ .byte 6 # DW_AT_encoding
+ .byte 1 # DW_AT_byte_size
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end0:
+.Lcu_begin1:
+ .long .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size (in bytes)
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] 0xc:0x43 DW_TAG_compile_unit
+ .byte 0 # DW_AT_producer
+ .short 33 # DW_AT_language
+ .byte 3 # DW_AT_name
+ .long .Lstr_offsets_base0 # DW_AT_str_offsets_base
+ .long .Lline_table_start0 # DW_AT_stmt_list
+ .byte 2 # DW_AT_comp_dir
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .long .Laddr_table_base0 # DW_AT_addr_base
+ .byte 10 # Abbrev [10] 0x23:0x12 DW_TAG_subprogram
+ .byte 4 # DW_AT_linkage_name
+ .byte 5 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 53 # DW_AT_type
+ # DW_AT_external
+ # DW_AT_inline
+ .byte 11 # Abbrev [11] 0x2c:0x8 DW_TAG_formal_parameter
+ .byte 7 # DW_AT_name
+ .byte 2 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .long 53 # DW_AT_type
+ .byte 0 # End Of Children Mark
+ .byte 9 # Abbrev [9] 0x35:0x4 DW_TAG_base_type
+ .byte 6 # DW_AT_name
+ .byte 5 # DW_AT_encoding
+ .byte 4 # DW_AT_byte_size
+ .byte 12 # Abbrev [12] 0x39:0x15 DW_TAG_subprogram
+ .byte 2 # DW_AT_low_pc
+ .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
+ .byte 1 # DW_AT_frame_base
+ .byte 86
+ .long 35 # DW_AT_abstract_origin
+ .byte 13 # Abbrev [13] 0x45:0x8 DW_TAG_formal_parameter
+ .byte 2 # DW_AT_location
+ .byte 145
+ .byte 124
+ .long 44 # DW_AT_abstract_origin
+ .byte 0 # End Of Children Mark
+ .byte 0 # End Of Children Mark
+.Ldebug_info_end1:
+ .section .debug_str_offsets,"", at progbits
+ .long 52 # Length of String Offsets Set
+ .short 5
+ .short 0
+.Lstr_offsets_base0:
+ .section .debug_str,"MS", at progbits,1
+.Linfo_string0:
+ .asciz "clang version 19.0.0git" # string offset=0
+.Linfo_string1:
+ .asciz "main.cpp" # string offset=24
+.Linfo_string2:
+ .asciz "/home/ayermolo/local/tasks/T182867349" # string offset=33
+.Linfo_string3:
+ .asciz "helper.cpp" # string offset=71
+.Linfo_string4:
+ .asciz "_Z3fooi" # string offset=82
+.Linfo_string5:
+ .asciz "foo" # string offset=90
+.Linfo_string6:
+ .asciz "int" # string offset=94
+.Linfo_string7:
+ .asciz "i" # string offset=98
+.Linfo_string8:
+ .asciz "main" # string offset=100
+.Linfo_string9:
+ .asciz "argc" # string offset=105
+.Linfo_string10:
+ .asciz "argv" # string offset=110
+.Linfo_string11:
+ .asciz "char" # string offset=115
+ .section .debug_str_offsets,"", at progbits
+ .long .Linfo_string0
+ .long .Linfo_string1
+ .long .Linfo_string2
+ .long .Linfo_string3
+ .long .Linfo_string4
+ .long .Linfo_string5
+ .long .Linfo_string6
+ .long .Linfo_string7
+ .long .Linfo_string8
+ .long .Linfo_string9
+ .long .Linfo_string10
+ .long .Linfo_string11
+ .section .debug_addr,"", at progbits
+ .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+ .short 5 # DWARF version number
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+.Laddr_table_base0:
+ .quad .Lfunc_begin0
+ .quad .Ltmp1
+ .quad .Lfunc_begin1
+.Ldebug_addr_end0:
+ .section .debug_names,"", at progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 2 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 5 # Header: bucket count
+ .long 5 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 8 # Header: augmentation string size
+ .ascii "LLVM0700" # Header: augmentation string
+ .long .Lcu_begin0 # Compilation unit 0
+ .long .Lcu_begin1 # Compilation unit 1
+ .long 0 # Bucket 0
+ .long 1 # Bucket 1
+ .long 0 # Bucket 2
+ .long 3 # Bucket 3
+ .long 4 # Bucket 4
+ .long 2090499946 # Hash in Bucket 1
+ .long -1257882370 # Hash in Bucket 1
+ .long 193495088 # Hash in Bucket 3
+ .long 193491849 # Hash in Bucket 4
+ .long 2090147939 # Hash in Bucket 4
+ .long .Linfo_string8 # String in Bucket 1: main
+ .long .Linfo_string4 # String in Bucket 1: _Z3fooi
+ .long .Linfo_string6 # String in Bucket 3: int
+ .long .Linfo_string5 # String in Bucket 4: foo
+ .long .Linfo_string11 # String in Bucket 4: char
+ .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames3-.Lnames_entries0 # Offset in Bucket 1
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 3
+ .long .Lnames2-.Lnames_entries0 # Offset in Bucket 4
+ .long .Lnames4-.Lnames_entries0 # Offset in Bucket 4
+.Lnames_abbrev_start0:
+ .byte 1 # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .byte 1 # DW_IDX_compile_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 2 # Abbrev code
+ .byte 29 # DW_TAG_inlined_subroutine
+ .byte 1 # DW_IDX_compile_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 3 # Abbrev code
+ .byte 36 # DW_TAG_base_type
+ .byte 1 # DW_IDX_compile_unit
+ .byte 11 # DW_FORM_data1
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 4 # DW_IDX_parent
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames1:
+.L3:
+ .byte 1 # Abbreviation code
+ .byte 0 # DW_IDX_compile_unit
+ .long 35 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: main
+.Lnames3:
+.L0:
+ .byte 1 # Abbreviation code
+ .byte 1 # DW_IDX_compile_unit
+ .long 57 # DW_IDX_die_offset
+.L2: # DW_IDX_parent
+ .byte 2 # Abbreviation code
+ .byte 0 # DW_IDX_compile_unit
+ .long 83 # DW_IDX_die_offset
+ .long .L3-.Lnames_entries0 # DW_IDX_parent
+ .byte 0 # End of list: _Z3fooi
+.Lnames0:
+.L4:
+ .byte 3 # Abbreviation code
+ .byte 1 # DW_IDX_compile_unit
+ .long 53 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: int
+.Lnames2:
+ .byte 1 # Abbreviation code
+ .byte 1 # DW_IDX_compile_unit
+ .long 57 # DW_IDX_die_offset
+ .byte 2 # DW_IDX_parent
+ # Abbreviation code
+ .byte 0 # DW_IDX_compile_unit
+ .long 83 # DW_IDX_die_offset
+ .long .L3-.Lnames_entries0 # DW_IDX_parent
+ .byte 0 # End of list: foo
+.Lnames4:
+.L1:
+ .byte 3 # Abbreviation code
+ .byte 0 # DW_IDX_compile_unit
+ .long 116 # DW_IDX_die_offset
+ .byte 0 # DW_IDX_parent
+ # End of list: char
+ .p2align 2, 0x0
+.Lnames_end0:
+ .ident "clang version 19.0.0git"
+ .ident "clang version 19.0.0git"
+ .section ".note.GNU-stack","", at progbits
+ .section .debug_line,"", at progbits
+.Lline_table_start0:
More information about the llvm-commits
mailing list