summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h15
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h6
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp8
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp7
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/debug-names-find-dwo.s162
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp61
7 files changed, 225 insertions, 39 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index 741cec3507c..1d448728338 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -56,12 +56,6 @@ public:
/// in this Accelerator Entry.
virtual Optional<uint64_t> getCUOffset() const = 0;
- /// 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. 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
/// Accelerator Entry.
@@ -130,7 +124,13 @@ public:
public:
Optional<uint64_t> getCUOffset() const override;
- Optional<uint64_t> getDIESectionOffset() const override;
+
+ /// 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. The returned offset is relative to the start of the
+ /// Section containing the DIE.
+ Optional<uint64_t> getDIESectionOffset() const;
+
Optional<dwarf::Tag> getTag() const override;
/// Returns the value of the Atom in this Accelerator Entry, if the Entry
@@ -286,7 +286,6 @@ public:
public:
Optional<uint64_t> getCUOffset() const override;
- Optional<uint64_t> getDIESectionOffset() const override;
Optional<dwarf::Tag> getTag() const override { return tag(); }
/// Returns the Index into the Compilation Unit list of the owning Name
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 6634eedbcd0..fe7430c9f04 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -205,6 +205,9 @@ public:
DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
+ /// Return the compile unit that includes an offset (relative to .debug_info).
+ DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
+
/// Get a DIE given an exact offset.
DWARFDie getDIEForOffset(uint32_t Offset);
@@ -321,9 +324,6 @@ public:
Error loadRegisterInfo(const object::ObjectFile &Obj);
private:
- /// Return the compile unit that includes an offset (relative to .debug_info).
- DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
-
/// Return the compile unit which contains instruction with provided
/// address.
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index b6ea11ec88e..fa98b728492 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -442,7 +442,10 @@ public:
}
const char *getCompilationDir();
- Optional<uint64_t> getDWOId() const { return getHeader().getDWOId(); }
+ Optional<uint64_t> getDWOId() {
+ extractDIEsIfNeeded(/*CUDieOnly*/ true);
+ return getHeader().getDWOId();
+ }
void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
/// Return a vector of address ranges resulting from a (possibly encoded)
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index c2ba9e6027b..0ded97cabf2 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -556,14 +556,6 @@ 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() << formatv("Tag: {0}\n", Abbr->Tag);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index fe44071d9a2..e456de5b103 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -1088,7 +1088,7 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
continue;
}
uint32_t CUOffset = NI.getCUOffset(CUIndex);
- uint64_t DIEOffset = *EntryOr->getDIESectionOffset();
+ uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
if (!DIE) {
error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
@@ -1261,9 +1261,10 @@ unsigned DWARFVerifier::verifyNameIndexCompleteness(
// Now we know that our Die should be present in the Index. Let's check if
// that's the case.
unsigned NumErrors = 0;
+ uint64_t DieUnitOffset = Die.getOffset() - Die.getDwarfUnit()->getOffset();
for (StringRef Name : EntryNames) {
- if (none_of(NI.equal_range(Name), [&Die](const DWARFDebugNames::Entry &E) {
- return E.getDIESectionOffset() == uint64_t(Die.getOffset());
+ if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) {
+ return E.getDIEUnitOffset() == DieUnitOffset;
})) {
error() << formatv("Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with "
"name {3} missing.\n",
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find-dwo.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find-dwo.s
new file mode 100644
index 00000000000..a12aa2e90f1
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-find-dwo.s
@@ -0,0 +1,162 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj | \
+# RUN: llvm-dwarfdump -find=foobar - | FileCheck %s
+
+# CHECK: DW_TAG_variable
+# CHECK-NEXT: DW_AT_name ("foobar")
+
+ .text
+ .file "<stdin>"
+ .file 1 "/tmp/cu1.c"
+ .type foobar,@object # @foobar
+ .comm foobar,8,8
+ .section .debug_str,"MS",@progbits,1
+.Lskel_string0:
+ .asciz "foo.dwo" # string offset=0
+.Lskel_string1:
+ .asciz "/tmp" # string offset=8
+.Lskel_string2:
+ .asciz "foobar" # string offset=13
+ .section .debug_loc.dwo,"",@progbits
+ .section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .byte 16 # DW_AT_stmt_list
+ .byte 23 # DW_FORM_sec_offset
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .byte 14 # DW_FORM_strp
+ .byte 27 # DW_AT_comp_dir
+ .byte 14 # DW_FORM_strp
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .ascii "\263B" # DW_AT_GNU_addr_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long 32 # Length of Unit
+ .short 4 # DWARF version number
+ .long .debug_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x19 DW_TAG_compile_unit
+ .long 0 # DW_AT_stmt_list
+ .long .Lskel_string0 # DW_AT_GNU_dwo_name
+ .long .Lskel_string1 # DW_AT_comp_dir
+ .quad -1328675031687321003 # DW_AT_GNU_dwo_id
+ .long .debug_addr # DW_AT_GNU_addr_base
+ .section .debug_ranges,"",@progbits
+ .section .debug_macinfo,"",@progbits
+ .byte 0 # End Of Macro List Mark
+ .section .debug_str.dwo,"MS",@progbits,1
+.Linfo_string0:
+ .asciz "foo.dwo" # string offset=0
+.Linfo_string1:
+ .asciz "clang version 7.0.0 (trunk 325496) (llvm/trunk 325732)" # string offset=8
+.Linfo_string2:
+ .asciz "/tmp/cu1.c" # string offset=63
+.Linfo_string3:
+ .asciz "foobar" # string offset=74
+ .section .debug_str_offsets.dwo,"",@progbits
+ .long 0
+ .long 8
+ .long 63
+ .long 74
+ .section .debug_info.dwo,"",@progbits
+ .long 34 # Length of Unit
+ .short 4 # DWARF version number
+ .long 0 # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] 0xb:0x1b DW_TAG_compile_unit
+ .byte 0 # DW_AT_GNU_dwo_name
+ .byte 1 # DW_AT_producer
+ .short 12 # DW_AT_language
+ .byte 2 # DW_AT_name
+ .quad -1328675031687321003 # DW_AT_GNU_dwo_id
+ .byte 2 # Abbrev [2] 0x19:0xb DW_TAG_variable
+ .byte 3 # DW_AT_name
+ .long 36 # DW_AT_type
+ # DW_AT_external
+ .byte 1 # DW_AT_decl_file
+ .byte 1 # DW_AT_decl_line
+ .byte 2 # DW_AT_location
+ .byte 251
+ .byte 0
+ .byte 3 # Abbrev [3] 0x24:0x1 DW_TAG_pointer_type
+ .byte 0 # End Of Children Mark
+ .section .debug_abbrev.dwo,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 1 # DW_CHILDREN_yes
+ .ascii "\260B" # DW_AT_GNU_dwo_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 37 # DW_AT_producer
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 19 # DW_AT_language
+ .byte 5 # DW_FORM_data2
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .ascii "\261B" # DW_AT_GNU_dwo_id
+ .byte 7 # DW_FORM_data8
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 2 # Abbreviation Code
+ .byte 52 # DW_TAG_variable
+ .byte 0 # DW_CHILDREN_no
+ .byte 3 # DW_AT_name
+ .ascii "\202>" # DW_FORM_GNU_str_index
+ .byte 73 # DW_AT_type
+ .byte 19 # DW_FORM_ref4
+ .byte 63 # DW_AT_external
+ .byte 25 # DW_FORM_flag_present
+ .byte 58 # DW_AT_decl_file
+ .byte 11 # DW_FORM_data1
+ .byte 59 # DW_AT_decl_line
+ .byte 11 # DW_FORM_data1
+ .byte 2 # DW_AT_location
+ .byte 24 # DW_FORM_exprloc
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 3 # Abbreviation Code
+ .byte 15 # DW_TAG_pointer_type
+ .byte 0 # DW_CHILDREN_no
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0 # EOM(3)
+ .section .debug_addr,"",@progbits
+ .quad foobar
+ .section .debug_names,"",@progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: unit length
+.Lnames_start0:
+ .short 5 # Header: version
+ .short 0 # Header: padding
+ .long 1 # Header: compilation unit count
+ .long 0 # Header: local type unit count
+ .long 0 # Header: foreign type unit count
+ .long 1 # Header: bucket count
+ .long 1 # 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 1 # Bucket 0
+ .long -35364674 # Hash in Bucket 0
+ .long .Lskel_string2 # String in Bucket 0: foobar
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0
+.Lnames_abbrev_start0:
+ .byte 52 # Abbrev code
+ .byte 52 # DW_TAG_variable
+ .byte 3 # DW_IDX_die_offset
+ .byte 19 # DW_FORM_ref4
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev
+ .byte 0 # End of abbrev list
+.Lnames_abbrev_end0:
+.Lnames_entries0:
+.Lnames0:
+ .byte 52 # Abbreviation code
+ .long 25 # DW_IDX_die_offset
+ .long 0 # End of list: foobar
+ .p2align 2
+.Lnames_end0:
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 433c681a108..d9d36625083 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -309,31 +309,60 @@ static void filterByName(const StringSet<> &Names,
}
-template <typename AccelTable>
-static void getDIEOffset(const AccelTable &Accel, StringRef Name,
- SmallVectorImpl<uint64_t> &Offsets) {
- for (const auto &Entry : Accel.equal_range(Name))
- if (llvm::Optional<uint64_t> Off = Entry.getDIESectionOffset())
- Offsets.push_back(*Off);
+static void getDies(DWARFContext &DICtx, const AppleAcceleratorTable &Accel,
+ StringRef Name, SmallVectorImpl<DWARFDie> &Dies) {
+ for (const auto &Entry : Accel.equal_range(Name)) {
+ if (llvm::Optional<uint64_t> Off = Entry.getDIESectionOffset()) {
+ if (DWARFDie Die = DICtx.getDIEForOffset(*Off))
+ Dies.push_back(Die);
+ }
+ }
+}
+
+static DWARFDie toDie(const DWARFDebugNames::Entry &Entry,
+ DWARFContext &DICtx) {
+ llvm::Optional<uint64_t> CUOff = Entry.getCUOffset();
+ llvm::Optional<uint64_t> Off = Entry.getDIEUnitOffset();
+ if (!CUOff || !Off)
+ return DWARFDie();
+
+ DWARFCompileUnit *CU = DICtx.getCompileUnitForOffset(*CUOff);
+ if (!CU)
+ return DWARFDie();
+
+ if (Optional<uint64_t> DWOId = CU->getDWOId()) {
+ // This is a skeleton unit. Look up the DIE in the DWO unit.
+ CU = DICtx.getDWOCompileUnitForHash(*DWOId);
+ if (!CU)
+ return DWARFDie();
+ }
+
+ return CU->getDIEForOffset(CU->getOffset() + *Off);
+}
+
+static void getDies(DWARFContext &DICtx, const DWARFDebugNames &Accel,
+ StringRef Name, SmallVectorImpl<DWARFDie> &Dies) {
+ for (const auto &Entry : Accel.equal_range(Name)) {
+ if (DWARFDie Die = toDie(Entry, DICtx))
+ Dies.push_back(Die);
+ }
}
/// Print only DIEs that have a certain name.
static void filterByAccelName(ArrayRef<std::string> Names, DWARFContext &DICtx,
raw_ostream &OS) {
- SmallVector<uint64_t, 4> Offsets;
+ SmallVector<DWARFDie, 4> Dies;
for (const auto &Name : Names) {
- getDIEOffset(DICtx.getAppleNames(), Name, Offsets);
- getDIEOffset(DICtx.getAppleTypes(), Name, Offsets);
- getDIEOffset(DICtx.getAppleNamespaces(), Name, Offsets);
- getDIEOffset(DICtx.getDebugNames(), Name, Offsets);
+ getDies(DICtx, DICtx.getAppleNames(), Name, Dies);
+ getDies(DICtx, DICtx.getAppleTypes(), Name, Dies);
+ getDies(DICtx, DICtx.getAppleNamespaces(), Name, Dies);
+ getDies(DICtx, DICtx.getDebugNames(), Name, Dies);
}
- llvm::sort(Offsets.begin(), Offsets.end());
- Offsets.erase(std::unique(Offsets.begin(), Offsets.end()), Offsets.end());
+ llvm::sort(Dies.begin(), Dies.end());
+ Dies.erase(std::unique(Dies.begin(), Dies.end()), Dies.end());
- for (uint64_t Off: Offsets) {
- DWARFDie Die = DICtx.getDIEForOffset(Off);
+ for (DWARFDie Die : Dies)
Die.dump(OS, 0, getDumpOpts());
- }
}
/// Handle the --lookup option and dump the DIEs and line info for the given
OpenPOWER on IntegriCloud