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 (GlobalData.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 (GlobalData.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 (Quiet && 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 (GlobalData.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 (CU.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 (GlobalData.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 (GlobalData.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.