diff --git a/lld/MachO/Dwarf.cpp b/lld/MachO/Dwarf.cpp
--- a/lld/MachO/Dwarf.cpp
+++ b/lld/MachO/Dwarf.cpp
@@ -20,26 +20,14 @@
 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;
-      }
+  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.h b/lld/MachO/InputFiles.h
--- a/lld/MachO/InputFiles.h
+++ b/lld/MachO/InputFiles.h
@@ -95,6 +95,7 @@
   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/InputFiles.cpp b/lld/MachO/InputFiles.cpp
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -174,7 +174,18 @@
     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 @@
 
     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 @@
   // 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/Writer.cpp b/lld/MachO/Writer.cpp
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -588,10 +588,6 @@
   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
--- 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.