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 //
656 // Runs concurrently, so it must stay a no-op: it may only be
657 // entered when the serial pass in addObjectFile() has already
658 // populated the module map.
659 if (!GlobalData.getOptions().UpdateIndexTablesOnly &&
660 registerModuleReference(
661 CUDie: CU.getOrigUnit().getUnitDIE(), Loader: nullptr,
662 OnCUDieLoaded: [](const DWARFUnit &) {}, Indent: 0))
663 CU.setStage(CompileUnit::Stage::PatchesUpdated);
664 else
665 CU.setStage(CompileUnit::Stage::Loaded);
666 }
667 } break;
668
669 case CompileUnit::Stage::Loaded: {
670 // Mark all the DIEs that need to be present in the generated output.
671 // If ODR requested, build type names.
672 if (!CU.resolveDependenciesAndMarkLiveness(InterCUProcessingStarted,
673 HasNewInterconnectedCUs)) {
674 assert(HasNewInterconnectedCUs &&
675 "Flag indicating new inter-connections is not set");
676 return false;
677 }
678
679 CU.setStage(CompileUnit::Stage::LivenessAnalysisDone);
680 } break;
681
682 case CompileUnit::Stage::LivenessAnalysisDone: {
683 if (InterCUProcessingStarted) {
684 if (CU.updateDependenciesCompleteness())
685 HasNewGlobalDependency = true;
686 return false;
687 } else {
688 if (Error Err = finiteLoop(Iteration: [&]() -> Expected<bool> {
689 return CU.updateDependenciesCompleteness();
690 }))
691 return std::move(Err);
692
693 CU.setStage(CompileUnit::Stage::UpdateDependenciesCompleteness);
694 }
695 } break;
696
697 case CompileUnit::Stage::UpdateDependenciesCompleteness:
698#ifndef NDEBUG
699 CU.verifyDependencies();
700#endif
701
702 if (ArtificialTypeUnit) {
703 if (Error Err =
704 CU.assignTypeNames(TypePoolRef&: ArtificialTypeUnit->getTypePool()))
705 return std::move(Err);
706 }
707 CU.setStage(CompileUnit::Stage::TypeNamesAssigned);
708 break;
709
710 case CompileUnit::Stage::TypeNamesAssigned:
711 // Clone input compile unit.
712 if (CU.isClangModule() ||
713 GlobalData.getOptions().UpdateIndexTablesOnly ||
714 CU.getContainingFile().Addresses->hasValidRelocs()) {
715 if (Error Err = CU.cloneAndEmit(TargetTriple: GlobalData.getTargetTriple(),
716 ArtificialTypeUnit))
717 return std::move(Err);
718 }
719
720 CU.setStage(CompileUnit::Stage::Cloned);
721 break;
722
723 case CompileUnit::Stage::Cloned:
724 // Update DIEs referencies.
725 CU.updateDieRefPatchesWithClonedOffsets();
726
727 // Later than cloning, so that the offsets are final, and no later,
728 // because a unit which got this far can no longer be skipped and have
729 // its section dropped from the output.
730 if (CU.isClangModule())
731 CU.noteModuleAnchors();
732
733 CU.setStage(CompileUnit::Stage::PatchesUpdated);
734 break;
735
736 case CompileUnit::Stage::PatchesUpdated:
737 // Cleanup resources.
738 CU.cleanupDataAfterClonning();
739 CU.setStage(CompileUnit::Stage::Cleaned);
740 break;
741
742 case CompileUnit::Stage::Cleaned:
743 assert(false);
744 break;
745
746 case CompileUnit::Stage::Skipped:
747 // Nothing to do.
748 break;
749 }
750
751 return true;
752 })) {
753 CU.error(Err: std::move(Err));
754 CU.cleanupDataAfterClonning();
755 CU.setStage(CompileUnit::Stage::Skipped);
756 }
757}
758
759Error DWARFLinkerImpl::LinkContext::emitInvariantSections() {
760 if (!GlobalData.getTargetTriple().has_value())
761 return Error::success();
762
763 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugLoc).OS
764 << InputDWARFFile.Dwarf->getDWARFObj().getLocSection().Data;
765 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugLocLists).OS
766 << InputDWARFFile.Dwarf->getDWARFObj().getLoclistsSection().Data;
767 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugRange).OS
768 << InputDWARFFile.Dwarf->getDWARFObj().getRangesSection().Data;
769 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugRngLists).OS
770 << InputDWARFFile.Dwarf->getDWARFObj().getRnglistsSection().Data;
771 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugARanges).OS
772 << InputDWARFFile.Dwarf->getDWARFObj().getArangesSection();
773 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugFrame).OS
774 << InputDWARFFile.Dwarf->getDWARFObj().getFrameSection().Data;
775 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugAddr).OS
776 << InputDWARFFile.Dwarf->getDWARFObj().getAddrSection().Data;
777
778 return Error::success();
779}
780
781Error DWARFLinkerImpl::LinkContext::scanFrameData() {
782 if (GlobalData.getOptions().UpdateIndexTablesOnly)
783 return Error::success();
784 if (!GlobalData.getTargetTriple().has_value())
785 return Error::success();
786
787 if (InputDWARFFile.Dwarf == nullptr)
788 return Error::success();
789 if (CompileUnits.empty())
790 return Error::success();
791
792 const DWARFObject &InputDWARFObj = InputDWARFFile.Dwarf->getDWARFObj();
793
794 StringRef OrigFrameData = InputDWARFObj.getFrameSection().Data;
795 if (OrigFrameData.empty())
796 return Error::success();
797
798 auto Scan = std::make_unique<FrameScanResult>();
799 Scan->FrameData = OrigFrameData;
800 Scan->AddressSize = InputDWARFObj.getAddressSize();
801
802 RangesTy AllUnitsRanges;
803 for (std::unique_ptr<CompileUnit> &Unit : CompileUnits) {
804 for (auto CurRange : Unit->getFunctionRanges())
805 AllUnitsRanges.insert(Range: CurRange.Range, Value: CurRange.Value);
806 }
807
808 StringRef FrameBytes = Scan->FrameData;
809 DataExtractor Data(FrameBytes, InputDWARFObj.isLittleEndian());
810 uint64_t InputOffset = 0;
811 const unsigned SrcAddrSize = Scan->AddressSize;
812 // Width of the CIE_pointer field at the start of every FDE (and of the
813 // CIE_id sentinel at the start of every CIE) in DWARF32 .debug_frame.
814 constexpr unsigned CIEPointerSize = 4;
815
816 // CIEs defined in this input, keyed by their input offsets.
817 DenseMap<uint64_t, StringRef> LocalCIEs;
818 DenseSet<uint64_t> AddedCIEs;
819
820 while (Data.isValidOffset(offset: InputOffset)) {
821 uint64_t EntryOffset = InputOffset;
822 uint32_t InitialLength = Data.getU32(offset_ptr: &InputOffset);
823 if (InitialLength == 0xFFFFFFFF)
824 return createFileError(F: InputDWARFFile.FileName,
825 E: createStringError(EC: std::errc::invalid_argument,
826 Fmt: "Dwarf64 bits not supported"));
827
828 // Reject lengths that don't fit in the input section. substr() saturates
829 // silently, which would otherwise let a malformed length poison the
830 // CIE bytes used as the registry key.
831 if (InitialLength > FrameBytes.size() - InputOffset)
832 return createFileError(
833 F: InputDWARFFile.FileName,
834 E: createStringError(EC: std::errc::invalid_argument,
835 Fmt: "Truncated .debug_frame entry."));
836
837 uint32_t CIEId = Data.getU32(offset_ptr: &InputOffset);
838 if (CIEId == 0xFFFFFFFF) {
839 // This is a CIE, store it.
840 StringRef CIEData = FrameBytes.substr(Start: EntryOffset, N: InitialLength + 4);
841 LocalCIEs[EntryOffset] = CIEData;
842 // The -4 is to account for the CIEId we just read.
843 InputOffset += InitialLength - 4;
844 continue;
845 }
846
847 uint64_t Loc = Data.getUnsigned(offset_ptr: &InputOffset, byte_size: SrcAddrSize);
848
849 // Some compilers seem to emit frame info that doesn't start at
850 // the function entry point, thus we can't just lookup the address
851 // in the debug map. Use the AddressInfo's range map to see if the FDE
852 // describes something that we can relocate.
853 std::optional<AddressRangeValuePair> Range =
854 AllUnitsRanges.getRangeThatContains(Addr: Loc);
855 if (!Range) {
856 // The +4 is to account for the size of the InitialLength field itself.
857 InputOffset = EntryOffset + InitialLength + 4;
858 continue;
859 }
860
861 // This is an FDE, and we have a mapping.
862 StringRef CIEData = LocalCIEs.lookup(Val: CIEId);
863 if (CIEData.empty())
864 return createFileError(
865 F: InputDWARFFile.FileName,
866 E: createStringError(EC: std::errc::invalid_argument,
867 Fmt: "Inconsistent debug_frame content. Dropping."));
868
869 // Reject FDEs whose length doesn't even cover the CIE_pointer and
870 // initial_location fields; otherwise the unsigned subtraction below
871 // would wrap and substr() would saturate to a giant garbage blob.
872 if (InitialLength < CIEPointerSize + SrcAddrSize)
873 return createFileError(F: InputDWARFFile.FileName,
874 E: createStringError(EC: std::errc::invalid_argument,
875 Fmt: "Truncated .debug_frame FDE."));
876
877 // Promote each CIE on first reference; CIEs no FDE references are
878 // dropped from the output.
879 if (AddedCIEs.insert(V: CIEId).second)
880 Scan->CIEs.push_back(Elt: CIEData);
881
882 unsigned FDERemainingBytes = InitialLength - (CIEPointerSize + SrcAddrSize);
883 Scan->FDEs.push_back(Elt: {.CIEBytes: CIEData, .Address: Loc + Range->Value,
884 .Instructions: FrameBytes.substr(Start: InputOffset, N: FDERemainingBytes)});
885 InputOffset += FDERemainingBytes;
886 }
887
888 FrameScan = std::move(Scan);
889 return Error::success();
890}
891
892void DWARFLinkerImpl::LinkContext::registerCIEs(CIERegistry &CIEs) {
893 assert(FrameScan && "registerCIEs called without FrameScan");
894 SectionDescriptor &OutSection =
895 getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugFrame);
896
897 uint32_t NextLocalOffset = 0;
898 for (StringRef CIEBytes : FrameScan->CIEs) {
899 auto [It, Inserted] =
900 CIEs.try_emplace(Key: CIEBytes, Args: CIELocation{.OwnerSection: &OutSection, .LocalOffset: NextLocalOffset});
901 if (Inserted) {
902 FrameScan->OwnedCIEs.push_back(Elt: CIEBytes);
903 NextLocalOffset += static_cast<uint32_t>(CIEBytes.size());
904 }
905 }
906}
907
908Error DWARFLinkerImpl::LinkContext::emitDebugFrame(const CIERegistry &CIEs) {
909 assert(FrameScan && "emitDebugFrame called without FrameScan");
910 SectionDescriptor &OutSection =
911 getSectionDescriptor(SectionKind: DebugSectionKind::DebugFrame);
912
913 // Emit owned CIEs at the offsets registerCIEs reserved for them.
914 for (StringRef CIEBytes : FrameScan->OwnedCIEs)
915 OutSection.OS << CIEBytes;
916
917 const dwarf::FormParams FP = OutSection.getFormParams();
918 const unsigned SrcAddrSize = FrameScan->AddressSize;
919
920 for (const FrameScanResult::FDE &FDE : FrameScan->FDEs) {
921 auto It = CIEs.find(Key: FDE.CIEBytes);
922 assert(It != CIEs.end() && "CIE missing from registry");
923 SectionDescriptor *CIEOwnerSection = It->second.OwnerSection;
924 const uint32_t CIELocalOffset = It->second.LocalOffset;
925
926 const uint64_t FDEPos = OutSection.OS.tell();
927 // Note: this guards against a single context's section exceeding the
928 // DWARF32 limit. It does NOT catch the post-glue overflow that would
929 // happen if the concatenated .debug_frame across all contexts pushes
930 // past 4 GB; that case slips through silently because StartOffset is
931 // not yet assigned. A post-glue check would belong in the patch
932 // resolver in OutputSections.cpp.
933 if (FDEPos > FP.getDwarfMaxOffset())
934 return createFileError(
935 F: InputDWARFFile.FileName,
936 E: createStringError(S: ".debug_frame section offset "
937 "0x" +
938 Twine::utohexstr(Val: FDEPos) + " exceeds the " +
939 dwarf::FormatString(Format: FP.Format) + " limit"));
940
941 // CIE_pointer field follows the 4-byte initial_length.
942 OutSection.notePatch(Patch: DebugOffsetPatch{FDEPos + 4, CIEOwnerSection, true});
943
944 emitFDE(CIEOffset: CIELocalOffset, AddrSize: SrcAddrSize, Address: FDE.Address, FDEBytes: FDE.Instructions,
945 Section&: OutSection);
946 }
947
948 FrameScan.reset();
949 return Error::success();
950}
951
952Error DWARFLinkerImpl::LinkContext::unloadInput() {
953 // Scan the input's .debug_frame now, while the DWARFContext is still
954 // loaded, so the later (post-pool) emission pass can run against the
955 // scan result alone.
956 Error ScanErr = scanFrameData();
957 InputDWARFFile.unload();
958 return ScanErr;
959}
960
961/// Emit a FDE into the debug_frame section. \p FDEBytes
962/// contains the FDE data without the length, CIE offset and address
963/// which will be replaced with the parameter values.
964void DWARFLinkerImpl::LinkContext::emitFDE(uint32_t CIEOffset,
965 uint32_t AddrSize, uint64_t Address,
966 StringRef FDEBytes,
967 SectionDescriptor &Section) {
968 Section.emitIntVal(Val: FDEBytes.size() + 4 + AddrSize, Size: 4);
969 Section.emitIntVal(Val: CIEOffset, Size: 4);
970 Section.emitIntVal(Val: Address, Size: AddrSize);
971 Section.OS.write(Ptr: FDEBytes.data(), Size: FDEBytes.size());
972}
973
974void DWARFLinkerImpl::glueCompileUnitsAndWriteToTheOutput() {
975 if (!GlobalData.getTargetTriple().has_value())
976 return;
977 assert(SectionHandler);
978
979 // Go through all object files, all compile units and assign
980 // offsets to them.
981 assignOffsets();
982
983 // Patch size/offsets fields according to the assigned CU offsets.
984 patchOffsetsAndSizes();
985
986 // Emit common sections and write debug tables from all object files/compile
987 // units into the resulting file.
988 emitCommonSectionsAndWriteCompileUnitsToTheOutput();
989
990 if (ArtificialTypeUnit != nullptr)
991 ArtificialTypeUnit.reset();
992
993 // Write common debug sections into the resulting file.
994 writeCommonSectionsToTheOutput();
995
996 // Cleanup data.
997 cleanupDataAfterDWARFOutputIsWritten();
998
999 if (GlobalData.getOptions().Statistics)
1000 printStatistic();
1001}
1002
1003void DWARFLinkerImpl::printStatistic() {
1004
1005 // For each object file map how many bytes were emitted.
1006 StringMap<DebugInfoSize> SizeByObject;
1007
1008 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) {
1009 uint64_t AllDebugInfoSectionsSize = 0;
1010
1011 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1012 if (std::optional<SectionDescriptor *> DebugInfo =
1013 CU->tryGetSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo))
1014 AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size();
1015
1016 auto &Size = SizeByObject[Context->InputDWARFFile.FileName];
1017 Size.Input = Context->OriginalDebugInfoSize;
1018 Size.Output = AllDebugInfoSectionsSize;
1019 }
1020
1021 // Create a vector sorted in descending order by output size.
1022 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
1023 for (auto &E : SizeByObject)
1024 Sorted.emplace_back(args: E.first(), args&: E.second);
1025 llvm::sort(C&: Sorted, Comp: [](auto &LHS, auto &RHS) {
1026 return LHS.second.Output > RHS.second.Output;
1027 });
1028
1029 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
1030 const float Difference = Output - Input;
1031 const float Sum = Input + Output;
1032 if (Sum == 0)
1033 return 0;
1034 return (Difference / (Sum / 2));
1035 };
1036
1037 int64_t InputTotal = 0;
1038 int64_t OutputTotal = 0;
1039 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
1040
1041 // Print header.
1042 outs() << ".debug_info section size (in bytes)\n";
1043 outs() << "----------------------------------------------------------------"
1044 "---------------\n";
1045 outs() << "Filename Object "
1046 " dSYM Change\n";
1047 outs() << "----------------------------------------------------------------"
1048 "---------------\n";
1049
1050 // Print body.
1051 for (auto &E : Sorted) {
1052 InputTotal += E.second.Input;
1053 OutputTotal += E.second.Output;
1054 llvm::outs() << formatv(
1055 Fmt: FormatStr, Vals: sys::path::filename(path: E.first).take_back(N: 45), Vals&: E.second.Input,
1056 Vals&: E.second.Output, Vals: ComputePercentange(E.second.Input, E.second.Output));
1057 }
1058 // Print total and footer.
1059 outs() << "----------------------------------------------------------------"
1060 "---------------\n";
1061 llvm::outs() << formatv(Fmt: FormatStr, Vals: "Total", Vals&: InputTotal, Vals&: OutputTotal,
1062 Vals: ComputePercentange(InputTotal, OutputTotal));
1063 outs() << "----------------------------------------------------------------"
1064 "---------------\n\n";
1065}
1066
1067void DWARFLinkerImpl::assignOffsets() {
1068 llvm::parallel::TaskGroup TGroup;
1069 TGroup.spawn(f: [&]() { assignOffsetsToStrings(); });
1070 TGroup.spawn(f: [&]() { assignOffsetsToSections(); });
1071}
1072
1073void DWARFLinkerImpl::assignOffsetsToStrings() {
1074 size_t CurDebugStrIndex = 1; // start from 1 to take into account zero entry.
1075 uint64_t CurDebugStrOffset =
1076 1; // start from 1 to take into account zero entry.
1077 size_t CurDebugLineStrIndex = 0;
1078 uint64_t CurDebugLineStrOffset = 0;
1079
1080 // Enumerates all strings, add them into the DwarfStringPoolEntry map,
1081 // assign offset and index to the string if it is not indexed yet.
1082 forEachOutputString(StringHandler: [&](StringDestinationKind Kind,
1083 const StringEntry *String) {
1084 switch (Kind) {
1085 case StringDestinationKind::DebugStr: {
1086 DwarfStringPoolEntryWithExtString *Entry = DebugStrStrings.add(String);
1087 assert(Entry != nullptr);
1088
1089 if (!Entry->isIndexed()) {
1090 Entry->Offset = CurDebugStrOffset;
1091 CurDebugStrOffset += Entry->String.size() + 1;
1092 Entry->Index = CurDebugStrIndex++;
1093 }
1094 } break;
1095 case StringDestinationKind::DebugLineStr: {
1096 DwarfStringPoolEntryWithExtString *Entry =
1097 DebugLineStrStrings.add(String);
1098 assert(Entry != nullptr);
1099
1100 if (!Entry->isIndexed()) {
1101 Entry->Offset = CurDebugLineStrOffset;
1102 CurDebugLineStrOffset += Entry->String.size() + 1;
1103 Entry->Index = CurDebugLineStrIndex++;
1104 }
1105 } break;
1106 }
1107 });
1108}
1109
1110void DWARFLinkerImpl::assignOffsetsToSections() {
1111 std::array<uint64_t, SectionKindsNum> SectionSizesAccumulator = {0};
1112
1113 forEachObjectSectionsSet(SectionsSetHandler: [&](OutputSections &UnitSections) {
1114 UnitSections.assignSectionsOffsetAndAccumulateSize(SectionSizesAccumulator);
1115 });
1116}
1117
1118void DWARFLinkerImpl::forEachOutputString(
1119 function_ref<void(StringDestinationKind Kind, const StringEntry *String)>
1120 StringHandler) {
1121 // To save space we do not create any separate string table.
1122 // We use already allocated string patches and accelerator entries:
1123 // enumerate them in natural order and assign offsets.
1124 // ASSUMPTION: strings should be stored into .debug_str/.debug_line_str
1125 // sections in the same order as they were assigned offsets.
1126 forEachCompileUnit(UnitHandler: [&](CompileUnit *CU) {
1127 CU->forEach(Handler: [&](SectionDescriptor &OutSection) {
1128 OutSection.ListDebugStrPatch.forEach(Handler: [&](DebugStrPatch &Patch) {
1129 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1130 });
1131
1132 OutSection.ListDebugLineStrPatch.forEach(Handler: [&](DebugLineStrPatch &Patch) {
1133 StringHandler(StringDestinationKind::DebugLineStr, Patch.String);
1134 });
1135 });
1136
1137 CU->forEachAcceleratorRecord(Handler: [&](DwarfUnit::AccelInfo &Info) {
1138 StringHandler(DebugStr, Info.String);
1139 });
1140 });
1141
1142 if (ArtificialTypeUnit != nullptr) {
1143 ArtificialTypeUnit->forEach(Handler: [&](SectionDescriptor &OutSection) {
1144 OutSection.ListDebugStrPatch.forEach(Handler: [&](DebugStrPatch &Patch) {
1145 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1146 });
1147
1148 OutSection.ListDebugLineStrPatch.forEach(Handler: [&](DebugLineStrPatch &Patch) {
1149 StringHandler(StringDestinationKind::DebugLineStr, Patch.String);
1150 });
1151
1152 OutSection.ListDebugTypeStrPatch.forEach(Handler: [&](DebugTypeStrPatch &Patch) {
1153 if (Patch.Die == nullptr)
1154 return;
1155
1156 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
1157 if (&TypeEntry->getFinalDie() != Patch.Die)
1158 return;
1159
1160 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1161 });
1162
1163 OutSection.ListDebugTypeLineStrPatch.forEach(
1164 Handler: [&](DebugTypeLineStrPatch &Patch) {
1165 if (Patch.Die == nullptr)
1166 return;
1167
1168 TypeEntryBody *TypeEntry = Patch.TypeName->getValue().load();
1169 if (&TypeEntry->getFinalDie() != Patch.Die)
1170 return;
1171
1172 StringHandler(StringDestinationKind::DebugStr, Patch.String);
1173 });
1174 });
1175 }
1176}
1177
1178void DWARFLinkerImpl::forEachObjectSectionsSet(
1179 function_ref<void(OutputSections &)> SectionsSetHandler) {
1180 // Handle artificial type unit first.
1181 if (ArtificialTypeUnit != nullptr)
1182 SectionsSetHandler(*ArtificialTypeUnit);
1183
1184 // Then all modules(before regular compilation units).
1185 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1186 for (std::unique_ptr<CompileUnit> &ModuleUnit :
1187 Context->ModulesCompileUnits)
1188 if (ModuleUnit->getStage() != CompileUnit::Stage::Skipped)
1189 SectionsSetHandler(*ModuleUnit);
1190
1191 // Finally all compilation units.
1192 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts) {
1193 // Handle object file common sections.
1194 SectionsSetHandler(*Context);
1195
1196 // Handle compilation units.
1197 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1198 if (CU->getStage() != CompileUnit::Stage::Skipped)
1199 SectionsSetHandler(*CU);
1200 }
1201}
1202
1203void DWARFLinkerImpl::forEachCompileAndTypeUnit(
1204 function_ref<void(DwarfUnit *CU)> UnitHandler) {
1205 if (ArtificialTypeUnit != nullptr)
1206 UnitHandler(ArtificialTypeUnit.get());
1207
1208 // Enumerate module units.
1209 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1210 for (std::unique_ptr<CompileUnit> &ModuleUnit :
1211 Context->ModulesCompileUnits)
1212 if (ModuleUnit->getStage() != CompileUnit::Stage::Skipped)
1213 UnitHandler(ModuleUnit.get());
1214
1215 // Enumerate compile units.
1216 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1217 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1218 if (CU->getStage() != CompileUnit::Stage::Skipped)
1219 UnitHandler(CU.get());
1220}
1221
1222void DWARFLinkerImpl::forEachCompileUnit(
1223 function_ref<void(CompileUnit *CU)> UnitHandler) {
1224 // Enumerate module units.
1225 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1226 for (std::unique_ptr<CompileUnit> &ModuleUnit :
1227 Context->ModulesCompileUnits)
1228 if (ModuleUnit->getStage() != CompileUnit::Stage::Skipped)
1229 UnitHandler(ModuleUnit.get());
1230
1231 // Enumerate compile units.
1232 for (const std::unique_ptr<LinkContext> &Context : ObjectContexts)
1233 for (std::unique_ptr<CompileUnit> &CU : Context->CompileUnits)
1234 if (CU->getStage() != CompileUnit::Stage::Skipped)
1235 UnitHandler(CU.get());
1236}
1237
1238void DWARFLinkerImpl::patchOffsetsAndSizes() {
1239 forEachObjectSectionsSet(SectionsSetHandler: [&](OutputSections &SectionsSet) {
1240 SectionsSet.forEach(Handler: [&](SectionDescriptor &OutSection) {
1241 SectionsSet.applyPatches(Section&: OutSection, DebugStrStrings, DebugLineStrStrings,
1242 TypeUnitPtr: ArtificialTypeUnit.get());
1243 });
1244 });
1245}
1246
1247void DWARFLinkerImpl::emitCommonSectionsAndWriteCompileUnitsToTheOutput() {
1248 llvm::parallel::TaskGroup TG;
1249
1250 // Create section descriptors ahead if they are not exist at the moment.
1251 // SectionDescriptors container is not thread safe. Thus we should be sure
1252 // that descriptors would not be created in following parallel tasks.
1253
1254 CommonSections.getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugStr);
1255 CommonSections.getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugLineStr);
1256
1257 if (llvm::is_contained(Range&: GlobalData.Options.AccelTables,
1258 Element: AccelTableKind::Apple)) {
1259 CommonSections.getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::AppleNames);
1260 CommonSections.getOrCreateSectionDescriptor(
1261 SectionKind: DebugSectionKind::AppleNamespaces);
1262 CommonSections.getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::AppleObjC);
1263 CommonSections.getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::AppleTypes);
1264 }
1265
1266 if (llvm::is_contained(Range&: GlobalData.Options.AccelTables,
1267 Element: AccelTableKind::DebugNames))
1268 CommonSections.getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugNames);
1269
1270 // Emit .debug_str and .debug_line_str sections.
1271 TG.spawn(f: [&]() { emitStringSections(); });
1272
1273 if (llvm::is_contained(Range&: GlobalData.Options.AccelTables,
1274 Element: AccelTableKind::Apple)) {
1275 // Emit apple accelerator sections.
1276 TG.spawn(f: [&]() {
1277 emitAppleAcceleratorSections(TargetTriple: (*GlobalData.getTargetTriple()).get());
1278 });
1279 }
1280
1281 if (llvm::is_contained(Range&: GlobalData.Options.AccelTables,
1282 Element: AccelTableKind::DebugNames)) {
1283 // Emit .debug_names section.
1284 TG.spawn(f: [&]() {
1285 emitDWARFv5DebugNamesSection(TargetTriple: (*GlobalData.getTargetTriple()).get());
1286 });
1287 }
1288
1289 // Write compile units to the output file.
1290 TG.spawn(f: [&]() { writeCompileUnitsToTheOutput(); });
1291}
1292
1293void DWARFLinkerImpl::emitStringSections() {
1294 uint64_t DebugStrNextOffset = 0;
1295 uint64_t DebugLineStrNextOffset = 0;
1296
1297 // Emit zero length string. Accelerator tables does not work correctly
1298 // if the first string is not zero length string.
1299 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::DebugStr)
1300 .emitInplaceString(String: "");
1301 DebugStrNextOffset++;
1302
1303 forEachOutputString(
1304 StringHandler: [&](StringDestinationKind Kind, const StringEntry *String) {
1305 switch (Kind) {
1306 case StringDestinationKind::DebugStr: {
1307 DwarfStringPoolEntryWithExtString *StringToEmit =
1308 DebugStrStrings.getExistingEntry(String);
1309 assert(StringToEmit->isIndexed());
1310
1311 // Strings may be repeated. Use accumulated DebugStrNextOffset
1312 // to understand whether corresponding string is already emitted.
1313 // Skip string if its offset less than accumulated offset.
1314 if (StringToEmit->Offset >= DebugStrNextOffset) {
1315 DebugStrNextOffset =
1316 StringToEmit->Offset + StringToEmit->String.size() + 1;
1317 // Emit the string itself.
1318 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::DebugStr)
1319 .emitInplaceString(String: StringToEmit->String);
1320 }
1321 } break;
1322 case StringDestinationKind::DebugLineStr: {
1323 DwarfStringPoolEntryWithExtString *StringToEmit =
1324 DebugLineStrStrings.getExistingEntry(String);
1325 assert(StringToEmit->isIndexed());
1326
1327 // Strings may be repeated. Use accumulated DebugLineStrStrings
1328 // to understand whether corresponding string is already emitted.
1329 // Skip string if its offset less than accumulated offset.
1330 if (StringToEmit->Offset >= DebugLineStrNextOffset) {
1331 DebugLineStrNextOffset =
1332 StringToEmit->Offset + StringToEmit->String.size() + 1;
1333 // Emit the string itself.
1334 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::DebugLineStr)
1335 .emitInplaceString(String: StringToEmit->String);
1336 }
1337 } break;
1338 }
1339 });
1340}
1341
1342void DWARFLinkerImpl::emitAppleAcceleratorSections(const Triple &TargetTriple) {
1343 AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
1344 AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
1345 AccelTable<AppleAccelTableStaticOffsetData> AppleObjC;
1346 AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
1347
1348 forEachCompileAndTypeUnit(UnitHandler: [&](DwarfUnit *CU) {
1349 CU->forEachAcceleratorRecord(Handler: [&](const DwarfUnit::AccelInfo &Info) {
1350 uint64_t OutOffset = Info.OutOffset;
1351 switch (Info.Type) {
1352 case DwarfUnit::AccelType::None: {
1353 llvm_unreachable("Unknown accelerator record");
1354 } break;
1355 case DwarfUnit::AccelType::Namespace: {
1356 AppleNamespaces.addName(
1357 Name: *DebugStrStrings.getExistingEntry(String: Info.String),
1358 Args: CU->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo).StartOffset +
1359 OutOffset);
1360 } break;
1361 case DwarfUnit::AccelType::Name: {
1362 AppleNames.addName(
1363 Name: *DebugStrStrings.getExistingEntry(String: Info.String),
1364 Args: CU->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo).StartOffset +
1365 OutOffset);
1366 } break;
1367 case DwarfUnit::AccelType::ObjC: {
1368 AppleObjC.addName(
1369 Name: *DebugStrStrings.getExistingEntry(String: Info.String),
1370 Args: CU->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo).StartOffset +
1371 OutOffset);
1372 } break;
1373 case DwarfUnit::AccelType::Type: {
1374 AppleTypes.addName(
1375 Name: *DebugStrStrings.getExistingEntry(String: Info.String),
1376 Args: CU->getSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo).StartOffset +
1377 OutOffset,
1378 Args: Info.Tag,
1379 Args: Info.ObjcClassImplementation ? dwarf::DW_FLAG_type_implementation
1380 : 0,
1381 Args: Info.QualifiedNameHash);
1382 } break;
1383 }
1384 });
1385 });
1386
1387 {
1388 // FIXME: we use AsmPrinter to emit accelerator sections.
1389 // It might be beneficial to directly emit accelerator data
1390 // to the raw_svector_ostream.
1391 SectionDescriptor &OutSection =
1392 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::AppleNamespaces);
1393 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1394 OutSection.OS);
1395 if (Error Err = Emitter.init(TheTriple: TargetTriple, Swift5ReflectionSegmentName: "__DWARF")) {
1396 consumeError(Err: std::move(Err));
1397 return;
1398 }
1399
1400 // Emit table.
1401 Emitter.emitAppleNamespaces(Table&: AppleNamespaces);
1402 Emitter.finish();
1403
1404 // Set start offset and size for output section.
1405 OutSection.setSizesForSectionCreatedByAsmPrinter();
1406 }
1407
1408 {
1409 // FIXME: we use AsmPrinter to emit accelerator sections.
1410 // It might be beneficial to directly emit accelerator data
1411 // to the raw_svector_ostream.
1412 SectionDescriptor &OutSection =
1413 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::AppleNames);
1414 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1415 OutSection.OS);
1416 if (Error Err = Emitter.init(TheTriple: TargetTriple, Swift5ReflectionSegmentName: "__DWARF")) {
1417 consumeError(Err: std::move(Err));
1418 return;
1419 }
1420
1421 // Emit table.
1422 Emitter.emitAppleNames(Table&: AppleNames);
1423 Emitter.finish();
1424
1425 // Set start offset ans size for output section.
1426 OutSection.setSizesForSectionCreatedByAsmPrinter();
1427 }
1428
1429 {
1430 // FIXME: we use AsmPrinter to emit accelerator sections.
1431 // It might be beneficial to directly emit accelerator data
1432 // to the raw_svector_ostream.
1433 SectionDescriptor &OutSection =
1434 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::AppleObjC);
1435 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1436 OutSection.OS);
1437 if (Error Err = Emitter.init(TheTriple: TargetTriple, Swift5ReflectionSegmentName: "__DWARF")) {
1438 consumeError(Err: std::move(Err));
1439 return;
1440 }
1441
1442 // Emit table.
1443 Emitter.emitAppleObjc(Table&: AppleObjC);
1444 Emitter.finish();
1445
1446 // Set start offset ans size for output section.
1447 OutSection.setSizesForSectionCreatedByAsmPrinter();
1448 }
1449
1450 {
1451 // FIXME: we use AsmPrinter to emit accelerator sections.
1452 // It might be beneficial to directly emit accelerator data
1453 // to the raw_svector_ostream.
1454 SectionDescriptor &OutSection =
1455 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::AppleTypes);
1456 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1457 OutSection.OS);
1458 if (Error Err = Emitter.init(TheTriple: TargetTriple, Swift5ReflectionSegmentName: "__DWARF")) {
1459 consumeError(Err: std::move(Err));
1460 return;
1461 }
1462
1463 // Emit table.
1464 Emitter.emitAppleTypes(Table&: AppleTypes);
1465 Emitter.finish();
1466
1467 // Set start offset ans size for output section.
1468 OutSection.setSizesForSectionCreatedByAsmPrinter();
1469 }
1470}
1471
1472void DWARFLinkerImpl::emitDWARFv5DebugNamesSection(const Triple &TargetTriple) {
1473 std::unique_ptr<DWARF5AccelTable> DebugNames;
1474
1475 DebugNamesUnitsOffsets CompUnits;
1476 CompUnitIDToIdx CUidToIdx;
1477
1478 unsigned Id = 0;
1479
1480 forEachCompileAndTypeUnit(UnitHandler: [&](DwarfUnit *CU) {
1481 bool HasRecords = false;
1482 CU->forEachAcceleratorRecord(Handler: [&](const DwarfUnit::AccelInfo &Info) {
1483 if (DebugNames == nullptr)
1484 DebugNames = std::make_unique<DWARF5AccelTable>();
1485
1486 HasRecords = true;
1487 switch (Info.Type) {
1488 case DwarfUnit::AccelType::Name:
1489 case DwarfUnit::AccelType::Namespace:
1490 case DwarfUnit::AccelType::Type: {
1491 DebugNames->addName(Name: *DebugStrStrings.getExistingEntry(String: Info.String),
1492 Args: Info.OutOffset, Args: Info.ParentOffset, Args: Info.Tag,
1493 Args: CU->getUniqueID(),
1494 Args: CU->getTag() == dwarf::DW_TAG_type_unit);
1495 } break;
1496
1497 default:
1498 break; // Nothing to do.
1499 };
1500 });
1501
1502 if (HasRecords) {
1503 CompUnits.push_back(
1504 x: CU->getOrCreateSectionDescriptor(SectionKind: DebugSectionKind::DebugInfo)
1505 .StartOffset);
1506 CUidToIdx[CU->getUniqueID()] = Id++;
1507 }
1508 });
1509
1510 if (DebugNames != nullptr) {
1511 // FIXME: we use AsmPrinter to emit accelerator sections.
1512 // It might be beneficial to directly emit accelerator data
1513 // to the raw_svector_ostream.
1514 SectionDescriptor &OutSection =
1515 CommonSections.getSectionDescriptor(SectionKind: DebugSectionKind::DebugNames);
1516 DwarfEmitterImpl Emitter(DWARFLinker::OutputFileType::Object,
1517 OutSection.OS);
1518 if (Error Err = Emitter.init(TheTriple: TargetTriple, Swift5ReflectionSegmentName: "__DWARF")) {
1519 consumeError(Err: std::move(Err));
1520 return;
1521 }
1522
1523 // Emit table.
1524 Emitter.emitDebugNames(Table&: *DebugNames, CUOffsets&: CompUnits, UnitIDToIdxMap&: CUidToIdx);
1525 Emitter.finish();
1526
1527 // Set start offset ans size for output section.
1528 OutSection.setSizesForSectionCreatedByAsmPrinter();
1529 }
1530}
1531
1532void DWARFLinkerImpl::cleanupDataAfterDWARFOutputIsWritten() {
1533 GlobalData.getStringPool().clear();
1534 DebugStrStrings.clear();
1535 DebugLineStrStrings.clear();
1536}
1537
1538void DWARFLinkerImpl::writeCompileUnitsToTheOutput() {
1539 // Enumerate all sections and store them into the final emitter.
1540 forEachObjectSectionsSet(SectionsSetHandler: [&](OutputSections &Sections) {
1541 Sections.forEach(Handler: [&](std::shared_ptr<SectionDescriptor> OutSection) {
1542 // Emit section content.
1543 SectionHandler(OutSection);
1544 });
1545 });
1546}
1547
1548void DWARFLinkerImpl::writeCommonSectionsToTheOutput() {
1549 CommonSections.forEach(Handler: [&](std::shared_ptr<SectionDescriptor> OutSection) {
1550 SectionHandler(OutSection);
1551 });
1552}
1553