blob: e44797d7bc4d32d754534492e2192eaed9e46879 [file] [log] [blame]
Frederic Riss231f7142014-12-12 17:31:24 +00001//===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include "DebugMap.h"
Frederic Rissd3455182015-01-28 18:27:01 +000010#include "BinaryHolder.h"
11#include "DebugMap.h"
Frederic Riss231f7142014-12-12 17:31:24 +000012#include "dsymutil.h"
Zachary Turner82af9432015-01-30 18:07:45 +000013#include "llvm/DebugInfo/DWARF/DWARFContext.h"
14#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
Frederic Riss1b9da422015-02-13 23:18:29 +000015#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
Frederic Riss1036e642015-02-13 23:18:22 +000016#include "llvm/Object/MachO.h"
Frederic Riss84c09a52015-02-13 23:18:34 +000017#include "llvm/Support/Dwarf.h"
18#include "llvm/Support/LEB128.h"
Frederic Rissd3455182015-01-28 18:27:01 +000019#include <string>
Frederic Riss231f7142014-12-12 17:31:24 +000020
21namespace llvm {
22namespace dsymutil {
23
Frederic Rissd3455182015-01-28 18:27:01 +000024namespace {
25
Frederic Rissdef4fb72015-02-28 00:29:01 +000026void warn(const Twine &Warning, const Twine &Context) {
27 errs() << Twine("while processing ") + Context + ":\n";
28 errs() << Twine("warning: ") + Warning + "\n";
29}
30
Frederic Riss563cba62015-01-28 22:15:14 +000031/// \brief Stores all information relating to a compile unit, be it in
32/// its original instance in the object file to its brand new cloned
33/// and linked DIE tree.
34class CompileUnit {
35public:
36 /// \brief Information gathered about a DIE in the object file.
37 struct DIEInfo {
Frederic Riss84c09a52015-02-13 23:18:34 +000038 uint64_t Address; ///< Linked address of the described entity.
39 uint32_t ParentIdx; ///< The index of this DIE's parent.
40 bool Keep; ///< Is the DIE part of the linked output?
41 bool InDebugMap; ///< Was this DIE's entity found in the map?
Frederic Riss563cba62015-01-28 22:15:14 +000042 };
43
44 CompileUnit(DWARFUnit &OrigUnit) : OrigUnit(OrigUnit) {
45 Info.resize(OrigUnit.getNumDIEs());
46 }
47
Frederic Rissc3349d42015-02-13 23:18:27 +000048 DWARFUnit &getOrigUnit() const { return OrigUnit; }
Frederic Riss563cba62015-01-28 22:15:14 +000049
50 DIEInfo &getInfo(unsigned Idx) { return Info[Idx]; }
51 const DIEInfo &getInfo(unsigned Idx) const { return Info[Idx]; }
52
53private:
54 DWARFUnit &OrigUnit;
55 std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index.
56};
57
Frederic Rissd3455182015-01-28 18:27:01 +000058/// \brief The core of the Dwarf linking logic.
Frederic Riss1036e642015-02-13 23:18:22 +000059///
60/// The link of the dwarf information from the object files will be
61/// driven by the selection of 'root DIEs', which are DIEs that
62/// describe variables or functions that are present in the linked
63/// binary (and thus have entries in the debug map). All the debug
64/// information that will be linked (the DIEs, but also the line
65/// tables, ranges, ...) is derived from that set of root DIEs.
66///
67/// The root DIEs are identified because they contain relocations that
68/// correspond to a debug map entry at specific places (the low_pc for
69/// a function, the location for a variable). These relocations are
70/// called ValidRelocs in the DwarfLinker and are gathered as a very
71/// first step when we start processing a DebugMapObject.
Frederic Rissd3455182015-01-28 18:27:01 +000072class DwarfLinker {
73public:
Frederic Rissb9818322015-02-28 00:29:07 +000074 DwarfLinker(StringRef OutputFilename, const LinkOptions &Options)
75 : OutputFilename(OutputFilename), Options(Options),
76 BinHolder(Options.Verbose) {}
Frederic Rissd3455182015-01-28 18:27:01 +000077
78 /// \brief Link the contents of the DebugMap.
79 bool link(const DebugMap &);
80
81private:
Frederic Riss563cba62015-01-28 22:15:14 +000082 /// \brief Called at the start of a debug object link.
83 void startDebugObject(DWARFContext &);
84
85 /// \brief Called at the end of a debug object link.
86 void endDebugObject();
87
Frederic Riss1036e642015-02-13 23:18:22 +000088 /// \defgroup FindValidRelocations Translate debug map into a list
89 /// of relevant relocations
90 ///
91 /// @{
92 struct ValidReloc {
93 uint32_t Offset;
94 uint32_t Size;
95 uint64_t Addend;
96 const DebugMapObject::DebugMapEntry *Mapping;
97
98 ValidReloc(uint32_t Offset, uint32_t Size, uint64_t Addend,
99 const DebugMapObject::DebugMapEntry *Mapping)
100 : Offset(Offset), Size(Size), Addend(Addend), Mapping(Mapping) {}
101
102 bool operator<(const ValidReloc &RHS) const { return Offset < RHS.Offset; }
103 };
104
105 /// \brief The valid relocations for the current DebugMapObject.
106 /// This vector is sorted by relocation offset.
107 std::vector<ValidReloc> ValidRelocs;
108
109 /// \brief Index into ValidRelocs of the next relocation to
110 /// consider. As we walk the DIEs in acsending file offset and as
111 /// ValidRelocs is sorted by file offset, keeping this index
112 /// uptodate is all we have to do to have a cheap lookup during the
113 /// root DIE selection.
114 unsigned NextValidReloc;
115
116 bool findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
117 const DebugMapObject &DMO);
118
119 bool findValidRelocs(const object::SectionRef &Section,
120 const object::ObjectFile &Obj,
121 const DebugMapObject &DMO);
122
123 void findValidRelocsMachO(const object::SectionRef &Section,
124 const object::MachOObjectFile &Obj,
125 const DebugMapObject &DMO);
126 /// @}
Frederic Riss1b9da422015-02-13 23:18:29 +0000127
Frederic Riss84c09a52015-02-13 23:18:34 +0000128 /// \defgroup FindRootDIEs Find DIEs corresponding to debug map entries.
129 ///
130 /// @{
131 /// \brief Recursively walk the \p DIE tree and look for DIEs to
132 /// keep. Store that information in \p CU's DIEInfo.
133 void lookForDIEsToKeep(const DWARFDebugInfoEntryMinimal &DIE,
134 const DebugMapObject &DMO, CompileUnit &CU,
135 unsigned Flags);
136
137 /// \brief Flags passed to DwarfLinker::lookForDIEsToKeep
138 enum TravesalFlags {
139 TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
140 TF_InFunctionScope = 1 << 1, ///< Current scope is a fucntion scope.
141 TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
142 TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
143 };
144
145 /// \brief Mark the passed DIE as well as all the ones it depends on
146 /// as kept.
147 void keepDIEAndDenpendencies(const DWARFDebugInfoEntryMinimal &DIE,
148 CompileUnit::DIEInfo &MyInfo,
149 const DebugMapObject &DMO, CompileUnit &CU,
150 unsigned Flags);
151
152 unsigned shouldKeepDIE(const DWARFDebugInfoEntryMinimal &DIE,
153 CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
154 unsigned Flags);
155
156 unsigned shouldKeepVariableDIE(const DWARFDebugInfoEntryMinimal &DIE,
157 CompileUnit &Unit,
158 CompileUnit::DIEInfo &MyInfo, unsigned Flags);
159
160 unsigned shouldKeepSubprogramDIE(const DWARFDebugInfoEntryMinimal &DIE,
161 CompileUnit &Unit,
162 CompileUnit::DIEInfo &MyInfo,
163 unsigned Flags);
164
165 bool hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
166 CompileUnit::DIEInfo &Info);
167 /// @}
168
Frederic Riss1b9da422015-02-13 23:18:29 +0000169 /// \defgroup Helpers Various helper methods.
170 ///
171 /// @{
172 const DWARFDebugInfoEntryMinimal *
173 resolveDIEReference(DWARFFormValue &RefValue, const DWARFUnit &Unit,
174 const DWARFDebugInfoEntryMinimal &DIE,
175 CompileUnit *&ReferencedCU);
176
177 CompileUnit *getUnitForOffset(unsigned Offset);
178
179 void reportWarning(const Twine &Warning, const DWARFUnit *Unit = nullptr,
180 const DWARFDebugInfoEntryMinimal *DIE = nullptr);
181 /// @}
182
Frederic Riss563cba62015-01-28 22:15:14 +0000183private:
Frederic Rissd3455182015-01-28 18:27:01 +0000184 std::string OutputFilename;
Frederic Rissb9818322015-02-28 00:29:07 +0000185 LinkOptions Options;
Frederic Rissd3455182015-01-28 18:27:01 +0000186 BinaryHolder BinHolder;
Frederic Riss563cba62015-01-28 22:15:14 +0000187
188 /// The units of the current debug map object.
189 std::vector<CompileUnit> Units;
Frederic Riss1b9da422015-02-13 23:18:29 +0000190
191 /// The debug map object curently under consideration.
192 DebugMapObject *CurrentDebugObject;
Frederic Rissd3455182015-01-28 18:27:01 +0000193};
194
Frederic Riss1b9da422015-02-13 23:18:29 +0000195/// \brief Similar to DWARFUnitSection::getUnitForOffset(), but
196/// returning our CompileUnit object instead.
197CompileUnit *DwarfLinker::getUnitForOffset(unsigned Offset) {
198 auto CU =
199 std::upper_bound(Units.begin(), Units.end(), Offset,
200 [](uint32_t LHS, const CompileUnit &RHS) {
201 return LHS < RHS.getOrigUnit().getNextUnitOffset();
202 });
203 return CU != Units.end() ? &*CU : nullptr;
204}
205
206/// \brief Resolve the DIE attribute reference that has been
207/// extracted in \p RefValue. The resulting DIE migh be in another
208/// CompileUnit which is stored into \p ReferencedCU.
209/// \returns null if resolving fails for any reason.
210const DWARFDebugInfoEntryMinimal *DwarfLinker::resolveDIEReference(
211 DWARFFormValue &RefValue, const DWARFUnit &Unit,
212 const DWARFDebugInfoEntryMinimal &DIE, CompileUnit *&RefCU) {
213 assert(RefValue.isFormClass(DWARFFormValue::FC_Reference));
214 uint64_t RefOffset = *RefValue.getAsReference(&Unit);
215
216 if ((RefCU = getUnitForOffset(RefOffset)))
217 if (const auto *RefDie = RefCU->getOrigUnit().getDIEForOffset(RefOffset))
218 return RefDie;
219
220 reportWarning("could not find referenced DIE", &Unit, &DIE);
221 return nullptr;
222}
223
224/// \brief Report a warning to the user, optionaly including
225/// information about a specific \p DIE related to the warning.
226void DwarfLinker::reportWarning(const Twine &Warning, const DWARFUnit *Unit,
227 const DWARFDebugInfoEntryMinimal *DIE) {
Frederic Rissdef4fb72015-02-28 00:29:01 +0000228 StringRef Context = "<debug map>";
Frederic Riss1b9da422015-02-13 23:18:29 +0000229 if (CurrentDebugObject)
Frederic Rissdef4fb72015-02-28 00:29:01 +0000230 Context = CurrentDebugObject->getObjectFilename();
231 warn(Warning, Context);
Frederic Riss1b9da422015-02-13 23:18:29 +0000232
Frederic Rissb9818322015-02-28 00:29:07 +0000233 if (!Options.Verbose || !DIE)
Frederic Riss1b9da422015-02-13 23:18:29 +0000234 return;
235
236 errs() << " in DIE:\n";
237 DIE->dump(errs(), const_cast<DWARFUnit *>(Unit), 0 /* RecurseDepth */,
238 6 /* Indent */);
239}
240
Frederic Riss563cba62015-01-28 22:15:14 +0000241/// \brief Recursive helper to gather the child->parent relationships in the
242/// original compile unit.
Frederic Riss9aa725b2015-02-13 23:18:31 +0000243static void gatherDIEParents(const DWARFDebugInfoEntryMinimal *DIE,
244 unsigned ParentIdx, CompileUnit &CU) {
Frederic Riss563cba62015-01-28 22:15:14 +0000245 unsigned MyIdx = CU.getOrigUnit().getDIEIndex(DIE);
246 CU.getInfo(MyIdx).ParentIdx = ParentIdx;
247
248 if (DIE->hasChildren())
249 for (auto *Child = DIE->getFirstChild(); Child && !Child->isNULL();
250 Child = Child->getSibling())
Frederic Riss9aa725b2015-02-13 23:18:31 +0000251 gatherDIEParents(Child, MyIdx, CU);
Frederic Riss563cba62015-01-28 22:15:14 +0000252}
253
Frederic Riss84c09a52015-02-13 23:18:34 +0000254static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) {
255 switch (Tag) {
256 default:
257 return false;
258 case dwarf::DW_TAG_subprogram:
259 case dwarf::DW_TAG_lexical_block:
260 case dwarf::DW_TAG_subroutine_type:
261 case dwarf::DW_TAG_structure_type:
262 case dwarf::DW_TAG_class_type:
263 case dwarf::DW_TAG_union_type:
264 return true;
265 }
266 llvm_unreachable("Invalid Tag");
267}
268
Frederic Riss563cba62015-01-28 22:15:14 +0000269void DwarfLinker::startDebugObject(DWARFContext &Dwarf) {
270 Units.reserve(Dwarf.getNumCompileUnits());
Frederic Riss1036e642015-02-13 23:18:22 +0000271 NextValidReloc = 0;
Frederic Riss563cba62015-01-28 22:15:14 +0000272}
273
Frederic Riss1036e642015-02-13 23:18:22 +0000274void DwarfLinker::endDebugObject() {
275 Units.clear();
276 ValidRelocs.clear();
277}
278
279/// \brief Iterate over the relocations of the given \p Section and
280/// store the ones that correspond to debug map entries into the
281/// ValidRelocs array.
282void DwarfLinker::findValidRelocsMachO(const object::SectionRef &Section,
283 const object::MachOObjectFile &Obj,
284 const DebugMapObject &DMO) {
285 StringRef Contents;
286 Section.getContents(Contents);
287 DataExtractor Data(Contents, Obj.isLittleEndian(), 0);
288
289 for (const object::RelocationRef &Reloc : Section.relocations()) {
290 object::DataRefImpl RelocDataRef = Reloc.getRawDataRefImpl();
291 MachO::any_relocation_info MachOReloc = Obj.getRelocation(RelocDataRef);
292 unsigned RelocSize = 1 << Obj.getAnyRelocationLength(MachOReloc);
293 uint64_t Offset64;
294 if ((RelocSize != 4 && RelocSize != 8) || Reloc.getOffset(Offset64)) {
Frederic Riss1b9da422015-02-13 23:18:29 +0000295 reportWarning(" unsupported relocation in debug_info section.");
Frederic Riss1036e642015-02-13 23:18:22 +0000296 continue;
297 }
298 uint32_t Offset = Offset64;
299 // Mach-o uses REL relocations, the addend is at the relocation offset.
300 uint64_t Addend = Data.getUnsigned(&Offset, RelocSize);
301
302 auto Sym = Reloc.getSymbol();
303 if (Sym != Obj.symbol_end()) {
304 StringRef SymbolName;
305 if (Sym->getName(SymbolName)) {
Frederic Riss1b9da422015-02-13 23:18:29 +0000306 reportWarning("error getting relocation symbol name.");
Frederic Riss1036e642015-02-13 23:18:22 +0000307 continue;
308 }
309 if (const auto *Mapping = DMO.lookupSymbol(SymbolName))
310 ValidRelocs.emplace_back(Offset64, RelocSize, Addend, Mapping);
311 } else if (const auto *Mapping = DMO.lookupObjectAddress(Addend)) {
312 // Do not store the addend. The addend was the address of the
313 // symbol in the object file, the address in the binary that is
314 // stored in the debug map doesn't need to be offseted.
315 ValidRelocs.emplace_back(Offset64, RelocSize, 0, Mapping);
316 }
317 }
318}
319
320/// \brief Dispatch the valid relocation finding logic to the
321/// appropriate handler depending on the object file format.
322bool DwarfLinker::findValidRelocs(const object::SectionRef &Section,
323 const object::ObjectFile &Obj,
324 const DebugMapObject &DMO) {
325 // Dispatch to the right handler depending on the file type.
326 if (auto *MachOObj = dyn_cast<object::MachOObjectFile>(&Obj))
327 findValidRelocsMachO(Section, *MachOObj, DMO);
328 else
Frederic Riss1b9da422015-02-13 23:18:29 +0000329 reportWarning(Twine("unsupported object file type: ") + Obj.getFileName());
Frederic Riss1036e642015-02-13 23:18:22 +0000330
331 if (ValidRelocs.empty())
332 return false;
333
334 // Sort the relocations by offset. We will walk the DIEs linearly in
335 // the file, this allows us to just keep an index in the relocation
336 // array that we advance during our walk, rather than resorting to
337 // some associative container. See DwarfLinker::NextValidReloc.
338 std::sort(ValidRelocs.begin(), ValidRelocs.end());
339 return true;
340}
341
342/// \brief Look for relocations in the debug_info section that match
343/// entries in the debug map. These relocations will drive the Dwarf
344/// link by indicating which DIEs refer to symbols present in the
345/// linked binary.
346/// \returns wether there are any valid relocations in the debug info.
347bool DwarfLinker::findValidRelocsInDebugInfo(const object::ObjectFile &Obj,
348 const DebugMapObject &DMO) {
349 // Find the debug_info section.
350 for (const object::SectionRef &Section : Obj.sections()) {
351 StringRef SectionName;
352 Section.getName(SectionName);
353 SectionName = SectionName.substr(SectionName.find_first_not_of("._"));
354 if (SectionName != "debug_info")
355 continue;
356 return findValidRelocs(Section, Obj, DMO);
357 }
358 return false;
359}
Frederic Riss563cba62015-01-28 22:15:14 +0000360
Frederic Riss84c09a52015-02-13 23:18:34 +0000361/// \brief Checks that there is a relocation against an actual debug
362/// map entry between \p StartOffset and \p NextOffset.
363///
364/// This function must be called with offsets in strictly ascending
365/// order because it never looks back at relocations it already 'went past'.
366/// \returns true and sets Info.InDebugMap if it is the case.
367bool DwarfLinker::hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset,
368 CompileUnit::DIEInfo &Info) {
369 assert(NextValidReloc == 0 ||
370 StartOffset > ValidRelocs[NextValidReloc - 1].Offset);
371 if (NextValidReloc >= ValidRelocs.size())
372 return false;
373
374 uint64_t RelocOffset = ValidRelocs[NextValidReloc].Offset;
375
376 // We might need to skip some relocs that we didn't consider. For
377 // example the high_pc of a discarded DIE might contain a reloc that
378 // is in the list because it actually corresponds to the start of a
379 // function that is in the debug map.
380 while (RelocOffset < StartOffset && NextValidReloc < ValidRelocs.size() - 1)
381 RelocOffset = ValidRelocs[++NextValidReloc].Offset;
382
383 if (RelocOffset < StartOffset || RelocOffset >= EndOffset)
384 return false;
385
386 const auto &ValidReloc = ValidRelocs[NextValidReloc++];
Frederic Rissb9818322015-02-28 00:29:07 +0000387 if (Options.Verbose)
Frederic Riss84c09a52015-02-13 23:18:34 +0000388 outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey()
389 << " " << format("\t%016" PRIx64 " => %016" PRIx64,
390 ValidReloc.Mapping->getValue().ObjectAddress,
391 ValidReloc.Mapping->getValue().BinaryAddress);
392
393 Info.Address =
394 ValidReloc.Mapping->getValue().BinaryAddress + ValidReloc.Addend;
395 Info.InDebugMap = true;
396 return true;
397}
398
399/// \brief Get the starting and ending (exclusive) offset for the
400/// attribute with index \p Idx descibed by \p Abbrev. \p Offset is
401/// supposed to point to the position of the first attribute described
402/// by \p Abbrev.
403/// \return [StartOffset, EndOffset) as a pair.
404static std::pair<uint32_t, uint32_t>
405getAttributeOffsets(const DWARFAbbreviationDeclaration *Abbrev, unsigned Idx,
406 unsigned Offset, const DWARFUnit &Unit) {
407 DataExtractor Data = Unit.getDebugInfoExtractor();
408
409 for (unsigned i = 0; i < Idx; ++i)
410 DWARFFormValue::skipValue(Abbrev->getFormByIndex(i), Data, &Offset, &Unit);
411
412 uint32_t End = Offset;
413 DWARFFormValue::skipValue(Abbrev->getFormByIndex(Idx), Data, &End, &Unit);
414
415 return std::make_pair(Offset, End);
416}
417
418/// \brief Check if a variable describing DIE should be kept.
419/// \returns updated TraversalFlags.
420unsigned DwarfLinker::shouldKeepVariableDIE(
421 const DWARFDebugInfoEntryMinimal &DIE, CompileUnit &Unit,
422 CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
423 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
424
425 // Global variables with constant value can always be kept.
426 if (!(Flags & TF_InFunctionScope) &&
427 Abbrev->findAttributeIndex(dwarf::DW_AT_const_value) != -1U) {
428 MyInfo.InDebugMap = true;
429 return Flags | TF_Keep;
430 }
431
432 uint32_t LocationIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_location);
433 if (LocationIdx == -1U)
434 return Flags;
435
436 uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
437 const DWARFUnit &OrigUnit = Unit.getOrigUnit();
438 uint32_t LocationOffset, LocationEndOffset;
439 std::tie(LocationOffset, LocationEndOffset) =
440 getAttributeOffsets(Abbrev, LocationIdx, Offset, OrigUnit);
441
442 // See if there is a relocation to a valid debug map entry inside
443 // this variable's location. The order is important here. We want to
444 // always check in the variable has a valid relocation, so that the
445 // DIEInfo is filled. However, we don't want a static variable in a
446 // function to force us to keep the enclosing function.
447 if (!hasValidRelocation(LocationOffset, LocationEndOffset, MyInfo) ||
448 (Flags & TF_InFunctionScope))
449 return Flags;
450
Frederic Rissb9818322015-02-28 00:29:07 +0000451 if (Options.Verbose)
Frederic Riss84c09a52015-02-13 23:18:34 +0000452 DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */);
453
454 return Flags | TF_Keep;
455}
456
457/// \brief Check if a function describing DIE should be kept.
458/// \returns updated TraversalFlags.
459unsigned DwarfLinker::shouldKeepSubprogramDIE(
460 const DWARFDebugInfoEntryMinimal &DIE, CompileUnit &Unit,
461 CompileUnit::DIEInfo &MyInfo, unsigned Flags) {
462 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
463
464 Flags |= TF_InFunctionScope;
465
466 uint32_t LowPcIdx = Abbrev->findAttributeIndex(dwarf::DW_AT_low_pc);
467 if (LowPcIdx == -1U)
468 return Flags;
469
470 uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
471 const DWARFUnit &OrigUnit = Unit.getOrigUnit();
472 uint32_t LowPcOffset, LowPcEndOffset;
473 std::tie(LowPcOffset, LowPcEndOffset) =
474 getAttributeOffsets(Abbrev, LowPcIdx, Offset, OrigUnit);
475
476 uint64_t LowPc =
477 DIE.getAttributeValueAsAddress(&OrigUnit, dwarf::DW_AT_low_pc, -1ULL);
478 assert(LowPc != -1ULL && "low_pc attribute is not an address.");
479 if (LowPc == -1ULL ||
480 !hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo))
481 return Flags;
482
Frederic Rissb9818322015-02-28 00:29:07 +0000483 if (Options.Verbose)
Frederic Riss84c09a52015-02-13 23:18:34 +0000484 DIE.dump(outs(), const_cast<DWARFUnit *>(&OrigUnit), 0, 8 /* Indent */);
485
486 return Flags | TF_Keep;
487}
488
489/// \brief Check if a DIE should be kept.
490/// \returns updated TraversalFlags.
491unsigned DwarfLinker::shouldKeepDIE(const DWARFDebugInfoEntryMinimal &DIE,
492 CompileUnit &Unit,
493 CompileUnit::DIEInfo &MyInfo,
494 unsigned Flags) {
495 switch (DIE.getTag()) {
496 case dwarf::DW_TAG_constant:
497 case dwarf::DW_TAG_variable:
498 return shouldKeepVariableDIE(DIE, Unit, MyInfo, Flags);
499 case dwarf::DW_TAG_subprogram:
500 return shouldKeepSubprogramDIE(DIE, Unit, MyInfo, Flags);
501 case dwarf::DW_TAG_module:
502 case dwarf::DW_TAG_imported_module:
503 case dwarf::DW_TAG_imported_declaration:
504 case dwarf::DW_TAG_imported_unit:
505 // We always want to keep these.
506 return Flags | TF_Keep;
507 }
508
509 return Flags;
510}
511
512
513/// \brief Mark the passed DIE as well as all the ones it depends on
514/// as kept.
515///
516/// This function is called by lookForDIEsToKeep on DIEs that are
517/// newly discovered to be needed in the link. It recursively calls
518/// back to lookForDIEsToKeep while adding TF_DependencyWalk to the
519/// TraversalFlags to inform it that it's not doing the primary DIE
520/// tree walk.
521void DwarfLinker::keepDIEAndDenpendencies(const DWARFDebugInfoEntryMinimal &DIE,
522 CompileUnit::DIEInfo &MyInfo,
523 const DebugMapObject &DMO,
524 CompileUnit &CU, unsigned Flags) {
525 const DWARFUnit &Unit = CU.getOrigUnit();
526 MyInfo.Keep = true;
527
528 // First mark all the parent chain as kept.
529 unsigned AncestorIdx = MyInfo.ParentIdx;
530 while (!CU.getInfo(AncestorIdx).Keep) {
531 lookForDIEsToKeep(*Unit.getDIEAtIndex(AncestorIdx), DMO, CU,
532 TF_ParentWalk | TF_Keep | TF_DependencyWalk);
533 AncestorIdx = CU.getInfo(AncestorIdx).ParentIdx;
534 }
535
536 // Then we need to mark all the DIEs referenced by this DIE's
537 // attributes as kept.
538 DataExtractor Data = Unit.getDebugInfoExtractor();
539 const auto *Abbrev = DIE.getAbbreviationDeclarationPtr();
540 uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode());
541
542 // Mark all DIEs referenced through atttributes as kept.
543 for (const auto &AttrSpec : Abbrev->attributes()) {
544 DWARFFormValue Val(AttrSpec.Form);
545
546 if (!Val.isFormClass(DWARFFormValue::FC_Reference)) {
547 DWARFFormValue::skipValue(AttrSpec.Form, Data, &Offset, &Unit);
548 continue;
549 }
550
551 Val.extractValue(Data, &Offset, &Unit);
552 CompileUnit *ReferencedCU;
553 if (const auto *RefDIE = resolveDIEReference(Val, Unit, DIE, ReferencedCU))
554 lookForDIEsToKeep(*RefDIE, DMO, *ReferencedCU,
555 TF_Keep | TF_DependencyWalk);
556 }
557}
558
559/// \brief Recursively walk the \p DIE tree and look for DIEs to
560/// keep. Store that information in \p CU's DIEInfo.
561///
562/// This function is the entry point of the DIE selection
563/// algorithm. It is expected to walk the DIE tree in file order and
564/// (though the mediation of its helper) call hasValidRelocation() on
565/// each DIE that might be a 'root DIE' (See DwarfLinker class
566/// comment).
567/// While walking the dependencies of root DIEs, this function is
568/// also called, but during these dependency walks the file order is
569/// not respected. The TF_DependencyWalk flag tells us which kind of
570/// traversal we are currently doing.
571void DwarfLinker::lookForDIEsToKeep(const DWARFDebugInfoEntryMinimal &DIE,
572 const DebugMapObject &DMO, CompileUnit &CU,
573 unsigned Flags) {
574 unsigned Idx = CU.getOrigUnit().getDIEIndex(&DIE);
575 CompileUnit::DIEInfo &MyInfo = CU.getInfo(Idx);
576 bool AlreadyKept = MyInfo.Keep;
577
578 // If the Keep flag is set, we are marking a required DIE's
579 // dependencies. If our target is already marked as kept, we're all
580 // set.
581 if ((Flags & TF_DependencyWalk) && AlreadyKept)
582 return;
583
584 // We must not call shouldKeepDIE while called from keepDIEAndDenpendencies,
585 // because it would screw up the relocation finding logic.
586 if (!(Flags & TF_DependencyWalk))
587 Flags = shouldKeepDIE(DIE, CU, MyInfo, Flags);
588
589 // If it is a newly kept DIE mark it as well as all its dependencies as kept.
590 if (!AlreadyKept && (Flags & TF_Keep))
591 keepDIEAndDenpendencies(DIE, MyInfo, DMO, CU, Flags);
592
593 // The TF_ParentWalk flag tells us that we are currently walking up
594 // the parent chain of a required DIE, and we don't want to mark all
595 // the children of the parents as kept (consider for example a
596 // DW_TAG_namespace node in the parent chain). There are however a
597 // set of DIE types for which we want to ignore that directive and still
598 // walk their children.
599 if (dieNeedsChildrenToBeMeaningful(DIE.getTag()))
600 Flags &= ~TF_ParentWalk;
601
602 if (!DIE.hasChildren() || (Flags & TF_ParentWalk))
603 return;
604
605 for (auto *Child = DIE.getFirstChild(); Child && !Child->isNULL();
606 Child = Child->getSibling())
607 lookForDIEsToKeep(*Child, DMO, CU, Flags);
608}
609
Frederic Rissd3455182015-01-28 18:27:01 +0000610bool DwarfLinker::link(const DebugMap &Map) {
611
612 if (Map.begin() == Map.end()) {
613 errs() << "Empty debug map.\n";
614 return false;
615 }
616
617 for (const auto &Obj : Map.objects()) {
Frederic Riss1b9da422015-02-13 23:18:29 +0000618 CurrentDebugObject = Obj.get();
619
Frederic Rissb9818322015-02-28 00:29:07 +0000620 if (Options.Verbose)
Frederic Rissd3455182015-01-28 18:27:01 +0000621 outs() << "DEBUG MAP OBJECT: " << Obj->getObjectFilename() << "\n";
622 auto ErrOrObj = BinHolder.GetObjectFile(Obj->getObjectFilename());
623 if (std::error_code EC = ErrOrObj.getError()) {
Frederic Riss1b9da422015-02-13 23:18:29 +0000624 reportWarning(Twine(Obj->getObjectFilename()) + ": " + EC.message());
Frederic Rissd3455182015-01-28 18:27:01 +0000625 continue;
626 }
627
Frederic Riss1036e642015-02-13 23:18:22 +0000628 // Look for relocations that correspond to debug map entries.
629 if (!findValidRelocsInDebugInfo(*ErrOrObj, *Obj)) {
Frederic Rissb9818322015-02-28 00:29:07 +0000630 if (Options.Verbose)
Frederic Riss1036e642015-02-13 23:18:22 +0000631 outs() << "No valid relocations found. Skipping.\n";
632 continue;
633 }
634
Frederic Riss563cba62015-01-28 22:15:14 +0000635 // Setup access to the debug info.
Frederic Rissd3455182015-01-28 18:27:01 +0000636 DWARFContextInMemory DwarfContext(*ErrOrObj);
Frederic Riss563cba62015-01-28 22:15:14 +0000637 startDebugObject(DwarfContext);
Frederic Rissd3455182015-01-28 18:27:01 +0000638
Frederic Riss563cba62015-01-28 22:15:14 +0000639 // In a first phase, just read in the debug info and store the DIE
640 // parent links that we will use during the next phase.
Frederic Rissd3455182015-01-28 18:27:01 +0000641 for (const auto &CU : DwarfContext.compile_units()) {
642 auto *CUDie = CU->getCompileUnitDIE(false);
Frederic Rissb9818322015-02-28 00:29:07 +0000643 if (Options.Verbose) {
Frederic Rissd3455182015-01-28 18:27:01 +0000644 outs() << "Input compilation unit:";
645 CUDie->dump(outs(), CU.get(), 0);
646 }
Frederic Riss563cba62015-01-28 22:15:14 +0000647 Units.emplace_back(*CU);
Frederic Riss9aa725b2015-02-13 23:18:31 +0000648 gatherDIEParents(CUDie, 0, Units.back());
Frederic Rissd3455182015-01-28 18:27:01 +0000649 }
Frederic Riss563cba62015-01-28 22:15:14 +0000650
Frederic Riss84c09a52015-02-13 23:18:34 +0000651 // Then mark all the DIEs that need to be present in the linked
652 // output and collect some information about them. Note that this
653 // loop can not be merged with the previous one becaue cross-cu
654 // references require the ParentIdx to be setup for every CU in
655 // the object file before calling this.
656 for (auto &CurrentUnit : Units)
657 lookForDIEsToKeep(*CurrentUnit.getOrigUnit().getCompileUnitDIE(), *Obj,
658 CurrentUnit, 0);
659
Frederic Riss563cba62015-01-28 22:15:14 +0000660 // Clean-up before starting working on the next object.
661 endDebugObject();
Frederic Rissd3455182015-01-28 18:27:01 +0000662 }
663
Frederic Riss231f7142014-12-12 17:31:24 +0000664 return true;
665}
666}
Frederic Rissd3455182015-01-28 18:27:01 +0000667
Frederic Rissb9818322015-02-28 00:29:07 +0000668bool linkDwarf(StringRef OutputFilename, const DebugMap &DM,
669 const LinkOptions &Options) {
670 DwarfLinker Linker(OutputFilename, Options);
Frederic Rissd3455182015-01-28 18:27:01 +0000671 return Linker.link(DM);
672}
673}
Frederic Riss231f7142014-12-12 17:31:24 +0000674}