[lld] r314866 - [ELF] Decompress debug info sections early

Shoaib Meenai via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 17:19:41 PDT 2017


Author: smeenai
Date: Tue Oct  3 17:19:41 2017
New Revision: 314866

URL: http://llvm.org/viewvc/llvm-project?rev=314866&view=rev
Log:
[ELF] Decompress debug info sections early

When reporting a symbol conflict, LLD parses the debug info to report
source location information. Sections have not been decompressed at this
point, so if an object file contains zlib compressed debug info, LLD
ends up passing this compressed debug info to the DWARF parser, which
causes debug info parsing failures and can trigger assertions in the
parser (as the test case demonstrates).

Decompress debug sections when constructing the LLDDwarfObj to avoid
this issue. This doesn't handle GNU-style compressed debug info sections
(.zdebug_*), which at present are simply ignored by LLDDwarfObj; those
can be done in a follow-up.

Differential Revision: https://reviews.llvm.org/D38491

Added:
    lld/trunk/test/ELF/compressed-debug-conflict.s
Modified:
    lld/trunk/ELF/GdbIndex.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/SyntheticSections.cpp

Modified: lld/trunk/ELF/GdbIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/GdbIndex.cpp?rev=314866&r1=314865&r2=314866&view=diff
==============================================================================
--- lld/trunk/ELF/GdbIndex.cpp (original)
+++ lld/trunk/ELF/GdbIndex.cpp Tue Oct  3 17:19:41 2017
@@ -33,6 +33,7 @@ template <class ELFT> LLDDwarfObj<ELFT>:
                                  .Case(".debug_ranges", &RangeSection)
                                  .Case(".debug_line", &LineSection)
                                  .Default(nullptr)) {
+      Sec->maybeUncompress();
       M->Data = toStringRef(Sec->Data);
       M->Sec = Sec;
       continue;

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=314866&r1=314865&r2=314866&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue Oct  3 17:19:41 2017
@@ -210,9 +210,15 @@ OutputSection *SectionBase::getOutputSec
   return Sec ? Sec->getParent() : nullptr;
 }
 
-// Uncompress section contents. Note that this function is called
-// from parallelForEach, so it must be thread-safe.
-void InputSectionBase::uncompress() {
+// Uncompress section contents if required. Note that this function
+// is called from parallelForEach, so it must be thread-safe.
+void InputSectionBase::maybeUncompress() {
+  if (UncompressBuf)
+    return;
+
+  if (!Decompressor::isCompressedELFSection(Flags, Name))
+    return;
+
   Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data),
                                                 Config->IsLE, Config->Is64));
 

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=314866&r1=314865&r2=314866&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Tue Oct  3 17:19:41 2017
@@ -165,7 +165,7 @@ public:
 
   InputSection *getLinkOrderDep() const;
 
-  void uncompress();
+  void maybeUncompress();
 
   // Returns a source location string. Used to construct an error message.
   template <class ELFT> std::string getLocation(uint64_t Offset);

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=314866&r1=314865&r2=314866&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Oct  3 17:19:41 2017
@@ -2300,8 +2300,7 @@ void elf::decompressAndMergeSections() {
   parallelForEach(InputSections, [](InputSectionBase *S) {
     if (!S->Live)
       return;
-    if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
-      S->uncompress();
+    S->maybeUncompress();
     if (auto *MS = dyn_cast<MergeInputSection>(S))
       MS->splitIntoPieces();
   });

Added: lld/trunk/test/ELF/compressed-debug-conflict.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/compressed-debug-conflict.s?rev=314866&view=auto
==============================================================================
--- lld/trunk/test/ELF/compressed-debug-conflict.s (added)
+++ lld/trunk/test/ELF/compressed-debug-conflict.s Tue Oct  3 17:19:41 2017
@@ -0,0 +1,29 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple i686-linux-gnu -compress-debug-sections=zlib %s -o %t.o
+# RUN: llvm-readobj -sections %t.o | FileCheck -check-prefix=OBJ %s
+# RUN: not ld.lld %t.o %t.o -o %tout 2>&1 | FileCheck -check-prefix=ERROR %s
+
+# OBJ:      Sections [
+# OBJ:        Section {
+# OBJ:          Index: 3
+# OBJ-NEXT:     Name: .debug_line (16)
+# OBJ-NEXT:     Type: SHT_PROGBITS (0x1)
+# OBJ-NEXT:     Flags [ (0x800)
+# OBJ-NEXT:       SHF_COMPRESSED (0x800)
+# OBJ-NEXT:     ]
+
+# ERROR:      error: duplicate symbol: main
+# ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2)
+# ERROR-NEXT: >>>
+# ERROR-NEXT: >>> defined at reduced.c:2 (/tmp/reduced.c:2)
+# ERROR-NEXT: >>>
+
+	.text
+	.file	"reduced.c"
+	.globl	main
+main:
+	.file	1 "/tmp" "reduced.c"
+	.loc	1 2 0
+	xorl	%eax, %eax
+	retl
+	.file	2 "/tmp/repeat/repeat/repeat/repeat" "repeat.h"




More information about the llvm-commits mailing list