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;
}
}
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);
+ }
}
}
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
// 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();
}
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>);
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)
# 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.