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