blob: 356f403b6313bdabd40dae3a2d3a08fef156e997 [file] [log] [blame]
commit 1ccde533425a4ba9d379510206ad680ff9702129
Author: Fangrui Song <maskray@google.com>
Date: Tue Apr 28 18:53:12 2020 -0700
[ELF] --gdb-index: support .debug_loclists
--gdb-index currently crashes when reading a translation unit with
DWARF v5 .debug_loclists . Call stack:
```
SyntheticSections.cpp GdbIndexSection::create
SyntheticSections.cpp readAddressAreas
DWARFUnit.cpp DWARFUnit::tryExtractDIEsIfNeeded
DWARFListTable.cpp DWARFListTableHeader::extract
...
DWARFDataExtractor.cpp DWARFDataExtractor::getRelocatedValue
lld/ELF/DWARF.cpp LLDDwarfObj<ELFT>::find (sec.sec is nullptr)
...
```
This patch adds support for .debug_loclists to make `DWARFUnit::tryExtractDIEsIfNeeded` happy.
Building --gdb-index does not need .debug_loclists
Reviewed By: dblaikie, grimar
Differential Revision: https://reviews.llvm.org/D79061
diff --git a/lld/ELF/DWARF.cpp b/lld/ELF/DWARF.cpp
index bf4fff76c31..f1587d93e53 100644
--- a/lld/ELF/DWARF.cpp
+++ b/lld/ELF/DWARF.cpp
@@ -36,6 +36,7 @@ template <class ELFT> LLDDwarfObj<ELFT>::LLDDwarfObj(ObjFile<ELFT> *obj) {
.Case(".debug_gnu_pubnames", &gnuPubnamesSection)
.Case(".debug_gnu_pubtypes", &gnuPubtypesSection)
.Case(".debug_info", &infoSection)
+ .Case(".debug_loclists", &loclistsSection)
.Case(".debug_ranges", &rangesSection)
.Case(".debug_rnglists", &rnglistsSection)
.Case(".debug_str_offsets", &strOffsetsSection)
diff --git a/lld/ELF/DWARF.h b/lld/ELF/DWARF.h
index 51ec9092f17..8609e35faf9 100644
--- a/lld/ELF/DWARF.h
+++ b/lld/ELF/DWARF.h
@@ -32,6 +32,10 @@ public:
f(infoSection);
}
+ const llvm::DWARFSection &getLoclistsSection() const override {
+ return loclistsSection;
+ }
+
const llvm::DWARFSection &getRangesSection() const override {
return rangesSection;
}
@@ -81,6 +85,7 @@ private:
LLDDWARFSection gnuPubnamesSection;
LLDDWARFSection gnuPubtypesSection;
LLDDWARFSection infoSection;
+ LLDDWARFSection loclistsSection;
LLDDWARFSection rangesSection;
LLDDWARFSection rnglistsSection;
LLDDWARFSection strOffsetsSection;
diff --git a/lld/test/ELF/gdb-index-loclists.s b/lld/test/ELF/gdb-index-loclists.s
new file mode 100644
index 00000000000..e3769b69537
--- /dev/null
+++ b/lld/test/ELF/gdb-index-loclists.s
@@ -0,0 +1,37 @@
+# REQUIRES: x86
+## Regression test that we don't crash on DWARF v5 .debug_loclists
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: ld.lld --gdb-index %t.o -o /dev/null
+
+.section .debug_abbrev,"",@progbits
+ .byte 1 # Abbreviation Code
+ .byte 17 # DW_TAG_compile_unit
+ .byte 0 # DW_CHILDREN_no
+ .ascii "\214\001" # DW_AT_loclists_base
+ .byte 23 # DW_FORM_sec_offset
+ .byte 0 # EOM(1)
+ .byte 0 # EOM(2)
+ .byte 0
+
+.section .debug_info,"",@progbits
+.Lcu_begin0:
+ .long .Lcu_end0-.Lcu_begin0-4 # Length of Unit
+ .short 5 # DWARF version number
+ .byte 1 # DWARF Unit Type
+ .byte 8 # Address Size
+ .long 0 # Offset Into Abbrev. Section
+ .byte 1 # Abbrev [1] DW_TAG_compile_unit
+ .long .Lloclists_table_base0 # DW_AT_loclists_base
+.Lcu_end0:
+
+.section .debug_loclists,"",@progbits
+ .long .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0 # Length
+.Ldebug_loclist_table_start0:
+ .short 5 # Version
+ .byte 8 # Address size
+ .byte 0 # Segment selector size
+ .long 0 # Offset entry count
+.Lloclists_table_base0:
+ .byte 0 # DW_LLE_end_of_list
+.Ldebug_loclist_table_end0: