LLVM: lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
16
17using namespace llvm;
20
26 GlobalData.setWarningHandler(WarningHandler);
27}
28
35
36 if (File.Dwarf) {
37 if (!File.Dwarf->compile_units().empty())
38 CompileUnits.reserve(File.Dwarf->getNumCompileUnits());
39
40
41 Format.Version = File.Dwarf->getMaxVersion();
42 Format.AddrSize = File.Dwarf->getCUAddrSize();
43 Endianness = File.Dwarf->isLittleEndian() ? llvm::endianness::little
44 : llvm::endianness::big;
45 }
46}
47
51
55
60
63 ObjectContexts.emplace_back(std::make_unique(
65
67 for (const std::unique_ptr &CU :
68 ObjectContexts.back()->InputDWARFFile.Dwarf->compile_units()) {
71
72 if (!CUDie)
73 continue;
74
75 OnCUDieLoaded(*CU);
76
77
78 if (.getOptions().UpdateIndexTablesOnly)
79 ObjectContexts.back()->registerModuleReference(CUDie, Loader,
80 OnCUDieLoaded);
81 }
82 }
83}
84
88
90
92
94 return Err;
95
99
100 if (std::optional<std::reference_wrapper> CurTriple =
102 GlobalEndianness = (*CurTriple).get().isLittleEndian()
105 }
106 std::optional<uint16_t> Language;
107
108 for (std::unique_ptr &Context : ObjectContexts) {
109 if (Context->InputDWARFFile.Dwarf == nullptr) {
110 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness);
111 continue;
112 }
113
114 if (GlobalData.getOptions().Verbose) {
115 outs() << "DEBUG MAP OBJECT: " << Context->InputDWARFFile.FileName
116 << "\n";
117
118 for (const std::unique_ptr &OrigCU :
119 Context->InputDWARFFile.Dwarf->compile_units()) {
120 outs() << "Input compilation unit:";
124 OrigCU->getUnitDIE().dump(outs(), 0, DumpOpts);
125 }
126 }
127
128
129 if (GlobalData.getOptions().VerifyInputDWARF)
131
133 GlobalEndianness = Context->getEndianness();
135 std::max(GlobalFormat.AddrSize, Context->getFormParams().AddrSize);
136
137 Context->setOutputFormat(Context->getFormParams(), GlobalEndianness);
138
139
140
141
142 for (const std::unique_ptr &OrigCU :
143 Context->InputDWARFFile.Dwarf->compile_units()) {
144 DWARFDie UnitDie = OrigCU->getUnitDIE();
145
146 if (!Language) {
147 if (std::optional Val =
148 UnitDie.find(dwarf::DW_AT_language)) {
151 Language = LangVal;
152 }
153 }
154 }
155 }
156
157 if (GlobalFormat.AddrSize == 0) {
158 if (std::optional<std::reference_wrapper> TargetTriple =
160 GlobalFormat.AddrSize = (*TargetTriple).get().isArch32Bit() ? 4 : 8;
161 else
163 }
164
165 CommonSections.setOutputFormat(GlobalFormat, GlobalEndianness);
166
167 if (.Options.NoODR && Language.has_value()) {
169 TGroup.spawn([&]() {
172 });
173 }
174
175
176 if (GlobalData.getOptions().Threads == 0)
178 else
181
182
183 if (GlobalData.getOptions().Threads == 1) {
184 for (std::unique_ptr &Context : ObjectContexts) {
185
187 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
188
189 Context->InputDWARFFile.unload();
190 }
191 } else {
193 for (std::unique_ptr &Context : ObjectContexts)
194 Pool.async([&]() {
195
197 GlobalData.error(std::move(Err), Context->InputDWARFFile.FileName);
198
199 Context->InputDWARFFile.unload();
200 });
201
203 }
204
206 .getRoot()
207 ->getValue()
208 .load()
209 ->Children.empty()) {
210 if (GlobalData.getTargetTriple().has_value())
212 (*GlobalData.getTargetTriple()).get()))
213 return Err;
214 }
215
216
217
218
220
222}
223
226
227 std::string Buffer;
231 if (GlobalData.getOptions().InputVerificationHandler)
232 GlobalData.getOptions().InputVerificationHandler(File, OS.str());
233 }
234}
235
237 if (GlobalData.getOptions().TargetDWARFVersion == 0)
239 "target DWARF version is not set");
240
241 if (GlobalData.getOptions().Verbose && GlobalData.getOptions().Threads != 1) {
244 "set number of threads to 1 to make --verbose to work properly.", "");
245 }
246
247
248 if (GlobalData.getOptions().UpdateIndexTablesOnly &&
251
253}
254
255
256
260
263 CUDie.find({dwarf::DW_AT_dwo_id, dwarf::DW_AT_GNU_dwo_id}));
264 if (DwoId)
265 return *DwoId;
266 return 0;
267}
268
269static std::string
272 if (ObjectPrefixMap.empty())
273 return Path.str();
274
276 for (const auto &Entry : ObjectPrefixMap)
278 break;
279 return p.str().str();
280}
281
285 CUDie.find({dwarf::DW_AT_dwo_name, dwarf::DW_AT_GNU_dwo_name}), "");
286
287 if (PCMFile.empty())
288 return PCMFile;
289
290 if (ObjectPrefixMap)
291 PCMFile = remapPath(PCMFile, *ObjectPrefixMap);
292
293 return PCMFile;
294}
295
297 const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet) {
298 if (PCMFile.empty())
299 return std::make_pair(false, false);
300
301
303
305 if (Name.empty()) {
307 GlobalData.warn("anonymous module skeleton CU for " + PCMFile + ".",
309 return std::make_pair(true, true);
310 }
311
314 outs() << "Found clang module reference " << PCMFile;
315 }
316
319
320
321
322 if ( && GlobalData.getOptions().Verbose && (Cached->second != DwoId))
324 Twine("hash mismatch: this object file was built against a "
325 "different version of the module ") +
326 PCMFile + ".",
329 outs() << " [cached].\n";
330 return std::make_pair(true, true);
331 }
332
333 return std::make_pair(true, false);
334}
335
336
337
338
339
340
341
345 std::string PCMFile =
347 std::pair<bool, bool> IsClangModuleRef =
349
350 if (!IsClangModuleRef.first)
351 return false;
352
353 if (IsClangModuleRef.second)
354 return true;
355
357 outs() << " ...\n";
358
359
360
362
364 loadClangModule(Loader, CUDie, PCMFile, OnCUDieLoaded, Indent + 2)) {
366 return false;
367 }
368 return true;
369}
370
374
377
378
383
384
385
386 if (Loader == nullptr) {
387 GlobalData.error("cann't load clang module: loader is not specified.",
390 }
391
392 auto ErrOrObj = Loader(InputDWARFFile.FileName, Path);
393 if (!ErrOrObj)
395
396 std::unique_ptr Unit;
397 for (const auto &CU : ErrOrObj->Dwarf->compile_units()) {
398 OnCUDieLoaded(*CU);
399
400 auto ChildCUDie = CU->getUnitDIE();
401 if (!ChildCUDie)
402 continue;
404 if (Unit) {
405 std::string Err =
406 (PCMFile +
407 ": Clang modules are expected to have exactly 1 compile unit.\n");
410 }
411
412
413
415 if (PCMDwoId != DwoId) {
418 Twine("hash mismatch: this object file was built against a "
419 "different version of the module ") +
420 PCMFile + ".",
422
424 }
425
426
427 if (!ChildCUDie.hasChildren())
428 continue;
429
430
431 Unit = std::make_unique(
434 }
435 }
436
437 if (Unit) {
439
441 }
442
444}
445
450
451
454
455
458 });
459
460
461
462 if (.getOptions().UpdateIndexTablesOnly &&
465 outs() << "No valid relocations found. Skipping.\n";
467 }
468
470
471
472
473 for (const auto &OrigCU : InputDWARFFile.Dwarf->compile_units()) {
474
475 auto CUDie = OrigCU->getUnitDIE();
476 std::string PCMFile =
478
479
480
481 if (!CUDie || GlobalData.getOptions().UpdateIndexTablesOnly ||
483 CompileUnits.emplace_back(std::make_unique(
486
487
489 }
490 };
491
493
494
495
498 });
499
500
503
506
507
509 if (CU->isInterconnectedCU()) {
510 CU->maybeResetToLoadedStage();
513 }
514 });
515
516
520 });
521
523 }))
524 return Err;
525
526
533 });
535 }))
536 return Err;
538 if (CU->isInterconnectedCU() &&
541 });
542
543
547 });
548
549
553 });
554
555
559 });
560
561
565 });
566 }
567
568 if (GlobalData.getOptions().UpdateIndexTablesOnly) {
569
570
572 return Err;
574
575
578
579
580 TGroup.spawn([&]() {
582 ResultErr = std::move(Err);
583 });
584 return ResultErr;
585 }
586
588}
589
594 return;
595
597 if (CU.getStage() >= DoUntilStage)
598 return false;
599
600 switch (CU.getStage()) {
602
603
604 if (.loadInputDIEs()) {
605
606
608 } else {
609 CU.analyzeDWARFStructure();
610
611
612
613
614
615
617 CU.getOrigUnit().getUnitDIE(), nullptr,
620 else
622 }
623 } break;
624
626
627
631 "Flag indicating new inter-connections is not set");
632 return false;
633 }
634
636 } break;
637
640 if (CU.updateDependenciesCompleteness())
642 return false;
643 } else {
645 return CU.updateDependenciesCompleteness();
646 }))
647 return std::move(Err);
648
650 }
651 } break;
652
654#ifndef NDEBUG
655 CU.verifyDependencies();
656#endif
657
661 return std::move(Err);
662 }
664 break;
665
667
668 if (CU.isClangModule() ||
669 GlobalData.getOptions().UpdateIndexTablesOnly ||
670 CU.getContaingFile().Addresses->hasValidRelocs()) {
673 return std::move(Err);
674 }
675
677 break;
678
680
681 CU.updateDieRefPatchesWithClonedOffsets();
683 break;
684
686
687 CU.cleanupDataAfterClonning();
689 break;
690
693 break;
694
696
697 break;
698 }
699
700 return true;
701 })) {
702 CU.error(std::move(Err));
703 CU.cleanupDataAfterClonning();
705 }
706}
707
729
731 if (.getTargetTriple().has_value())
733
736
738
740 if (OrigFrameData.empty())
742
744 for (std::unique_ptr &Unit : CompileUnits) {
745 for (auto CurRange : Unit->getFunctionRanges())
746 AllUnitsRanges.insert(CurRange.Range, CurRange.Value);
747 }
748
749 unsigned SrcAddrSize = InputDWARFObj.getAddressSize();
750
753
756
757
758
760
761
762
764
765 while (Data.isValidOffset(InputOffset)) {
766 uint64_t EntryOffset = InputOffset;
767 uint32_t InitialLength = Data.getU32(&InputOffset);
768 if (InitialLength == 0xFFFFFFFF)
771 "Dwarf64 bits no supported"));
772
774 if (CIEId == 0xFFFFFFFF) {
775
776 StringRef CIEData = OrigFrameData.substr(EntryOffset, InitialLength + 4);
777 LocalCIES[EntryOffset] = CIEData;
778
779 InputOffset += InitialLength - 4;
780 continue;
781 }
782
783 uint64_t Loc = Data.getUnsigned(&InputOffset, SrcAddrSize);
784
785
786
787
788
789 std::optional Range =
792
793 InputOffset = EntryOffset + InitialLength + 4;
794 continue;
795 }
796
797
798
799 StringRef CIEData = LocalCIES[CIEId];
800 if (CIEData.empty())
804 "Inconsistent debug_frame content. Dropping."));
805
807
808
809
810 auto IteratorInserted =
811 EmittedCIEs.insert(std::make_pair(CIEData, OffsetToCIERecord));
812 OffsetToCIERecord = IteratorInserted.first->getValue();
813
814
815 if (IteratorInserted.second)
816 OutSection.OS << CIEData;
817
818
819
820
821
822
823 OutSection.notePatch(
825
826
827
828
829 unsigned FDERemainingBytes = InitialLength - (4 + SrcAddrSize);
830 emitFDE(OffsetToCIERecord, SrcAddrSize, Loc + Range->Value,
831 OrigFrameData.substr(InputOffset, FDERemainingBytes), OutSection);
832 InputOffset += FDERemainingBytes;
833 }
834
836}
837
838
839
840
845 Section.emitIntVal(FDEBytes.size() + 4 + AddrSize, 4);
846 Section.emitIntVal(CIEOffset, 4);
847 Section.emitIntVal(Address, AddrSize);
848 Section.OS.write(FDEBytes.data(), FDEBytes.size());
849}
850
852 if (.getTargetTriple().has_value())
853 return;
855
856
857
859
860
862
863
864
866
869
870
872
873
875
876 if (GlobalData.getOptions().Statistics)
878}
879
881
882
884
885 for (const std::unique_ptr &Context : ObjectContexts) {
886 uint64_t AllDebugInfoSectionsSize = 0;
887
888 for (std::unique_ptr &CU : Context->CompileUnits)
889 if (std::optional<SectionDescriptor *> DebugInfo =
891 AllDebugInfoSectionsSize += (*DebugInfo)->getContents().size();
892
893 auto &Size = SizeByObject[Context->InputDWARFFile.FileName];
894 Size.Input = Context->OriginalDebugInfoSize;
895 Size.Output = AllDebugInfoSectionsSize;
896 }
897
898
899 std::vector<std::pair<StringRef, DebugInfoSize>> Sorted;
900 for (auto &E : SizeByObject)
901 Sorted.emplace_back(E.first(), E.second);
902 llvm::sort(Sorted, [](auto &LHS, auto &RHS) {
903 return LHS.second.Output > RHS.second.Output;
904 });
905
906 auto ComputePercentange = [](int64_t Input, int64_t Output) -> float {
907 const float Difference = Output - Input;
908 const float Sum = Input + Output;
909 if (Sum == 0)
910 return 0;
911 return (Difference / (Sum / 2));
912 };
913
914 int64_t InputTotal = 0;
915 int64_t OutputTotal = 0;
916 const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
917
918
919 outs() << ".debug_info section size (in bytes)\n";
920 outs() << "----------------------------------------------------------------"
921 "---------------\n";
922 outs() << "Filename Object "
923 " dSYM Change\n";
924 outs() << "----------------------------------------------------------------"
925 "---------------\n";
926
927
928 for (auto &E : Sorted) {
929 InputTotal += E.second.Input;
930 OutputTotal += E.second.Output;
933 E.second.Output, ComputePercentange(E.second.Input, E.second.Output));
934 }
935
936 outs() << "----------------------------------------------------------------"
937 "---------------\n";
938 llvm::outs() << formatv(FormatStr, "Total", InputTotal, OutputTotal,
939 ComputePercentange(InputTotal, OutputTotal));
940 outs() << "----------------------------------------------------------------"
941 "---------------\n\n";
942}
943
949
951 size_t CurDebugStrIndex = 1;
953 1;
954 size_t CurDebugLineStrIndex = 0;
955 uint64_t CurDebugLineStrOffset = 0;
956
957
958
961 switch (Kind) {
964 assert(Entry != nullptr);
965
966 if (!Entry->isIndexed()) {
967 Entry->Offset = CurDebugStrOffset;
968 CurDebugStrOffset += Entry->String.size() + 1;
969 Entry->Index = CurDebugStrIndex++;
970 }
971 } break;
975 assert(Entry != nullptr);
976
977 if (!Entry->isIndexed()) {
978 Entry->Offset = CurDebugLineStrOffset;
979 CurDebugLineStrOffset += Entry->String.size() + 1;
980 Entry->Index = CurDebugLineStrIndex++;
981 }
982 } break;
983 }
984 });
985}
986
988 std::array<uint64_t, SectionKindsNum> SectionSizesAccumulator = {0};
989
992 });
993}
994
997 StringHandler) {
998
999
1000
1001
1002
1005 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
1007 });
1008
1009 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
1011 });
1012 });
1013
1015 StringHandler(DebugStr, Info.String);
1016 });
1017 });
1018
1021 OutSection.ListDebugStrPatch.forEach([&](DebugStrPatch &Patch) {
1023 });
1024
1025 OutSection.ListDebugLineStrPatch.forEach([&](DebugLineStrPatch &Patch) {
1027 });
1028
1029 OutSection.ListDebugTypeStrPatch.forEach([&](DebugTypeStrPatch &Patch) {
1030 if (Patch.Die == nullptr)
1031 return;
1032
1034 });
1035
1036 OutSection.ListDebugTypeLineStrPatch.forEach(
1038 if (Patch.Die == nullptr)
1039 return;
1040
1042 });
1043 });
1044 }
1045}
1046
1049
1052
1053
1054 for (const std::unique_ptr &Context : ObjectContexts)
1057 SectionsSetHandler(*ModuleUnit.Unit);
1058
1059
1060 for (const std::unique_ptr &Context : ObjectContexts) {
1061
1062 SectionsSetHandler(*Context);
1063
1064
1065 for (std::unique_ptr &CU : Context->CompileUnits)
1067 SectionsSetHandler(*CU);
1068 }
1069}
1070
1075
1076
1077 for (const std::unique_ptr &Context : ObjectContexts)
1080 UnitHandler(ModuleUnit.Unit.get());
1081
1082
1083 for (const std::unique_ptr &Context : ObjectContexts)
1084 for (std::unique_ptr &CU : Context->CompileUnits)
1086 UnitHandler(CU.get());
1087}
1088
1091
1092 for (const std::unique_ptr &Context : ObjectContexts)
1095 UnitHandler(ModuleUnit.Unit.get());
1096
1097
1098 for (const std::unique_ptr &Context : ObjectContexts)
1099 for (std::unique_ptr &CU : Context->CompileUnits)
1101 UnitHandler(CU.get());
1102}
1103
1112
1115
1116
1117
1118
1119
1122
1130 }
1131
1135
1136
1138
1141
1142 TG.spawn([&]() {
1144 });
1145 }
1146
1149
1150 TG.spawn([&]() {
1152 });
1153 }
1154
1155
1157}
1158
1160 uint64_t DebugStrNextOffset = 0;
1161 uint64_t DebugLineStrNextOffset = 0;
1162
1163
1164
1166 .emitInplaceString("");
1167 DebugStrNextOffset++;
1168
1171 switch (Kind) {
1176
1177
1178
1179
1180 if (StringToEmit->Offset >= DebugStrNextOffset) {
1181 DebugStrNextOffset =
1183
1185 .emitInplaceString(StringToEmit->String);
1186 }
1187 } break;
1192
1193
1194
1195
1196 if (StringToEmit->Offset >= DebugLineStrNextOffset) {
1197 DebugLineStrNextOffset =
1199
1201 .emitInplaceString(StringToEmit->String);
1202 }
1203 } break;
1204 }
1205 });
1206}
1207
1213
1216 uint64_t OutOffset = Info.OutOffset;
1217 switch (Info.Type) {
1220 } break;
1225 OutOffset);
1226 } break;
1231 OutOffset);
1232 } break;
1237 OutOffset);
1238 } break;
1243 OutOffset,
1244 Info.Tag,
1246 : 0,
1247 Info.QualifiedNameHash);
1248 } break;
1249 }
1250 });
1251 });
1252
1253 {
1254
1255
1256
1260 OutSection.OS);
1261 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1263 return;
1264 }
1265
1266
1269
1270
1272 }
1273
1274 {
1275
1276
1277
1281 OutSection.OS);
1282 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1284 return;
1285 }
1286
1287
1290
1291
1293 }
1294
1295 {
1296
1297
1298
1302 OutSection.OS);
1303 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1305 return;
1306 }
1307
1308
1311
1312
1314 }
1315
1316 {
1317
1318
1319
1323 OutSection.OS);
1324 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1326 return;
1327 }
1328
1329
1332
1333
1335 }
1336}
1337
1339 std::unique_ptr DebugNames;
1340
1343
1344 unsigned Id = 0;
1345
1347 bool HasRecords = false;
1350 DebugNames = std::make_unique();
1351
1352 HasRecords = true;
1353 switch (Info.Type) {
1358 Info.OutOffset, std::nullopt ,
1359 Info.Tag, CU->getUniqueID(),
1360 CU->getTag() == dwarf::DW_TAG_type_unit);
1361 } break;
1362
1363 default:
1364 break;
1365 };
1366 });
1367
1368 if (HasRecords) {
1369 CompUnits.push_back(
1371 .StartOffset);
1372 CUidToIdx[CU->getUniqueID()] = Id++;
1373 }
1374 });
1375
1377
1378
1379
1383 OutSection.OS);
1384 if (Error Err = Emitter.init(TargetTriple, "__DWARF")) {
1386 return;
1387 }
1388
1389
1392
1393
1395 }
1396}
1397
1403
1405
1407 Sections.forEach([&](std::shared_ptr OutSection) {
1408
1410 });
1411 });
1412}
1413
1415 CommonSections.forEach([&](std::shared_ptr OutSection) {
1417 });
1418}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
static fatal_error_handler_t ErrorHandler
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
The Input class is used to parse a yaml document into in-memory structs and vectors.
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
std::optional< T > getRangeThatContains(uint64_t Addr) const
void insert(AddressRange Range, int64_t Value)
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
LLVM_ABI std::optional< DWARFFormValue > find(dwarf::Attribute Attr) const
Extract the specified attribute from this DIE.
virtual bool isLittleEndian() const =0
virtual StringRef getFileName() const
virtual const DWARFSection & getFrameSection() const
virtual uint8_t getAddressSize() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
void wait() override
Blocking wait for all the tasks to execute first.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
auto async(Function &&F, Args &&...ArgList)
Asynchronous submission of a task to the pool.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class represents DWARF information for source file and it's address map.
std::map< std::string, std::string > ObjectPrefixMapTy
function_ref< void(const DWARFUnit &Unit)> CompileUnitHandlerTy
std::function< void( const Twine &Warning, StringRef Context, const DWARFDie *DIE)> MessageHandlerTy
@ DebugNames
.debug_names.
@ Apple
.apple_names, .apple_namespaces, .apple_types, .apple_objc.
std::function< ErrorOr< DWARFFile & >( StringRef ContainerName, StringRef Path)> ObjFileLoaderTy
Stores all information related to a compile unit, be it in its original instance of the object file o...
Stage
The stages of new compile unit processing.
@ Cloned
Output DWARF is generated.
@ TypeNamesAssigned
Type names assigned to DIEs.
@ CreatedNotLoaded
Created, linked with input DWARF file.
@ PatchesUpdated
Offsets inside patch records are updated.
@ Cleaned
Resources(Input DWARF, Output DWARF tree) are released.
@ Loaded
Input DWARF is loaded.
@ LivenessAnalysisDone
Input DWARF is analysed(DIEs pointing to the real code section arediscovered, type names are assigned...
@ UpdateDependenciesCompleteness
Check if dependencies have incompatible placement.
@ Skipped
Compile Unit should be skipped.
void forEachObjectSectionsSet(function_ref< void(OutputSections &SectionsSet)> SectionsSetHandler)
Enumerates sections for modules, invariant for object files, compile units.
Definition DWARFLinkerImpl.cpp:1047
void emitDWARFv5DebugNamesSection(const Triple &TargetTriple)
Emit .debug_names section.
Definition DWARFLinkerImpl.cpp:1338
void writeCompileUnitsToTheOutput()
Enumerate all compile units and put their data into the output stream.
Definition DWARFLinkerImpl.cpp:1404
void forEachCompileUnit(function_ref< void(CompileUnit *CU)> UnitHandler)
Enumerates all comple units.
Definition DWARFLinkerImpl.cpp:1089
void assignOffsetsToStrings()
Enumerate all compile units and assign offsets to their strings.
Definition DWARFLinkerImpl.cpp:950
void assignOffsets()
Enumerate all compile units and assign offsets to their sections and strings.
Definition DWARFLinkerImpl.cpp:944
Error link() override
Link debug info for added files.
Definition DWARFLinkerImpl.cpp:89
Error validateAndUpdateOptions()
Validate specified options.
Definition DWARFLinkerImpl.cpp:236
void writeCommonSectionsToTheOutput()
Enumerate common sections and put their data into the output stream.
Definition DWARFLinkerImpl.cpp:1414
void assignOffsetsToSections()
Enumerate all compile units and assign offsets to their sections.
Definition DWARFLinkerImpl.cpp:987
void printStatistic()
Print statistic for processed Debug Info.
Definition DWARFLinkerImpl.cpp:880
void glueCompileUnitsAndWriteToTheOutput()
Take already linked compile units and glue them into single file.
Definition DWARFLinkerImpl.cpp:851
void emitAppleAcceleratorSections(const Triple &TargetTriple)
Emit apple accelerator sections.
Definition DWARFLinkerImpl.cpp:1208
void verifyInput(const DWARFFile &File)
Verify input DWARF file.
Definition DWARFLinkerImpl.cpp:224
void forEachCompileAndTypeUnit(function_ref< void(DwarfUnit *CU)> UnitHandler)
Enumerates all compile and type units.
Definition DWARFLinkerImpl.cpp:1071
void emitStringSections()
Emit string sections.
Definition DWARFLinkerImpl.cpp:1159
DWARFLinkerImpl(MessageHandlerTy ErrorHandler, MessageHandlerTy WarningHandler)
Definition DWARFLinkerImpl.cpp:21
void addObjectFile(DWARFFile &File, ObjFileLoaderTy Loader=nullptr, CompileUnitHandlerTy OnCUDieLoaded=[](const DWARFUnit &) {}) override
Add object file to be linked.
Definition DWARFLinkerImpl.cpp:61
void cleanupDataAfterDWARFOutputIsWritten()
Cleanup data(string pools) after output sections are generated.
Definition DWARFLinkerImpl.cpp:1398
void forEachOutputString(function_ref< void(StringDestinationKind, const StringEntry *)> StringHandler)
Enumerates all strings.
Definition DWARFLinkerImpl.cpp:995
void emitCommonSectionsAndWriteCompileUnitsToTheOutput()
Emit debug sections common for all input files.
Definition DWARFLinkerImpl.cpp:1113
void patchOffsetsAndSizes()
Enumerates all patches and update them with the correct values.
Definition DWARFLinkerImpl.cpp:1104
This class emits DWARF data to the output stream.
Base class for all Dwarf units(Compile unit/Type table unit).
This class keeps data and services common for the whole linking process.
This class keeps contents and offsets to the debug sections.
void applyPatches(SectionDescriptor &Section, StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, TypeUnit *TypeUnitPtr)
Enumerate all sections, for each section apply all section patches.
OutputSections(LinkingGlobalData &GlobalData)
LinkingGlobalData & GlobalData
void forEach(function_ref< void(SectionDescriptor &)> Handler)
Enumerate all sections and call Handler for each.
llvm::endianness getEndianness() const
Endiannes for the sections.
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
void assignSectionsOffsetAndAccumulateSize(std::array< uint64_t, SectionKindsNum > &SectionSizesAccumulator)
Enumerate all sections, for each section set current offset (kept by SectionSizesAccumulator),...
Type Unit is used to represent an artificial compilation unit which keeps all type information.
An efficient, type-erasing, non-owning reference to a callable.
LLVM_ABI void spawn(std::function< void()> f)
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
LinkingGlobalData GlobalData
std::atomic< size_t > UniqueUnitID
Unique ID for compile unit.
uint64_t OverallNumberOfCU
Overall compile units number.
SmallVector< std::unique_ptr< LinkContext > > ObjectContexts
Keeps all linking contexts.
StringEntryToDwarfStringPoolEntryMap DebugLineStrStrings
DwarfStringPoolEntries for .debug_line_str section.
SectionHandlerTy SectionHandler
Hanler for output sections.
std::unique_ptr< TypeUnit > ArtificialTypeUnit
Type unit.
StringEntryToDwarfStringPoolEntryMap DebugStrStrings
DwarfStringPoolEntries for .debug_str section.
OutputSections CommonSections
Common sections.
StringMap< uint64_t > ClangModules
Mapping the PCM filename to the DwoId.
void setEstimatedObjfilesAmount(unsigned ObjFilesNum) override
Set estimated objects files amount, for preliminary data allocation.
Definition DWARFLinkerImpl.cpp:85
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isODRLanguage(uint16_t Language)
std::vector< std::variant< MCSymbol *, uint64_t > > DebugNamesUnitsOffsets
DenseMap< unsigned, unsigned > CompUnitIDToIdx
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
Error finiteLoop(function_ref< Expected< bool >()> Iteration, size_t MaxCounter=100000)
This function calls Iteration() until it returns false.
AddressRangesMap RangesTy
Mapped value in the address map is the offset to apply to the linked address.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
@ DW_FLAG_type_implementation
std::optional< uint64_t > toUnsigned(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract an unsigned constant.
LLVM_ABI ThreadPoolStrategy strategy
LLVM_ABI bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
Error createFileError(const Twine &F, Error E)
Concatenate a source file path and/or name with an Error.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
LLVM_ABI raw_fd_ostream & outs()
This returns a reference to a raw_fd_ostream for standard output.
static std::string remapPath(StringRef Path, const DWARFLinkerBase::ObjectPrefixMapTy &ObjectPrefixMap)
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
static void resolveRelativeObjectPath(SmallVectorImpl< char > &Buf, DWARFDie CU)
Resolve the relative path to a build artifact referenced by DWARF by applying DW_AT_comp_dir.
static std::string getPCMFile(const DWARFDie &CUDie, const DWARFLinkerBase::ObjectPrefixMapTy *ObjectPrefixMap)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
void sort(IteratorTy Start, IteratorTy End)
ThreadPoolStrategy optimal_concurrency(unsigned TaskCount=0)
Returns an optimal thread strategy to execute specified amount of tasks.
static uint64_t getDwoId(const DWARFDie &CUDie)
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
SingleThreadExecutor DefaultThreadPool
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn)
void consumeError(Error Err)
Consume a Error without doing anything.
Implement std::hash so that hash_code can be used in STL containers.
Container for dump options that control which debug information will be dumped.
DIDumpOptions noImplicitRecursion() const
Return the options with RecurseDepth set to 0 unless explicitly required.
unsigned ChildRecurseDepth
DwarfStringPoolEntry with string keeping externally.
A helper struct providing information about the byte size of DW_FORM values that vary in size dependi...
Keep information for referenced clang module: already loaded DWARF info of the clang module and a Com...
RefModuleUnit(DWARFFile &File, std::unique_ptr< CompileUnit > Unit)
Definition DWARFLinkerImpl.cpp:48
std::unique_ptr< CompileUnit > Unit
uint64_t getInputDebugInfoSize() const
Computes the total size of the debug info.
bool InterCUProcessingStarted
Flag indicating that all inter-connected units are loaded and the dwarf linking process for these uni...
bool registerModuleReference(const DWARFDie &CUDie, ObjFileLoaderTy Loader, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent=0)
If this compile unit is really a skeleton CU that points to a clang module, register it in ClangModul...
Definition DWARFLinkerImpl.cpp:342
Error loadClangModule(ObjFileLoaderTy Loader, const DWARFDie &CUDie, const std::string &PCMFile, CompileUnitHandlerTy OnCUDieLoaded, unsigned Indent=0)
Recursively add the debug info in this clang module .pcm file (and all the modules imported by it in ...
Definition DWARFLinkerImpl.cpp:371
DWARFFile & InputDWARFFile
Object file descriptor.
LinkContext(LinkingGlobalData &GlobalData, DWARFFile &File, StringMap< uint64_t > &ClangModules, std::atomic< size_t > &UniqueUnitID)
Definition DWARFLinkerImpl.cpp:29
uint64_t OriginalDebugInfoSize
Size of Debug info before optimizing.
Error emitInvariantSections()
Emit invariant sections.
Definition DWARFLinkerImpl.cpp:708
std::pair< bool, bool > isClangModuleRef(const DWARFDie &CUDie, std::string &PCMFile, unsigned Indent, bool Quiet)
Check whether specified CUDie is a Clang module reference.
Definition DWARFLinkerImpl.cpp:296
void addModulesCompileUnit(RefModuleUnit &&Unit)
Add Compile Unit corresponding to the module.
Definition DWARFLinkerImpl.cpp:56
void emitFDE(uint32_t CIEOffset, uint32_t AddrSize, uint64_t Address, StringRef FDEBytes, SectionDescriptor &Section)
Emit FDE record.
Definition DWARFLinkerImpl.cpp:841
UnitListTy CompileUnits
Set of Compilation Units(may be accessed asynchroniously for reading).
void linkSingleCompileUnit(CompileUnit &CU, TypeUnit *ArtificialTypeUnit, enum CompileUnit::Stage DoUntilStage=CompileUnit::Stage::Cleaned)
Link specified compile unit until specified stage.
Definition DWARFLinkerImpl.cpp:590
std::atomic< bool > HasNewInterconnectedCUs
Flag indicating that new inter-connected compilation units were discovered.
StringMap< uint64_t > & ClangModules
Error cloneAndEmitDebugFrame()
Clone and emit .debug_frame.
Definition DWARFLinkerImpl.cpp:730
std::atomic< size_t > & UniqueUnitID
Counter for compile units ID.
Error link(TypeUnit *ArtificialTypeUnit)
Link compile units for this context.
Definition DWARFLinkerImpl.cpp:446
std::atomic< bool > HasNewGlobalDependency
std::function< CompileUnit *(uint64_t)> getUnitForOffset
ModuleUnitListTy ModulesCompileUnits
Set of Compile Units for modules.
This structure is used to update strings offsets into .debug_line_str.
This structure is used to update strings offsets into .debug_str.
const StringEntry * String
This structure keeps fields which would be used for creating accelerator table.
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.