summaryrefslogtreecommitdiffstats
path: root/llvm/tools/dsymutil/DwarfLinker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/dsymutil/DwarfLinker.cpp')
-rw-r--r--llvm/tools/dsymutil/DwarfLinker.cpp96
1 files changed, 85 insertions, 11 deletions
diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp
index f21873f2fb5..e685a59277b 100644
--- a/llvm/tools/dsymutil/DwarfLinker.cpp
+++ b/llvm/tools/dsymutil/DwarfLinker.cpp
@@ -321,6 +321,7 @@ void DwarfLinker::startDebugObject(LinkContext &Context) {
void DwarfLinker::endDebugObject(LinkContext &Context) {
Context.Clear();
+
for (auto I = DIEBlocks.begin(), E = DIEBlocks.end(); I != E; ++I)
(*I)->~DIEBlock();
for (auto I = DIELocs.begin(), E = DIELocs.end(); I != E; ++I)
@@ -1746,6 +1747,20 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit,
}
void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
+ switch (Options.TheAccelTableKind) {
+ case AccelTableKind::Apple:
+ emitAppleAcceleratorEntriesForUnit(Unit);
+ break;
+ case AccelTableKind::Dwarf:
+ emitDwarfAcceleratorEntriesForUnit(Unit);
+ break;
+ case AccelTableKind::Default:
+ llvm_unreachable("The default must be updated to a concrete value.");
+ break;
+ }
+}
+
+void DwarfLinker::emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit) {
// Add namespaces.
for (const auto &Namespace : Unit.getNamespaces())
AppleNamespaces.addName(Namespace.Name,
@@ -1774,6 +1789,18 @@ void DwarfLinker::emitAcceleratorEntriesForUnit(CompileUnit &Unit) {
AppleObjc.addName(ObjC.Name, ObjC.Die->getOffset() + Unit.getStartOffset());
}
+void DwarfLinker::emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit) {
+ for (const auto &Namespace : Unit.getNamespaces())
+ DebugNames.addName(Namespace.Name, Namespace.Die->getOffset(),
+ Namespace.Die->getTag(), Unit.getUniqueID());
+ for (const auto &Pubname : Unit.getPubnames())
+ DebugNames.addName(Pubname.Name, Pubname.Die->getOffset(),
+ Pubname.Die->getTag(), Unit.getUniqueID());
+ for (const auto &Pubtype : Unit.getPubtypes())
+ DebugNames.addName(Pubtype.Name, Pubtype.Die->getOffset(),
+ Pubtype.Die->getTag(), Unit.getUniqueID());
+}
+
/// Read the frame info stored in the object, and emit the
/// patched frame descriptions for the linked binary.
///
@@ -2063,9 +2090,9 @@ Error DwarfLinker::loadClangModule(StringRef Filename, StringRef ModulePath,
// Setup access to the debug info.
auto DwarfContext = DWARFContext::create(*ErrOrObj);
RelocationManager RelocMgr(*this);
- for (const auto &CU : DwarfContext->compile_units()) {
- maybeUpdateMaxDwarfVersion(CU->getVersion());
+ for (const auto &CU : DwarfContext->compile_units()) {
+ updateDwarfVersion(CU->getVersion());
// Recursively get all modules imported by this one.
auto CUDie = CU->getUnitDIE(false);
if (!CUDie)
@@ -2172,6 +2199,26 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits(
}
}
+void DwarfLinker::updateAccelKind(DWARFContext &Dwarf) {
+ if (Options.TheAccelTableKind != AccelTableKind::Default)
+ return;
+
+ auto &DwarfObj = Dwarf.getDWARFObj();
+
+ if (!AtLeastOneDwarfAccelTable &&
+ (!DwarfObj.getAppleNamesSection().Data.empty() ||
+ !DwarfObj.getAppleTypesSection().Data.empty() ||
+ !DwarfObj.getAppleNamespacesSection().Data.empty() ||
+ !DwarfObj.getAppleObjCSection().Data.empty())) {
+ AtLeastOneAppleAccelTable = true;
+ }
+
+ if (!AtLeastOneDwarfAccelTable &&
+ !DwarfObj.getDebugNamesSection().Data.empty()) {
+ AtLeastOneDwarfAccelTable = true;
+ }
+}
+
bool DwarfLinker::emitPaperTrailWarnings(const DebugMapObject &DMO,
const DebugMap &Map,
OffsetsStringPool &StringPool) {
@@ -2245,8 +2292,12 @@ bool DwarfLinker::link(const DebugMap &Map) {
unsigned NumObjects = Map.getNumberOfObjects();
std::vector<LinkContext> ObjectContexts;
ObjectContexts.reserve(NumObjects);
- for (const auto &Obj : Map.objects())
+ for (const auto &Obj : Map.objects()) {
ObjectContexts.emplace_back(Map, *this, *Obj.get());
+ LinkContext &LC = ObjectContexts.back();
+ if (LC.ObjectFile)
+ updateAccelKind(*LC.DwarfContext);
+ }
// This Dwarf string pool which is only used for uniquing. This one should
// never be used for offsets as its not thread-safe or predictable.
@@ -2260,6 +2311,19 @@ bool DwarfLinker::link(const DebugMap &Map) {
// ODR Contexts for the link.
DeclContextTree ODRContexts;
+ // If we haven't decided on an accelerator table kind yet, we base ourselves
+ // on the DWARF we have seen so far. At this point we haven't pulled in debug
+ // information from modules yet, so it is technically possible that they
+ // would affect the decision. However, as they're built with the same
+ // compiler and flags, it is safe to assume that they will follow the
+ // decision made here.
+ if (Options.TheAccelTableKind == AccelTableKind::Default) {
+ if (AtLeastOneDwarfAccelTable && !AtLeastOneAppleAccelTable)
+ Options.TheAccelTableKind = AccelTableKind::Dwarf;
+ else
+ Options.TheAccelTableKind = AccelTableKind::Apple;
+ }
+
for (LinkContext &LinkContext : ObjectContexts) {
if (Options.Verbose)
outs() << "DEBUG MAP OBJECT: " << LinkContext.DMO.getObjectFilename()
@@ -2325,7 +2389,9 @@ bool DwarfLinker::link(const DebugMap &Map) {
// In a first phase, just read in the debug info and load all clang modules.
LinkContext.CompileUnits.reserve(
LinkContext.DwarfContext->getNumCompileUnits());
+
for (const auto &CU : LinkContext.DwarfContext->compile_units()) {
+ updateDwarfVersion(CU->getVersion());
auto CUDie = CU->getUnitDIE(false);
if (Options.Verbose) {
outs() << "Input compilation unit:";
@@ -2341,13 +2407,11 @@ bool DwarfLinker::link(const DebugMap &Map) {
UniquingStringPool, ODRContexts, UnitID)) {
LinkContext.CompileUnits.push_back(llvm::make_unique<CompileUnit>(
*CU, UnitID++, !Options.NoODR && !Options.Update, ""));
- maybeUpdateMaxDwarfVersion(CU->getVersion());
}
}
}
- // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway,
- // to be able to emit papertrail warnings.
+ // If we haven't seen any CUs, pick an arbitrary valid Dwarf version anyway.
if (MaxDwarfVersion == 0)
MaxDwarfVersion = 3;
@@ -2444,10 +2508,20 @@ bool DwarfLinker::link(const DebugMap &Map) {
if (!Options.NoOutput) {
Streamer->emitAbbrevs(Abbreviations, MaxDwarfVersion);
Streamer->emitStrings(OffsetsStringPool);
- Streamer->emitAppleNames(AppleNames);
- Streamer->emitAppleNamespaces(AppleNamespaces);
- Streamer->emitAppleTypes(AppleTypes);
- Streamer->emitAppleObjc(AppleObjc);
+ switch (Options.TheAccelTableKind) {
+ case AccelTableKind::Apple:
+ Streamer->emitAppleNames(AppleNames);
+ Streamer->emitAppleNamespaces(AppleNamespaces);
+ Streamer->emitAppleTypes(AppleTypes);
+ Streamer->emitAppleObjc(AppleObjc);
+ break;
+ case AccelTableKind::Dwarf:
+ Streamer->emitDebugNames(DebugNames);
+ break;
+ case AccelTableKind::Default:
+ llvm_unreachable("Default should have already been resolved.");
+ break;
+ }
}
};
@@ -2465,7 +2539,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
}
return Options.NoOutput ? true : Streamer->finish(Map);
-}
+} // namespace dsymutil
bool linkDwarf(raw_fd_ostream &OutFile, BinaryHolder &BinHolder,
const DebugMap &DM, const LinkOptions &Options) {
OpenPOWER on IntegriCloud