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