1 //=== DWARFLinkerImpl.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "DWARFLinkerImpl.h"
10 #include "DIEGenerator.h"
11 #include "DependencyTracker.h"
12 #include "llvm/DWARFLinker/Utils.h"
13 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
14 #include "llvm/Support/FormatVariadic.h"
15 #include "llvm/Support/Parallel.h"
16 #include "llvm/Support/ThreadPool.h"
17
18 using namespace llvm;
19 using namespace dwarf_linker;
20 using namespace dwarf_linker::parallel;
21
DWARFLinkerImpl(MessageHandlerTy ErrorHandler,MessageHandlerTy WarningHandler,TranslatorFuncTy StringsTranslator)22 DWARFLinkerImpl::DWARFLinkerImpl(MessageHandlerTy ErrorHandler,
23 MessageHandlerTy WarningHandler,
24 TranslatorFuncTy StringsTranslator)
25 : UniqueUnitID(0), DebugStrStrings(GlobalData),
26 DebugLineStrStrings(GlobalData), CommonSections(GlobalData) {
27 GlobalData.setTranslator(StringsTranslator);
28 GlobalData.setErrorHandler(ErrorHandler);
29 GlobalData.setWarningHandler(WarningHandler);
30 }
31
LinkContext(LinkingGlobalData & GlobalData,DWARFFile & File,StringMap<uint64_t> & ClangModules,std::atomic<size_t> & UniqueUnitID)32 DWARFLinkerImpl::LinkContext::LinkContext(LinkingGlobalData &GlobalData,
33 DWARFFile &File,
34 StringMap<uint64_t> &ClangModules,
35 std::atomic<size_t> &UniqueUnitID)
36 : OutputSections(GlobalData), InputDWARFFile(File),
37 ClangModules(ClangModules), UniqueUnitID(UniqueUnitID) {
38
39 if (File.Dwarf) {
40 if (!File.Dwarf->compile_units().empty())
41 CompileUnits.reserve(File.Dwarf->getNumCompileUnits());
42
43 // Set context format&endianness based on the input file.
44 Format.Version = File.Dwarf->getMaxVersion();
45 Format.AddrSize = File.Dwarf->getCUAddrSize();
46 Endianness = File.Dwarf->isLittleEndian() ? llvm::endianness::little
47 : llvm::endianness::big;
48 }
49 }
50
RefModuleUnit(DWARFFile & File,std::unique_ptr<CompileUnit> Unit)51 DWARFLinkerImpl::LinkContext::RefModuleUnit::RefModuleUnit(
52 DWARFFile &File, std::unique_ptr<CompileUnit> Unit)
53 : File(File), Unit(std::move(Unit)) {}
54
RefModuleUnit(LinkContext::RefModuleUnit && Other)55 DWARFLinkerImpl::LinkContext::RefModuleUnit::RefModuleUnit(
56 LinkContext::RefModuleUnit &&Other)
57 : File(Other.File), Unit(std::move(Other.Unit)) {}
58
addModulesCompileUnit(LinkContext::RefModuleUnit && Unit)59 void DWARFLinkerImpl::LinkContext::addModulesCompileUnit(
60 LinkContext::RefModuleUnit &&Unit) {
61 ModulesCompileUnits.emplace_back(std::move(Unit));
62 }
63
addObjectFile(DWARFFile & File,ObjFileLoaderTy Loader,CompileUnitHandlerTy OnCUDieLoaded)64 void DWARFLinkerImpl::addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader,
65 CompileUnitHandlerTy OnCUDieLoaded) {
66 ObjectContexts.emplace_back(std::make_unique<LinkContext>(
67 GlobalData, File, ClangModules, UniqueUnitID));
68
69 if (ObjectContexts.back()->InputDWARFFile.Dwarf) {
70 for (const std::unique_ptr<DWARFUnit> &CU :
71 ObjectContexts.back()->InputDWARFFile.Dwarf->compile_units()) {
72 DWARFDie CUDie = CU->getUnitDIE();
73 OverallNumberOfCU++;
74
75 if (!CUDie)
76 continue;
77
78 OnCUDieLoaded(*CU);
79
80 // Register mofule reference.
81 if (!GlobalData.getOptions().UpdateIndexTablesOnly)
82 ObjectContexts.back()->registerModuleReference(CUDie, Loader,
83 OnCUDieLoaded);
84 }
85 }
86 }
87
setEstimatedObjfilesAmount(unsigned ObjFilesNum)88 void DWARFLinkerImpl::setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
89 ObjectContexts.reserve(ObjFilesNum);
90 }
91
link()92 Error DWARFLinkerImpl::link() {
93 // reset compile unit unique ID counter.
94 UniqueUnitID = 0;
95
96 if (Error Err = validateAndUpdateOptions())
97 return Err;
98
99 dwarf::FormParams GlobalFormat = {GlobalData.getOptions().TargetDWARFVersion,
100 0, dwarf::DwarfFormat::DWARF32};
101 llvm::endianness GlobalEndianness = llvm::endianness::native;
102
103 if (std::optional<std::reference_wrapper<const Triple>> CurTriple =
104 GlobalData.getTargetTriple()) {
105 GlobalEndianness = (*CurTriple).get().isLittleEndian()
106 ? llvm::endianness::little
107 : llvm::endianness::big;
108 }
109 std::optional<uint16_t> Language;
110
111 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) {
112 if (Context->InputDWARFFile.Dwarf.get() == nullptr) {
113 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness);
114 continue;
115 }
116
117 if (GlobalData.getOptions().Verbose) {
118 outs() << "DEBUG MAP OBJECT: " << Context->InputDWARFFile.FileName
119 << "\n";
120
121 for (const std::unique_ptr<DWARFUnit> &OrigCU :
122 Context->InputDWARFFile.Dwarf->compile_units()) {
123 outs() << "Input compilation unit:";
124 DIDumpOptions DumpOpts;
125 DumpOpts.ChildRecurseDepth = 0;
126 DumpOpts.Verbose = GlobalData.getOptions().Verbose;
127 OrigCU->getUnitDIE().dump(outs(), 0, DumpOpts);
128 }
129 }
130
131 // Verify input DWARF if requested.
132 if (GlobalData.getOptions().VerifyInputDWARF)
133 verifyInput(Context->InputDWARFFile);
134
135 if (!GlobalData.getTargetTriple())
136 GlobalEndianness = Context->getEndianness();
137 GlobalFormat.AddrSize =
138 std::max(GlobalFormat.AddrSize, Context->getFormParams().AddrSize);
139
140 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness);
141
142 // FIXME: move creation of CompileUnits into the addObjectFile.
143 // This would allow to not scan for context Language and Modules state
144 // twice. And then following handling might be removed.
145 for (const std::unique_ptr<DWARFUnit> &OrigCU :
146 Context->InputDWARFFile.Dwarf->compile_units()) {
147 DWARFDie UnitDie = OrigCU.get()->getUnitDIE();
148
149 if (!Language) {
150 if (std::optional<DWARFFormValue> Val =
151 UnitDie.find(dwarf::DW_AT_language)) {
152 uint16_t LangVal = dwarf::toUnsigned(Val, 0);
153 if (isODRLanguage(LangVal))
154 Language = LangVal;
155 }
156 }
157 }
158 }
159
160 if (GlobalFormat.AddrSize == 0) {
161 if (std::optional<std::reference_wrapper<const Triple>> TargetTriple =
162 GlobalData.getTargetTriple())
163 GlobalFormat.AddrSize = (*TargetTriple).get().isArch32Bit() ? 4 : 8;
164 else
165 GlobalFormat.AddrSize = 8;
166 }
167
168 CommonSections.setOutputFormat(GlobalFormat, GlobalEndianness);
169
170 if (!GlobalData.Options.NoODR && Language.has_value()) {
171 llvm::parallel::TaskGroup TGroup;
172 TGroup.spawn([&]() {
173 ArtificialTypeUnit = std::make_unique<TypeUnit>(
174 GlobalData, UniqueUnitID++, Language, GlobalFormat, GlobalEndianness);
175 });
176 }
177
178 // Set parallel options.
179 if (GlobalData.getOptions().Threads == 0)
180 llvm::parallel::strategy = optimal_concurrency(OverallNumberOfCU);
181 else
182 llvm::parallel::strategy =
183 hardware_concurrency(GlobalData.getOptions().Threads);
184
185 // Link object files.
186 if (GlobalData.getOptions().Threads == 1) {
187 for (std::unique_ptr<LinkContext> &Context : ObjectContexts) {
188 // Link object file.
189 if (Error Err = Context->link(ArtificialTypeUnit.get()))
190 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
191
192 Context->InputDWARFFile.unload();
193 }
194 } else {
195 ThreadPool Pool(llvm::parallel::strategy);
196 for (std::unique_ptr<LinkContext> &Context : ObjectContexts)
197 Pool.async([&]() {
198 // Link object file.
199 if (Error Err = Context->link(ArtificialTypeUnit.get()))
200 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
201
202 Context->InputDWARFFile.unload();
203 });
204
205 Pool.wait();
206 }
207
208 if (ArtificialTypeUnit.get() != nullptr && !ArtificialTypeUnit->getTypePool()
209 .getRoot()
210 ->getValue()
211 .load()
212 ->Children.empty()) {
213 if (GlobalData.getTargetTriple().has_value())
214 if (Error Err = ArtificialTypeUnit.get()->finishCloningAndEmit(
215 (*GlobalData.getTargetTriple()).get()))
216 return Err;
217 }
218
219 // At this stage each compile units are cloned to their own set of debug
220 // sections. Now, update patches, assign offsets and assemble final file
221 // glueing debug tables from each compile unit.
222 glueCompileUnitsAndWriteToTheOutput();
223
224 return Error::success();
225 }
226
verifyInput(const DWARFFile & File)227 void DWARFLinkerImpl::verifyInput(const DWARFFile &File) {
228 assert(File.Dwarf);
229
230 std::string Buffer;
231 raw_string_ostream OS(Buffer);
232 DIDumpOptions DumpOpts;
233 if (!File.Dwarf->verify(OS, DumpOpts.noImplicitRecursion())) {
234 if (GlobalData.getOptions().InputVerificationHandler)
235 GlobalData.getOptions().InputVerificationHandler(File, OS.str());
236 }
237 }
238
validateAndUpdateOptions()239 Error DWARFLinkerImpl::validateAndUpdateOptions() {
240 if (GlobalData.getOptions().TargetDWARFVersion == 0)
241 return createStringError(std::errc::invalid_argument,
242 "target DWARF version is not set");
243
244 if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) {
245 GlobalData.Options.Threads = 1;
246 GlobalData.warn(
247 "set number of threads to 1 to make --verbose to work properly.", "");
248 }
249
250 // Do not do types deduplication in case --update.
251 if (GlobalData.getOptions().UpdateIndexTablesOnly &&
252 !GlobalData.Options.NoODR)
253 GlobalData.Options.NoODR = true;
254
255 return Error::success();
256 }
257
258 /// Resolve the relative path to a build artifact referenced by DWARF by
259 /// applying DW_AT_comp_dir.
resolveRelativeObjectPath(SmallVectorImpl<char> & Buf,DWARFDie CU)260 static void resolveRelativeObjectPath(SmallVectorImpl<char> &Buf, DWARFDie CU) {
261 sys::path::append(Buf, dwarf::toString(CU.find(dwarf::DW_AT_comp_dir), ""));
262 }
263
getDwoId(const DWARFDie & CUDie)264 static uint64_t getDwoId(const DWARFDie &CUDie) {
265 auto DwoId = dwarf::toUnsigned(
266 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
267 if (DwoId)
268 return *DwoId;
269 return 0;
270 }
271
272 static std::string
remapPath(StringRef Path,const DWARFLinker::ObjectPrefixMapTy & ObjectPrefixMap)273 remapPath(StringRef Path,
274 const DWARFLinker::ObjectPrefixMapTy &ObjectPrefixMap) {
275 if (ObjectPrefixMap.empty())
276 return Path.str();
277
278 SmallString<256> p = Path;
279 for (const auto &Entry : ObjectPrefixMap)
280 if (llvm::sys::path::replace_path_prefix(p, Entry.first, Entry.second))
281 break;
282 return p.str().str();
283 }
284
getPCMFile(const DWARFDie & CUDie,DWARFLinker::ObjectPrefixMapTy * ObjectPrefixMap)285 static std::string getPCMFile(const DWARFDie &CUDie,
286 DWARFLinker::ObjectPrefixMapTy *ObjectPrefixMap) {
287 std::string PCMFile = dwarf::toString(
288 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
289
290 if (PCMFile.empty())
291 return PCMFile;
292
293 if (ObjectPrefixMap)
294 PCMFile = remapPath(PCMFile, *ObjectPrefixMap);
295
296 return PCMFile;
297 }
298
isClangModuleRef(const DWARFDie & CUDie,std::string & PCMFile,unsigned Indent,bool Quiet)299 std::pair<bool, bool> DWARFLinkerImpl::LinkContext::isClangModuleRef(
300 const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet) {
301 if (PCMFile.empty())
302 return std::make_pair(false, false);
303
304 // Clang module DWARF skeleton CUs abuse this for the path to the module.
305 uint64_t DwoId = getDwoId(CUDie);
306
307 std::string Name = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
308 if (Name.empty()) {
309 if (!Quiet)
310 GlobalData.warn("anonymous module skeleton CU for " + PCMFile + ".",
311 InputDWARFFile.FileName);
312 return std::make_pair(true, true);
313 }
314
315 if (!Quiet && GlobalData.getOptions().Verbose) {
316 outs().indent(Indent);
317 outs() << "Found clang module reference " << PCMFile;
318 }
319
320 auto Cached = ClangModules.find(PCMFile);
321 if (Cached != ClangModules.end()) {
322 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
323 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
324 // ASTFileSignatures will change randomly when a module is rebuilt.
325 if (!Quiet && GlobalData.getOptions().Verbose && (Cached->second != DwoId))
326 GlobalData.warn(
327 Twine("hash mismatch: this object file was built against a "
328 "different version of the module ") +
329 PCMFile + ".",
330 InputDWARFFile.FileName);
331 if (!Quiet && GlobalData.getOptions().Verbose)
332 outs() << " [cached].\n";
333 return std::make_pair(true, true);
334 }
335
336 return std::make_pair(true, false);
337 }
338
339 /// If this compile unit is really a skeleton CU that points to a
340 /// clang module, register it in ClangModules and return true.
341 ///
342 /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
343 /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
344 /// hash.
registerModuleReference(const DWARFDie & CUDie,ObjFileLoaderTy Loader,CompileUnitHandlerTy OnCUDieLoaded,unsigned Indent)345 bool DWARFLinkerImpl::LinkContext::registerModuleReference(
346 const DWARFDie &CUDie, ObjFileLoaderTy Loader,
347 CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
348 std::string PCMFile =
349 getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap);
350 std::pair<bool, bool> IsClangModuleRef =
351 isClangModuleRef(CUDie, PCMFile, Indent, false);
352
353 if (!IsClangModuleRef.first)
354 return false;
355
356 if (IsClangModuleRef.second)
357 return true;
358
359 if (GlobalData.getOptions().Verbose)
360 outs() << " ...\n";
361
362 // Cyclic dependencies are disallowed by Clang, but we still
363 // shouldn't run into an infinite loop, so mark it as processed now.
364 ClangModules.insert({PCMFile, getDwoId(CUDie)});
365
366 if (Error E =
367 loadClangModule(Loader, CUDie, PCMFile, OnCUDieLoaded, Indent + 2)) {
368 consumeError(std::move(E));
369 return false;
370 }
371 return true;
372 }
373
loadClangModule(ObjFileLoaderTy Loader,const DWARFDie & CUDie,const std::string & PCMFile,CompileUnitHandlerTy OnCUDieLoaded,unsigned Indent)374 Error DWARFLinkerImpl::LinkContext::loadClangModule(
375 ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile,
376 CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent) {
377
378 uint64_t DwoId = getDwoId(CUDie);
379 std::string ModuleName = dwarf::toString(CUDie.find(dwarf::DW_AT_name), "");
380
381 /// Using a SmallString<0> because loadClangModule() is recursive.
382 SmallString<0> Path(GlobalData.getOptions().PrependPath);
383 if (sys::path::is_relative(PCMFile))
384 resolveRelativeObjectPath(Path, CUDie);
385 sys::path::append(Path, PCMFile);
386 // Don't use the cached binary holder because we have no thread-safety
387 // guarantee and the lifetime is limited.
388
389 if (Loader == nullptr) {
390 GlobalData.error("cann't load clang module: loader is not specified.",
391 InputDWARFFile.FileName);
392 return Error::success();
393 }
394
395 auto ErrOrObj = Loader(InputDWARFFile.FileName, Path);
396 if (!ErrOrObj)
397 return Error::success();
398
399 std::unique_ptr<CompileUnit> Unit;
400 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) {
401 OnCUDieLoaded(*CU);
402 // Recursively get all modules imported by this one.
403 auto ChildCUDie = CU->getUnitDIE();
404 if (!ChildCUDie)
405 continue;
406 if (!registerModuleReference(ChildCUDie, Loader, OnCUDieLoaded, Indent)) {
407 if (Unit) {
408 std::string Err =
409 (PCMFile +
410 ": Clang modules are expected to have exactly 1 compile unit.\n");
411 GlobalData.error(Err, InputDWARFFile.FileName);
412 return make_error<StringError>(Err, inconvertibleErrorCode());
413 }
414 // FIXME: Until PR27449 (https://llvm.org/bugs/show_bug.cgi?id=27449) is
415 // fixed in clang, only warn about DWO_id mismatches in verbose mode.
416 // ASTFileSignatures will change randomly when a module is rebuilt.
417 uint64_t PCMDwoId = getDwoId(ChildCUDie);
418 if (PCMDwoId != DwoId) {
419 if (GlobalData.getOptions().Verbose)
420 GlobalData.warn(
421 Twine("hash mismatch: this object file was built against a "
422 "different version of the module ") +
423 PCMFile + ".",
424 InputDWARFFile.FileName);
425 // Update the cache entry with the DwoId of the module loaded from disk.
426 ClangModules[PCMFile] = PCMDwoId;
427 }
428
429 // Empty modules units should not be cloned.
430 if (!ChildCUDie.hasChildren())
431 continue;
432
433 // Add this module.
434 Unit = std::make_unique<CompileUnit>(
435 GlobalData, *CU, UniqueUnitID.fetch_add(1), ModuleName, *ErrOrObj,
436 getUnitForOffset, CU->getFormParams(), getEndianness());
437 }
438 }
439
440 if (Unit) {
441 ModulesCompileUnits.emplace_back(RefModuleUnit{*ErrOrObj, std::move(Unit)});
442 // Preload line table, as it can't be loaded asynchronously.
443 ModulesCompileUnits.back().Unit->loadLineTable();
444 }
445
446 return Error::success();
447 }
448
link(TypeUnit * ArtificialTypeUnit)449 Error DWARFLinkerImpl::LinkContext::link(TypeUnit *ArtificialTypeUnit) {
450 InterCUProcessingStarted = false;
451 if (!InputDWARFFile.Dwarf)
452 return Error::success();
453
454 // Preload macro tables, as they can't be loaded asynchronously.
455 InputDWARFFile.Dwarf->getDebugMacinfo();
456 InputDWARFFile.Dwarf->getDebugMacro();
457
458 // Link modules compile units first.
459 parallelForEach(ModulesCompileUnits, [&](RefModuleUnit &RefModule) {
460 linkSingleCompileUnit(*RefModule.Unit, ArtificialTypeUnit);
461 });
462
463 // Check for live relocations. If there is no any live relocation then we
464 // can skip entire object file.
465 if (!GlobalData.getOptions().UpdateIndexTablesOnly &&
466 !InputDWARFFile.Addresses->hasValidRelocs()) {
467 if (GlobalData.getOptions().Verbose)
468 outs() << "No valid relocations found. Skipping.\n";
469 return Error::success();
470 }
471
472 OriginalDebugInfoSize = getInputDebugInfoSize();
473
474 // Create CompileUnit structures to keep information about source
475 // DWARFUnit`s, load line tables.
476 for (const auto &OrigCU : InputDWARFFile.Dwarf->compile_units()) {
477 // Load only unit DIE at this stage.
478 auto CUDie = OrigCU->getUnitDIE();
479 std::string PCMFile =
480 getPCMFile(CUDie, GlobalData.getOptions().ObjectPrefixMap);
481
482 // The !isClangModuleRef condition effectively skips over fully resolved
483 // skeleton units.
484 if (!CUDie || GlobalData.getOptions().UpdateIndexTablesOnly ||
485 !isClangModuleRef(CUDie, PCMFile, 0, true).first) {
486 CompileUnits.emplace_back(std::make_unique<CompileUnit>(
487 GlobalData, *OrigCU, UniqueUnitID.fetch_add(1), "", InputDWARFFile,
488 getUnitForOffset, OrigCU->getFormParams(), getEndianness()));
489
490 // Preload line table, as it can't be loaded asynchronously.
491 CompileUnits.back()->loadLineTable();
492 }
493 };
494
495 HasNewInterconnectedCUs = false;
496
497 // Link self-sufficient compile units and discover inter-connected compile
498 // units.
499 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
500 linkSingleCompileUnit(*CU, ArtificialTypeUnit);
501 });
502
503 // Link all inter-connected units.
504 if (HasNewInterconnectedCUs) {
505 InterCUProcessingStarted = true;
506
507 if (Error Err = finiteLoop([&]() -> Expected<bool> {
508 HasNewInterconnectedCUs = false;
509
510 // Load inter-connected units.
511 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
512 if (CU->isInterconnectedCU()) {
513 CU->maybeResetToLoadedStage();
514 linkSingleCompileUnit(*CU, ArtificialTypeUnit,
515 CompileUnit::Stage::Loaded);
516 }
517 });
518
519 // Do liveness analysis for inter-connected units.
520 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
521 linkSingleCompileUnit(*CU, ArtificialTypeUnit,
522 CompileUnit::Stage::LivenessAnalysisDone);
523 });
524
525 return HasNewInterconnectedCUs.load();
526 }))
527 return Err;
528
529 // Update dependencies.
530 if (Error Err = finiteLoop([&]() -> Expected<bool> {
531 HasNewGlobalDependency = false;
532 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
533 linkSingleCompileUnit(
534 *CU, ArtificialTypeUnit,
535 CompileUnit::Stage::UpdateDependenciesCompleteness);
536 });
537 return HasNewGlobalDependency.load();
538 }))
539 return Err;
540 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
541 if (CU->isInterconnectedCU() &&
542 CU->getStage() == CompileUnit::Stage::LivenessAnalysisDone)
543 CU->setStage(CompileUnit::Stage::UpdateDependenciesCompleteness);
544 });
545
546 // Assign type names.
547 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
548 linkSingleCompileUnit(*CU, ArtificialTypeUnit,
549 CompileUnit::Stage::TypeNamesAssigned);
550 });
551
552 // Clone inter-connected units.
553 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
554 linkSingleCompileUnit(*CU, ArtificialTypeUnit,
555 CompileUnit::Stage::Cloned);
556 });
557
558 // Update patches for inter-connected units.
559 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
560 linkSingleCompileUnit(*CU, ArtificialTypeUnit,
561 CompileUnit::Stage::PatchesUpdated);
562 });
563
564 // Release data.
565 parallelForEach(CompileUnits, [&](std::unique_ptr<CompileUnit> &CU) {
566 linkSingleCompileUnit(*CU, ArtificialTypeUnit,
567 CompileUnit::Stage::Cleaned);
568 });
569 }
570
571 if (GlobalData.getOptions().UpdateIndexTablesOnly) {
572 // Emit Invariant sections.
573
574 if (Error Err = emitInvariantSections())
575 return Err;
576 } else if (!CompileUnits.empty()) {
577 // Emit .debug_frame section.
578
579 Error ResultErr = Error::success();
580 llvm::parallel::TaskGroup TGroup;
581 // We use task group here as PerThreadBumpPtrAllocator should be called from
582 // the threads created by ThreadPoolExecutor.
583 TGroup.spawn([&]() {
584 if (Error Err = cloneAndEmitDebugFrame())
585 ResultErr = std::move(Err);
586 });
587 return ResultErr;
588 }
589
590 return Error::success();
591 }
592
linkSingleCompileUnit(CompileUnit & CU,TypeUnit * ArtificialTypeUnit,enum CompileUnit::Stage DoUntilStage)593 void DWARFLinkerImpl::LinkContext::linkSingleCompileUnit(
594 CompileUnit &CU, TypeUnit *ArtificialTypeUnit,
595 enum CompileUnit::Stage DoUntilStage) {
596 if (InterCUProcessingStarted != CU.isInterconnectedCU())
597 return;
598
599 if (Error Err = finiteLoop([&]() -> Expected<bool> {
600 if (CU.getStage() >= DoUntilStage)
601 return false;
602
603 switch (CU.getStage()) {
604 case CompileUnit::Stage::CreatedNotLoaded: {
605 // Load input compilation unit DIEs.
606 // Analyze properties of DIEs.
607 if (!CU.loadInputDIEs()) {
608 // We do not need to do liveness analysis for invalid compilation
609 // unit.
610 CU.setStage(CompileUnit::Stage::Skipped);
611 } else {
612 CU.analyzeDWARFStructure();
613
614 // The registerModuleReference() condition effectively skips
615 // over fully resolved skeleton units. This second pass of
616 // registerModuleReferences doesn't do any new work, but it
617 // will collect top-level errors, which are suppressed. Module
618 // warnings were already displayed in the first iteration.
619 if (registerModuleReference(
620 CU.getOrigUnit().getUnitDIE(), nullptr,
621 [](const DWARFUnit &) {}, 0))
622 CU.setStage(CompileUnit::Stage::PatchesUpdated);
623 else
624 CU.setStage(CompileUnit::Stage::Loaded);
625 }
626 } break;
627
628 case CompileUnit::Stage::Loaded: {
629 // Mark all the DIEs that need to be present in the generated output.
630 // If ODR requested, build type names.
631 if (!CU.resolveDependenciesAndMarkLiveness(InterCUProcessingStarted,
632 HasNewInterconnectedCUs)) {
633 assert(HasNewInterconnectedCUs &&
634 "Flag indicating new inter-connections is not set");
635 return false;
636 }
637
638 CU.setStage(CompileUnit::Stage::LivenessAnalysisDone);
639 } break;
640
641 case CompileUnit::Stage::LivenessAnalysisDone: {
642 if (InterCUProcessingStarted) {
643 if (CU.updateDependenciesCompleteness())
644 HasNewGlobalDependency = true;
645 return false;
646 } else {
647 if (Error Err = finiteLoop([&]() -> Expected<bool> {
648 return CU.updateDependenciesCompleteness();
649 }))
650 return std::move(Err);
651
652 CU.setStage(CompileUnit::Stage::UpdateDependenciesCompleteness);
653 }
654 } break;
655
656 case CompileUnit::Stage::UpdateDependenciesCompleteness:
657 #ifndef NDEBUG
658 CU.verifyDependencies();
659 #endif
660
661 if (ArtificialTypeUnit) {
662 if (Error Err =
663 CU.assignTypeNames(ArtificialTypeUnit->getTypePool()))
664 return std::move(Err);
665 }
666 CU.setStage(CompileUnit::Stage::TypeNamesAssigned);
667 break;
668
669 case CompileUnit::Stage::TypeNamesAssigned:
670 // Clone input compile unit.
671 if (CU.isClangModule() ||
672 GlobalData.getOptions().UpdateIndexTablesOnly ||
673 CU.getContaingFile().Addresses->hasValidRelocs()) {
674 if (Error Err = CU.cloneAndEmit(GlobalData.getTargetTriple(),
675 ArtificialTypeUnit))
676 return std::move(Err);
677 }
678
679 CU.setStage(CompileUnit::Stage::Cloned);
680 break;
681
682 case CompileUnit::Stage::Cloned:
683 // Update DIEs referencies.
684 CU.updateDieRefPatchesWithClonedOffsets();
685 CU.setStage(CompileUnit::Stage::PatchesUpdated);
686 break;
687
688 case CompileUnit::Stage::PatchesUpdated:
689 // Cleanup resources.
690 CU.cleanupDataAfterClonning();
691 CU.setStage(CompileUnit::Stage::Cleaned);
692 break;
693
694 case CompileUnit::Stage::Cleaned:
695 assert(false);
696 break;
697
698 case CompileUnit::Stage::Skipped:
699 // Nothing to do.
700 break;
701 }
702
703 return true;
704 })) {
705 CU.error(std::move(Err));
706 CU.cleanupDataAfterClonning();
707 CU.setStage(CompileUnit::Stage::Skipped);
708 }
709 }
710
emitInvariantSections()711 Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
712 if (!GlobalData.getTargetTriple().has_value())
713 return Error::success();
714
715 getOrCreateSectionDescriptor(DebugSectionKind::DebugLoc).OS
716 << InputDWARFFile.Dwarf->getDWARFObj().getLocSection().Data;
717 getOrCreateSectionDescriptor(DebugSectionKind::DebugLocLists).OS
718 << InputDWARFFile.Dwarf->getDWARFObj().getLoclistsSection().Data;
719 getOrCreateSectionDescriptor(DebugSectionKind::DebugRange).OS
720 << InputDWARFFile.Dwarf->getDWARFObj().getRangesSection().Data;
721 getOrCreateSectionDescriptor(DebugSectionKind::DebugRngLists).OS
722 << InputDWARFFile.Dwarf->getDWARFObj().getRnglistsSection().Data;
723 getOrCreateSectionDescriptor(DebugSectionKind::DebugARanges).OS
724 << InputDWARFFile.Dwarf->getDWARFObj().getArangesSection();
725 getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame).OS
726 << InputDWARFFile.Dwarf->getDWARFObj().getFrameSection().Data;
727 getOrCreateSectionDescriptor(DebugSectionKind::DebugAddr).OS
728 << InputDWARFFile.Dwarf->getDWARFObj().getAddrSection().Data;
729
730 return Error::success();
731 }
732
cloneAndEmitDebugFrame()733 Error DWARFLinkerImpl::LinkContext::cloneAndEmitDebugFrame() {
734 if (!GlobalData.getTargetTriple().has_value())
735 return Error::success();
736
737 if (InputDWARFFile.Dwarf.get() == nullptr)
738 return Error::success();
739
740 const DWARFObject &InputDWARFObj = InputDWARFFile.Dwarf->getDWARFObj();
741
742 StringRef OrigFrameData = InputDWARFObj.getFrameSection().Data;
743 if (OrigFrameData.empty())
744 return Error::success();
745
746 RangesTy AllUnitsRanges;
747 for (std::unique_ptr<CompileUnit> &Unit : CompileUnits) {
748 for (auto CurRange : Unit->getFunctionRanges())
749 AllUnitsRanges.insert(CurRange.Range, CurRange.Value);
750 }
751
752 unsigned SrcAddrSize = InputDWARFObj.getAddressSize();
753
754 SectionDescriptor &OutSection =
755 getOrCreateSectionDescriptor(DebugSectionKind::DebugFrame);
756
757 DataExtractor Data(OrigFrameData, InputDWARFObj.isLittleEndian(), 0);
758 uint64_t InputOffset = 0;
759
760 // Store the data of the CIEs defined in this object, keyed by their
761 // offsets.
762 DenseMap<uint64_t, StringRef> LocalCIES;
763
764 /// The CIEs that have been emitted in the output section. The actual CIE
765 /// data serves a the key to this StringMap.
766 StringMap<uint32_t> EmittedCIEs;
767
768 while (Data.isValidOffset(InputOffset)) {
769 uint64_t EntryOffset = InputOffset;
770 uint32_t InitialLength = Data.getU32(&InputOffset);
771 if (InitialLength == 0xFFFFFFFF)
772 return createFileError(InputDWARFObj.getFileName(),
773 createStringError(std::errc::invalid_argument,
774 "Dwarf64 bits no supported"));
775
776 uint32_t CIEId = Data.getU32(&InputOffset);
777 if (CIEId == 0xFFFFFFFF) {
778 // This is a CIE, store it.
779 StringRef CIEData = OrigFrameData.substr(EntryOffset, InitialLength + 4);
780 LocalCIES[EntryOffset] = CIEData;
781 // The -4 is to account for the CIEId we just read.
782 InputOffset += InitialLength - 4;
783 continue;
784 }
785
786 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize);
787
788 // Some compilers seem to emit frame info that doesn't start at
789 // the function entry point, thus we can't just lookup the address
790 // in the debug map. Use the AddressInfo's range map to see if the FDE
791 // describes something that we can relocate.
792 std::optional<AddressRangeValuePair> Range =
793 AllUnitsRanges.getRangeThatContains(Loc);
794 if (!Range) {
795 // The +4 is to account for the size of the InitialLength field itself.
796 InputOffset = EntryOffset + InitialLength + 4;
797 continue;
798 }
799
800 // This is an FDE, and we have a mapping.
801 // Have we already emitted a corresponding CIE?
802 StringRef CIEData = LocalCIES[CIEId];
803 if (CIEData.empty())
804 return createFileError(
805 InputDWARFObj.getFileName(),
806 createStringError(std::errc::invalid_argument,
807 "Inconsistent debug_frame content. Dropping."));
808
809 uint64_t OffsetToCIERecord = OutSection.OS.tell();
810
811 // Look if we already emitted a CIE that corresponds to the
812 // referenced one (the CIE data is the key of that lookup).
813 auto IteratorInserted =
814 EmittedCIEs.insert(std::make_pair(CIEData, OffsetToCIERecord));
815 OffsetToCIERecord = IteratorInserted.first->getValue();
816
817 // Emit CIE for this ID if it is not emitted yet.
818 if (IteratorInserted.second)
819 OutSection.OS << CIEData;
820
821 // Remember offset to the FDE record, so that we might update
822 // field referencing CIE record(containing OffsetToCIERecord),
823 // when final offsets are known. OffsetToCIERecord(which is written later)
824 // is local to the current .debug_frame section, it should be updated
825 // with final offset of the .debug_frame section.
826 OutSection.notePatch(
827 DebugOffsetPatch{OutSection.OS.tell() + 4, &OutSection, true});
828
829 // Emit the FDE with updated address and CIE pointer.
830 // (4 + AddrSize) is the size of the CIEId + initial_location
831 // fields that will get reconstructed by emitFDE().
832 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize);
833 emitFDE(OffsetToCIERecord, SrcAddrSize, Loc + Range->Value,
834 OrigFrameData.substr(InputOffset, FDERemainingBytes), OutSection);
835 InputOffset += FDERemainingBytes;
836 }
837
838 return Error::success();
839 }
840
841 /// Emit a FDE into the debug_frame section. \p FDEBytes
842 /// contains the FDE data without the length, CIE offset and address
843 /// which will be replaced with the parameter values.
emitFDE(uint32_t CIEOffset,uint32_t AddrSize,uint64_t Address,StringRef FDEBytes,SectionDescriptor & Section)844 void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset,
845 uint32_t AddrSize, uint64_t Address,
846 StringRef FDEBytes,
847 SectionDescriptor &Section) {
848 Section.emitIntVal(FDEBytes.size() + 4 + AddrSize, 4);
849 Section.emitIntVal(CIEOffset, 4);
850 Section.emitIntVal(Address, AddrSize);
851 Section.OS.write(FDEBytes.data(), FDEBytes.size());
852 }
853
glueCompileUnitsAndWriteToTheOutput()854 void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() {
855 if (!GlobalData.getTargetTriple().has_value())
856 return;
857 assert(SectionHandler);
858
859 // Go through all object files, all compile units and assign
860 // offsets to them.
861 assignOffsets();
862
863 // Patch size/offsets fields according to the assigned CU offsets.
864 patchOffsetsAndSizes();
865
866 // Emit common sections and write debug tables from all object files/compile
867 // units into the resulting file.
868 emitCommonSectionsAndWriteCompileUnitsToTheOutput();
869
870 if (ArtificialTypeUnit.get() != nullptr)
871 ArtificialTypeUnit.reset();
872
873 // Write common debug sections into the resulting file.
874 writeCommonSectionsToTheOutput();
875
876 // Cleanup data.
877 cleanupDataAfterDWARFOutputIsWritten();
878
879 if (GlobalData.getOptions().Statistics)
880 printStatistic();
881 }
882
printStatistic()883 void DWARFLinkerImpl::printStatistic() {
884
885 // For each object file map how many bytes were emitted.
886 StringMap<DebugInfoSize> SizeByObject;
887
888 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) {
889 uint64_t AllDebugInfoSectionsSize = 0;
890
891 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
892 if (std::optional<SectionDescriptor *> DebugInfo =
893 CU->tryGetSectionDescriptor(DebugSectionKind::DebugInfo))
894 AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size();
895
896 SizeByObject[Context->InputDWARFFile.FileName].Input =
897 Context->OriginalDebugInfoSize;
898 SizeByObject[Context->InputDWARFFile.FileName].Output =
899 AllDebugInfoSectionsSize;
900 }
901
902 // Create a vector sorted in descending order by output size.
903 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
904 for (auto &E : SizeByObject)
905 Sorted.emplace_back(E.first(), E.second);
906 llvm::sort(Sorted, [](auto &LHS, auto &RHS) {
907 return LHS.second.Output > RHS.second.Output;
908 });
909
910 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
911 const float Difference = Output - Input;
912 const float Sum = Input + Output;
913 if (Sum == 0)
914 return 0;
915 return (Difference / (Sum / 2));
916 };
917
918 int64_t InputTotal = 0;
919 int64_t OutputTotal = 0;
920 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
921
922 // Print header.
923 outs() << ".debug_info section size (in bytes)\n";
924 outs() << "----------------------------------------------------------------"
925 "---------------\n";
926 outs() << "Filename Object "
927 " dSYM Change\n";
928 outs() << "----------------------------------------------------------------"
929 "---------------\n";
930
931 // Print body.
932 for (auto &E : Sorted) {
933 InputTotal += E.second.Input;
934 OutputTotal += E.second.Output;
935 llvm::outs() << formatv(
936 FormatStr, sys::path::filename(E.first).take_back(45), E.second.Input,
937 E.second.Output, ComputePercentange(E.second.Input, E.second.Output));
938 }
939 // Print total and footer.
940 outs() << "----------------------------------------------------------------"
941 "---------------\n";
942 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal,
943 ComputePercentange(InputTotal, OutputTotal));
944 outs() << "----------------------------------------------------------------"
945 "---------------\n\n";
946 }
947
assignOffsets()948 void DWARFLinkerImpl::assignOffsets() {
949 llvm::parallel::TaskGroup TGroup;
950 TGroup.spawn([&]() { assignOffsetsToStrings(); });
951 TGroup.spawn([&]() { assignOffsetsToSections(); });
952 }
953
assignOffsetsToStrings()954 void DWARFLinkerImpl::assignOffsetsToStrings() {
955 size_t CurDebugStrIndex = 1; // start from 1 to take into account zero entry.
956 uint64_t CurDebugStrOffset =
957 1; // start from 1 to take into account zero entry.
958 size_t CurDebugLineStrIndex = 0;
959 uint64_t CurDebugLineStrOffset = 0;
960
961 // Enumerates all strings, add them into the DwarfStringPoolEntry map,
962 // assign offset and index to the string if it is not indexed yet.
963 forEachOutputString([&](StringDestinationKind Kind,
964 const StringEntry *String) {
965 switch (Kind) {
966 case StringDestinationKind::DebugStr: {
967 DwarfStringPoolEntryWithExtString *Entry = DebugStrStrings.add(String);
968 assert(Entry != nullptr);
969
970 if (!Entry->isIndexed()) {
971 Entry->Offset = CurDebugStrOffset;
972 CurDebugStrOffset += Entry->String.size() + 1;
973 Entry->Index = CurDebugStrIndex++;
974 }
975 } break;
976 case StringDestinationKind::DebugLineStr: {
977 DwarfStringPoolEntryWithExtString *Entry =
978 DebugLineStrStrings.add(String);
979 assert(Entry != nullptr);
980
981 if (!Entry->isIndexed()) {
982 Entry->Offset = CurDebugLineStrOffset;
983 CurDebugLineStrOffset += Entry->String.size() + 1;
984 Entry->Index = CurDebugLineStrIndex++;
985 }
986 } break;
987 }
988 });
989 }
990
assignOffsetsToSections()991 void DWARFLinkerImpl::assignOffsetsToSections() {
992 std::array<uint64_t, SectionKindsNum> SectionSizesAccumulator = {0};
993
994 forEachObjectSectionsSet([&](OutputSections &UnitSections) {
995 UnitSections.assignSectionsOffsetAndAccumulateSize(SectionSizesAccumulator);
996 });
997 }
998
forEachOutputString(function_ref<void (StringDestinationKind Kind,const StringEntry * String)> StringHandler)999 void DWARFLinkerImpl::forEachOutputString(
1000 function_ref<void(StringDestinationKind Kind, const StringEntry *String)>
1001 StringHandler) {
1002 // To save space we do not create any separate string table.
1003 // We use already allocated string patches and accelerator entries:
1004 // enumerate them in natural order and assign offsets.
1005 // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str
1006 // sections in the same order as they were assigned offsets.
1007 forEachCompileUnit([&](CompileUnit *CU) {
1008 CU->forEach([&](SectionDescriptor &OutSection) {
1009 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
1010 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1011 });
1012
1013 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
1014 StringHandler(StringDestinationKind::DebugLineStr, Patch.String);
1015 });
1016 });
1017
1018 CU->forEachAcceleratorRecord([&](DwarfUnit::AccelInfo &Info) {
1019 StringHandler(DebugStr, Info.String);
1020 });
1021 });
1022
1023 if (ArtificialTypeUnit.get() != nullptr) {
1024 ArtificialTypeUnit->forEach([&](SectionDescriptor &OutSection) {
1025 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
1026 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1027 });
1028
1029 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
1030 StringHandler(StringDestinationKind::DebugLineStr, Patch.String);
1031 });
1032
1033 OutSection.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) {
1034 if (Patch.Die == nullptr)
1035 return;
1036
1037 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1038 });
1039
1040 OutSection.ListDebugTypeLineStrPatch.forEach(
1041 [&](DebugTypeLineStrPatch &Patch) {
1042 if (Patch.Die == nullptr)
1043 return;
1044
1045 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1046 });
1047 });
1048 }
1049 }
1050
forEachObjectSectionsSet(function_ref<void (OutputSections &)> SectionsSetHandler)1051 void DWARFLinkerImpl::forEachObjectSectionsSet(
1052 function_ref<void(OutputSections &)> SectionsSetHandler) {
1053 // Handle artificial type unit first.
1054 if (ArtificialTypeUnit.get() != nullptr)
1055 SectionsSetHandler(*ArtificialTypeUnit);
1056
1057 // Then all modules(before regular compilation units).
1058 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1059 for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits)
1060 if (ModuleUnit.Unit->getStage() != CompileUnit::Stage::Skipped)
1061 SectionsSetHandler(*ModuleUnit.Unit);
1062
1063 // Finally all compilation units.
1064 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) {
1065 // Handle object file common sections.
1066 SectionsSetHandler(*Context);
1067
1068 // Handle compilation units.
1069 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1070 if (CU->getStage() != CompileUnit::Stage::Skipped)
1071 SectionsSetHandler(*CU);
1072 }
1073 }
1074
forEachCompileAndTypeUnit(function_ref<void (DwarfUnit * CU)> UnitHandler)1075 void DWARFLinkerImpl::forEachCompileAndTypeUnit(
1076 function_ref<void(DwarfUnit *CU)> UnitHandler) {
1077 if (ArtificialTypeUnit.get() != nullptr)
1078 UnitHandler(ArtificialTypeUnit.get());
1079
1080 // Enumerate module units.
1081 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1082 for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits)
1083 if (ModuleUnit.Unit->getStage() != CompileUnit::Stage::Skipped)
1084 UnitHandler(ModuleUnit.Unit.get());
1085
1086 // Enumerate compile units.
1087 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1088 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1089 if (CU->getStage() != CompileUnit::Stage::Skipped)
1090 UnitHandler(CU.get());
1091 }
1092
forEachCompileUnit(function_ref<void (CompileUnit * CU)> UnitHandler)1093 void DWARFLinkerImpl::forEachCompileUnit(
1094 function_ref<void(CompileUnit *CU)> UnitHandler) {
1095 // Enumerate module units.
1096 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1097 for (LinkContext::RefModuleUnit &ModuleUnit : Context->ModulesCompileUnits)
1098 if (ModuleUnit.Unit->getStage() != CompileUnit::Stage::Skipped)
1099 UnitHandler(ModuleUnit.Unit.get());
1100
1101 // Enumerate compile units.
1102 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1103 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1104 if (CU->getStage() != CompileUnit::Stage::Skipped)
1105 UnitHandler(CU.get());
1106 }
1107
patchOffsetsAndSizes()1108 void DWARFLinkerImpl::patchOffsetsAndSizes() {
1109 forEachObjectSectionsSet([&](OutputSections &SectionsSet) {
1110 SectionsSet.forEach([&](SectionDescriptor &OutSection) {
1111 SectionsSet.applyPatches(OutSection, DebugStrStrings, DebugLineStrStrings,
1112 ArtificialTypeUnit.get());
1113 });
1114 });
1115 }
1116
emitCommonSectionsAndWriteCompileUnitsToTheOutput()1117 void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() {
1118 llvm::parallel::TaskGroup TG;
1119
1120 // Create section descriptors ahead if they are not exist at the moment.
1121 // SectionDescriptors container is not thread safe. Thus we should be sure
1122 // that descriptors would not be created in following parallel tasks.
1123
1124 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugStr);
1125 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugLineStr);
1126
1127 if (llvm::is_contained(GlobalData.Options.AccelTables,
1128 AccelTableKind::Apple)) {
1129 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleNames);
1130 CommonSections.getOrCreateSectionDescriptor(
1131 DebugSectionKind::AppleNamespaces);
1132 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleObjC);
1133 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::AppleTypes);
1134 }
1135
1136 if (llvm::is_contained(GlobalData.Options.AccelTables,
1137 AccelTableKind::DebugNames))
1138 CommonSections.getOrCreateSectionDescriptor(DebugSectionKind::DebugNames);
1139
1140 // Emit .debug_str and .debug_line_str sections.
1141 TG.spawn([&]() { emitStringSections(); });
1142
1143 if (llvm::is_contained(GlobalData.Options.AccelTables,
1144 AccelTableKind::Apple)) {
1145 // Emit apple accelerator sections.
1146 TG.spawn([&]() {
1147 emitAppleAcceleratorSections((*GlobalData.getTargetTriple()).get());
1148 });
1149 }
1150
1151 if (llvm::is_contained(GlobalData.Options.AccelTables,
1152 AccelTableKind::DebugNames)) {
1153 // Emit .debug_names section.
1154 TG.spawn([&]() {
1155 emitDWARFv5DebugNamesSection((*GlobalData.getTargetTriple()).get());
1156 });
1157 }
1158
1159 // Write compile units to the output file.
1160 TG.spawn([&]() { writeCompileUnitsToTheOutput(); });
1161 }
1162
emitStringSections()1163 void DWARFLinkerImpl::emitStringSections() {
1164 uint64_t DebugStrNextOffset = 0;
1165 uint64_t DebugLineStrNextOffset = 0;
1166
1167 // Emit zero length string. Accelerator tables does not work correctly
1168 // if the first string is not zero length string.
1169 CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr)
1170 .emitInplaceString("");
1171 DebugStrNextOffset++;
1172
1173 forEachOutputString(
1174 [&](StringDestinationKind Kind, const StringEntry *String) {
1175 switch (Kind) {
1176 case StringDestinationKind::DebugStr: {
1177 DwarfStringPoolEntryWithExtString *StringToEmit =
1178 DebugStrStrings.getExistingEntry(String);
1179 assert(StringToEmit->isIndexed());
1180
1181 // Strings may be repeated. Use accumulated DebugStrNextOffset
1182 // to understand whether corresponding string is already emitted.
1183 // Skip string if its offset less than accumulated offset.
1184 if (StringToEmit->Offset >= DebugStrNextOffset) {
1185 DebugStrNextOffset =
1186 StringToEmit->Offset + StringToEmit->String.size() + 1;
1187 // Emit the string itself.
1188 CommonSections.getSectionDescriptor(DebugSectionKind::DebugStr)
1189 .emitInplaceString(StringToEmit->String);
1190 }
1191 } break;
1192 case StringDestinationKind::DebugLineStr: {
1193 DwarfStringPoolEntryWithExtString *StringToEmit =
1194 DebugLineStrStrings.getExistingEntry(String);
1195 assert(StringToEmit->isIndexed());
1196
1197 // Strings may be repeated. Use accumulated DebugLineStrStrings
1198 // to understand whether corresponding string is already emitted.
1199 // Skip string if its offset less than accumulated offset.
1200 if (StringToEmit->Offset >= DebugLineStrNextOffset) {
1201 DebugLineStrNextOffset =
1202 StringToEmit->Offset + StringToEmit->String.size() + 1;
1203 // Emit the string itself.
1204 CommonSections.getSectionDescriptor(DebugSectionKind::DebugLineStr)
1205 .emitInplaceString(StringToEmit->String);
1206 }
1207 } break;
1208 }
1209 });
1210 }
1211
emitAppleAcceleratorSections(const Triple & TargetTriple)1212 void DWARFLinkerImpl::emitAppleAcceleratorSections(const Triple &TargetTriple) {
1213 AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
1214 AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
1215 AccelTable<AppleAccelTableStaticOffsetData> AppleObjC;
1216 AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
1217
1218 forEachCompileAndTypeUnit([&](DwarfUnit *CU) {
1219 CU->forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
1220 uint64_t OutOffset = Info.OutOffset;
1221 switch (Info.Type) {
1222 case DwarfUnit::AccelType::None: {
1223 llvm_unreachable("Unknown accelerator record");
1224 } break;
1225 case DwarfUnit::AccelType::Namespace: {
1226 AppleNamespaces.addName(
1227 *DebugStrStrings.getExistingEntry(Info.String),
1228 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1229 OutOffset);
1230 } break;
1231 case DwarfUnit::AccelType::Name: {
1232 AppleNames.addName(
1233 *DebugStrStrings.getExistingEntry(Info.String),
1234 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1235 OutOffset);
1236 } break;
1237 case DwarfUnit::AccelType::ObjC: {
1238 AppleObjC.addName(
1239 *DebugStrStrings.getExistingEntry(Info.String),
1240 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1241 OutOffset);
1242 } break;
1243 case DwarfUnit::AccelType::Type: {
1244 AppleTypes.addName(
1245 *DebugStrStrings.getExistingEntry(Info.String),
1246 CU->getSectionDescriptor(DebugSectionKind::DebugInfo).StartOffset +
1247 OutOffset,
1248 Info.Tag,
1249 Info.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation
1250 : 0,
1251 Info.QualifiedNameHash);
1252 } break;
1253 }
1254 });
1255 });
1256
1257 {
1258 // FIXME: we use AsmPrinter to emit accelerator sections.
1259 // It might be beneficial to directly emit accelerator data
1260 // to the raw_svector_ostream.
1261 SectionDescriptor &OutSection =
1262 CommonSections.getSectionDescriptor(DebugSectionKind::AppleNamespaces);
1263 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1264 OutSection.OS);
1265 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1266 consumeError(std::move(Err));
1267 return;
1268 }
1269
1270 // Emit table.
1271 Emitter.emitAppleNamespaces(AppleNamespaces);
1272 Emitter.finish();
1273
1274 // Set start offset and size for output section.
1275 OutSection.setSizesForSectionCreatedByAsmPrinter();
1276 }
1277
1278 {
1279 // FIXME: we use AsmPrinter to emit accelerator sections.
1280 // It might be beneficial to directly emit accelerator data
1281 // to the raw_svector_ostream.
1282 SectionDescriptor &OutSection =
1283 CommonSections.getSectionDescriptor(DebugSectionKind::AppleNames);
1284 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1285 OutSection.OS);
1286 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1287 consumeError(std::move(Err));
1288 return;
1289 }
1290
1291 // Emit table.
1292 Emitter.emitAppleNames(AppleNames);
1293 Emitter.finish();
1294
1295 // Set start offset ans size for output section.
1296 OutSection.setSizesForSectionCreatedByAsmPrinter();
1297 }
1298
1299 {
1300 // FIXME: we use AsmPrinter to emit accelerator sections.
1301 // It might be beneficial to directly emit accelerator data
1302 // to the raw_svector_ostream.
1303 SectionDescriptor &OutSection =
1304 CommonSections.getSectionDescriptor(DebugSectionKind::AppleObjC);
1305 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1306 OutSection.OS);
1307 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1308 consumeError(std::move(Err));
1309 return;
1310 }
1311
1312 // Emit table.
1313 Emitter.emitAppleObjc(AppleObjC);
1314 Emitter.finish();
1315
1316 // Set start offset ans size for output section.
1317 OutSection.setSizesForSectionCreatedByAsmPrinter();
1318 }
1319
1320 {
1321 // FIXME: we use AsmPrinter to emit accelerator sections.
1322 // It might be beneficial to directly emit accelerator data
1323 // to the raw_svector_ostream.
1324 SectionDescriptor &OutSection =
1325 CommonSections.getSectionDescriptor(DebugSectionKind::AppleTypes);
1326 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1327 OutSection.OS);
1328 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1329 consumeError(std::move(Err));
1330 return;
1331 }
1332
1333 // Emit table.
1334 Emitter.emitAppleTypes(AppleTypes);
1335 Emitter.finish();
1336
1337 // Set start offset ans size for output section.
1338 OutSection.setSizesForSectionCreatedByAsmPrinter();
1339 }
1340 }
1341
emitDWARFv5DebugNamesSection(const Triple & TargetTriple)1342 void DWARFLinkerImpl::emitDWARFv5DebugNamesSection(const Triple &TargetTriple) {
1343 std::unique_ptr<DWARF5AccelTable> DebugNames;
1344
1345 DebugNamesUnitsOffsets CompUnits;
1346 CompUnitIDToIdx CUidToIdx;
1347
1348 unsigned Id = 0;
1349
1350 forEachCompileAndTypeUnit([&](DwarfUnit *CU) {
1351 bool HasRecords = false;
1352 CU->forEachAcceleratorRecord([&](const DwarfUnit::AccelInfo &Info) {
1353 if (DebugNames.get() == nullptr)
1354 DebugNames = std::make_unique<DWARF5AccelTable>();
1355
1356 HasRecords = true;
1357 switch (Info.Type) {
1358 case DwarfUnit::AccelType::Name:
1359 case DwarfUnit::AccelType::Namespace:
1360 case DwarfUnit::AccelType::Type: {
1361 DebugNames->addName(*DebugStrStrings.getExistingEntry(Info.String),
1362 Info.OutOffset, std::nullopt /*ParentDIEOffset*/,
1363 Info.Tag, CU->getUniqueID());
1364 } break;
1365
1366 default:
1367 break; // Nothing to do.
1368 };
1369 });
1370
1371 if (HasRecords) {
1372 CompUnits.push_back(
1373 CU->getOrCreateSectionDescriptor(DebugSectionKind::DebugInfo)
1374 .StartOffset);
1375 CUidToIdx[CU->getUniqueID()] = Id++;
1376 }
1377 });
1378
1379 if (DebugNames.get() != nullptr) {
1380 // FIXME: we use AsmPrinter to emit accelerator sections.
1381 // It might be beneficial to directly emit accelerator data
1382 // to the raw_svector_ostream.
1383 SectionDescriptor &OutSection =
1384 CommonSections.getSectionDescriptor(DebugSectionKind::DebugNames);
1385 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1386 OutSection.OS);
1387 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1388 consumeError(std::move(Err));
1389 return;
1390 }
1391
1392 // Emit table.
1393 Emitter.emitDebugNames(*DebugNames, CompUnits, CUidToIdx);
1394 Emitter.finish();
1395
1396 // Set start offset ans size for output section.
1397 OutSection.setSizesForSectionCreatedByAsmPrinter();
1398 }
1399 }
1400
cleanupDataAfterDWARFOutputIsWritten()1401 void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() {
1402 GlobalData.getStringPool().clear();
1403 DebugStrStrings.clear();
1404 DebugLineStrStrings.clear();
1405 }
1406
writeCompileUnitsToTheOutput()1407 void DWARFLinkerImpl::writeCompileUnitsToTheOutput() {
1408 // Enumerate all sections and store them into the final emitter.
1409 forEachObjectSectionsSet([&](OutputSections &Sections) {
1410 Sections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
1411 // Emit section content.
1412 SectionHandler(OutSection);
1413 });
1414 });
1415 }
1416
writeCommonSectionsToTheOutput()1417 void DWARFLinkerImpl::writeCommonSectionsToTheOutput() {
1418 CommonSections.forEach([&](std::shared_ptr<SectionDescriptor> OutSection) {
1419 SectionHandler(OutSection);
1420 });
1421 }
1422