[lld] 863f7a7 - [lld-macho] Don't attempt to emit rebase opcodes for debug sections

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 10 15:58:33 PST 2020


Author: Jez Ng
Date: 2020-12-10T15:57:51-08:00
New Revision: 863f7a745e6ba5b9aebca82eeba1a2fb1db53e20

URL: https://github.com/llvm/llvm-project/commit/863f7a745e6ba5b9aebca82eeba1a2fb1db53e20
DIFF: https://github.com/llvm/llvm-project/commit/863f7a745e6ba5b9aebca82eeba1a2fb1db53e20.diff

LOG: [lld-macho] Don't attempt to emit rebase opcodes for debug sections

This was causing a crash as we were attempting to look up the
nonexistent parent OutputSection of the debug sections. We didn't detect
it earlier because there was no test for PIEs with debug info (PIEs
require us to emit rebases for X86_64_RELOC_UNSIGNED).

This diff filters out the debug sections while loading the ObjFiles. In
addition to fixing the above problem, it also lets us avoid doing
redundant work -- we no longer parse / apply relocations / attempt to
emit dyld opcodes for these sections that we don't emit.

Fixes llvm.org/PR48392.

Reviewed By: thakis

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

Added: 
    

Modified: 
    lld/MachO/Dwarf.cpp
    lld/MachO/InputFiles.cpp
    lld/MachO/InputFiles.h
    lld/MachO/Writer.cpp
    lld/test/MachO/stabs.s

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Dwarf.cpp b/lld/MachO/Dwarf.cpp
index 121f54fb1f79..3e794922ad1d 100644
--- a/lld/MachO/Dwarf.cpp
+++ b/lld/MachO/Dwarf.cpp
@@ -20,26 +20,19 @@ using namespace llvm;
 std::unique_ptr<DwarfObject> DwarfObject::create(ObjFile *obj) {
   auto dObj = std::make_unique<DwarfObject>();
   bool hasDwarfInfo = false;
-  for (SubsectionMap subsecMap : obj->subsections) {
-    for (auto it : subsecMap) {
-      InputSection *isec = it.second;
-      if (!(isDebugSection(isec->flags) &&
-            isec->segname == segment_names::dwarf))
-        continue;
-
-      if (isec->name == "__debug_info") {
-        dObj->infoSection.Data = toStringRef(isec->data);
-        hasDwarfInfo = true;
-        continue;
-      }
-
-      if (StringRef *s = StringSwitch<StringRef *>(isec->name)
-                             .Case("__debug_abbrev", &dObj->abbrevSection)
-                             .Case("__debug_str", &dObj->strSection)
-                             .Default(nullptr)) {
-        *s = toStringRef(isec->data);
-        hasDwarfInfo = true;
-      }
+  // LLD only needs to extract the source file path from the debug info, so we
+  // initialize DwarfObject with just the sections necessary to get that path.
+  // The debugger will locate the debug info via the object file paths that we
+  // emit in our STABS symbols, so we don't need to process & emit them
+  // ourselves.
+  for (InputSection *isec : obj->debugSections) {
+    if (StringRef *s = StringSwitch<StringRef *>(isec->name)
+                           .Case("__debug_info", &dObj->infoSection.Data)
+                           .Case("__debug_abbrev", &dObj->abbrevSection)
+                           .Case("__debug_str", &dObj->strSection)
+                           .Default(nullptr)) {
+      *s = toStringRef(isec->data);
+      hasDwarfInfo = true;
     }
   }
 

diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index c452648a1b11..3e0ad220bff1 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -174,7 +174,18 @@ void ObjFile::parseSections(ArrayRef<section_64> sections) {
     else
       isec->align = 1 << sec.align;
     isec->flags = sec.flags;
-    subsections.push_back({{0, isec}});
+
+    if (!(isDebugSection(isec->flags) &&
+          isec->segname == segment_names::dwarf)) {
+      subsections.push_back({{0, isec}});
+    } else {
+      // Instead of emitting DWARF sections, we emit STABS symbols to the
+      // object files that contain them. We filter them out early to avoid
+      // parsing their relocations unnecessarily. But we must still push an
+      // empty map to ensure the indices line up for the remaining sections.
+      subsections.push_back({});
+      debugSections.push_back(isec);
+    }
   }
 }
 
@@ -307,6 +318,7 @@ void ObjFile::parseSymbols(ArrayRef<structs::nlist_64> nList,
 
     const section_64 &sec = sectionHeaders[sym.n_sect - 1];
     SubsectionMap &subsecMap = subsections[sym.n_sect - 1];
+    assert(!subsecMap.empty());
     uint64_t offset = sym.n_value - sec.addr;
 
     // If the input file does not use subsections-via-symbols, all symbols can
@@ -410,7 +422,8 @@ ObjFile::ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName)
   // The relocations may refer to the symbols, so we parse them after we have
   // parsed all the symbols.
   for (size_t i = 0, n = subsections.size(); i < n; ++i)
-    parseRelocations(sectionHeaders[i], subsections[i]);
+    if (!subsections[i].empty())
+      parseRelocations(sectionHeaders[i], subsections[i]);
 
   parseDebugInfo();
 }

diff  --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
index 877ccaef2fef..2b492280c6f5 100644
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -95,6 +95,7 @@ class ObjFile : public InputFile {
   llvm::DWARFUnit *compileUnit = nullptr;
   const uint32_t modTime;
   ArrayRef<llvm::MachO::section_64> sectionHeaders;
+  std::vector<InputSection *> debugSections;
 
 private:
   void parseSections(ArrayRef<llvm::MachO::section_64>);

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 45ff11e7c443..2d033febb79b 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -603,10 +603,6 @@ void Writer::createOutputSections() {
   MapVector<std::pair<StringRef, StringRef>, MergedOutputSection *>
       mergedOutputSections;
   for (InputSection *isec : inputSections) {
-    // Instead of emitting DWARF sections, we emit STABS symbols to the object
-    // files that contain them.
-    if (isDebugSection(isec->flags) && isec->segname == segment_names::dwarf)
-      continue;
     MergedOutputSection *&osec =
         mergedOutputSections[{isec->segname, isec->name}];
     if (osec == nullptr)

diff  --git a/lld/test/MachO/stabs.s b/lld/test/MachO/stabs.s
index 445783269d11..9634a95be4a2 100644
--- a/lld/test/MachO/stabs.s
+++ b/lld/test/MachO/stabs.s
@@ -63,6 +63,14 @@
 # CHECK-NEXT:  {{[0-9af]+}}     T _no_debug
 # CHECK-EMPTY:
 
+## Check that we don't attempt to emit rebase opcodes for the debug sections
+## when building a PIE (since we have filtered the sections out).
+# RUN: %lld -lSystem -pie %t/test.o %t/foo.a %t/no-debug.o -o %t/test
+# RUN: llvm-objdump --macho --rebase %t/test | FileCheck %s --check-prefix=PIE
+# PIE:       Rebase table:
+# PIE-NEXT:  segment  section            address     type
+# PIE-EMPTY:
+
 #--- test.s
 
 ## Make sure we don't create STABS entries for absolute symbols.


        


More information about the llvm-commits mailing list