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,19 @@ std::unique_ptr DwarfObject::create(ObjFile *obj) { auto dObj = std::make_unique(); 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(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(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 sectionHeaders; + std::vector debugSections; private: void parseSections(ArrayRef); 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 @@ -603,10 +603,6 @@ MapVector, 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.