LLVM: lib/CodeGen/AsmPrinter/DwarfDebug.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

57#include

58#include

59#include

60#include

61

62using namespace llvm;

63

64#define DEBUG_TYPE "dwarfdebug"

65

66STATISTIC(NumCSParams, "Number of dbg call site params created");

67

69 "use-dwarf-ranges-base-address-specifier", cl::Hidden,

70 cl::desc("Use base address specifiers in debug_ranges"), cl::init(false));

71

74 cl::desc("Generate dwarf aranges"),

76

79 cl::desc("Generate DWARF4 type units."),

81

83 "split-dwarf-cross-cu-references", cl::Hidden,

84 cl::desc("Enable cross-cu references in DWO files"), cl::init(false));

85

87

90 cl::desc("Make an absence of debug location information explicit."),

94

96 "accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."),

98 "Default for platform"),

103

106 cl::desc("Use inlined strings rather than string section."),

111

114 cl::desc("Disable emission .debug_ranges section."),

116

118 "dwarf-sections-as-references", cl::Hidden,

119 cl::desc("Use sections+offset as references rather than labels."),

123

126 cl::desc("Emit the GNU .debug_macro format with DWARF <5"),

128

131 cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"),

135

141

144 cl::desc("Which DWARF linkage-name attributes to emit."),

146 "Default for platform"),

149 "Abstract subprograms")),

151

154 cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more "

155 "address pool entry sharing to reduce relocations/object size"),

157 "Default address minimization strategy"),

159 "Use rnglists for contiguous ranges if that allows "

160 "using a pre-existing base address"),

162 "Expressions",

163 "Use exprloc addrx+offset expressions for any "

164 "address with a prior base address"),

166 "Use addrx+offset extension form for any address "

167 "with a prior base address"),

169 "Stuff")),

171

172

175 cl::desc("Set to false to ignore Key Instructions metadata"));

176

178

179void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) {

180 getActiveStreamer().emitInt8(

183}

184

185void DebugLocDwarfExpression::emitSigned(int64_t Value) {

186 getActiveStreamer().emitSLEB128(Value, Twine(Value));

187}

188

189void DebugLocDwarfExpression::emitUnsigned(uint64_t Value) {

190 getActiveStreamer().emitULEB128(Value, Twine(Value));

191}

192

193void DebugLocDwarfExpression::emitData1(uint8_t Value) {

194 getActiveStreamer().emitInt8(Value, Twine(Value));

195}

196

197void DebugLocDwarfExpression::emitBaseTypeRef(uint64_t Idx) {

199 getActiveStreamer().emitULEB128(Idx, Twine(Idx), ULEB128PadSize);

200}

201

204

205 return false;

206}

207

209 assert(!IsBuffering && "Already buffering?");

210 if (!TmpBuf)

211 TmpBuf = std::make_unique(OutBS.GenerateComments);

212 IsBuffering = true;

213}

214

216

218 return TmpBuf ? TmpBuf->Bytes.size() : 0;

219}

220

222 if (!TmpBuf)

223 return;

224 for (auto Byte : enumerate(TmpBuf->Bytes)) {

225 const char *Comment = (Byte.index() < TmpBuf->Comments.size())

226 ? TmpBuf->Comments[Byte.index()].c_str()

227 : "";

228 OutBS.emitInt8(Byte.value(), Comment);

229 }

230 TmpBuf->Bytes.clear();

231 TmpBuf->Comments.clear();

232}

233

237

238

242 const bool IsVariadic = !SingleLocExprOpt;

243

244

245 if (!IsVariadic && MI->isNonListDebugValue()) {

246 assert(MI->getNumDebugOperands() == 1 &&

247 "Mismatched DIExpression and debug operands for debug instruction.");

248 Expr = *SingleLocExprOpt;

249 }

250 assert(MI->getNumOperands() >= 3);

253 if (Op.isReg()) {

255 MI->isNonListDebugValue() && MI->isDebugOffsetImm());

257 } else if (Op.isTargetIndex()) {

260 } else if (Op.isImm())

262 else if (Op.isFPImm())

264 else if (Op.isCImm())

266 else

267 llvm_unreachable("Unexpected debug operand in DBG_VALUE* instruction!");

268 }

269 return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);

270}

271

273 std::optionalDIExpression::FragmentInfo Fragment = Expr.getFragmentInfo();

274 return Fragment ? Fragment->OffsetInBits : 0;

275}

276

280}

281

284}

285

288 Expr(ValueLoc.getExpression()) {

289 if (!Expr->getNumElements())

290 Expr = nullptr;

291}

292

295

299

305 return FIE.Expr && FIE.Expr->isFragment();

306 })) &&

307 "conflicting locations for variable");

308}

309

311 bool GenerateTypeUnits,

314

317

318

319

320 if (GenerateTypeUnits && (DwarfVersion < 5 || !TT.isOSBinFormatELF()))

322

323

324

325

326 if (DwarfVersion >= 5)

332}

333

336 InfoHolder(A, "info_string", DIEValueAllocator),

337 SkeletonHolder(A, "skel_string", DIEValueAllocator),

338 IsDarwin(A->TM.getTargetTriple().isOSDarwin()) {

339 const Triple &TT = Asm->TM.getTargetTriple();

340

341

342

344 DebuggerTuning = Asm->TM.Options.DebuggerTuning;

345 else if (IsDarwin)

347 else if (TT.isPS())

349 else if (TT.isOSAIX())

351 else

353

355 UseInlineStrings = TT.isNVPTX() || tuneForDBX();

356 else

358

359

361

362 HasAppleExtensionAttributes = tuneForLLDB();

363

364

365 HasSplitDwarf = Asm->TM.Options.MCOptions.SplitDwarfFile.empty();

366

367

370 else

372

373 unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion;

374 unsigned DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber

375 : MMI->getModule()->getDwarfVersion();

376

377 DwarfVersion =

379

380 bool Dwarf64 = DwarfVersion >= 3 &&

381 TT.isArch64Bit();

382

383

384

385

386

387

388 Dwarf64 &=

389 ((Asm->TM.Options.MCOptions.Dwarf64 || MMI->getModule()->isDwarf64()) &&

390 TT.isOSBinFormatELF()) ||

391 TT.isOSBinFormatXCOFF();

392

393 if (!Dwarf64 && TT.isArch64Bit() && TT.isOSBinFormatXCOFF())

395

397

398

400 UseSectionsAsReferences = TT.isNVPTX();

401 else

403

404

405 GenerateTypeUnits = (A->TM.getTargetTriple().isOSBinFormatELF() ||

406 A->TM.getTargetTriple().isOSBinFormatWasm()) &&

408

410 DwarfVersion, GenerateTypeUnits, DebuggerTuning, A->TM.getTargetTriple());

411

412

413

414

415

416

417 UseGNUTLSOpcode = tuneForGDB() || DwarfVersion < 3;

418

419 UseDWARF2Bitfields = DwarfVersion < 4;

420

421

422

423

424

425 UseSegmentedStringOffsetsTable = DwarfVersion >= 5;

426

427

428

429 EmitDebugEntryValues = Asm->TM.Options.ShouldEmitDebugEntryValues();

430

431

432

433 UseDebugMacroSection =

437 else

439

440

441

442 if (DwarfVersion >= 5)

444

445 Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);

446 Asm->OutStreamer->getContext().setDwarfFormat(Dwarf64 ? dwarf::DWARF64

448}

449

450

452

454 return Name.starts_with("+") || Name.starts_with("-");

455}

456

459 return false;

460

461 return Name.contains(") ");

462}

463

467 Class = In.slice(In.find('[') + 1, In.find(' '));

468 Category = "";

469 return;

470 }

471

472 Class = In.slice(In.find('[') + 1, In.find('('));

473 Category = In.slice(In.find('[') + 1, In.find(' '));

474}

475

477 return In.slice(In.find(' ') + 1, In.find(']'));

478}

479

480

488 return;

489

490 if (!SP->isDefinition())

491 return;

492

493 if (SP->getName() != "")

494 addAccelName(Unit, NameTableKind, SP->getName(), Die);

495

496

497

500

501

502

503

505 (useAllLinkageNames() || InfoHolder.getAbstractScopeDIEs().lookup(SP)))

507

508

509

513 addAccelObjC(Unit, NameTableKind, Class, Die);

514 if (Category != "")

515 addAccelObjC(Unit, NameTableKind, Category, Die);

516

518 }

519}

520

521

522

524 if (Scope->isAbstractScope())

525 return false;

526

527

530 return true;

531

532 if (Ranges.size() > 1)

533 return false;

534

535

536

538}

539

542 if (auto *SkelCU = CU.getSkeleton())

543 if (CU.getCUNode()->getSplitDebugInlining())

544 F(*SkelCU);

545}

546

550

554 auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());

555 if (CU.getSkeleton())

557

558 return CU;

559}

560

561void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,

563 assert(Scope && Scope->getScopeNode());

564 assert(Scope->isAbstractScope());

565 assert(!Scope->getInlinedAt());

566

568

569

570

571 auto &CU = getOrCreateDwarfCompileUnit(SP->getUnit());

573 TargetCU.constructAbstractSubprogramScopeDIE(Scope);

574 if (auto *SkelCU = CU.getSkeleton())

575 if (CU.getCUNode()->getSplitDebugInlining())

576 SkelCU->constructAbstractSubprogramScopeDIE(Scope);

577}

578

579

580

589

590

592

593

595

596

599 std::vector<uint64_t> Elts = Addition->getElements().vec();

600

602 llvm::erase(Elts, dwarf::DW_OP_stack_value);

605 return CombinedExpr;

606}

607

608

609

610template

614 for (auto Param : DescribedParams) {

615 bool ShouldCombineExpressions = Expr && Param.Expr->getNumElements() > 0;

616

617

618

619 if (ShouldCombineExpressions && Expr->isEntryValue())

620 continue;

621

622

623

624

625

628 : Expr;

629 assert((!CombinedExpr || CombinedExpr->isValid()) &&

630 "Combined debug expression is invalid");

631

635 ++NumCSParams;

636 }

637}

638

639

640

641

645 auto &ParamsForFwdReg = Worklist[Reg];

646 for (auto Param : ParamsToAdd) {

649 return D.ParamReg == Param.ParamReg;

650 }) &&

651 "Same parameter described twice by forwarding reg");

652

653

654

655

656

658 ParamsForFwdReg.push_back({Param.ParamReg, CombinedExpr});

659 }

660}

661

662

667

674

675

676

677

678

679

680

681

682

683

684

685

686

687

688

689

690

691

692

693

695

696

697

699 auto getForwardingRegsDefinedByMI = [&](const MachineInstr &MI,

701 if (MI.isDebugInstr())

702 return;

703

705 if (MO.getReg().isPhysical()) {

706 for (auto &FwdReg : ForwardedRegWorklist)

707 if (TRI.regsOverlap(FwdReg.first, MO.getReg()))

708 Defs.insert(FwdReg.first);

709 NewClobberedRegUnits.insert_range(TRI.regunits(MO.getReg()));

710 }

711 }

712 };

713

714

716

717 getForwardingRegsDefinedByMI(*CurMI, FwdRegDefs);

718 if (FwdRegDefs.empty()) {

719

720 ClobberedRegUnits.insert_range(NewClobberedRegUnits);

721 return;

722 }

723

724

725

726

727 auto IsRegClobberedInMeantime = [&](Register Reg) -> bool {

728 for (auto &RegUnit : ClobberedRegUnits)

729 if (TRI.hasRegUnit(Reg, RegUnit))

730 return true;

731 return false;

732 };

733

734 for (auto ParamFwdReg : FwdRegDefs) {

735 if (auto ParamValue = TII.describeLoadedValue(*CurMI, ParamFwdReg)) {

736 if (ParamValue->first.isImm()) {

737 int64_t Val = ParamValue->first.getImm();

739 ForwardedRegWorklist[ParamFwdReg], Params);

740 } else if (ParamValue->first.isReg()) {

741 Register RegLoc = ParamValue->first.getReg();

742 Register SP = TLI.getStackPointerRegisterToSaveRestore();

744 bool IsSPorFP = (RegLoc == SP) || (RegLoc == FP);

745 if (!IsRegClobberedInMeantime(RegLoc) &&

746 (TRI.isCalleeSavedPhysReg(RegLoc, *MF) || IsSPorFP)) {

749 ForwardedRegWorklist[ParamFwdReg], Params);

750 } else {

751

752

753

754

755

756

758 ForwardedRegWorklist[ParamFwdReg]);

759 }

760 }

761 }

762 }

763

764

765 for (auto ParamFwdReg : FwdRegDefs)

766 ForwardedRegWorklist.erase(ParamFwdReg);

767

768

769 ClobberedRegUnits.insert_range(NewClobberedRegUnits);

770

771

772

773 for (auto &New : TmpWorklistItems)

774 addToFwdRegWorklist(ForwardedRegWorklist, New.first, EmptyExpr, New.second);

775 TmpWorklistItems.clear();

776}

777

782

784 return true;

785

786

787

788

790 return false;

791

792 if (ForwardedRegWorklist.empty())

793 return false;

794

795

797 return true;

798

799 interpretValues(CurMI, ForwardedRegWorklist, Params, ClobberedRegUnits);

800

801 return true;

802}

803

804

805

810 auto CSInfo = CalleesMap.find(CallMI);

811

812

813 if (CSInfo == CalleesMap.end())

814 return;

815

817

818

820

822

825

826

827 for (const auto &ArgReg : CSInfo->second.ArgRegPairs) {

828 bool InsertedReg =

829 ForwardedRegWorklist.insert({ArgReg.Reg, {{ArgReg.Reg, EmptyExpr}}})

830 .second;

831 assert(InsertedReg && "Single register used to forward two arguments?");

832 (void)InsertedReg;

833 }

834

835

836 for (const auto &MO : CallMI->uses())

837 if (MO.isReg() && MO.isUndef())

838 ForwardedRegWorklist.erase(MO.getReg());

839

840

841

842

843

844

845

846

847

848 bool ShouldTryEmitEntryVals = MBB->getIterator() == MF->begin();

849

850

853 auto Suc = std::next(CallMI->getIterator());

854

856 (void)BundleEnd;

857 assert(std::next(Suc) == BundleEnd &&

858 "More than one instruction in call delay slot");

859

860 if (interpretNextInstr(&*Suc, ForwardedRegWorklist, Params, ClobberedRegUnits))

861 return;

862 }

863

864

865 for (; I != MBB->rend(); ++I) {

866

867 if (interpretNextInstr(&*I, ForwardedRegWorklist, Params, ClobberedRegUnits))

868 return;

869 }

870

871

872 if (ShouldTryEmitEntryVals) {

873

876 for (auto &RegEntry : ForwardedRegWorklist) {

879 }

880 }

881}

882

883void DwarfDebug::constructCallSiteEntryDIEs(const DISubprogram &SP,

886

887

888 if (SP.areAllCallsDescribed() || SP.isDefinition())

889 return;

890

891

892

893

894

895 CU.addFlag(ScopeDIE, CU.getDwarf5OrGNUAttr(dwarf::DW_AT_call_all_calls));

896

898 assert(TII && "TargetInstrInfo not found: cannot label tail calls");

899

900

901 auto delaySlotSupported = [&](const MachineInstr &MI) {

902 if (MI.isBundledWithSucc())

903 return false;

904 auto Suc = std::next(MI.getIterator());

906 (void)CallInstrBundle;

908 (void)DelaySlotBundle;

909

910

911

912

915 "Call and its successor instruction don't have same label after.");

916 return true;

917 };

918

919

920 for (const MachineBasicBlock &MBB : MF) {

921 for (const MachineInstr &MI : MBB.instrs()) {

922

923

924

925 if (MI.isBundle())

926 continue;

927

928

929

930 if (MI.isCandidateForAdditionalCallInfo())

931 continue;

932

933

934

936 continue;

937

938

939 if (MI.hasDelaySlot() && !delaySlotSupported(*&MI))

940 return;

941

943

944

945

946

948 bool PhysRegCalleeOperand =

950

951

952 if (CalleeOp.getOperandNo() < MI.getDesc().operands().size()) {

953 const MCOperandInfo &MCOI =

955 PhysRegCalleeOperand =

957 }

958

959 unsigned CallReg = 0;

960 const DISubprogram *CalleeSP = nullptr;

961 const Function *CalleeDecl = nullptr;

962 if (PhysRegCalleeOperand) {

963 CallReg = CalleeOp.getReg();

964 } else if (CalleeOp.isGlobal()) {

966 if (CalleeDecl)

967 CalleeSP = CalleeDecl->getSubprogram();

968 }

969

970

971

972 if (CalleeSP == nullptr && CallReg == 0 && AllocSiteTy == nullptr)

973 continue;

974

975

976

978

979

980

981

982 const MachineInstr *TopLevelCallMI =

984

985

986

987

988

989 const MCSymbol *PCAddr = (!IsTail || CU.useGNUAnalogForDwarf5Feature())

991 : nullptr;

992

993

994

997

998 assert((IsTail || PCAddr) && "Non-tail call without return PC");

999

1000 LLVM_DEBUG(dbgs() << "CallSiteEntry: " << MF.getName() << " -> "

1001 << (CalleeDecl ? CalleeDecl->getName()

1002 : StringRef(MF.getSubtarget()

1003 .getRegisterInfo()

1004 ->getName(CallReg)))

1005 << (IsTail ? " [IsTail]" : "") << "\n");

1006

1007 DIE &CallSiteDIE =

1008 CU.constructCallSiteEntryDIE(ScopeDIE, CalleeSP, CalleeDecl, IsTail,

1009 PCAddr, CallAddr, CallReg, AllocSiteTy);

1010

1011

1014

1016 CU.constructCallSiteParmEntryDIEs(CallSiteDIE, Params);

1017 }

1018 }

1019 }

1020}

1021

1023 if (U.hasDwarfPubSections())

1024 return;

1025

1026 U.addFlag(D, dwarf::DW_AT_GNU_pubnames);

1027}

1028

1029void DwarfDebug::finishUnitAttributes(const DICompileUnit *DIUnit,

1033

1037 std::string ProducerWithFlags = Producer.str() + " " + Flags.str();

1038 NewCU.addString(Die, dwarf::DW_AT_producer, ProducerWithFlags);

1039 } else

1040 NewCU.addString(Die, dwarf::DW_AT_producer, Producer);

1041

1043 NewCU.addUInt(Die, dwarf::DW_AT_language_name, dwarf::DW_FORM_data2,

1044 Lang.getName());

1045

1046 if (uint32_t LangVersion = Lang.getVersion(); LangVersion != 0)

1047 NewCU.addUInt(Die, dwarf::DW_AT_language_version, std::nullopt,

1048 LangVersion);

1049 } else {

1050 NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,

1051 Lang.getName());

1052 }

1053

1054 NewCU.addString(Die, dwarf::DW_AT_name, FN);

1055 StringRef SysRoot = DIUnit->getSysRoot();

1056 if (!SysRoot.empty())

1057 NewCU.addString(Die, dwarf::DW_AT_LLVM_sysroot, SysRoot);

1058 StringRef SDK = DIUnit->getSDK();

1059 if (!SDK.empty())

1060 NewCU.addString(Die, dwarf::DW_AT_APPLE_sdk, SDK);

1061

1063

1066

1068

1069

1070

1071 if (!CompilationDir.empty())

1072 NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);

1073 addGnuPubAttributes(NewCU, Die);

1074 }

1075

1078 NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized);

1079

1081 if (Flags.empty())

1082 NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags);

1083

1085 NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,

1086 dwarf::DW_FORM_data1, RVer);

1087 }

1088

1090

1091 NewCU.addUInt(Die, dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8,

1094

1096 ? dwarf::DW_AT_dwo_name

1097 : dwarf::DW_AT_GNU_dwo_name;

1099 }

1100 }

1101}

1102

1103

1105DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {

1106 if (auto *CU = CUMap.lookup(DIUnit))

1107 return *CU;

1108

1113 !CUMap.empty()) {

1114 return *CUMap.begin()->second;

1115 }

1117

1118 auto OwnedUnit = std::make_unique(

1119 InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);

1120 DwarfCompileUnit &NewCU = *OwnedUnit;

1121 InfoHolder.addUnit(std::move(OwnedUnit));

1122

1123

1124

1125

1126

1127 if (Asm->OutStreamer->hasRawTextSupport() || SingleCU)

1128 Asm->OutStreamer->emitDwarfFile0Directive(

1131

1133 NewCU.setSkeleton(constructSkeletonCU(NewCU));

1134 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoDWOSection());

1135 } else {

1136 finishUnitAttributes(DIUnit, NewCU);

1137 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());

1138 }

1139

1140 CUMap.insert({DIUnit, &NewCU});

1141 CUDieMap.insert({&NewCU.getUnitDie(), &NewCU});

1142 return NewCU;

1143}

1144

1145

1150

1151

1152

1153

1154

1155 if (A.Expr || B.Expr)

1156 return !B.Expr;

1157 auto FragmentA = A.Expr->getFragmentInfo();

1158 auto FragmentB = B.Expr->getFragmentInfo();

1159 if (!FragmentA || !FragmentB)

1160 return !!FragmentB;

1161 return FragmentA->OffsetInBits < FragmentB->OffsetInBits;

1162 });

1166 return A.Expr == B.Expr;

1167 }),

1168 GVEs.end());

1169 return GVEs;

1170}

1171

1172

1173

1174

1177

1178 if (Asm)

1179 return;

1180

1181 unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(),

1182 M->debug_compile_units_end());

1183 if (NumDebugCUs == 0)

1184 return;

1185

1186 assert(NumDebugCUs > 0 && "Asm unexpectedly initialized");

1187 SingleCU = NumDebugCUs == 1;

1189 GVMap;

1192 Global.getDebugInfo(GVs);

1193 for (auto *GVE : GVs)

1194 GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});

1195 }

1196

1197

1198

1199

1202 .setStringOffsetsStartSym(Asm->createTempSymbol("str_offsets_base"));

1203

1204

1205

1206

1210 Asm->createTempSymbol("rnglists_table_base"));

1211

1213 InfoHolder.setRnglistsTableBaseSym(

1214 Asm->createTempSymbol("rnglists_dwo_table_base"));

1215 }

1216

1217

1218

1219 AddrPool.setLabel(Asm->createTempSymbol("addr_table_base"));

1220 DebugLocs.setSym(Asm->createTempSymbol("loclists_table_base"));

1221

1222 for (DICompileUnit *CUNode : M->debug_compile_units()) {

1223 if (CUNode->getImportedEntities().empty() &&

1224 CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&

1225 CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())

1226 continue;

1227

1229

1230

1231 for (auto *GVE : CUNode->getGlobalVariables()) {

1232

1233

1234

1235 auto &GVMapEntry = GVMap[GVE->getVariable()];

1236 auto *Expr = GVE->getExpression();

1237 if (!GVMapEntry.size() || (Expr && Expr->isConstant()))

1238 GVMapEntry.push_back({nullptr, Expr});

1239 }

1240

1242 for (auto *GVE : CUNode->getGlobalVariables()) {

1244 if (Processed.insert(GV).second)

1245 CU.getOrCreateGlobalVariableDIE(GV, sortGlobalExprs(GVMap[GV]));

1246 }

1247

1248 for (auto *Ty : CUNode->getEnumTypes())

1250

1251 for (auto *Ty : CUNode->getRetainedTypes()) {

1252

1253

1255

1256 CU.getOrCreateTypeDIE(RT);

1257 }

1258 }

1259}

1260

1261void DwarfDebug::finishEntityDefinitions() {

1262 for (const auto &Entity : ConcreteEntities) {

1263 DIE *Die = Entity->getDIE();

1265

1266

1267

1270 Unit->finishEntityDefinition(Entity.get());

1271 }

1272}

1273

1274void DwarfDebug::finishSubprogramDefinitions() {

1275 for (const DISubprogram *SP : ProcessedSPNodes) {

1278 getOrCreateDwarfCompileUnit(SP->getUnit()),

1279 [&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); });

1280 }

1281}

1282

1283void DwarfDebug::finalizeModuleInfo() {

1284 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();

1285

1286 finishSubprogramDefinitions();

1287

1288 finishEntityDefinitions();

1289

1290 bool HasEmittedSplitCU = false;

1291

1292

1293

1294 for (const auto &P : CUMap) {

1295 auto &TheCU = *P.second;

1296 if (TheCU.getCUNode()->isDebugDirectivesOnly())

1297 continue;

1298 TheCU.attachLexicalScopesAbstractOrigins();

1299

1300

1301 TheCU.constructContainingTypeDIEs();

1302

1303

1304

1305

1306 auto *SkCU = TheCU.getSkeleton();

1307

1308 bool HasSplitUnit = SkCU && !TheCU.getUnitDie().children().empty();

1309

1310 if (HasSplitUnit) {

1311 (void)HasEmittedSplitCU;

1313 "Multiple CUs emitted into a single dwo file");

1314 HasEmittedSplitCU = true;

1316 ? dwarf::DW_AT_dwo_name

1317 : dwarf::DW_AT_GNU_dwo_name;

1318 finishUnitAttributes(TheCU.getCUNode(), TheCU);

1319 StringRef DWOName = Asm->TM.Options.MCOptions.SplitDwarfFile;

1320 TheCU.addString(TheCU.getUnitDie(), attrDWOName, DWOName);

1321 SkCU->addString(SkCU->getUnitDie(), attrDWOName, DWOName);

1322

1323

1324

1325

1326 uint64_t ID =

1327 DIEHash(Asm, &TheCU).computeCUSignature(DWOName, TheCU.getUnitDie());

1329 TheCU.setDWOId(ID);

1330 SkCU->setDWOId(ID);

1331 } else {

1332 TheCU.addUInt(TheCU.getUnitDie(), dwarf::DW_AT_GNU_dwo_id,

1333 dwarf::DW_FORM_data8, ID);

1334 SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,

1335 dwarf::DW_FORM_data8, ID);

1336 }

1337

1338 if (getDwarfVersion() < 5 && !SkeletonHolder.getRangeLists().empty()) {

1340 SkCU->addSectionLabel(SkCU->getUnitDie(), dwarf::DW_AT_GNU_ranges_base,

1341 Sym, Sym);

1342 }

1343 } else if (SkCU) {

1344 finishUnitAttributes(SkCU->getCUNode(), *SkCU);

1345 }

1346

1347

1348

1349

1350

1351

1352

1353 DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;

1354

1355 if (unsigned NumRanges = TheCU.getRanges().size()) {

1356

1357

1358

1359

1360 if (!(Asm->TM.getTargetTriple().isNVPTX() && tuneForGDB())) {

1362

1363

1364

1365

1366 U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,

1367 0);

1368 else

1369 U.setBaseAddress(TheCU.getRanges().front().Begin);

1370 U.attachRangesOrLowHighPC(U.getUnitDie(), TheCU.takeRanges());

1371 }

1372 }

1373

1374

1375

1376 if ((HasSplitUnit || getDwarfVersion() >= 5) && !AddrPool.isEmpty())

1377 U.addAddrTableBase();

1378

1380 if (U.hasRangeLists())

1381 U.addRnglistsBase();

1382

1383 if (!DebugLocs.getLists().empty() && useSplitDwarf()) {

1384 U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_loclists_base,

1385 DebugLocs.getSym(),

1387 }

1388 }

1389

1391

1392

1393 if (CUNode->getMacros()) {

1394 if (UseDebugMacroSection) {

1396 TheCU.addSectionDelta(

1397 TheCU.getUnitDie(), dwarf::DW_AT_macros, U.getMacroLabelBegin(),

1399 else {

1401 ? dwarf::DW_AT_macros

1402 : dwarf::DW_AT_GNU_macros;

1403 U.addSectionLabel(U.getUnitDie(), MacrosAttr, U.getMacroLabelBegin(),

1405 }

1406 } else {

1408 TheCU.addSectionDelta(

1409 TheCU.getUnitDie(), dwarf::DW_AT_macro_info,

1410 U.getMacroLabelBegin(),

1412 else

1413 U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,

1414 U.getMacroLabelBegin(),

1416 }

1417 }

1418 }

1419

1420

1421 for (auto *CUNode : MMI->getModule()->debug_compile_units())

1422 if (CUNode->getDWOId())

1423 getOrCreateDwarfCompileUnit(CUNode);

1424

1425

1426 InfoHolder.computeSizeAndOffsets();

1428 SkeletonHolder.computeSizeAndOffsets();

1429

1430

1431

1432 AccelDebugNames.convertDieToOffset();

1433}

1434

1435

1437

1438 if (PrevCU)

1440 PrevCU = nullptr;

1441 assert(CurFn == nullptr);

1443

1444 for (const auto &P : CUMap) {

1447

1448

1449 for (auto *IE : CUNode->getImportedEntities()) {

1451 "Unexpected function-local entity in 'imports' CU field.");

1452 CU->getOrCreateImportedEntityDIE(IE);

1453 }

1454 for (const auto *D : CU->getDeferredLocalDecls()) {

1456 CU->getOrCreateImportedEntityDIE(IE);

1457 else

1459 }

1460

1461

1462 CU->createBaseTypeDIEs();

1463 }

1464

1465

1466

1467 if (Asm || Asm->hasDebugInfo())

1468 return;

1469

1470

1471 finalizeModuleInfo();

1472

1474

1475 emitDebugLocDWO();

1476 else

1477

1478 emitDebugLoc();

1479

1480

1481 emitAbbreviations();

1482

1483

1484 emitDebugInfo();

1485

1486

1487 if (UseARangesSection)

1488 emitDebugARanges();

1489

1490

1491 emitDebugRanges();

1492

1494

1495 emitDebugMacinfoDWO();

1496 else

1497

1498 emitDebugMacinfo();

1499

1500 emitDebugStr();

1501

1503 emitDebugStrDWO();

1504 emitDebugInfoDWO();

1505 emitDebugAbbrevDWO();

1506 emitDebugLineDWO();

1507 emitDebugRangesDWO();

1508 }

1509

1510 emitDebugAddr();

1511

1512

1515 emitAccelNames();

1516 emitAccelObjC();

1517 emitAccelNamespaces();

1518 emitAccelTypes();

1519 break;

1521 emitAccelDebugNames();

1522 break;

1524 break;

1526 llvm_unreachable("Default should have already been resolved.");

1527 }

1528

1529

1530 emitDebugPubSections();

1531

1532

1533

1534}

1535

1536void DwarfDebug::ensureAbstractEntityIsCreatedIfScoped(DwarfCompileUnit &CU,

1538 if (CU.getExistingAbstractEntity(Node))

1539 return;

1540

1543 CU.createAbstractEntity(Node, Scope);

1544}

1545

1550

1551

1552void DwarfDebug::collectVariableInfoFromMFTable(

1554 SmallDenseMap<InlinedEntity, DbgVariable *> MFVars;

1555 LLVM_DEBUG(dbgs() << "DwarfDebug: collecting variables from MF side table\n");

1556 for (const auto &VI : Asm->MF->getVariableDbgInfo()) {

1557 if (VI.Var)

1558 continue;

1559 assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&

1560 "Expected inlined-at fields to agree");

1561

1562 InlinedEntity Var(VI.Var, VI.Loc->getInlinedAt());

1563 Processed.insert(Var);

1564 LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);

1565

1566

1567 if (!Scope) {

1568 LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()

1569 << ", no variable scope found\n");

1570 continue;

1571 }

1572

1573 ensureAbstractEntityIsCreatedIfScoped(TheCU, Var.first, Scope->getScopeNode());

1574

1575

1576

1577 if (DbgVariable *PreviousLoc = MFVars.lookup(Var)) {

1578 auto *PreviousMMI = std::get_ifLoc::MMI(PreviousLoc);

1579 auto *PreviousEntryValue = std::get_ifLoc::EntryValue(PreviousLoc);

1580

1581 if (PreviousMMI && VI.inStackSlot())

1582 PreviousMMI->addFrameIndexExpr(VI.Expr, VI.getStackSlot());

1583

1584 else if (PreviousEntryValue && VI.inEntryValueRegister())

1585 PreviousEntryValue->addExpr(VI.getEntryValueRegister(), *VI.Expr);

1586 else {

1587

1588

1589

1590 if (PreviousLoc->holdsLoc::MMI())

1591 PreviousLoc->emplaceLoc::EntryValue(VI.getEntryValueRegister(),

1592 *VI.Expr);

1593 LLVM_DEBUG(dbgs() << "Dropping debug info for " << VI.Var->getName()

1594 << ", conflicting fragment location types\n");

1595 }

1596 continue;

1597 }

1598

1599 auto RegVar = std::make_unique(

1601 if (VI.inStackSlot())

1602 RegVar->emplaceLoc::MMI(VI.Expr, VI.getStackSlot());

1603 else

1604 RegVar->emplaceLoc::EntryValue(VI.getEntryValueRegister(), *VI.Expr);

1605 LLVM_DEBUG(dbgs() << "Created DbgVariable for " << VI.Var->getName()

1606 << "\n");

1607 InfoHolder.addScopeVariable(Scope, RegVar.get());

1608 MFVars.insert({Var, RegVar.get()});

1609 ConcreteEntities.push_back(std::move(RegVar));

1610 }

1611}

1612

1613

1614

1615

1616

1621 assert(DbgValue->getDebugLoc() && "DBG_VALUE without a debug location");

1625

1626 if (!LScope)

1627 return false;

1628 auto &LSRange = LScope->getRanges();

1629 if (LSRange.size() == 0)

1630 return false;

1631

1632 const MachineInstr *LScopeBegin = LSRange.front().first;

1633

1634

1635

1636 if (!Ordering.isBefore(DbgValue, LScopeBegin)) {

1637

1639 return false;

1640

1642 for (++Pred; Pred != MBB->rend(); ++Pred) {

1644 break;

1645 auto PredDL = Pred->getDebugLoc();

1646 if (!PredDL || Pred->isMetaInstruction())

1647 continue;

1648

1649

1650 if (DL->getScope() == PredDL->getScope())

1651 return false;

1653 if (!PredScope || LScope->dominates(PredScope))

1654 return false;

1655 }

1656 }

1657

1658

1659 if (!RangeEnd)

1660 return true;

1661

1662

1663

1664

1665

1666 if (MBB->pred_empty() &&

1669 return true;

1670

1671

1672 const MachineInstr *LScopeEnd = LSRange.back().second;

1673 if (Ordering.isBefore(RangeEnd, LScopeEnd))

1674 return false;

1675

1676

1677

1678 return true;

1679}

1680

1681

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699

1700

1701

1702

1703

1704

1705

1706

1707

1708

1709

1710

1711

1712

1713

1716 using OpenRange =

1717 std::pair<DbgValueHistoryMap::EntryIndex, DbgValueLoc>;

1719 bool isSafeForSingleLocation = true;

1720 const MachineInstr *StartDebugMI = nullptr;

1721 const MachineInstr *EndMI = nullptr;

1722

1723 for (auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {

1724 const MachineInstr *Instr = EI->getInstr();

1725

1726

1727 size_t Index = std::distance(EB, EI);

1728 erase_if(OpenRanges, [&](OpenRange &R) { return R.first <= Index; });

1729

1730

1731

1732 const MCSymbol *StartLabel =

1734 assert(StartLabel &&

1735 "Forgot label before/after instruction starting a range!");

1736

1738 if (std::next(EI) == Entries.end()) {

1739 const MachineBasicBlock &EndMBB = Asm->MF->back();

1740 EndLabel = Asm->MBBSectionRanges[EndMBB.getSectionID()].EndLabel;

1741 if (EI->isClobber())

1742 EndMI = EI->getInstr();

1743 }

1744 else if (std::next(EI)->isClobber())

1746 else

1748 assert(EndLabel && "Forgot label after instruction ending a range!");

1749

1750 if (EI->isDbgValue())

1751 LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Instr << "\n");

1752

1753

1754

1755

1756 if (EI->isDbgValue()) {

1757

1758

1759

1760

1761

1762

1763 if (Instr->isUndefDebugValue()) {

1766

1767

1768 if (Instr->getDebugExpression()->isFragment())

1769 isSafeForSingleLocation = false;

1770

1771 if (!StartDebugMI)

1772 StartDebugMI = Instr;

1773 } else {

1774 isSafeForSingleLocation = false;

1775 }

1776 }

1777

1778

1779

1780 if (OpenRanges.empty())

1781 continue;

1782

1783

1784 if (StartLabel == EndLabel) {

1785 LLVM_DEBUG(dbgs() << "Omitting location list entry with empty range.\n");

1786 continue;

1787 }

1788

1790 for (auto &R : OpenRanges)

1792

1793

1794

1795

1796

1797

1798 if (Asm->MF->hasBBSections() && StartLabel == Asm->getFunctionBegin() &&

1799 Instr->getParent()->sameSection(&Asm->MF->front())) {

1800 for (const auto &[MBBSectionId, MBBSectionRange] :

1801 Asm->MBBSectionRanges) {

1802 if (Instr->getParent()->getSectionID() == MBBSectionId) {

1803 DebugLoc.emplace_back(MBBSectionRange.BeginLabel, EndLabel, Values);

1804 break;

1805 }

1806 DebugLoc.emplace_back(MBBSectionRange.BeginLabel,

1807 MBBSectionRange.EndLabel, Values);

1808 }

1809 } else {

1810 DebugLoc.emplace_back(StartLabel, EndLabel, Values);

1811 }

1812

1813

1814

1815 auto CurEntry = DebugLoc.rbegin();

1817 dbgs() << CurEntry->getValues().size() << " Values:\n";

1818 for (auto &Value : CurEntry->getValues())

1820 dbgs() << "-----\n";

1821 });

1822

1823 auto PrevEntry = std::next(CurEntry);

1824 if (PrevEntry != DebugLoc.rend() && PrevEntry->MergeRanges(*CurEntry))

1826 }

1827

1828 if (!isSafeForSingleLocation ||

1830 return false;

1831

1833 return true;

1834

1835 if (Asm->MF->hasBBSections())

1836 return false;

1837

1838

1839

1840

1841

1842

1843 const MachineBasicBlock *RangeMBB = nullptr;

1844 if (DebugLoc[0].getBeginSym() == Asm->getFunctionBegin())

1845 RangeMBB = &Asm->MF->front();

1846 else

1847 RangeMBB = Entries.begin()->getInstr()->getParent();

1848 auto RangeIt = Asm->MBBSectionRanges.find(RangeMBB->getSectionID());

1849 assert(RangeIt != Asm->MBBSectionRanges.end() &&

1850 "Range MBB not found in MBBSectionRanges!");

1851 auto *CurEntry = DebugLoc.begin();

1852 auto *NextEntry = std::next(CurEntry);

1853 auto NextRangeIt = std::next(RangeIt);

1854 while (NextEntry != DebugLoc.end()) {

1855 if (NextRangeIt == Asm->MBBSectionRanges.end())

1856 return false;

1857

1858

1859

1860

1861

1862 if ((RangeIt->second.EndLabel != Asm->getFunctionEnd() &&

1863 CurEntry->getEndSym() != RangeIt->second.EndLabel) ||

1864 NextEntry->getBeginSym() != NextRangeIt->second.BeginLabel ||

1865 CurEntry->getValues() != NextEntry->getValues())

1866 return false;

1867 RangeIt = NextRangeIt;

1868 NextRangeIt = std::next(RangeIt);

1869 CurEntry = NextEntry;

1870 NextEntry = std::next(CurEntry);

1871 }

1872 return true;

1873}

1874

1880 ensureAbstractEntityIsCreatedIfScoped(TheCU, Node, Scope.getScopeNode());

1882 ConcreteEntities.push_back(

1884 Location));

1885 InfoHolder.addScopeVariable(&Scope,

1888 ConcreteEntities.push_back(

1890 Location, Sym));

1891 InfoHolder.addScopeLabel(&Scope,

1893 }

1894 return ConcreteEntities.back().get();

1895}

1896

1897

1901

1902 collectVariableInfoFromMFTable(TheCU, Processed);

1903

1905 InlinedEntity IV = I.first;

1906 if (Processed.count(IV))

1907 continue;

1908

1909

1910 const auto &HistoryMapEntries = I.second;

1911

1912

1913

1914 if (DbgValues.hasNonEmptyLocation(HistoryMapEntries))

1915 continue;

1916

1917 LexicalScope *Scope = nullptr;

1919 if (const DILocation *IA = IV.second)

1921 else

1923

1924 if (!Scope)

1925 continue;

1926

1928 DbgVariable *RegVar = cast(createConcreteEntity(TheCU,

1929 *Scope, LocalVar, IV.second));

1930

1931 const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();

1932 assert(MInsn->isDebugValue() && "History must begin with debug value");

1933

1934

1935

1936

1937 size_t HistSize = HistoryMapEntries.size();

1938 bool SingleValueWithClobber =

1939 HistSize == 2 && HistoryMapEntries[1].isClobber();

1940 if (HistSize == 1 || SingleValueWithClobber) {

1941 const auto *End =

1942 SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr;

1944 RegVar->emplaceLoc::Single(MInsn);

1945 continue;

1946 }

1947 }

1948

1949

1950 DebugLocStream::ListBuilder List(DebugLocs, TheCU, *Asm, *RegVar);

1951

1952

1954 bool isValidSingleLocation = buildLocationList(Entries, HistoryMapEntries);

1955

1956

1957

1958

1959 if (isValidSingleLocation) {

1960 RegVar->emplaceLoc::Single(Entries[0].getValues()[0]);

1961 continue;

1962 }

1963

1964

1965

1966

1969

1970

1971 for (auto &Entry : Entries)

1973 }

1974

1975

1976

1978 InlinedEntity IL = I.first;

1979 const MachineInstr *MI = I.second;

1980 if (MI == nullptr)

1981 continue;

1982

1983 LexicalScope *Scope = nullptr;

1985

1986 const DILocalScope *LocalScope =

1987 Label->getScope()->getNonLexicalBlockFileScope();

1988

1989 if (const DILocation *IA = IL.second)

1990 Scope = LScopes.findInlinedScope(LocalScope, IA);

1991 else

1992 Scope = LScopes.findLexicalScope(LocalScope);

1993

1994 if (!Scope)

1995 continue;

1996

1997 Processed.insert(IL);

1998

1999

2000

2002 createConcreteEntity(TheCU, *Scope, Label, IL.second, Sym);

2003 }

2004

2005

2006 for (const DINode *DN : SP->getRetainedNodes()) {

2009 if (!Processed.insert(InlinedEntity(DN, nullptr)).second)

2010 continue;

2011 LexicalScope *LexS = LScopes.findLexicalScope(LS);

2012 if (LexS)

2013 createConcreteEntity(TheCU, *LexS, DN, nullptr);

2014 } else {

2015 LocalDeclsPerLS[LS].insert(DN);

2016 }

2017 }

2018}

2019

2020

2024 bool NoDebug =

2026

2027

2028 auto delaySlotSupported = [](const MachineInstr &MI) {

2029 if (MI.isBundledWithSucc())

2030 return false;

2031 auto Suc = std::next(MI.getIterator());

2032 (void)Suc;

2033

2034

2035

2036 assert(Suc->isBundledWithPred() &&

2037 "Call bundle instructions are out of order");

2038 return true;

2039 };

2040

2041

2042 if (!NoDebug && SP->areAllCallsDescribed() &&

2044 (MI->hasDelaySlot() || delaySlotSupported(*MI))) {

2046 bool IsTail = TII->isTailCall(*MI);

2047

2048

2049 if (IsTail)

2051

2052

2053

2055 }

2056

2059 return;

2060

2061 if (NoDebug)

2062 return;

2063

2064 auto RecordLineZero = [&]() {

2065

2066

2067

2068 const MDNode *Scope = nullptr;

2069 unsigned Column = 0;

2073 }

2074 recordSourceLine(0, Column, Scope, 0);

2075 };

2076

2077

2078

2079 unsigned LastAsmLine =

2080 Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();

2081

2082

2083

2084

2085 if (MI->isMetaInstruction())

2086 return;

2088

2090 RecordLineZero();

2091 return;

2092 }

2093

2095 unsigned Flags = 0;

2096

2100

2103 }

2104 }

2105

2106 auto RecordSourceLine = [this](auto &DL, auto Flags) {

2108 if (Asm->OutStreamer->isVerboseAsm()) {

2110 DL.print(OS);

2111 }

2112 recordSourceLine(DL.getLine(), DL.getCol(), DL.getScope(), Flags,

2113 LocationString);

2114 };

2115

2116

2117

2118

2119

2120

2121 bool ScopeUsesKeyInstructions =

2123 DL->getScope()->getSubprogram()->getKeyInstructionsEnabled();

2124

2125 bool IsKey = false;

2126 if (ScopeUsesKeyInstructions && DL && DL.getLine())

2127 IsKey = KeyInstructions.contains(MI);

2128

2130

2131

2132

2133 assert(MI->getParent() == &*MI->getMF()->begin());

2134 recordSourceLine(SP->getScopeLine(), 0, SP,

2136 return;

2137 }

2138

2139 bool PrevInstInSameSection =

2141 PrevInstBB->getSectionID() == MI->getParent()->getSectionID());

2142 bool ForceIsStmt = ForceIsStmtInstrs.contains(MI);

2143 if (PrevInstInSameSection && !ForceIsStmt && DL.isSameSourceLocation(PrevInstLoc)) {

2144

2145 if (DL)

2146 return;

2147

2148

2149

2150 if (!IsKey) {

2151

2152

2153 if ((LastAsmLine == 0 && DL.getLine() != 0) || Flags) {

2154

2155 RecordSourceLine(DL, Flags);

2156 }

2157 return;

2158 }

2159 }

2160

2161 if (DL) {

2162

2163

2164

2165

2166

2167

2168 if (LastAsmLine == 0)

2169 return;

2170

2172 return;

2173

2174

2175

2176

2177

2178

2179

2182 RecordLineZero();

2183 return;

2184 }

2185

2186

2187

2188

2189 if (DL.getLine() == 0 && LastAsmLine == 0)

2190 return;

2194 }

2195

2196 if (ScopeUsesKeyInstructions) {

2197 if (IsKey)

2199 } else {

2200

2201

2203 if (DL.getLine() && (DL.getLine() != OldLine || ForceIsStmt))

2205 }

2206

2207 RecordSourceLine(DL, Flags);

2208

2209

2210 if (DL.getLine())

2212}

2213

2214

2215

2216

2217

2218

2219static std::pair<const MachineInstr *, bool>

2221

2222

2224 const MachineInstr *NonTrivialInst = nullptr;

2227

2228

2229

2230 bool IsEmptyPrologue =

2231 !(F.hasPrologueData() || F.getMetadata(LLVMContext::MD_func_sanitize));

2232

2233

2234

2236 -> std::optional<std::pair<const MachineInstr *, bool>> {

2237

2238 bool isCopy = (TII.isCopyInstr(MI) ? true : false);

2239 bool isTrivRemat = TII.isTriviallyReMaterializable(MI);

2241

2242 if (!isFrameSetup && MI.getDebugLoc()) {

2243

2244

2245

2246

2247

2248 if (MI.getDebugLoc().getLine())

2249 return std::make_pair(&MI, IsEmptyPrologue);

2250 }

2251

2252

2253

2254 if (isCopy && !isTrivRemat && !isFrameSetup && !NonTrivialInst)

2255 NonTrivialInst = &MI;

2256

2257 IsEmptyPrologue = false;

2258 return std::nullopt;

2259 };

2260

2261

2262

2263

2264

2265

2266 auto CurBlock = MF->begin();

2267 auto CurInst = CurBlock->begin();

2268

2269

2270

2271 while (CurBlock->empty())

2272 CurInst = (++CurBlock)->begin();

2273 assert(CurInst != CurBlock->end());

2274

2275

2276

2277 auto getNextInst = [&CurBlock, &CurInst, MF]() -> bool {

2278

2279 if (CurInst->isTerminator()) {

2280

2281

2282

2283 return false;

2284 }

2285

2286

2287

2288 if (CurBlock->pred_size() > 1)

2289 return false;

2290

2291

2292

2293

2294

2295

2296

2297 do {

2298 ++CurBlock;

2299 if (CurBlock == MF->end())

2300 return false;

2301 } while (CurBlock->empty());

2302 CurInst = CurBlock->begin();

2303 return true;

2304 };

2305

2306 while (true) {

2307

2308 if (!CurInst->isMetaInstruction()) {

2309 auto FoundInst = ExamineInst(*CurInst);

2310 if (FoundInst)

2311 return *FoundInst;

2312 }

2313

2314

2315

2316

2317

2318

2319

2320 if (CurInst->isCall()) {

2321 if (const DILocation *Loc = CurInst->getDebugLoc().get();

2322 Loc && Loc->getLine() == 0) {

2323

2324 unsigned ScopeLine = SP->getScopeLine();

2327 const_cast<MachineInstr *>(&*CurInst)->setDebugLoc(ScopeLineDILoc);

2328

2329

2330 return std::make_pair(&*CurInst, false);

2331 }

2332 }

2333

2334

2335

2336 auto NextInst = std::next(CurInst);

2337 if (NextInst != CurInst->getParent()->end()) {

2338

2339 CurInst = NextInst;

2340 continue;

2341 }

2342

2343 if (!getNextInst())

2344 break;

2345 }

2346

2347

2348

2349

2350

2351

2352

2353

2354 if (NonTrivialInst && NonTrivialInst->getParent() == &*MF->begin()) {

2355 IsEmptyPrologue = NonTrivialInst == &*MF->begin()->begin();

2356 return std::make_pair(NonTrivialInst, IsEmptyPrologue);

2357 }

2358

2359

2360 return std::make_pair(nullptr, IsEmptyPrologue);

2361}

2362

2363

2364

2366 const MDNode *S, unsigned Flags, unsigned CUID,

2368 ArrayRef<std::unique_ptr> DCUs,

2371 unsigned FileNo = 1;

2374 Fn = Scope->getFilename();

2375 if (Line != 0 && DwarfVersion >= 4)

2378

2380 .getOrCreateSourceID(Scope->getFile());

2381 }

2382 Asm.OutStreamer->emitDwarfLocDirective(FileNo, Line, Col, Flags, 0,

2383 Discriminator, Fn, Comment);

2384}

2385

2388

2390 return nullptr;

2391

2392 std::pair<const MachineInstr *, bool> PrologEnd = findPrologueEndLoc(&MF);

2394 bool IsEmptyPrologue = PrologEnd.second;

2395

2396

2397 if (IsEmptyPrologue) {

2398

2399

2401

2402

2403

2405 if (DL || DL->getLine() != 0)

2407

2408

2410 }

2411 }

2412

2413

2414

2416 (void)getOrCreateDwarfCompileUnit(SP->getUnit());

2417

2418

2422}

2423

2424void DwarfDebug::computeKeyInstructions(const MachineFunction *MF) {

2425

2426 KeyInstructions.clear();

2427

2428

2429

2430

2431

2433 std::pair<uint8_t, SmallVector<const MachineInstr *, 2>>>

2434 GroupCandidates;

2435

2437

2438

2439

2440

2441

2442

2443

2444

2445

2446

2447

2448

2449

2450 for (auto &MBB : *MF) {

2451

2452

2453

2454

2455

2457

2458

2459

2461

2462 for (auto &MI : MBB) {

2463 if (MI.isMetaInstruction())

2464 continue;

2465

2467 if (Loc || Loc->getLine())

2468 continue;

2469

2470

2472 Buoy = &MI;

2473 BuoyAtom = 0;

2474 }

2475

2476

2477

2478 bool IsCallLike = MI.isCall() || TII.isTailCall(MI);

2479 if (IsCallLike) {

2480

2481

2482

2483 KeyInstructions.insert(Buoy);

2484

2485

2486 Buoy = nullptr;

2487 BuoyAtom = 0;

2488

2489 if (Loc->getAtomGroup() || Loc->getAtomRank())

2490 continue;

2491 }

2492

2493 auto *InlinedAt = Loc->getInlinedAt();

2496 if (!Group || !Rank)

2497 continue;

2498

2499

2500 if (BuoyAtom && BuoyAtom != Group) {

2501 Buoy = &MI;

2502 BuoyAtom = Group;

2503 }

2504

2505 auto &[CandidateRank, CandidateInsts] =

2506 GroupCandidates[{InlinedAt, Group}];

2507

2508

2509

2510

2511

2512 assert((CandidateRank == 0 && CandidateInsts.empty()) ||

2513 (CandidateRank != 0 && !CandidateInsts.empty()));

2514

2515 assert(Rank && "expected nonzero rank");

2516

2517

2518 if (CandidateRank && CandidateRank < Rank)

2519 continue;

2520

2521

2522

2523

2524

2525 if (CandidateRank == Rank)

2526 llvm::remove_if(CandidateInsts, [&MI](const MachineInstr *Candidate) {

2527 return MI.getParent() == Candidate->getParent();

2528 });

2529 else if (CandidateRank > Rank)

2530 CandidateInsts.clear();

2531

2532 if (Buoy) {

2533

2534 CandidateInsts.push_back(Buoy);

2535 CandidateRank = Rank;

2536

2539 } else {

2540

2541

2543 if (CandidateInsts.empty())

2544 CandidateRank = 0;

2545 }

2546 }

2547 }

2548

2549 for (const auto &[_, Insts] : GroupCandidates.values())

2550 for (auto *I : Insts)

2551 KeyInstructions.insert(I);

2552}

2553

2554

2555

2556

2557

2558void DwarfDebug::findForceIsStmtInstrs(const MachineFunction *MF) {

2559 ForceIsStmtInstrs.clear();

2560

2561

2562

2563

2564

2565

2566

2567

2568

2569

2570

2571

2572

2573

2574

2575

2576

2577

2578

2579

2580

2581

2582

2583

2584

2585

2586

2588

2589

2590

2591 SmallDenseSet<MachineBasicBlock *, 4> PredMBBsToExamine;

2592 SmallDenseMap<MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs;

2593

2594

2595 for (auto &MBB : *const_cast<MachineFunction *>(MF)) {

2597 continue;

2598 for (auto &MI : MBB) {

2599 if (MI.getDebugLoc() && MI.getDebugLoc()->getLine()) {

2601 PotentialIsStmtMBBInstrs.insert({&MBB, &MI});

2602 break;

2603 }

2604 }

2605 }

2606

2607

2608

2609

2610

2611

2612 for (auto *MBB : PredMBBsToExamine) {

2613 auto CheckMBBEdge = [&](MachineBasicBlock *Succ, unsigned OutgoingLine) {

2614 auto MBBInstrIt = PotentialIsStmtMBBInstrs.find(Succ);

2615 if (MBBInstrIt == PotentialIsStmtMBBInstrs.end())

2616 return;

2617 MachineInstr *MI = MBBInstrIt->second;

2618 if (MI->getDebugLoc()->getLine() == OutgoingLine)

2619 return;

2620 PotentialIsStmtMBBInstrs.erase(MBBInstrIt);

2621 ForceIsStmtInstrs.insert(MI);

2622 };

2623

2624

2625

2628 CheckMBBEdge(Succ, 0);

2629 continue;

2630 }

2631

2632

2634 return PotentialIsStmtMBBInstrs.contains(SuccMBB);

2635 }))

2636 continue;

2637

2638

2641 {

2642 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;

2645

2646

2647

2648

2649 if (!AnalyzeFailed && Cond.empty() && FBB != nullptr &&

2652 assert(MIIt->isBranch() && "Bad result from analyzeBranch?");

2653 CheckMBBEdge(FBB, FBBLine);

2654 ++MIIt;

2656 } else {

2657

2659 }

2660 }

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672

2673

2674

2675

2676

2677 unsigned LastLine = 0;

2678 while (MIIt != MBB->rend()) {

2679 if (auto DL = MIIt->getDebugLoc(); DL && DL->getLine()) {

2680 LastLine = DL->getLine();

2681 break;

2682 }

2683 ++MIIt;

2684 }

2685 for (auto *Succ : SuccessorBBs)

2686 CheckMBBEdge(Succ, LastLine);

2687 }

2688}

2689

2690

2691

2693 CurFn = MF;

2694

2696 assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode());

2698 return;

2699

2701 FunctionLineTableLabel = CU.emitFuncLineTableOffsets()

2702 ? Asm->OutStreamer->emitLineTableLabel()

2703 : nullptr;

2704

2705 Asm->OutStreamer->getContext().setDwarfCompileUnitID(

2707

2708

2710 *MF, Asm->OutStreamer->getContext().getDwarfCompileUnitID());

2711

2712

2713

2714

2716 computeKeyInstructions(MF);

2717 findForceIsStmtInstrs(MF);

2718}

2719

2720unsigned

2722

2723

2724

2725 if (Asm->OutStreamer->hasRawTextSupport())

2726

2727 return 0;

2728 else

2729 return CU.getUniqueID();

2730}

2731

2733 const auto &CURanges = CU->getRanges();

2734 auto &LineTable = Asm->OutStreamer->getContext().getMCDwarfLineTable(

2736

2737 LineTable.getMCLineSections().addEndEntry(

2738 const_cast<MCSymbol *>(CURanges.back().End));

2739}

2740

2742

2743

2744

2745

2746 if (PrevCU)

2748 PrevCU = nullptr;

2749 CurFn = nullptr;

2750}

2751

2752

2756

2757 assert(CurFn == MF &&

2758 "endFunction should be called with the same function as beginFunction");

2759

2760

2761 Asm->OutStreamer->getContext().setDwarfCompileUnitID(0);

2762

2765 DwarfCompileUnit &TheCU = getOrCreateDwarfCompileUnit(SP->getUnit());

2768 CurFn = nullptr;

2769 return;

2770 }

2771

2773 collectEntityInfo(TheCU, SP, Processed);

2774

2775

2776

2777 for (const auto &R : Asm->MBBSectionRanges)

2778 TheCU.addRange({R.second.BeginLabel, R.second.EndLabel});

2779

2780

2781

2782

2785 LScopes.getAbstractScopesList().empty() && !IsDarwin) {

2786 for (const auto &R : Asm->MBBSectionRanges)

2788

2789 assert(InfoHolder.getScopeVariables().empty());

2791 CurFn = nullptr;

2792 return;

2793 }

2794

2795#ifndef NDEBUG

2796 size_t NumAbstractSubprograms = LScopes.getAbstractScopesList().size();

2797#endif

2800 for (const DINode *DN : SP->getRetainedNodes()) {

2802

2803 auto *LexS = LScopes.getOrCreateAbstractScope(LS);

2804 assert(LexS && "Expected the LexicalScope to be created.");

2806

2807 if (!Processed.insert(InlinedEntity(DN, nullptr)).second ||

2809 continue;

2811 } else {

2812

2813 LocalDeclsPerLS[LS].insert(DN);

2814 }

2816 LScopes.getAbstractScopesList().size() == NumAbstractSubprograms &&

2817 "getOrCreateAbstractScope() inserted an abstract subprogram scope");

2818 }

2819 constructAbstractSubprogramScopeDIE(TheCU, AScope);

2820 }

2821

2822 ProcessedSPNodes.insert(SP);

2823 DIE &ScopeDIE =

2826 if (LScopes.getAbstractScopesList().empty() &&

2828 SkelCU->constructSubprogramScopeDIE(SP, F, FnScope,

2829 FunctionLineTableLabel);

2830

2831 FunctionLineTableLabel = nullptr;

2832

2833

2834 constructCallSiteEntryDIEs(*SP, TheCU, ScopeDIE, *MF);

2835

2836

2837

2838

2839

2840 InfoHolder.getScopeVariables().clear();

2841 InfoHolder.getScopeLabels().clear();

2842 LocalDeclsPerLS.clear();

2844 CurFn = nullptr;

2845}

2846

2847

2848

2849void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,

2850 unsigned Flags, StringRef Location) {

2852 Asm->OutStreamer->getContext().getDwarfCompileUnitID(),

2854}

2855

2856

2857

2858

2859

2860

2861void DwarfDebug::emitDebugInfo() {

2863 Holder.emitUnits( false);

2864}

2865

2866

2867void DwarfDebug::emitAbbreviations() {

2868 DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;

2869

2870 Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());

2871}

2872

2873void DwarfDebug::emitStringOffsetsTableHeader() {

2874 DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;

2876 *Asm, Asm->getObjFileLowering().getDwarfStrOffSection(),

2878}

2879

2880template

2881void DwarfDebug::emitAccel(AccelTableT &Accel, MCSection *Section,

2883 Asm->OutStreamer->switchSection(Section);

2884

2885

2887}

2888

2889void DwarfDebug::emitAccelDebugNames() {

2890

2891 if (getUnits().empty())

2892 return;

2893

2895}

2896

2897

2898void DwarfDebug::emitAccelNames() {

2899 emitAccel(AccelNames, Asm->getObjFileLowering().getDwarfAccelNamesSection(),

2900 "Names");

2901}

2902

2903

2904

2905void DwarfDebug::emitAccelObjC() {

2906 emitAccel(AccelObjC, Asm->getObjFileLowering().getDwarfAccelObjCSection(),

2907 "ObjC");

2908}

2909

2910

2911void DwarfDebug::emitAccelNamespaces() {

2912 emitAccel(AccelNamespace,

2913 Asm->getObjFileLowering().getDwarfAccelNamespaceSection(),

2914 "namespac");

2915}

2916

2917

2918void DwarfDebug::emitAccelTypes() {

2919 emitAccel(AccelTypes, Asm->getObjFileLowering().getDwarfAccelTypesSection(),

2920 "types");

2921}

2922

2923

2924

2925

2926

2927

2928

2929

2930

2931

2932

2933

2934

2935

2936

2937

2939 const DIE *Die) {

2940

2941

2942

2943

2944

2945

2946

2947

2948

2949 if (Die->getTag() == dwarf::DW_TAG_compile_unit)

2953

2954

2955

2957 DIE &SpecDIE = SpecVal.getDIEEntry().getEntry();

2958 if (SpecDIE.findAttribute(dwarf::DW_AT_external))

2960 } else if (Die->findAttribute(dwarf::DW_AT_external))

2962

2963 switch (Die->getTag()) {

2964 case dwarf::DW_TAG_class_type:

2965 case dwarf::DW_TAG_structure_type:

2966 case dwarf::DW_TAG_union_type:

2967 case dwarf::DW_TAG_enumeration_type:

2972 case dwarf::DW_TAG_typedef:

2973 case dwarf::DW_TAG_base_type:

2974 case dwarf::DW_TAG_subrange_type:

2975 case dwarf::DW_TAG_template_alias:

2977 case dwarf::DW_TAG_namespace:

2979 case dwarf::DW_TAG_subprogram:

2981 case dwarf::DW_TAG_variable:

2983 case dwarf::DW_TAG_enumerator:

2986 default:

2988 }

2989}

2990

2991

2992

2993void DwarfDebug::emitDebugPubSections() {

2994 for (const auto &NU : CUMap) {

2995 DwarfCompileUnit *TheU = NU.second;

2997 continue;

2998

3001

3002 Asm->OutStreamer->switchSection(

3003 GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()

3004 : Asm->getObjFileLowering().getDwarfPubNamesSection());

3005 emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames());

3006

3007 Asm->OutStreamer->switchSection(

3008 GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()

3009 : Asm->getObjFileLowering().getDwarfPubTypesSection());

3010 emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes());

3011 }

3012}

3013

3014void DwarfDebug::emitSectionReference(const DwarfCompileUnit &CU) {

3016 Asm->emitDwarfOffset(CU.getSection()->getBeginSymbol(),

3017 CU.getDebugSectionOffset());

3018 else

3019 Asm->emitDwarfSymbolReference(CU.getLabelBegin());

3020}

3021

3022void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,

3027

3028

3029 MCSymbol *EndLabel = Asm->emitDwarfUnitLength(

3030 "pub" + Name, "Length of Public " + Name + " Info");

3031

3032 Asm->OutStreamer->AddComment("DWARF Version");

3034

3035 Asm->OutStreamer->AddComment("Offset of Compilation Unit Info");

3036 emitSectionReference(*TheU);

3037

3038 Asm->OutStreamer->AddComment("Compilation Unit Length");

3039 Asm->emitDwarfLengthOrOffset(TheU->getLength());

3040

3041

3043 for (const auto &GI : Globals)

3046 return A.second->getOffset() < B.second->getOffset();

3047 });

3048 for (const auto &[Name, Entity] : Vec) {

3049 Asm->OutStreamer->AddComment("DIE offset");

3050 Asm->emitDwarfLengthOrOffset(Entity->getOffset());

3051

3052 if (GnuStyle) {

3054 Asm->OutStreamer->AddComment(

3057 Asm->emitInt8(Desc.toBits());

3058 }

3059

3060 Asm->OutStreamer->AddComment("External Name");

3061 Asm->OutStreamer->emitBytes(StringRef(Name.data(), Name.size() + 1));

3062 }

3063

3064 Asm->OutStreamer->AddComment("End Mark");

3065 Asm->emitDwarfLengthOrOffset(0);

3066 Asm->OutStreamer->emitLabel(EndLabel);

3067}

3068

3069

3070void DwarfDebug::emitDebugStr() {

3071 MCSection *StringOffsetsSection = nullptr;

3073 emitStringOffsetsTableHeader();

3074 StringOffsetsSection = Asm->getObjFileLowering().getDwarfStrOffSection();

3075 }

3076 DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;

3077 Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection(),

3078 StringOffsetsSection, true);

3079}

3080

3084 auto &&Comments = DebugLocs.getComments(Entry);

3085 auto Comment = Comments.begin();

3086 auto End = Comments.end();

3087

3088

3089

3090

3091

3092

3093 unsigned PtrSize = Asm->MAI->getCodePointerSize();

3095 DebugLocs.getBytes(Entry).size()),

3096 Asm->getDataLayout().isLittleEndian(), PtrSize);

3098

3101 for (const auto &Op : Expr) {

3102 assert(Op.getCode() != dwarf::DW_OP_const_type &&

3103 "3 operand ops not yet supported");

3104 assert(Op.getSubCode() && "SubOps not yet supported");

3105 Streamer.emitInt8(Op.getCode(), Comment != End ? *(Comment++) : "");

3107 for (unsigned I = 0; I < Op.getDescription().Op.size(); ++I) {

3108 if (Op.getDescription().Op[I] == Encoding::BaseTypeRef) {

3110 Streamer.emitDIERef(*CU->ExprRefedBaseTypes[Op.getRawOperand(I)].Die);

3111

3112 for (unsigned J = 0; J < Length; ++J)

3113 if (Comment != End)

3114 Comment++;

3115 } else {

3117 Streamer.emitInt8(Data.getData()[J], Comment != End ? *(Comment++) : "");

3118 }

3119 Offset = Op.getOperandEndOffset(I);

3120 }

3122 }

3123}

3124

3128 auto *DIExpr = Value.getExpression();

3131

3132

3133

3134 if (DIExpr && DIExpr->isEntryValue()) {

3135

3136

3137 assert(Value.getLocEntries().size() == 1);

3138 assert(Value.getLocEntries()[0].isLocation());

3140 DwarfExpr.setLocation(Location, DIExpr);

3141

3143

3146 return;

3147 return DwarfExpr.addExpression(std::move(ExprCursor));

3148 }

3149

3150

3151 auto EmitValueLocEntry = [&DwarfExpr, &BT,

3154 if (Entry.isInt()) {

3155 if (BT && (BT->getEncoding() == dwarf::DW_ATE_boolean))

3157 else if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||

3158 BT->getEncoding() == dwarf::DW_ATE_signed_char))

3160 else

3162 } else if (Entry.isLocation()) {

3164 if (Location.isIndirect())

3166

3169 return false;

3170 } else if (Entry.isTargetIndexLocation()) {

3172

3173

3176 } else if (Entry.isConstantFP()) {

3178 !Cursor) {

3179 DwarfExpr.addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);

3180 } else if (Entry.getConstantFP()

3181 ->getValueAPF()

3182 .bitcastToAPInt()

3183 .getBitWidth() <= 64 ) {

3185 Entry.getConstantFP()->getValueAPF().bitcastToAPInt());

3186 } else {

3188 dbgs() << "Skipped DwarfExpression creation for ConstantFP of size"

3189 << Entry.getConstantFP()

3190 ->getValueAPF()

3191 .bitcastToAPInt()

3192 .getBitWidth()

3193 << " bits\n");

3194 return false;

3195 }

3196 }

3197 return true;

3198 };

3199

3200 if (Value.isVariadic()) {

3201 if (!EmitValueLocEntry(Value.getLocEntries()[0], ExprCursor))

3202 return;

3204 return;

3205 }

3206

3207

3208

3210 return Entry.isLocation() && !Entry.getLoc().getReg();

3211 }))

3212 return;

3213

3215 std::move(ExprCursor),

3216 [EmitValueLocEntry, &Value](unsigned Idx,

3218 return EmitValueLocEntry(Value.getLocEntries()[Idx], Cursor);

3219 });

3220}

3221

3226 assert(!Values.empty() &&

3227 "location list entries without values are redundant");

3228 assert(Begin != End && "unexpected location list entry with empty range");

3233 if (Value.isFragment()) {

3234

3236 return P.isFragment();

3237 }) && "all values are expected to be fragments");

3239

3240 for (const auto &Fragment : Values)

3242

3243 } else {

3244 assert(Values.size() == 1 && "only fragments may have >1 value");

3246 }

3250}

3251

3254

3255 Asm->OutStreamer->AddComment("Loc expr size");

3257 Asm->emitULEB128(DebugLocs.getBytes(Entry).size());

3258 else if (DebugLocs.getBytes(Entry).size() <= std::numeric_limits<uint16_t>::max())

3259 Asm->emitInt16(DebugLocs.getBytes(Entry).size());

3260 else {

3261

3262

3263 Asm->emitInt16(0);

3264 return;

3265 }

3266

3269}

3270

3271

3272

3273

3277

3278 Asm->OutStreamer->AddComment("Offset entry count");

3281

3284 Asm->getDwarfOffsetByteSize());

3285

3286 return TableEnd;

3287}

3288

3289

3290

3291

3295

3297

3298 Asm->OutStreamer->AddComment("Offset entry count");

3299 Asm->emitInt32(DebugLocs.getLists().size());

3300 Asm->OutStreamer->emitLabel(DebugLocs.getSym());

3301

3302 for (const auto &List : DebugLocs.getLists())

3303 Asm->emitLabelDifference(List.Label, DebugLocs.getSym(),

3304 Asm->getDwarfOffsetByteSize());

3305

3306 return TableEnd;

3307}

3308

3309template <typename Ranges, typename PayloadEmitter>

3310static void

3313 unsigned OffsetPair, unsigned StartxLength, unsigned StartxEndx,

3315 bool ShouldUseBaseAddress, PayloadEmitter EmitPayload) {

3316 auto Size = Asm->MAI->getCodePointerSize();

3318

3319

3320 Asm->OutStreamer->emitLabel(Sym);

3321

3322

3323

3325 SectionRanges;

3326

3327 for (const auto &Range : R)

3328 SectionRanges[&Range.Begin->getSection()].push_back(&Range);

3329

3330 const MCSymbol *CUBase = CU.getBaseAddress();

3331 bool BaseIsSet = false;

3332 for (const auto &P : SectionRanges) {

3333 auto *Base = CUBase;

3334 if ((Asm->TM.getTargetTriple().isNVPTX() && DD.tuneForGDB()) ||

3335 (DD.useSplitDwarf() && UseDwarf5 && P.first->isLinkerRelaxable())) {

3336

3337

3338

3339

3340

3341

3342

3343 BaseIsSet = false;

3344 Base = nullptr;

3345 } else if (Base && ShouldUseBaseAddress) {

3346 const MCSymbol *Begin = P.second.front()->Begin;

3348 if (!UseDwarf5) {

3349 Base = NewBase;

3350 BaseIsSet = true;

3351 Asm->OutStreamer->emitIntValue(-1, Size);

3352 Asm->OutStreamer->AddComment(" base address");

3353 Asm->OutStreamer->emitSymbolValue(Base, Size);

3354 } else if (NewBase != Begin || P.second.size() > 1) {

3355

3356

3357

3358 Base = NewBase;

3359 BaseIsSet = true;

3360 Asm->OutStreamer->AddComment(StringifyEnum(BaseAddressx));

3361 Asm->emitInt8(BaseAddressx);

3362 Asm->OutStreamer->AddComment(" base address index");

3364 }

3365 } else if (BaseIsSet && !UseDwarf5) {

3366 BaseIsSet = false;

3368 Asm->OutStreamer->emitIntValue(-1, Size);

3369 Asm->OutStreamer->emitIntValue(0, Size);

3370 }

3371

3372 for (const auto *RS : P.second) {

3373 const MCSymbol *Begin = RS->Begin;

3374 const MCSymbol *End = RS->End;

3375 assert(Begin && "Range without a begin symbol?");

3376 assert(End && "Range without an end symbol?");

3378 if (UseDwarf5) {

3379

3380 Asm->OutStreamer->AddComment(StringifyEnum(OffsetPair));

3381 Asm->emitInt8(OffsetPair);

3382 Asm->OutStreamer->AddComment(" starting offset");

3383 Asm->emitLabelDifferenceAsULEB128(Begin, Base);

3384 Asm->OutStreamer->AddComment(" ending offset");

3385 Asm->emitLabelDifferenceAsULEB128(End, Base);

3386 } else {

3387 Asm->emitLabelDifference(Begin, Base, Size);

3388 Asm->emitLabelDifference(End, Base, Size);

3389 }

3390 } else if (UseDwarf5) {

3391

3392

3393

3394

3395

3396

3398 Asm->OutStreamer->AddComment(StringifyEnum(StartxEndx));

3399 Asm->emitInt8(StartxEndx);

3400 Asm->OutStreamer->AddComment(" start index");

3402 Asm->OutStreamer->AddComment(" end index");

3404 } else {

3405 Asm->OutStreamer->AddComment(StringifyEnum(StartxLength));

3406 Asm->emitInt8(StartxLength);

3407 Asm->OutStreamer->AddComment(" start index");

3409 Asm->OutStreamer->AddComment(" length");

3410 Asm->emitLabelDifferenceAsULEB128(End, Begin);

3411 }

3412 } else {

3413 Asm->OutStreamer->emitSymbolValue(Begin, Size);

3414 Asm->OutStreamer->emitSymbolValue(End, Size);

3415 }

3416 EmitPayload(*RS);

3417 }

3418 }

3419

3420 if (UseDwarf5) {

3421 Asm->OutStreamer->AddComment(StringifyEnum(EndOfList));

3423 } else {

3424

3425 Asm->OutStreamer->emitIntValue(0, Size);

3426 Asm->OutStreamer->emitIntValue(0, Size);

3427 }

3428}

3429

3430

3434 dwarf::DW_LLE_base_addressx, dwarf::DW_LLE_offset_pair,

3435 dwarf::DW_LLE_startx_length, dwarf::DW_LLE_startx_endx,

3438 DD.emitDebugLocEntryLocation(E, List.CU);

3439 });

3440}

3441

3442void DwarfDebug::emitDebugLocImpl(MCSection *Sec) {

3443 if (DebugLocs.getLists().empty())

3444 return;

3445

3446 Asm->OutStreamer->switchSection(Sec);

3447

3448 MCSymbol *TableEnd = nullptr;

3451

3452 for (const auto &List : DebugLocs.getLists())

3454

3455 if (TableEnd)

3456 Asm->OutStreamer->emitLabel(TableEnd);

3457}

3458

3459

3460void DwarfDebug::emitDebugLoc() {

3461 emitDebugLocImpl(

3463 ? Asm->getObjFileLowering().getDwarfLoclistsSection()

3464 : Asm->getObjFileLowering().getDwarfLocSection());

3465}

3466

3467

3468void DwarfDebug::emitDebugLocDWO() {

3470 emitDebugLocImpl(

3471 Asm->getObjFileLowering().getDwarfLoclistsDWOSection());

3472

3473 return;

3474 }

3475

3476 for (const auto &List : DebugLocs.getLists()) {

3477 Asm->OutStreamer->switchSection(

3478 Asm->getObjFileLowering().getDwarfLocDWOSection());

3479 Asm->OutStreamer->emitLabel(List.Label);

3480

3481 for (const auto &Entry : DebugLocs.getEntries(List)) {

3482

3483

3484

3485

3486

3487

3488

3489

3490 Asm->emitInt8(dwarf::DW_LLE_startx_length);

3491 unsigned idx = AddrPool.getIndex(Entry.Begin);

3492 Asm->emitULEB128(idx);

3493

3494

3495 Asm->emitLabelDifference(Entry.End, Entry.Begin, 4);

3497 }

3498 Asm->emitInt8(dwarf::DW_LLE_end_of_list);

3499 }

3500}

3501

3505

3506

3507

3508void DwarfDebug::emitDebugARanges() {

3509 if (ArangeLabels.empty())

3510 return;

3511

3512

3514

3515

3516 for (const SymbolCU &SCU : ArangeLabels) {

3517 if (SCU.Sym->isInSection()) {

3518

3519 MCSection *Section = &SCU.Sym->getSection();

3520 SectionMap[Section].push_back(SCU);

3521 } else {

3522

3523

3524

3525 SectionMap[nullptr].push_back(SCU);

3526 }

3527 }

3528

3529 DenseMap<DwarfCompileUnit *, std::vector> Spans;

3530

3531 for (auto &I : SectionMap) {

3532 MCSection *Section = I.first;

3535

3536

3537

3538 if (!Section) {

3539 for (const SymbolCU &Cur : List) {

3540 ArangeSpan Span;

3541 Span.Start = Cur.Sym;

3542 Span.End = nullptr;

3544 Spans[Cur.CU].push_back(Span);

3545 }

3546 continue;

3547 }

3548

3549

3550 List.push_back(SymbolCU(nullptr, Asm->OutStreamer->endSection(Section)));

3551

3552

3554 for (size_t n = 1, e = List.size(); n < e; n++) {

3555 const SymbolCU &Prev = List[n - 1];

3556 const SymbolCU &Cur = List[n];

3557

3558

3559 if (Cur.CU != Prev.CU) {

3560 ArangeSpan Span;

3561 Span.Start = StartSym;

3564 Spans[Prev.CU].push_back(Span);

3565 StartSym = Cur.Sym;

3566 }

3567 }

3568 }

3569

3570

3571 Asm->OutStreamer->switchSection(

3572 Asm->getObjFileLowering().getDwarfARangesSection());

3573

3574 unsigned PtrSize = Asm->MAI->getCodePointerSize();

3575

3576

3577 std::vector<DwarfCompileUnit *> CUs;

3578 for (const auto &it : Spans) {

3579 DwarfCompileUnit *CU = it.first;

3580 CUs.push_back(CU);

3581 }

3582

3583

3584 llvm::sort(CUs, [](const DwarfCompileUnit *A, const DwarfCompileUnit *B) {

3585 return A->getUniqueID() < B->getUniqueID();

3586 });

3587

3588

3589 for (DwarfCompileUnit *CU : CUs) {

3590 std::vector &List = Spans[CU];

3591

3592

3593 if (auto *Skel = CU->getSkeleton())

3594 CU = Skel;

3595

3596

3597 unsigned ContentSize =

3598 sizeof(int16_t) +

3599 Asm->getDwarfOffsetByteSize() +

3600

3601 sizeof(int8_t) +

3602 sizeof(int8_t);

3603

3604 unsigned TupleSize = PtrSize * 2;

3605

3606

3608 Asm->getUnitLengthFieldByteSize() + ContentSize, Align(TupleSize));

3609

3611 ContentSize += (List.size() + 1) * TupleSize;

3612

3613

3614 Asm->emitDwarfUnitLength(ContentSize, "Length of ARange Set");

3615 Asm->OutStreamer->AddComment("DWARF Arange version number");

3617 Asm->OutStreamer->AddComment("Offset Into Debug Info Section");

3618 emitSectionReference(*CU);

3619 Asm->OutStreamer->AddComment("Address Size (in bytes)");

3620 Asm->emitInt8(PtrSize);

3621 Asm->OutStreamer->AddComment("Segment Size (in bytes)");

3622 Asm->emitInt8(0);

3623

3624 Asm->OutStreamer->emitFill(Padding, 0xff);

3625

3626 for (const ArangeSpan &Span : List) {

3627 Asm->emitLabelReference(Span.Start, PtrSize);

3628

3629

3630

3631

3632

3633

3634 auto SizeRef = SymSize.find(Span.Start);

3635 if ((SizeRef == SymSize.end() || SizeRef->second != 0) && Span.End) {

3636 Asm->emitLabelDifference(Span.End, Span.Start, PtrSize);

3637 } else {

3638

3639

3640 uint64_t Size;

3641 if (SizeRef == SymSize.end() || SizeRef->second == 0)

3643 else

3644 Size = SizeRef->second;

3645

3646 Asm->OutStreamer->emitIntValue(Size, PtrSize);

3647 }

3648 }

3649

3650 Asm->OutStreamer->AddComment("ARange terminator");

3651 Asm->OutStreamer->emitIntValue(0, PtrSize);

3652 Asm->OutStreamer->emitIntValue(0, PtrSize);

3653 }

3654}

3655

3656

3659 emitRangeList(DD, Asm, List.Label, List.Ranges, *List.CU,

3660 dwarf::DW_RLE_base_addressx, dwarf::DW_RLE_offset_pair,

3661 dwarf::DW_RLE_startx_length, dwarf::DW_RLE_startx_endx,

3663 List.CU->getCUNode()->getRangesBaseAddress() ||

3665 [](auto) {});

3666}

3667

3668void DwarfDebug::emitDebugRangesImpl(const DwarfFile &Holder, MCSection *Section) {

3670 return;

3671

3673 assert(!CUMap.empty());

3674 assert(llvm::any_of(CUMap, [](const decltype(CUMap)::value_type &Pair) {

3675 return !Pair.second->getCUNode()->isDebugDirectivesOnly();

3676 }));

3677

3678 Asm->OutStreamer->switchSection(Section);

3679

3680 MCSymbol *TableEnd = nullptr;

3683

3686

3687 if (TableEnd)

3688 Asm->OutStreamer->emitLabel(TableEnd);

3689}

3690

3691

3692

3693void DwarfDebug::emitDebugRanges() {

3694 const auto &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;

3695

3696 emitDebugRangesImpl(Holder,

3698 ? Asm->getObjFileLowering().getDwarfRnglistsSection()

3699 : Asm->getObjFileLowering().getDwarfRangesSection());

3700}

3701

3702void DwarfDebug::emitDebugRangesDWO() {

3703 emitDebugRangesImpl(InfoHolder,

3704 Asm->getObjFileLowering().getDwarfRnglistsDWOSection());

3705}

3706

3707

3708

3711 enum HeaderFlagMask {

3712#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,

3713#include "llvm/BinaryFormat/Dwarf.def"

3714 };

3715 Asm->OutStreamer->AddComment("Macro information version");

3716 Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);

3717

3718

3719 if (Asm->isDwarf64()) {

3720 Asm->OutStreamer->AddComment("Flags: 64 bit, debug_line_offset present");

3721 Asm->emitInt8(MACRO_FLAG_OFFSET_SIZE | MACRO_FLAG_DEBUG_LINE_OFFSET);

3722 } else {

3723 Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");

3724 Asm->emitInt8(MACRO_FLAG_DEBUG_LINE_OFFSET);

3725 }

3726 Asm->OutStreamer->AddComment("debug_line_offset");

3728 Asm->emitDwarfLengthOrOffset(0);

3729 else

3730 Asm->emitDwarfSymbolReference(CU.getLineTableStartSym());

3731}

3732

3733void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {

3734 for (auto *MN : Nodes) {

3736 emitMacro(*M);

3738 emitMacroFile(*F, U);

3739 else

3741 }

3742}

3743

3744void DwarfDebug::emitMacro(DIMacro &M) {

3745 StringRef Name = M.getName();

3746 StringRef Value = M.getValue();

3747

3748

3749

3750 std::string Str = Value.empty() ? Name.str() : (Name + " " + Value).str();

3751

3752 if (UseDebugMacroSection) {

3755 ? dwarf::DW_MACRO_define_strx

3756 : dwarf::DW_MACRO_undef_strx;

3759 Asm->OutStreamer->AddComment("Line Number");

3760 Asm->emitULEB128(M.getLine());

3761 Asm->OutStreamer->AddComment("Macro String");

3762 Asm->emitULEB128(

3763 InfoHolder.getStringPool().getIndexedEntry(*Asm, Str).getIndex());

3764 } else {

3766 ? dwarf::DW_MACRO_GNU_define_indirect

3767 : dwarf::DW_MACRO_GNU_undef_indirect;

3770 Asm->OutStreamer->AddComment("Line Number");

3771 Asm->emitULEB128(M.getLine());

3772 Asm->OutStreamer->AddComment("Macro String");

3773 Asm->emitDwarfSymbolReference(

3774 InfoHolder.getStringPool().getEntry(*Asm, Str).getSymbol());

3775 }

3776 } else {

3778 Asm->emitULEB128(M.getMacinfoType());

3779 Asm->OutStreamer->AddComment("Line Number");

3780 Asm->emitULEB128(M.getLine());

3781 Asm->OutStreamer->AddComment("Macro String");

3782 Asm->OutStreamer->emitBytes(Str);

3783 Asm->emitInt8('\0');

3784 }

3785}

3786

3787void DwarfDebug::emitMacroFileImpl(

3789 StringRef (*MacroFormToString)(unsigned Form)) {

3790

3791 Asm->OutStreamer->AddComment(MacroFormToString(StartFile));

3792 Asm->emitULEB128(StartFile);

3793 Asm->OutStreamer->AddComment("Line Number");

3795 Asm->OutStreamer->AddComment("File Number");

3798 Asm->emitULEB128(getDwoLineTable(U)->getFile(

3800 Asm->OutContext.getDwarfVersion(), F.getSource()));

3801 else

3802 Asm->emitULEB128(U.getOrCreateSourceID(&F));

3804 Asm->OutStreamer->AddComment(MacroFormToString(EndFile));

3805 Asm->emitULEB128(EndFile);

3806}

3807

3809

3810

3812 if (UseDebugMacroSection)

3813 emitMacroFileImpl(

3814 F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,

3816 else

3819}

3820

3821void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {

3822 for (const auto &P : CUMap) {

3823 auto &TheCU = *P.second;

3825 DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;

3827 DIMacroNodeArray Macros = CUNode->getMacros();

3828 if (Macros.empty())

3829 continue;

3830 Asm->OutStreamer->switchSection(Section);

3831 Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());

3832 if (UseDebugMacroSection)

3834 handleMacroNodes(Macros, U);

3835 Asm->OutStreamer->AddComment("End Of Macro List Mark");

3836 Asm->emitInt8(0);

3837 }

3838}

3839

3840

3841void DwarfDebug::emitDebugMacinfo() {

3842 auto &ObjLower = Asm->getObjFileLowering();

3843 emitDebugMacinfoImpl(UseDebugMacroSection

3844 ? ObjLower.getDwarfMacroSection()

3845 : ObjLower.getDwarfMacinfoSection());

3846}

3847

3848void DwarfDebug::emitDebugMacinfoDWO() {

3849 auto &ObjLower = Asm->getObjFileLowering();

3850 emitDebugMacinfoImpl(UseDebugMacroSection

3851 ? ObjLower.getDwarfMacroDWOSection()

3852 : ObjLower.getDwarfMacinfoDWOSection());

3853}

3854

3855

3856

3857void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,

3858 std::unique_ptr NewU) {

3859

3860 if (!CompilationDir.empty())

3861 NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);

3862 addGnuPubAttributes(*NewU, Die);

3863

3864 SkeletonHolder.addUnit(std::move(NewU));

3865}

3866

3868

3869 auto OwnedUnit = std::make_unique(

3870 CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder,

3872 DwarfCompileUnit &NewCU = *OwnedUnit;

3873 NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());

3874

3876

3879

3880 initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit));

3881

3882 return NewCU;

3883}

3884

3885

3886

3887void DwarfDebug::emitDebugInfoDWO() {

3889

3890 InfoHolder.emitUnits( true);

3891}

3892

3893

3894

3895void DwarfDebug::emitDebugAbbrevDWO() {

3897 InfoHolder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevDWOSection());

3898}

3899

3900void DwarfDebug::emitDebugLineDWO() {

3902 SplitTypeUnitFileTable.Emit(

3903 *Asm->OutStreamer, MCDwarfLineTableParams(),

3904 Asm->getObjFileLowering().getDwarfLineDWOSection());

3905}

3906

3907void DwarfDebug::emitStringOffsetsTableHeaderDWO() {

3909 InfoHolder.getStringPool().emitStringOffsetsTableHeader(

3910 *Asm, Asm->getObjFileLowering().getDwarfStrOffDWOSection(),

3911 InfoHolder.getStringOffsetsStartSym());

3912}

3913

3914

3915

3916

3917void DwarfDebug::emitDebugStrDWO() {

3919 emitStringOffsetsTableHeaderDWO();

3921 MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();

3922 InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),

3923 OffSec, false);

3924}

3925

3926

3927void DwarfDebug::emitDebugAddr() {

3928 AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());

3929}

3930

3933 return nullptr;

3934 const DICompileUnit *DIUnit = CU.getCUNode();

3935 SplitTypeUnitFileTable.maybeSetRootFile(

3938 return &SplitTypeUnitFileTable;

3939}

3940

3942 MD5 Hash;

3943 Hash.update(Identifier);

3944

3945

3946

3948 Hash.final(Result);

3949 return Result.high();

3950}

3951

3955

3956

3957

3958 if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())

3959 return;

3960

3961 auto Ins = TypeSignatures.try_emplace(CTy);

3962 if (!Ins.second) {

3963 CU.addDIETypeSignature(RefDie, Ins.first->second);

3964 return;

3965 }

3966

3968 bool TopLevelType = TypeUnitsUnderConstruction.empty();

3969 AddrPool.resetUsedFlag();

3970

3971 auto OwnedUnit = std::make_unique(

3972 CU, Asm, this, &InfoHolder, NumTypeUnitsCreated++, getDwoLineTable(CU));

3975 TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);

3976

3977 NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,

3978 CU.getSourceLanguage());

3979

3982 Ins.first->second = Signature;

3983

3985

3986

3987

3988

3990 if (!CompilationDir.empty())

3991 NewTU.addString(UnitDie, dwarf::DW_AT_comp_dir, CompilationDir);

3992 NewTU.addString(UnitDie, dwarf::DW_AT_dwo_name,

3993 Asm->TM.Options.MCOptions.SplitDwarfFile);

3994 }

3997 ? Asm->getObjFileLowering().getDwarfTypesDWOSection()

3998 : Asm->getObjFileLowering().getDwarfInfoDWOSection();

4000 } else {

4003 ? Asm->getObjFileLowering().getDwarfTypesSection(Signature)

4004 : Asm->getObjFileLowering().getDwarfInfoSection(Signature);

4006

4007 CU.applyStmtList(UnitDie);

4008 }

4009

4010

4011

4014

4016

4017 if (TopLevelType) {

4018 auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);

4019 TypeUnitsUnderConstruction.clear();

4020

4021

4022

4023 if (AddrPool.hasBeenUsed()) {

4024 AccelTypeUnitsDebugNames.clear();

4025

4026

4027

4028 for (const auto &TU : TypeUnitsToAdd)

4029 TypeSignatures.erase(TU.second);

4030

4031

4032

4033

4034

4037 CU.updateAcceleratorTables(CTy->getScope(), CTy, RefDie);

4038 return;

4039 }

4040

4041

4042

4043 for (auto &TU : TypeUnitsToAdd) {

4044 InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get());

4049 AccelDebugNames.addTypeUnitSignature(*TU.first);

4050 else

4051 AccelDebugNames.addTypeUnitSymbol(*TU.first);

4052 }

4053 }

4054 AccelTypeUnitsDebugNames.convertDieToOffset();

4055 AccelDebugNames.addTypeEntries(AccelTypeUnitsDebugNames);

4056 AccelTypeUnitsDebugNames.clear();

4058 }

4059 CU.addDIETypeSignature(RefDie, Signature);

4060}

4061

4062

4063

4064

4065

4066template

4067void DwarfDebug::addAccelNameImpl(

4072 Unit.getUnitDie().getTag() == dwarf::DW_TAG_skeleton_unit || Name.empty())

4073 return;

4074

4078 return;

4079

4082

4086 break;

4089 assert(((&Current == &AccelTypeUnitsDebugNames) ||

4090 ((&Current == &AccelDebugNames) &&

4091 (Unit.getUnitDie().getTag() != dwarf::DW_TAG_type_unit))) &&

4092 "Kind is CU but TU is being processed.");

4093 assert(((&Current == &AccelDebugNames) ||

4094 ((&Current == &AccelTypeUnitsDebugNames) &&

4095 (Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit))) &&

4096 "Kind is TU but CU is being processed.");

4097

4098

4099 Current.addName(Ref, Die, Unit.getUniqueID(),

4100 Unit.getUnitDie().getTag() == dwarf::DW_TAG_type_unit);

4101 break;

4102 }

4104 llvm_unreachable("Default should have already been resolved.");

4107 }

4108}

4109

4113 const DIE &Die) {

4114 addAccelNameImpl(Unit, NameTableKind, AccelNames, Name, Die);

4115}

4116

4120 const DIE &Die) {

4121

4123 addAccelNameImpl(Unit, NameTableKind, AccelObjC, Name, Die);

4124}

4125

4129 const DIE &Die) {

4130 addAccelNameImpl(Unit, NameTableKind, AccelNamespace, Name, Die);

4131}

4132

4136 const DIE &Die, char Flags) {

4137 addAccelNameImpl(Unit, NameTableKind, AccelTypes, Name, Die);

4138}

4139

4141 return Asm->OutStreamer->getContext().getDwarfVersion();

4142}

4143

4145 if (Asm->getDwarfVersion() >= 4)

4146 return dwarf::Form::DW_FORM_sec_offset;

4147 assert((Asm->isDwarf64() || (Asm->getDwarfVersion() == 3)) &&

4148 "DWARF64 is not defined prior DWARFv3");

4149 return Asm->isDwarf64() ? dwarf::Form::DW_FORM_data8

4150 : dwarf::Form::DW_FORM_data4;

4151}

4152

4154 return SectionLabels.lookup(S);

4155}

4156

4158 if (SectionLabels.insert(std::make_pair(&S->getSection(), S)).second)

4161}

4162

4163std::optionalMD5::MD5Result

4167 return std::nullopt;

4168 std::optional<DIFile::ChecksumInfo> Checksum = File->getChecksum();

4170 return std::nullopt;

4171

4172

4173

4174

4175 std::string ChecksumString = fromHex(Checksum->Value);

4177 llvm::copy(ChecksumString, CKMem.data());

4178 return CKMem;

4179}

4180

4183 return true;

4185 return false;

4187 return true;

4188 return false;

4189}

4190

4192 if (MBB.getAlignment() == Align(1))

4193 return;

4194

4195 auto *SP = MBB.getParent()->getFunction().getSubprogram();

4196 bool NoDebug =

4198

4199 if (NoDebug)

4200 return;

4201

4202 auto PrevLoc = Asm->OutStreamer->getContext().getCurrentDwarfLoc();

4203 if (PrevLoc.getLine()) {

4204 Asm->OutStreamer->emitDwarfLocDirective(

4205 PrevLoc.getFileNum(), 0, PrevLoc.getColumn(), 0, 0, 0, StringRef());

4207 Asm->OutStreamer->getCurrentSectionOnly());

4208 }

4209}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

const TargetInstrInfo & TII

This file implements a class to represent arbitrary precision integral constant values and operations...

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static Expected< bool > hasObjCCategory(BitstreamCursor &Stream)

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

#define clEnumValN(ENUMVAL, FLAGNAME, DESC)

#define clEnumVal(ENUMVAL, DESC)

This file contains the declarations for the subclasses of Constant, which represent the different fla...

static bool isObjCClass(StringRef Name)

Definition DwarfDebug.cpp:453

static cl::opt< bool > NoDwarfRangesSection("no-dwarf-ranges-section", cl::Hidden, cl::desc("Disable emission .debug_ranges section."), cl::init(false))

static void finishCallSiteParams(ValT Val, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > DescribedParams, ParamSet &Params)

Emit call site parameter entries that are described by the given value and debug expression.

Definition DwarfDebug.cpp:611

static cl::opt< bool > UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden, cl::desc("Emit the GNU .debug_macro format with DWARF <5"), cl::init(false))

static cl::opt< DefaultOnOff > DwarfInlinedStrings("dwarf-inlined-strings", cl::Hidden, cl::desc("Use inlined strings rather than string section."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))

static bool validThroughout(LexicalScopes &LScopes, const MachineInstr *DbgValue, const MachineInstr *RangeEnd, const InstructionOrdering &Ordering)

Determine whether a singular DBG_VALUE is valid for the entirety of its enclosing lexical scope.

Definition DwarfDebug.cpp:1617

static cl::opt< bool > GenerateARangeSection("generate-arange-section", cl::Hidden, cl::desc("Generate dwarf aranges"), cl::init(false))

static cl::opt< LinkageNameOption > DwarfLinkageNames("dwarf-linkage-names", cl::Hidden, cl::desc("Which DWARF linkage-name attributes to emit."), cl::values(clEnumValN(DefaultLinkageNames, "Default", "Default for platform"), clEnumValN(AllLinkageNames, "All", "All"), clEnumValN(AbstractLinkageNames, "Abstract", "Abstract subprograms")), cl::init(DefaultLinkageNames))

static void addToFwdRegWorklist(FwdRegWorklist &Worklist, unsigned Reg, const DIExpression *Expr, ArrayRef< FwdRegParamInfo > ParamsToAdd)

Add Reg to the worklist, if it's not already present, and mark that the given parameter registers' va...

Definition DwarfDebug.cpp:642

static cl::opt< bool > GenerateDwarfTypeUnits("generate-type-units", cl::Hidden, cl::desc("Generate DWARF4 type units."), cl::init(false))

SmallSet< MCRegUnit, 16 > ClobberedRegUnitSet

Container for the set of register units known to be clobbered on the path to a call site.

Definition DwarfDebug.cpp:594

static cl::opt< bool > KeyInstructionsAreStmts("dwarf-use-key-instructions", cl::Hidden, cl::init(true), cl::desc("Set to false to ignore Key Instructions metadata"))

Set to false to ignore Key Instructions metadata.

static bool interpretNextInstr(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)

Definition DwarfDebug.cpp:778

static SmallVectorImpl< DwarfCompileUnit::GlobalExpr > & sortGlobalExprs(SmallVectorImpl< DwarfCompileUnit::GlobalExpr > &GVEs)

Sort and unique GVEs by comparing their fragment offset.

Definition DwarfDebug.cpp:1147

LinkageNameOption

Definition DwarfDebug.cpp:136

@ DefaultLinkageNames

Definition DwarfDebug.cpp:137

@ AbstractLinkageNames

Definition DwarfDebug.cpp:139

@ AllLinkageNames

Definition DwarfDebug.cpp:138

static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU, const DIE *Die)

computeIndexValue - Compute the gdb index value for the DIE and CU.

Definition DwarfDebug.cpp:2938

static uint64_t getFragmentOffsetInBits(const DIExpression &Expr)

Definition DwarfDebug.cpp:272

static cl::opt< DefaultOnOff > DwarfOpConvert("dwarf-op-convert", cl::Hidden, cl::desc("Enable use of the DWARFv5 DW_OP_convert operator"), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))

static std::pair< const MachineInstr *, bool > findPrologueEndLoc(const MachineFunction *MF)

Definition DwarfDebug.cpp:2220

static void collectCallSiteParameters(const MachineInstr *CallMI, ParamSet &Params)

Try to interpret values loaded into registers that forward parameters for CallMI.

Definition DwarfDebug.cpp:806

static MCSymbol * emitRnglistsTableHeader(AsmPrinter *Asm, const DwarfFile &Holder)

Definition DwarfDebug.cpp:3274

static cl::opt< bool > SplitDwarfCrossCuReferences("split-dwarf-cross-cu-references", cl::Hidden, cl::desc("Enable cross-cu references in DWO files"), cl::init(false))

MapVector< uint64_t, SmallVector< FwdRegParamInfo, 2 > > FwdRegWorklist

Register worklist for finding call site values.

Definition DwarfDebug.cpp:591

static cl::opt< bool > UseDwarfRangesBaseAddressSpecifier("use-dwarf-ranges-base-address-specifier", cl::Hidden, cl::desc("Use base address specifiers in debug_ranges"), cl::init(false))

static void emitLocList(DwarfDebug &DD, AsmPrinter *Asm, const DebugLocStream::List &List)

Definition DwarfDebug.cpp:3431

static const DILocalScope * getRetainedNodeScope(const MDNode *N)

Definition DwarfDebug.cpp:1546

static constexpr unsigned ULEB128PadSize

Definition DwarfDebug.cpp:177

static cl::opt< DefaultOnOff > DwarfSectionsAsReferences("dwarf-sections-as-references", cl::Hidden, cl::desc("Use sections+offset as references rather than labels."), cl::values(clEnumVal(Default, "Default for platform"), clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")), cl::init(Default))

DefaultOnOff

Definition DwarfDebug.cpp:86

@ Default

Definition DwarfDebug.cpp:86

@ Enable

Definition DwarfDebug.cpp:86

@ Disable

Definition DwarfDebug.cpp:86

static AccelTableKind computeAccelTableKind(unsigned DwarfVersion, bool GenerateTypeUnits, DebuggerKind Tuning, const Triple &TT)

Definition DwarfDebug.cpp:310

static void emitRangeList(DwarfDebug &DD, AsmPrinter *Asm, MCSymbol *Sym, const Ranges &R, const DwarfCompileUnit &CU, unsigned BaseAddressx, unsigned OffsetPair, unsigned StartxLength, unsigned StartxEndx, unsigned EndOfList, StringRef(*StringifyEnum)(unsigned), bool ShouldUseBaseAddress, PayloadEmitter EmitPayload)

Definition DwarfDebug.cpp:3311

static void forBothCUs(DwarfCompileUnit &CU, Func F)

Definition DwarfDebug.cpp:540

static MCSymbol * emitLoclistsTableHeader(AsmPrinter *Asm, const DwarfDebug &DD)

Definition DwarfDebug.cpp:3292

static const DIExpression * combineDIExpressions(const DIExpression *Original, const DIExpression *Addition)

Append the expression Addition to Original and return the result.

Definition DwarfDebug.cpp:597

static void interpretValues(const MachineInstr *CurMI, FwdRegWorklist &ForwardedRegWorklist, ParamSet &Params, ClobberedRegUnitSet &ClobberedRegUnits)

Interpret values loaded into registers by CurMI.

Definition DwarfDebug.cpp:663

static cl::opt< DefaultOnOff > UnknownLocations("use-unknown-locations", cl::Hidden, cl::desc("Make an absence of debug location information explicit."), cl::values(clEnumVal(Default, "At top of block or after label"), clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")), cl::init(Default))

static void recordSourceLine(AsmPrinter &Asm, unsigned Line, unsigned Col, const MDNode *S, unsigned Flags, unsigned CUID, uint16_t DwarfVersion, ArrayRef< std::unique_ptr< DwarfCompileUnit > > DCUs, StringRef Comment={})

Register a source line with debug info.

Definition DwarfDebug.cpp:2365

static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD, const DwarfCompileUnit &CU, uint16_t DwarfVersion)

Emit the header of a DWARF 5 macro section, or the GNU extension for DWARF 4.

Definition DwarfDebug.cpp:3709

static cl::opt< AccelTableKind > AccelTables("accel-tables", cl::Hidden, cl::desc("Output dwarf accelerator tables."), cl::values(clEnumValN(AccelTableKind::Default, "Default", "Default for platform"), clEnumValN(AccelTableKind::None, "Disable", "Disabled."), clEnumValN(AccelTableKind::Apple, "Apple", "Apple"), clEnumValN(AccelTableKind::Dwarf, "Dwarf", "DWARF")), cl::init(AccelTableKind::Default))

static cl::opt< DwarfDebug::MinimizeAddrInV5 > MinimizeAddrInV5Option("minimize-addr-in-v5", cl::Hidden, cl::desc("Always use DW_AT_ranges in DWARFv5 whenever it could allow more " "address pool entry sharing to reduce relocations/object size"), cl::values(clEnumValN(DwarfDebug::MinimizeAddrInV5::Default, "Default", "Default address minimization strategy"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Ranges, "Ranges", "Use rnglists for contiguous ranges if that allows " "using a pre-existing base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Expressions, "Expressions", "Use exprloc addrx+offset expressions for any " "address with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Form, "Form", "Use addrx+offset extension form for any address " "with a prior base address"), clEnumValN(DwarfDebug::MinimizeAddrInV5::Disabled, "Disabled", "Stuff")), cl::init(DwarfDebug::MinimizeAddrInV5::Default))

static StringRef getObjCMethodName(StringRef In)

Definition DwarfDebug.cpp:476

static DbgValueLoc getDebugLocValue(const MachineInstr *MI)

Get .debug_loc entry for the instruction range starting at MI.

Definition DwarfDebug.cpp:239

static void getObjCClassCategory(StringRef In, StringRef &Class, StringRef &Category)

Definition DwarfDebug.cpp:464

Module.h This file contains the declarations for the Module class.

#define DWARF2_FLAG_IS_STMT

#define DWARF2_FLAG_PROLOGUE_END

#define DWARF2_FLAG_EPILOGUE_BEGIN

Register const TargetRegisterInfo * TRI

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

This file describes how to lower LLVM code to machine code.

static bool isCopy(MachineInstr *MI)

static const uint32_t IV[8]

Class recording the (high level) value of a variable.

This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...

void addName(DwarfStringPoolEntryRef Name, Types &&... Args)

unsigned getIndex(const MCSymbol *Sym, bool TLS=false)

Returns the index into the address pool with the given label/symbol.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

std::vector< T > vec() const

This class is intended to be used as a driving class for all asm writers.

DwarfDebug * getDwarfDebug()

TargetMachine & TM

Target machine description.

MachineFunction * MF

The current machine function.

std::unique_ptr< MCStreamer > OutStreamer

This is the MCStreamer object for the file we are generating.

uint16_t getDwarfVersion() const

virtual void emitInt8(uint8_t Byte, const Twine &Comment="")=0

virtual unsigned emitDIERef(const DIE &D)=0

Basic type, like 'int' or 'float'.

bool getDebugInfoForProfiling() const

bool isDebugDirectivesOnly() const

StringRef getFlags() const

static LLVM_ABI std::optional< DebugNameTableKind > getNameTableKind(StringRef Str)

unsigned getRuntimeVersion() const

bool getSplitDebugInlining() const

StringRef getSysRoot() const

StringRef getProducer() const

DISourceLanguageName getSourceLanguage() const

uint64_t getDWOId() const

StringRef getSplitDebugFilename() const

static LLVM_ABI std::optional< DebugEmissionKind > getEmissionKind(StringRef Str)

void setSection(MCSection *Section)

Set the section that this DIEUnit will be emitted into.

A structured debug information entry.

LLVM_ABI DIEValue findAttribute(dwarf::Attribute Attribute) const

Find a value in the DIE with the attribute given.

LLVM_ABI const DIE * getUnitDie() const

Climb up the parent chain to get the compile unit or type unit DIE that this DIE belongs to.

dwarf::Tag getTag() const

Holds a DIExpression and keeps track of how many operands have been consumed so far.

LLVM_ABI bool isEntryValue() const

Check if the expression consists of exactly one entry value operand.

static LLVM_ABI DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)

Append the opcodes Ops to DIExpr.

unsigned getNumElements() const

LLVM_ABI bool isImplicit() const

Return whether this is an implicit location description.

static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)

Retrieve the details of this fragment expression.

static LLVM_ABI std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)

If Expr is a valid single-location expression, i.e.

ArrayRef< uint64_t > getElements() const

LLVM_ABI bool isValid() const

LLVM_ABI DILocalScope * getNonLexicalBlockFileScope() const

Get the first non DILexicalBlockFile scope of this scope.

uint64_t getAtomGroup() const

uint8_t getAtomRank() const

DIMacroNodeArray getElements() const

Tagged DWARF-like metadata node.

StringRef getFilename() const

StringRef getDirectory() const

std::optional< StringRef > getSource() const

bool hasVersionedName() const

Subprogram description. Uses SubclassData1.

DIScope * getScope() const

Encoding

Size and signedness of expression operations' operands.

Used for tracking debug info about call site parameters.

This class is defined as the common parent of DbgVariable and DbgLabel such that it could levarage po...

SmallVector< Entry, 4 > Entries

A single location or constant within a variable location description, with either a single entry (wit...

The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.

const DILocalVariable * getVariable() const

const DIType * getType() const

Definition DwarfDebug.cpp:234

const MachineInstr * CurMI

If nonnull, stores the current machine instruction we're processing.

AsmPrinter * Asm

Target of debug info emission.

MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)

Return Label preceding the instruction.

MachineModuleInfo * MMI

Collected machine module information.

DebugLoc PrevInstLoc

Previous instruction's location information.

MCSymbol * getLabelAfterInsn(const MachineInstr *MI)

Return Label immediately following the instruction.

DebugHandlerBase(AsmPrinter *A)

void beginInstruction(const MachineInstr *MI) override

Process beginning of an instruction.

const MachineBasicBlock * PrevInstBB

void requestLabelAfterInsn(const MachineInstr *MI)

Ensure that a label will be emitted after MI.

DbgValueHistoryMap DbgValues

History of DBG_VALUE and clobber instructions for each user variable.

DbgLabelInstrMap DbgLabels

Mapping of inlined labels and DBG_LABEL machine instruction.

void beginModule(Module *M) override

const InstructionOrdering & getInstOrdering() const

void requestLabelBeforeInsn(const MachineInstr *MI)

Ensure that a label will be emitted before MI.

const MachineBasicBlock * EpilogBeginBlock

This block includes epilogue instructions.

const MachineInstr * PrologEndLoc

This location indicates end of function prologue and beginning of function body.

DwarfExpression implementation for .debug_loc entries.

void finalize(const AsmPrinter &AP, DebugLocStream::ListBuilder &List, const DIBasicType *BT, DwarfCompileUnit &TheCU)

Lower this entry into a DWARF expression.

Definition DwarfDebug.cpp:3222

Builder for DebugLocStream entries.

Builder for DebugLocStream lists.

ArrayRef< Entry > getEntries(const List &L) const

LLVM_ABI unsigned getLine() const

ValueT lookup(const_arg_type_t< KeyT > Val) const

lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...

iterator find(const_arg_type_t< KeyT > Val)

bool erase(const KeyT &Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Implements a dense probed hash-table based set.

void addRange(RangeSpan Range)

addRange - Add an address range to the list of ranges for this unit.

DIE & constructSubprogramScopeDIE(const DISubprogram *Sub, const Function &F, LexicalScope *Scope, MCSymbol *LineTableSym)

Construct a DIE for this subprogram scope.

void createAbstractEntity(const DINode *Node, LexicalScope *Scope)

DwarfCompileUnit * getSkeleton() const

void setSkeleton(DwarfCompileUnit &Skel)

Set the skeleton unit associated with this unit.

const StringMap< const DIE * > & getGlobalNames() const

DbgEntity * getExistingAbstractEntity(const DINode *Node)

const StringMap< const DIE * > & getGlobalTypes() const

bool hasDwarfPubSections() const

Collects and handles dwarf debug information.

bool useSegmentedStringOffsetsTable() const

Returns whether to generate a string offsets table with (possibly shared) contributions from each CU ...

std::optional< MD5::MD5Result > getMD5AsBytes(const DIFile *File) const

If the File has an MD5 checksum, return it as an MD5Result allocated in the MCContext.

Definition DwarfDebug.cpp:4164

bool emitDebugEntryValues() const

uint16_t getDwarfVersion() const

Returns the Dwarf Version.

Definition DwarfDebug.cpp:4140

void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)

Emit an entry for the debug loc section.

Definition DwarfDebug.cpp:3081

void addAccelNamespace(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)

Definition DwarfDebug.cpp:4126

void setCurrentDWARF5AccelTable(const DWARF5AccelTableKind Kind)

Sets the current DWARF5AccelTable to use.

bool alwaysUseRanges(const DwarfCompileUnit &) const

Returns whether range encodings should be used for single entry range lists.

Definition DwarfDebug.cpp:4181

void beginModule(Module *M) override

Emit all Dwarf sections that should come prior to the content.

Definition DwarfDebug.cpp:1175

void addSubprogramNames(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, const DISubprogram *SP, DIE &Die)

Definition DwarfDebug.cpp:481

bool useAllLinkageNames() const

Returns whether we should emit all DW_AT_[MIPS_]linkage_name.

void insertSectionLabel(const MCSymbol *S)

Definition DwarfDebug.cpp:4157

void addAccelObjC(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)

Definition DwarfDebug.cpp:4117

dwarf::Form getDwarfSectionOffsetForm() const

Returns a suitable DWARF form to represent a section offset, i.e.

Definition DwarfDebug.cpp:4144

bool useAppleExtensionAttributes() const

void skippedNonDebugFunction() override

Definition DwarfDebug.cpp:2741

void addArangeLabel(SymbolCU SCU)

Add a label so that arange data can be generated for it.

void beginInstruction(const MachineInstr *MI) override

Process beginning of an instruction.

Definition DwarfDebug.cpp:2021

AddressPool & getAddressPool()

DWARF5AccelTable & getCurrentDWARF5AccelTable()

Returns either CU or TU DWARF5AccelTable.

bool useSectionsAsReferences() const

Returns whether to use sections as labels rather than temp symbols.

const DebugLocStream & getDebugLocs() const

Returns the entries for the .debug_loc section.

bool shareAcrossDWOCUs() const

Definition DwarfDebug.cpp:547

void terminateLineTable(const DwarfCompileUnit *CU)

Terminate the line table by adding the last range label.

Definition DwarfDebug.cpp:2732

void endFunctionImpl(const MachineFunction *MF) override

Gather and emit post-function debug information.

Definition DwarfDebug.cpp:2753

DwarfCompileUnit & getOrCreateAbstractSubprogramCU(const DISubprogram *SP, DwarfCompileUnit &SrcCU)

Find the matching DwarfCompileUnit for the given SP referenced from SrcCU.

Definition DwarfDebug.cpp:552

void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry, const DwarfCompileUnit *CU)

Emit the location for a debug loc entry, including the size header.

Definition DwarfDebug.cpp:3252

const MCSymbol * getSectionLabel(const MCSection *S)

Definition DwarfDebug.cpp:4153

static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT, const DbgValueLoc &Value, DwarfExpression &DwarfExpr)

Definition DwarfDebug.cpp:3125

bool useSplitDwarf() const

Returns whether or not to change the current debug info for the split dwarf proposal support.

unsigned getDwarfCompileUnitIDForLineTable(const DwarfCompileUnit &CU)

Get Dwarf compile unit ID for line table.

Definition DwarfDebug.cpp:2721

const MachineInstr * emitInitialLocDirective(const MachineFunction &MF, unsigned CUID)

Emits inital debug location directive.

Definition DwarfDebug.cpp:2387

bool useRangesSection() const

Returns whether ranges section should be emitted.

void addAccelName(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die)

Definition DwarfDebug.cpp:4110

bool isLexicalScopeDIENull(LexicalScope *Scope)

A helper function to check whether the DIE for a given Scope is going to be null.

Definition DwarfDebug.cpp:523

void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &Die, const DICompositeType *CTy)

Add a DIE to the set of types that we're going to pull into type units.

Definition DwarfDebug.cpp:3952

void endModule() override

Emit all Dwarf sections that should come after the content.

Definition DwarfDebug.cpp:1436

void addAccelType(const DwarfUnit &Unit, const DICompileUnit::DebugNameTableKind NameTableKind, StringRef Name, const DIE &Die, char Flags)

Definition DwarfDebug.cpp:4133

void beginCodeAlignment(const MachineBasicBlock &MBB) override

Process beginning of code alignment.

Definition DwarfDebug.cpp:4191

DwarfDebug(AsmPrinter *A)

Definition DwarfDebug.cpp:334

void beginFunctionImpl(const MachineFunction *MF) override

Gather pre-function debug information.

Definition DwarfDebug.cpp:2692

AccelTableKind getAccelTableKind() const

Returns what kind (if any) of accelerator tables to emit.

static uint64_t makeTypeSignature(StringRef Identifier)

Perform an MD5 checksum of Identifier and return the lower 64 bits.

Definition DwarfDebug.cpp:3941

Base class containing the logic for constructing DWARF expressions independently of whether they are ...

void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)

Set the location (Loc) and DIExpression (DIExpr) to describe.

virtual void disableTemporaryBuffer()=0

Disable emission to the temporary buffer.

virtual unsigned getTemporaryBufferSize()=0

Return the emitted size, in number of bytes, for the data stored in the temporary buffer.

void finalize()

This needs to be called last to commit any pending changes.

void addFragmentOffset(const DIExpression *Expr)

If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...

void setMemoryLocationKind()

Lock this down to become a memory location description.

std::optional< uint8_t > TagOffset

void addBooleanConstant(int64_t Value)

Emit a boolean constant.

void addConstantFP(const APFloat &Value, const AsmPrinter &AP)

Emit an floating point constant.

bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)

Emit a machine register location.

void addUnsignedConstant(uint64_t Value)

Emit an unsigned constant.

void addExpression(DIExpressionCursor &&Expr)

Emit all remaining operations in the DIExpressionCursor.

void addSignedConstant(int64_t Value)

Emit a signed constant.

virtual void commitTemporaryBuffer()=0

Commit the data stored in the temporary buffer to the main output.

void addWasmLocation(unsigned Index, uint64_t Offset)

Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...

virtual void enableTemporaryBuffer()=0

Start emitting data to the temporary buffer.

void beginEntryValueExpression(DIExpressionCursor &ExprCursor)

Begin emission of an entry value dwarf operation.

void setRnglistsTableBaseSym(MCSymbol *Sym)

void emitUnits(bool UseOffsets)

Emit all of the units to the section listed with the given abbreviation section.

const SmallVectorImpl< RangeSpanList > & getRangeLists() const

getRangeLists - Get the vector of range lists.

MCSymbol * getStringOffsetsStartSym() const

MCSymbol * getRnglistsTableBaseSym() const

DwarfStringPool & getStringPool()

Returns the string pool.

void emitAbbrevs(MCSection *)

Emit a set of abbreviations to the specific section.

void emitStrings(MCSection *StrSection, MCSection *OffsetSection=nullptr, bool UseRelativeOffsets=false)

Emit all of the strings to the section given.

DwarfStringPoolEntryRef: Dwarf string pool entry reference.

LLVM_ABI_FOR_TEST EntryRef getEntry(AsmPrinter &Asm, StringRef Str)

Get a reference to an entry in the string pool.

LLVM_ABI_FOR_TEST void emitStringOffsetsTableHeader(AsmPrinter &Asm, MCSection *OffsetSection, MCSymbol *StartSym)

void setTypeSignature(uint64_t Signature)

void setType(const DIE *Ty)

This dwarf writer support class manages information associated with a source file.

void addStringOffsetsStart()

Add the DW_AT_str_offsets_base attribute to the unit DIE.

void addUInt(DIEValueList &Die, dwarf::Attribute Attribute, std::optional< dwarf::Form > Form, uint64_t Integer)

Add an unsigned integer attribute data and value.

void addString(DIE &Die, dwarf::Attribute Attribute, StringRef Str)

Add a string attribute data and value.

DIE * createTypeDIE(const DIScope *Context, DIE &ContextDIE, const DIType *Ty)

Creates type DIE with specific context.

const DICompileUnit * getCUNode() const

void addFlag(DIE &Die, dwarf::Attribute Attribute)

Add a flag that is true to the DIE.

unsigned getUniqueID() const

Gets Unique ID for this unit.

DISubprogram * getSubprogram() const

Get the attached subprogram.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

static StringRef dropLLVMManglingEscape(StringRef Name)

If the given string begins with the GlobalValue name mangling escape character '\1',...

Record instruction ordering so we can query their relative positions within a function.

This class is used to track scope information.

SmallVectorImpl< InsnRange > & getRanges()

const DILocalScope * getScopeNode() const

This class provides interface to collect and use lexical scoping information from machine instruction...

LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)

Find lexical scope, either regular or inlined, for the given DebugLoc.

LexicalScope * findAbstractScope(const DILocalScope *N)

Find an abstract scope or return null.

Single(DbgValueLoc ValueLoc)

Definition DwarfDebug.cpp:286

static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)

MCSection * getDwarfLoclistsSection() const

MCSection * getDwarfRangesSection() const

MCSection * getDwarfMacroSection() const

MCSection * getDwarfMacinfoDWOSection() const

MCSection * getDwarfMacinfoSection() const

MCSection * getDwarfMacroDWOSection() const

uint8_t OperandType

Information about the type of the operand.

Instances of this class represent a uniqued identifier for a section in the current translation unit.

MCSymbol * getBeginSymbol()

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

uint32_t getIndex() const

Get the (implementation defined) index.

MCSection & getSection() const

Get the section associated with a defined, non-absolute symbol.

LLVM_ABI void update(ArrayRef< uint8_t > Data)

Updates the hash for the byte stream provided.

LLVM_ABI void final(MD5Result &Result)

Finishes off the hash and puts the result in result.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

succ_iterator succ_begin()

MBBSectionID getSectionID() const

Returns the section ID of this basic block.

iterator_range< succ_iterator > successors()

reverse_iterator rbegin()

iterator_range< pred_iterator > predecessors()

MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

const CallSiteInfoMap & getCallSitesInfo() const

Function & getFunction()

Return the LLVM function that this machine code represents.

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

bool isCall(QueryType Type=AnyInBundle) const

unsigned getNumOperands() const

Retuns the total number of operands.

bool hasDelaySlot(QueryType Type=AnyInBundle) const

Returns true if the specified instruction has a delay slot which must be filled by the code generator...

mop_range uses()

Returns all operands which may be register uses.

LLVM_ABI const MachineFunction * getMF() const

Return the function that contains the basic block that this instruction belongs to.

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

bool isDebugValue() const

MachineOperand class - Representation of each machine instruction operand.

LLVM_ABI unsigned getOperandNo() const

Returns the index of this operand in the instruction that it belongs to.

const GlobalValue * getGlobal() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

Register getReg() const

getReg - Returns the register number.

This class implements a map that also provides access to all stored values in a deterministic order.

VectorType::iterator erase(typename VectorType::iterator Iterator)

Remove the element given by Iterator.

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

A Module instance is used to store all the information related to an LLVM module.

Wrapper class representing virtual and physical registers.

constexpr bool isPhysical() const

Return true if the specified register number is in the physical register namespace.

bool empty() const

Determine if the SetVector is empty or not.

A SetVector that performs no allocations if smaller than a certain size.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

void insert_range(Range &&R)

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...

void assign(size_type NumElts, ValueParamT Elt)

reference emplace_back(ArgTypes &&... Args)

iterator erase(const_iterator CI)

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...

StringRef - Represent a constant reference to a string, i.e.

constexpr bool empty() const

empty - Check if the string is empty.

TargetInstrInfo - Interface to description of machine instruction set.

virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const

Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....

virtual bool isTailCall(const MachineInstr &Inst) const

Determines whether Inst is a tail call instruction.

virtual const MachineOperand & getCalleeOperand(const MachineInstr &MI) const

Returns the callee operand from the given MI.

const Triple & getTargetTriple() const

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

virtual const TargetLowering * getTargetLowering() const

Triple - Helper class for working with autoconf configuration names.

bool isWasm() const

Tests whether the target is wasm (32- and 64-bit).

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM Value Representation.

LLVM_ABI StringRef getName() const

Return a constant reference to the value's name.

std::pair< iterator, bool > insert(const ValueT &V)

void insert_range(Range &&R)

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

reverse_self_iterator getReverseIterator()

self_iterator getIterator()

A raw_ostream that writes to an SmallVector or SmallString.

LLVM_ABI StringRef RangeListEncodingString(unsigned Encoding)

LLVM_ABI StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage)

LLVM_ABI StringRef MacroString(unsigned Encoding)

LLVM_ABI StringRef LocListEncodingString(unsigned Encoding)

LLVM_ABI StringRef GnuMacroString(unsigned Encoding)

LLVM_ABI StringRef MacinfoString(unsigned Encoding)

LLVM_ABI StringRef OperationEncodingString(unsigned Encoding)

LLVM_ABI StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

ValuesClass values(OptsTy... Options)

Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...

initializer< Ty > init(const Ty &Val)

bool isCPlusPlus(SourceLanguage S)

@ DW_ARANGES_VERSION

Section version number for .debug_aranges.

@ DW_PUBNAMES_VERSION

Section version number for .debug_pubnames.

@ DWARF_VERSION

Other constants.

Scope

Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...

LLVM_ABI MCSymbol * emitListsTableHeaderStart(MCStreamer &S)

NodeAddr< InstrNode * > Instr

This is an optimization pass for GlobalISel generic memory operations.

bool operator<(int64_t V1, const APSInt &V2)

FunctionAddr VTableAddr Value

MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)

Returns an iterator to the first instruction in the bundle containing I.

bool all_of(R &&range, UnaryPredicate P)

Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.

std::string fromHex(StringRef Input)

Convert hexadecimal string Input to its binary representation. The return string is half the size of ...

auto enumerate(FirstRange &&First, RestRanges &&...Rest)

Given two or more input ranges, returns a new range whose values are tuples (A, B,...

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

bool isRangeRelaxable(const MCSymbol *Begin, const MCSymbol *End)

auto cast_or_null(const Y &Val)

auto unique(Range &&R, Predicate P)

bool isa_and_nonnull(const Y &Val)

SmallVector< DbgCallSiteParam, 4 > ParamSet

Collection used for storing debug call site parameters.

auto dyn_cast_or_null(const Y &Val)

void erase(Container &C, ValueType V)

Wrapper function to remove a value from a container:

bool any_of(R &&range, UnaryPredicate P)

Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.

void sort(IteratorTy Start, IteratorTy End)

AccelTableKind

The kind of accelerator tables we should emit.

@ Default

Platform default.

@ Apple

.apple_names, .apple_namespaces, .apple_types, .apple_objc.

@ Dwarf

DWARF v5 .debug_names.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

bool none_of(R &&Range, UnaryPredicate P)

Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

MachineBasicBlock::instr_iterator getBundleEnd(MachineBasicBlock::instr_iterator I)

Returns an iterator pointing beyond the bundle containing I.

bool is_sorted(R &&Range, Compare C)

Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

uint64_t offsetToAlignment(uint64_t Value, Align Alignment)

Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...

@ Global

Append to llvm.global_dtors.

@ Ref

The access may reference the value stored in memory.

auto remove_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

void emitAppleAccelTable(AsmPrinter *Asm, AccelTable< DataT > &Contents, StringRef Prefix, const MCSymbol *SecBegin)

Emit an Apple Accelerator Table consisting of entries in the specified AccelTable.

DWARFExpression::Operation Op

OutputIt copy(R &&Range, OutputIt Out)

LLVM_ABI void emitDWARF5AccelTable(AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, ArrayRef< std::unique_ptr< DwarfCompileUnit > > CUs)

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

void erase_if(Container &C, UnaryPredicate P)

Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...

DebuggerKind

Identify a debugger for "tuning" the debug info.

@ SCE

Tune debug info for SCE targets (e.g. PS4).

@ DBX

Tune debug info for dbx.

@ Default

No specific tuning requested.

@ GDB

Tune debug info for gdb.

@ LLDB

Tune debug info for lldb.

Implement std::hash so that hash_code can be used in STL containers.

Definition DwarfDebug.cpp:3502

const MCSymbol * Start

Definition DwarfDebug.cpp:3503

const MCSymbol * End

Definition DwarfDebug.cpp:3503

Represents a parameter whose call site value can be described by applying a debug expression to a reg...

Definition DwarfDebug.cpp:581

uint64_t ParamReg

The described parameter register.

Definition DwarfDebug.cpp:583

const DIExpression * Expr

Debug expression that has been built up when walking through the instruction chain that produces the ...

Definition DwarfDebug.cpp:587

This struct is a compact representation of a valid (non-zero power of two) alignment.

A pair of GlobalVariable and DIExpression.

Represents an entry-value location, or a fragment of one.

void addFrameIndexExpr(const DIExpression *Expr, int FI)

Definition DwarfDebug.cpp:300

std::set< FrameIndexExpr > FrameIndexExprs

const std::set< FrameIndexExpr > & getFrameIndexExprs() const

Get the FI entries, sorted by fragment offset.

Definition DwarfDebug.cpp:296

A MapVector that performs no allocations if smaller than a certain size.

Helper used to pair up a symbol and its DWARF compile unit.

This struct describes target specific location.

Describes an entry of the various gnu_pub* debug sections.