summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h21
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp41
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-data.s75
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-ref.s75
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/debug-names-find.s10
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp2
6 files changed, 204 insertions, 20 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index e52d54a5a3c..a984d9f7809 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -56,10 +56,11 @@ public:
/// in this Accelerator Entry.
virtual Optional<uint64_t> getCUOffset() const = 0;
- /// Returns the Offset of the Debug Info Entry associated with this
+ /// Returns the Section Offset of the Debug Info Entry associated with this
/// Accelerator Entry or None if the DIE offset is not recorded in this
- /// Accelerator Entry.
- virtual Optional<uint64_t> getDIEOffset() const = 0;
+ /// Accelerator Entry. The returned offset is relative to the start of the
+ /// Section containing the DIE.
+ virtual Optional<uint64_t> getDIESectionOffset() const = 0;
/// Returns the Tag of the Debug Info Entry associated with this
/// Accelerator Entry or None if the Tag is not recorded in this
@@ -104,6 +105,8 @@ class AppleAcceleratorTable : public DWARFAcceleratorTable {
uint32_t DIEOffsetBase;
SmallVector<std::pair<AtomType, Form>, 3> Atoms;
+
+ Optional<uint64_t> extractOffset(Optional<DWARFFormValue> Value) const;
};
struct Header Hdr;
@@ -127,7 +130,7 @@ public:
public:
Optional<uint64_t> getCUOffset() const override;
- Optional<uint64_t> getDIEOffset() const override;
+ Optional<uint64_t> getDIESectionOffset() const override;
Optional<dwarf::Tag> getTag() const override;
/// Returns the value of the Atom in this Accelerator Entry, if the Entry
@@ -284,18 +287,24 @@ public:
/// Index or None if this Accelerator Entry does not have an associated
/// Compilation Unit. It is up to the user to verify that the returned Index
/// is valid in the owning NameIndex (or use getCUOffset(), which will
- /// handle that check itself).
+ /// handle that check itself). Note that entries in NameIndexes which index
+ /// just a single Compilation Unit are implicitly associated with that unit,
+ /// so this function will return 0 even without an explicit
+ /// DW_IDX_compile_unit attribute.
Optional<uint64_t> getCUIndex() const;
public:
Optional<uint64_t> getCUOffset() const override;
- Optional<uint64_t> getDIEOffset() const override;
+ Optional<uint64_t> getDIESectionOffset() const override;
Optional<dwarf::Tag> getTag() const override { return tag(); }
/// .debug_names-specific getter, which always succeeds (DWARF v5 index
/// entries always have a tag).
dwarf::Tag tag() const { return Abbr->Tag; }
+ /// Returns the Offset of the DIE within the containing CU or TU.
+ Optional<uint64_t> getDIEUnitOffset() const;
+
/// Return the Abbreviation that can be used to interpret the raw values of
/// this Accelerator Entry.
const Abbrev &getAbbrev() const { return *Abbr; }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 3d26cf69b94..4771d213741 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -159,6 +159,23 @@ void AppleAcceleratorTable::Header::dump(ScopedPrinter &W) const {
W.printNumber("HeaderData length", HeaderDataLength);
}
+Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset(
+ Optional<DWARFFormValue> Value) const {
+ if (!Value)
+ return None;
+
+ switch (Value->getForm()) {
+ case dwarf::DW_FORM_ref1:
+ case dwarf::DW_FORM_ref2:
+ case dwarf::DW_FORM_ref4:
+ case dwarf::DW_FORM_ref8:
+ case dwarf::DW_FORM_ref_udata:
+ return Value->getRawUValue() + DIEOffsetBase;
+ default:
+ return Value->getAsSectionOffset();
+ }
+}
+
bool AppleAcceleratorTable::dumpName(ScopedPrinter &W,
SmallVectorImpl<DWARFFormValue> &AtomForms,
uint32_t *DataOffset) const {
@@ -276,16 +293,12 @@ AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType Atom) const {
return None;
}
-Optional<uint64_t> AppleAcceleratorTable::Entry::getDIEOffset() const {
- if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_ATOM_die_offset))
- return Off->getAsSectionOffset();
- return None;
+Optional<uint64_t> AppleAcceleratorTable::Entry::getDIESectionOffset() const {
+ return HdrData->extractOffset(lookup(dwarf::DW_ATOM_die_offset));
}
Optional<uint64_t> AppleAcceleratorTable::Entry::getCUOffset() const {
- if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_ATOM_cu_offset))
- return Off->getAsSectionOffset();
- return None;
+ return HdrData->extractOffset(lookup(dwarf::DW_ATOM_cu_offset));
}
Optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const {
@@ -537,7 +550,7 @@ DWARFDebugNames::Entry::lookup(dwarf::Index Index) const {
return None;
}
-Optional<uint64_t> DWARFDebugNames::Entry::getDIEOffset() const {
+Optional<uint64_t> DWARFDebugNames::Entry::getDIEUnitOffset() const {
if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_die_offset))
return Off->getAsSectionOffset();
return None;
@@ -546,6 +559,10 @@ Optional<uint64_t> DWARFDebugNames::Entry::getDIEOffset() const {
Optional<uint64_t> DWARFDebugNames::Entry::getCUIndex() const {
if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit))
return Off->getAsUnsignedConstant();
+ // In a per-CU index, the entries without a DW_IDX_compile_unit attribute
+ // implicitly refer to the single CU.
+ if (NameIdx->getCUCount() == 1)
+ return 0;
return None;
}
@@ -556,6 +573,14 @@ Optional<uint64_t> DWARFDebugNames::Entry::getCUOffset() const {
return NameIdx->getCUOffset(*Index);
}
+Optional<uint64_t> DWARFDebugNames::Entry::getDIESectionOffset() const {
+ Optional<uint64_t> CUOff = getCUOffset();
+ Optional<uint64_t> DIEOff = getDIEUnitOffset();
+ if (CUOff && DIEOff)
+ return *CUOff + *DIEOff;
+ return None;
+}
+
void DWARFDebugNames::Entry::dump(ScopedPrinter &W) const {
W.printHex("Abbrev", Abbr->Code);
W.startLine() << "Tag: " << formatTag(Abbr->Tag) << "\n";
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-data.s b/llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-data.s
new file mode 100644
index 00000000000..aaf1e44beea
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-data.s
@@ -0,0 +1,75 @@
+# This test sets non-zero Die Offset Base field in the accelerator table header,
+# and makes sure it is *not* added to the DW_FORM_data*** forms.
+
+# RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o %t
+# RUN: llvm-dwarfdump -find=main %t | FileCheck %s
+
+# CHECK: DW_TAG_subprogram
+# CHECK-NEXT: DW_AT_name ("main")
+# CHECK-NEXT: DW_AT_external
+
+ .section __DWARF,__debug_str,regular,debug
+Ldebug_str:
+Lstring_producer:
+ .asciz "Hand-written dwarf"
+Lstring_main:
+ .asciz "main"
+
+ .section __DWARF,__debug_abbrev,regular,debug
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+
+ .section __DWARF,__debug_info,regular,debug
+Ldebug_info:
+ .long Lcu_end0-Lcu_start0 # Length of Unit
+Lcu_start0:
+ .short 4 # DWARF version number
+ .long 0 # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] DW_TAG_compile_unit
+ .long Lstring_producer-Ldebug_str # DW_AT_producer
+ .short 12 # DW_AT_language
+Ldie_main:
+ .byte 2 # Abbrev [2] DW_TAG_subprogram
+ .long Lstring_main-Ldebug_str # DW_AT_name
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+Lcu_end0:
+
+ .section __DWARF,__apple_names,regular,debug
+Lnames_begin:
+ .long 1212240712 ## Header Magic
+ .short 1 ## Header Version
+ .short 0 ## Header Hash Function
+ .long 1 ## Header Bucket Count
+ .long 1 ## Header Hash Count
+ .long 12 ## Header Data Length
+ .long 1 ## HeaderData Die Offset Base
+ .long 1 ## HeaderData Atom Count
+ .short 1 ## DW_ATOM_die_offset
+ .short 6 ## DW_FORM_data4
+ .long 0 ## Bucket 0
+ .long 2090499946 ## Hash in Bucket 0
+ .long LNames0-Lnames_begin ## Offset in Bucket 0
+LNames0:
+ .long Lstring_main-Ldebug_str ## main
+ .long 1 ## Num DIEs
+ .long Ldie_main-Ldebug_info
+ .long 0
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-ref.s b/llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-ref.s
new file mode 100644
index 00000000000..e08b0430c89
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/apple-names-die-offset-ref.s
@@ -0,0 +1,75 @@
+# This test sets non-zero Die Offset Base field in the accelerator table header,
+# and makes sure it is added to the DW_FORM_ref*** forms.
+
+# RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o %t
+# RUN: llvm-dwarfdump -find=main %t | FileCheck %s
+
+# CHECK: DW_TAG_subprogram
+# CHECK-NEXT: DW_AT_name ("main")
+# CHECK-NEXT: DW_AT_external
+
+ .section __DWARF,__debug_str,regular,debug
+Ldebug_str:
+Lstring_producer:
+ .asciz "Hand-written dwarf"
+Lstring_main:
+ .asciz "main"
+
+ .section __DWARF,__debug_abbrev,regular,debug
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .byte 37 # DW_AT_producer
+ .byte 14 # DW_FORM_strp
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 46 # DW_TAG_subprogram
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .byte 14 # DW_FORM_strp
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+
+ .section __DWARF,__debug_info,regular,debug
+Ldebug_info:
+ .long Lcu_end0-Lcu_start0 # Length of Unit
+Lcu_start0:
+ .short 4 # DWARF version number
+ .long 0 # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] DW_TAG_compile_unit
+ .long Lstring_producer-Ldebug_str # DW_AT_producer
+ .short 12 # DW_AT_language
+Ldie_main:
+ .byte 2 # Abbrev [2] DW_TAG_subprogram
+ .long Lstring_main-Ldebug_str # DW_AT_name
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+Lcu_end0:
+
+ .section __DWARF,__apple_names,regular,debug
+Lnames_begin:
+ .long 1212240712 ## Header Magic
+ .short 1 ## Header Version
+ .short 0 ## Header Hash Function
+ .long 1 ## Header Bucket Count
+ .long 1 ## Header Hash Count
+ .long 12 ## Header Data Length
+ .long 1 ## HeaderData Die Offset Base
+ .long 1 ## HeaderData Atom Count
+ .short 1 ## DW_ATOM_die_offset
+ .short 0x13 ## DW_FORM_ref4
+ .long 0 ## Bucket 0
+ .long 2090499946 ## Hash in Bucket 0
+ .long LNames0-Lnames_begin ## Offset in Bucket 0
+LNames0:
+ .long Lstring_main-Ldebug_str ## main
+ .long 1 ## Num DIEs
+ .long Ldie_main-Ldebug_info-1
+ .long 0
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find.s
index 280c3d771b0..e65ede13c3b 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find.s
@@ -129,15 +129,15 @@
.Lnames_entries0:
.Lnames0:
.byte 46 # Abbrev code
- .long .Ldie_bar # DW_IDX_die_offset
+ .long .Ldie_bar-.Lcu_begin0 # DW_IDX_die_offset
.long 0 # End of list: bar
.Lnames1:
.byte 46 # Abbrev code
- .long .Ldie_foo # DW_IDX_die_offset
+ .long .Ldie_foo-.Lcu_begin0 # DW_IDX_die_offset
.long 0 # End of list: foo
.Lnames2:
.byte 46 # Abbrev code
- .long .Ldie_foo # DW_IDX_die_offset
+ .long .Ldie_foo-.Lcu_begin0 # DW_IDX_die_offset
.long 0 # End of list: _Z3foov
.p2align 2
.Lnames_end0:
@@ -171,12 +171,12 @@
.Lnames_entries1:
.Lnames3:
.byte 46 # Abbrev code
- .long .Ldie_baz # DW_IDX_die_offset
+ .long .Ldie_baz-.Lcu_begin1 # DW_IDX_die_offset
.long 0 # End of list: baz
.p2align 2
.Lnames4:
.byte 46 # Abbrev code
- .long .Ldie_bazz # DW_IDX_die_offset
+ .long .Ldie_bazz-.Lcu_begin1 # DW_IDX_die_offset
.long 0 # End of list: baz
.p2align 2
.Lnames_end1:
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 1795172ae5a..2a9af874d22 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -340,7 +340,7 @@ template <typename AccelTable>
static llvm::Optional<uint64_t> getDIEOffset(const AccelTable &Accel,
StringRef Name) {
for (const auto &Entry : Accel.equal_range(Name))
- if (llvm::Optional<uint64_t> Off = Entry.getDIEOffset())
+ if (llvm::Optional<uint64_t> Off = Entry.getDIESectionOffset())
return *Off;
return None;
}
OpenPOWER on IntegriCloud