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