summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp5
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/debug-names-multi-find.s92
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/find.test8
-rw-r--r--llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp54
4 files changed, 126 insertions, 33 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 1fa3bc09f4b..852536b8b11 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -312,6 +312,7 @@ void AppleAcceleratorTable::ValueIterator::Next() {
if (Data >= NumData ||
!AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
NumData = 0;
+ DataOffset = 0;
return;
}
Current.extract(*AccelTable, &DataOffset);
@@ -849,8 +850,8 @@ void DWARFDebugNames::ValueIterator::next() {
if (getEntryAtCurrentOffset())
return;
- // If we're a local iterator, we're done.
- if (IsLocal) {
+ // If we're a local iterator or we have reached the last Index, we're done.
+ if (IsLocal || CurrentIndex == &CurrentIndex->Section.NameIndices.back()) {
setEnd();
return;
}
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug-names-multi-find.s b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-multi-find.s
new file mode 100644
index 00000000000..799c9df0898
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug-names-multi-find.s
@@ -0,0 +1,92 @@
+# RUN: llvm-mc -triple x86_64-pc-linux %s -filetype=obj -o %t
+# RUN: llvm-dwarfdump -find=foo - <%t | FileCheck %s
+
+# CHECK: 12: DW_TAG_subprogram
+# CHECK-NEXT: DW_AT_name ("foo")
+# CHECK-NEXT: DW_AT_external
+# CHECK: 17: DW_TAG_subprogram
+# CHECK-NEXT: DW_AT_name ("foo")
+# CHECK-NEXT: DW_AT_external
+
+ .section .debug_str,"MS",@progbits,1
+.Lstring_foo:
+ .asciz "foo"
+.Lstring_producer:
+ .asciz "Hand-written dwarf"
+
+ .section .debug_abbrev,"",@progbits
+.Lsection_abbrev:
+ .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 .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Lcu_end0-.Lcu_start0 # Length of Unit
+.Lcu_start0:
+ .short 4 # DWARF version number
+ .long .Lsection_abbrev # Offset Into Abbrev. Section
+ .byte 8 # Address Size (in bytes)
+ .byte 1 # Abbrev [1] DW_TAG_compile_unit
+ .long .Lstring_producer # DW_AT_producer
+ .short 12 # DW_AT_language
+.Ldie_foo:
+ .byte 2 # Abbrev [2] DW_TAG_subprogram
+ .long .Lstring_foo # DW_AT_name
+ # DW_AT_external
+.Ldie_foo2:
+ .byte 2 # Abbrev [2] DW_TAG_subprogram
+ .long .Lstring_foo # DW_AT_name
+ # DW_AT_external
+ .byte 0 # End Of Children Mark
+.Lcu_end0:
+
+ .section .debug_names,"",@progbits
+ .long .Lnames_end0-.Lnames_start0 # Header: contribution 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 0 # Header: bucket count
+ .long 1 # Header: name count
+ .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size
+ .long 0 # Header: augmentation length
+ .long .Lcu_begin0 # Compilation unit 0
+ .long .Lstring_foo # String in Bucket 0: foo
+ .long .Lnames0-.Lnames_entries0 # Offset in Bucket 0
+.Lnames_abbrev_start0:
+ .byte 46 # Abbrev code
+ .byte 46 # DW_TAG_subprogram
+ .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 46 # Abbrev code
+ .long .Ldie_foo-.Lcu_begin0 # DW_IDX_die_offset
+ .byte 46 # Abbrev code
+ .long .Ldie_foo2-.Lcu_begin0 # DW_IDX_die_offset
+ .long 0 # End of list: foo
+ .p2align 2
+.Lnames_end0:
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/find.test b/llvm/test/tools/llvm-dwarfdump/X86/find.test
index 0606c674f91..4174e51529d 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/find.test
+++ b/llvm/test/tools/llvm-dwarfdump/X86/find.test
@@ -5,8 +5,6 @@ EMPTY: {{^$}}
RUN: llvm-mc %S/brief.s -filetype obj -triple x86_64-apple-darwin -o - \
RUN: | llvm-dwarfdump -find=main - | FileCheck %s
-CHECK: .debug_info contents:
-CHECK-NOT: {{:}}
CHECK: : DW_TAG_subprogram
CHECK-NOT: {{:}}
CHECK: DW_AT_name ("main")
@@ -15,13 +13,13 @@ CHECK-NOT: {{:}}
RUN: llvm-dwarfdump %S/../../dsymutil/Inputs/libfat-test.a \
RUN: -find=x86_64h_var -find=i386_var \
RUN: | FileCheck %s --check-prefix=MULTI
-MULTI: .debug_info contents:
+MULTI: libfat-test.a(i386)
MULTI-NOT: {{: DW}}
MULTI: : DW_TAG_variable
MULTI-NOT: {{: DW}}
MULTI: DW_AT_name ("i386_var")
+MULTI: libfat-test.a(x86_64h)
MULTI-NOT: {{: DW}}
-MULTI: .debug_info contents:
MULTI: : DW_TAG_variable
MULTI-NOT: {{: DW}}
MULTI: DW_AT_name ("x86_64h_var")
@@ -29,8 +27,6 @@ MULTI-NOT: {{: DW}}
RUN: llvm-mc %S/brief.s -filetype obj -triple x86_64-apple-darwin -o - \
RUN: | llvm-dwarfdump -find=int - | FileCheck %s --check-prefix=TYPES
-TYPES: .debug_info contents:
-TYPES-NOT: {{:}}
TYPES: : DW_TAG_base_type
TYPES-NOT: {{:}}
TYPES: DW_AT_name ("int")
diff --git a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 300a00b01be..433c681a108 100644
--- a/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/llvm/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -309,6 +309,33 @@ 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);
+}
+
+/// 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;
+ 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);
+ }
+ llvm::sort(Offsets.begin(), Offsets.end());
+ Offsets.erase(std::unique(Offsets.begin(), Offsets.end()), Offsets.end());
+
+ for (uint64_t Off: Offsets) {
+ DWARFDie Die = DICtx.getDIEForOffset(Off);
+ Die.dump(OS, 0, getDumpOpts());
+ }
+}
+
/// Handle the --lookup option and dump the DIEs and line info for the given
/// address.
static bool lookup(DWARFContext &DICtx, uint64_t Address, raw_ostream &OS) {
@@ -335,15 +362,6 @@ static bool lookup(DWARFContext &DICtx, uint64_t Address, raw_ostream &OS) {
bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
Twine Filename, raw_ostream &OS);
-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.getDIESectionOffset())
- return *Off;
- return None;
-}
-
static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
raw_ostream &OS) {
logAllUnhandledErrors(DICtx.loadRegisterInfo(Obj), errs(),
@@ -369,22 +387,8 @@ static bool dumpObjectFile(ObjectFile &Obj, DWARFContext &DICtx, Twine Filename,
// Handle the --find option and lower it to --debug-info=<offset>.
if (!Find.empty()) {
- DumpOffsets[DIDT_ID_DebugInfo] = [&]() -> llvm::Optional<uint64_t> {
- for (auto Name : Find) {
- if (auto Offset = getDIEOffset(DICtx.getAppleNames(), Name))
- return DumpOffsets[DIDT_ID_DebugInfo] = *Offset;
- if (auto Offset = getDIEOffset(DICtx.getAppleTypes(), Name))
- return DumpOffsets[DIDT_ID_DebugInfo] = *Offset;
- if (auto Offset = getDIEOffset(DICtx.getAppleNamespaces(), Name))
- return DumpOffsets[DIDT_ID_DebugInfo] = *Offset;
- if (auto Offset = getDIEOffset(DICtx.getDebugNames(), Name))
- return DumpOffsets[DIDT_ID_DebugInfo] = *Offset;
- }
- return None;
- }();
- // Early exit if --find was specified but the current file doesn't have it.
- if (!DumpOffsets[DIDT_ID_DebugInfo])
- return true;
+ filterByAccelName(Find, DICtx, OS);
+ return true;
}
// Dump the complete DWARF structure.
OpenPOWER on IntegriCloud