LLVM: lib/MC/MCAsmStreamer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

37#include

38#include

39

40using namespace llvm;

41

42namespace {

43

44class MCAsmStreamer final : public MCStreamer {

45 std::unique_ptr<formatted_raw_ostream> OSOwner;

46 formatted_raw_ostream &OS;

47 const MCAsmInfo *MAI;

48 std::unique_ptr InstPrinter;

49 std::unique_ptr Assembler;

50

51 SmallString<128> ExplicitCommentToEmit;

52 SmallString<128> CommentToEmit;

53 raw_svector_ostream CommentStream;

54 raw_null_ostream NullStream;

55

56 bool EmittedSectionDirective = false;

57

58 bool IsVerboseAsm = false;

59 bool ShowInst = false;

60 bool UseDwarfDirectory = false;

61

62 void EmitRegisterName(int64_t Register);

63 void PrintQuotedString(StringRef Data, raw_ostream &OS) const;

64 void printDwarfFileDirective(unsigned FileNo, StringRef Directory,

65 StringRef Filename,

66 std::optionalMD5::MD5Result Checksum,

67 std::optional Source,

68 bool UseDwarfDirectory,

69 raw_svector_ostream &OS) const;

70 void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;

71 void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;

72

73public:

74 MCAsmStreamer(MCContext &Context, std::unique_ptr<formatted_raw_ostream> os,

75 std::unique_ptr printer,

76 std::unique_ptr emitter,

77 std::unique_ptr asmbackend)

78 : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),

80 Assembler(std::make_unique(

82 (asmbackend) ? asmbackend->createObjectWriter(NullStream)

83 : nullptr)),

84 CommentStream(CommentToEmit) {

86 if (Assembler->getBackendPtr())

87 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());

88

89 Context.setUseNamesOnTempLabels(true);

90

91 auto *TO = Context.getTargetOptions();

92 if (!TO)

93 return;

94 IsVerboseAsm = TO->AsmVerbose;

95 if (IsVerboseAsm)

96 InstPrinter->setCommentStream(CommentStream);

97 ShowInst = TO->ShowMCInst;

98 switch (TO->MCUseDwarfDirectory) {

100 UseDwarfDirectory = false;

101 break;

103 UseDwarfDirectory = true;

104 break;

106 UseDwarfDirectory =

107 Context.getAsmInfo()->enableDwarfFileDirectoryDefault();

108 break;

109 }

110 }

111

112 MCAssembler &getAssembler() { return *Assembler; }

113 MCAssembler *getAssemblerPtr() override { return nullptr; }

114

115 inline void EmitEOL() {

116

117 emitExplicitComments();

118

119 if (!IsVerboseAsm) {

120 OS << '\n';

121 return;

122 }

123 EmitCommentsAndEOL();

124 }

125

126 void emitSyntaxDirective() override;

127

128 void EmitCommentsAndEOL();

129

130

131 bool isVerboseAsm() const override { return IsVerboseAsm; }

132

133

134 bool hasRawTextSupport() const override { return true; }

135

136

137

138

139 void AddComment(const Twine &T, bool EOL = true) override;

140

141

142 void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);

143

144

145

146

147 raw_ostream &getCommentOS() override {

148 if (!IsVerboseAsm)

149 return nulls();

150 return CommentStream;

151 }

152

153 void emitRawComment(const Twine &T, bool TabPrefix = true) override;

154

155 void addExplicitComment(const Twine &T) override;

156 void emitExplicitComments() override;

157

158

159 void addBlankLine() override { EmitEOL(); }

160

161

162

163

164 void switchSection(MCSection *Section, uint32_t Subsection) override;

165 bool popSection() override;

166

167 void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,

168 bool KeepOriginalSym) override;

169

170 void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;

171

172 void emitGNUAttribute(unsigned Tag, unsigned Value) override;

173

174 StringRef getMnemonic(const MCInst &MI) const override {

175 auto [Ptr, Bits] = InstPrinter->getMnemonic(MI);

176 assert((Bits != 0 || Ptr == nullptr) &&

177 "Invalid char pointer for instruction with no mnemonic");

178 return Ptr;

179 }

180

181 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;

182

183 void emitSubsectionsViaSymbols() override;

184 void emitLinkerOptions(ArrayRefstd::string Options) override;

186 void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,

187 unsigned Update, VersionTuple SDKVersion) override;

188 void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,

189 unsigned Update, VersionTuple SDKVersion) override;

190 void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,

191 unsigned Minor, unsigned Update,

192 VersionTuple SDKVersion) override;

193

194 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;

195 void emitConditionalAssignment(MCSymbol *Symbol,

196 const MCExpr *Value) override;

197 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;

199

200 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;

201 void beginCOFFSymbolDef(const MCSymbol *Symbol) override;

202 void emitCOFFSymbolStorageClass(int StorageClass) override;

203 void emitCOFFSymbolType(int Type) override;

204 void endCOFFSymbolDef() override;

205 void emitCOFFSafeSEH(MCSymbol const *Symbol) override;

206 void emitCOFFSymbolIndex(MCSymbol const *Symbol) override;

207 void emitCOFFSectionIndex(MCSymbol const *Symbol) override;

208 void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;

209 void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;

210 void emitCOFFSecNumber(MCSymbol const *Symbol) override;

211 void emitCOFFSecOffset(MCSymbol const *Symbol) override;

212 void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,

213 MCSymbol *CsectSym, Align Alignment) override;

214 void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,

217 void emitXCOFFRenameDirective(const MCSymbol *Name,

218 StringRef Rename) override;

219

220 void emitXCOFFRefDirective(const MCSymbol *Symbol) override;

221

222 void emitXCOFFExceptDirective(const MCSymbol *Symbol,

223 const MCSymbol *Trap,

224 unsigned Lang, unsigned Reason,

225 unsigned FunctionSize, bool hasDebug) override;

226 void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) override;

227

228 void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;

229 void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,

230 Align ByteAlignment) override;

231

232

233

234

235

236

237 void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,

238 Align ByteAlignment) override;

239

240 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,

241 uint64_t Size = 0, Align ByteAlignment = Align(1),

242 SMLoc Loc = SMLoc()) override;

243

244 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,

245 Align ByteAlignment = Align(1)) override;

246

247 void emitBinaryData(StringRef Data) override;

248

249 void emitBytes(StringRef Data) override;

250

251 void emitValueImpl(const MCExpr *Value, unsigned Size,

252 SMLoc Loc = SMLoc()) override;

253 void emitIntValue(uint64_t Value, unsigned Size) override;

254 void emitIntValueInHex(uint64_t Value, unsigned Size) override;

255 void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size) override;

256

257 void emitULEB128Value(const MCExpr *Value) override;

258

259 void emitSLEB128Value(const MCExpr *Value) override;

260

261 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,

262 SMLoc Loc = SMLoc()) override;

263

264 void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,

265 SMLoc Loc = SMLoc()) override;

266

267 void emitAlignmentDirective(uint64_t ByteAlignment,

268 std::optional<int64_t> Value, unsigned ValueSize,

269 unsigned MaxBytesToEmit);

270

271 void emitValueToAlignment(Align Alignment, int64_t Fill = 0,

272 uint8_t FillLen = 1,

273 unsigned MaxBytesToEmit = 0) override;

274

275 void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,

276 unsigned MaxBytesToEmit = 0) override;

277

278 void emitValueToOffset(const MCExpr *Offset,

279 unsigned char Value,

280 SMLoc Loc) override;

281

282 void emitFileDirective(StringRef Filename) override;

283 void emitFileDirective(StringRef Filename, StringRef CompilerVersion,

284 StringRef TimeStamp, StringRef Description) override;

285 Expected tryEmitDwarfFileDirective(

286 unsigned FileNo, StringRef Directory, StringRef Filename,

287 std::optionalMD5::MD5Result Checksum = std::nullopt,

288 std::optional Source = std::nullopt,

289 unsigned CUID = 0) override;

290 void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,

291 std::optionalMD5::MD5Result Checksum,

292 std::optional Source,

293 unsigned CUID = 0) override;

294 void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,

295 unsigned Flags, unsigned Isa,

296 unsigned Discriminator, StringRef FileName,

297 StringRef Location = {}) override;

298 void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override;

299

300 MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;

301

302 bool emitCVFileDirective(unsigned FileNo, StringRef Filename,

303 ArrayRef<uint8_t> Checksum,

304 unsigned ChecksumKind) override;

305 bool emitCVFuncIdDirective(unsigned FuncId) override;

306 bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,

307 unsigned IAFile, unsigned IALine,

308 unsigned IACol, SMLoc Loc) override;

309 void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,

310 unsigned Column, bool PrologueEnd, bool IsStmt,

311 StringRef FileName, SMLoc Loc) override;

312 void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,

313 const MCSymbol *FnEnd) override;

314 void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,

315 unsigned SourceFileId,

316 unsigned SourceLineNum,

317 const MCSymbol *FnStartSym,

318 const MCSymbol *FnEndSym) override;

319

320 void PrintCVDefRangePrefix(

321 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);

322

323 void emitCVDefRangeDirective(

324 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

325 codeview::DefRangeRegisterRelHeader DRHdr) override;

326

327 void emitCVDefRangeDirective(

328 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

329 codeview::DefRangeSubfieldRegisterHeader DRHdr) override;

330

331 void emitCVDefRangeDirective(

332 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

333 codeview::DefRangeRegisterHeader DRHdr) override;

334

335 void emitCVDefRangeDirective(

336 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

337 codeview::DefRangeFramePointerRelHeader DRHdr) override;

338

339 void emitCVStringTableDirective() override;

340 void emitCVFileChecksumsDirective() override;

341 void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;

342 void emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;

343

344 void emitIdent(StringRef IdentString) override;

345 void emitCFIBKeyFrame() override;

346 void emitCFIMTETaggedFrame() override;

347 void emitCFISections(bool EH, bool Debug, bool SFrame) override;

348 void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;

349 void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;

350 void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) override;

351 void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,

353 void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;

354 void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;

355 void emitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;

356 void emitCFIRememberState(SMLoc Loc) override;

357 void emitCFIRestoreState(SMLoc Loc) override;

358 void emitCFIRestore(int64_t Register, SMLoc Loc) override;

359 void emitCFISameValue(int64_t Register, SMLoc Loc) override;

360 void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;

361 void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) override;

362 void emitCFIEscape(StringRef Values, SMLoc Loc) override;

363 void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) override;

364 void emitCFISignalFrame() override;

365 void emitCFIUndefined(int64_t Register, SMLoc Loc) override;

366 void emitCFIRegister(int64_t Register1, int64_t Register2,

367 SMLoc Loc) override;

368 void emitCFIWindowSave(SMLoc Loc) override;

369 void emitCFINegateRAState(SMLoc Loc) override;

370 void emitCFINegateRAStateWithPC(SMLoc Loc) override;

371 void emitCFIReturnColumn(int64_t Register) override;

372 void emitCFILabelDirective(SMLoc Loc, StringRef Name) override;

373 void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;

374

375 void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;

376 void emitWinCFIEndProc(SMLoc Loc) override;

377 void emitWinCFIFuncletOrFuncEnd(SMLoc Loc) override;

378 void emitWinCFIStartChained(SMLoc Loc) override;

379 void emitWinCFIEndChained(SMLoc Loc) override;

380 void emitWinCFIPushReg(MCRegister Register, SMLoc Loc) override;

381 void emitWinCFISetFrame(MCRegister Register, unsigned Offset,

382 SMLoc Loc) override;

383 void emitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;

384 void emitWinCFISaveReg(MCRegister Register, unsigned Offset,

385 SMLoc Loc) override;

386 void emitWinCFISaveXMM(MCRegister Register, unsigned Offset,

387 SMLoc Loc) override;

388 void emitWinCFIPushFrame(bool Code, SMLoc Loc) override;

389 void emitWinCFIEndProlog(SMLoc Loc) override;

390 void emitWinCFIBeginEpilogue(SMLoc Loc) override;

391 void emitWinCFIEndEpilogue(SMLoc Loc) override;

392 void emitWinCFIUnwindV2Start(SMLoc Loc) override;

393 void emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc) override;

394

395 void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,

396 SMLoc Loc) override;

397 void emitWinEHHandlerData(SMLoc Loc) override;

398

399 void emitCGProfileEntry(const MCSymbolRefExpr *From,

400 const MCSymbolRefExpr *To, uint64_t Count) override;

401

402 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;

403

404 void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,

405 uint64_t Attr, uint64_t Discriminator,

407 MCSymbol *FnSym) override;

408

409 void emitRelocDirective(const MCExpr &Offset, StringRef Name,

410 const MCExpr *Expr, SMLoc Loc) override;

411

412 void emitAddrsig() override;

413 void emitAddrsigSym(const MCSymbol *Sym) override;

414

415

416

417

418 void emitRawTextImpl(StringRef String) override;

419

420 void finishImpl() override;

421

422 void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;

423

424 MCSymbol *emitDwarfUnitLength(const Twine &Prefix,

425 const Twine &Comment) override;

426

427 void emitDwarfLineStartLabel(MCSymbol *StartSym) override;

428

429 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,

430 MCSymbol *EndLabel = nullptr) override;

431

432 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,

433 const MCSymbol *Label,

434 unsigned PointerSize) override;

435};

436

437}

438

439void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {

440 if (!IsVerboseAsm) return;

441

442 T.toVector(CommentToEmit);

443

444 if (EOL)

445 CommentToEmit.push_back('\n');

446}

447

448void MCAsmStreamer::EmitCommentsAndEOL() {

450 OS << '\n';

451 return;

452 }

453

454 StringRef Comments = CommentToEmit;

455

457 "Comment array not newline terminated");

458 do {

459

461 size_t Position = Comments.find('\n');

463

464 Comments = Comments.substr(Position+1);

465 } while (!Comments.empty());

466

467 CommentToEmit.clear();

468}

469

471 assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");

472 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));

473}

474

475void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {

476 if (TabPrefix)

477 OS << '\t';

479 EmitEOL();

480}

481

482void MCAsmStreamer::addExplicitComment(const Twine &T) {

483 StringRef c = T.getSingleStringRef();

485 return;

487 ExplicitCommentToEmit.append("\t");

489

491 } else if (c.starts_with(StringRef("/*"))) {

492 size_t p = 2, len = c.size() - 2;

493

494 do {

495 size_t newp = std::min(len, c.find_first_of("\r\n", p));

496 ExplicitCommentToEmit.append("\t");

498 ExplicitCommentToEmit.append(c.slice(p, newp).str());

499

500 if (newp < len)

501 ExplicitCommentToEmit.append("\n");

502 p = newp + 1;

503 } while (p < len);

505 ExplicitCommentToEmit.append("\t");

506 ExplicitCommentToEmit.append(c.str());

507 } else if (c.front() == '#') {

508

509 ExplicitCommentToEmit.append("\t");

512 } else

513 assert(false && "Unexpected Assembly Comment");

514

515 if (c.back() == '\n')

516 emitExplicitComments();

517}

518

519void MCAsmStreamer::emitExplicitComments() {

520 StringRef Comments = ExplicitCommentToEmit;

521 if (!Comments.empty())

522 OS << Comments;

523 ExplicitCommentToEmit.clear();

524}

525

526void MCAsmStreamer::switchSection(MCSection *Section, uint32_t Subsection) {

528 if (!EmittedSectionDirective ||

530 EmittedSectionDirective = true;

531 if (MCTargetStreamer *TS = getTargetStreamer()) {

532 TS->changeSection(Cur.first, Section, Subsection, OS);

533 } else {

536 }

537 }

539}

540

541bool MCAsmStreamer::popSection() {

543 return false;

544 auto [Sec, Subsec] = getCurrentSection();

546 return true;

547}

548

549void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,

550 StringRef Name,

551 bool KeepOriginalSym) {

552 OS << ".symver ";

553 OriginalSym->print(OS, MAI);

554 OS << ", " << Name;

555 if (!KeepOriginalSym && Name.contains("@@@"))

556 OS << ", remove";

557 EmitEOL();

558}

559

560void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {

562

563

564

565 if (Symbol->isVariable() &&

567 Symbol->setOffset(0);

568

569 Symbol->print(OS, MAI);

571

572 EmitEOL();

573}

574

575void MCAsmStreamer::emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {

577

578#ifndef NDEBUG

580 assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");

581 assert(str != "" && "Invalid LOH name");

582#endif

583

585 bool IsFirst = true;

586 for (const MCSymbol *Arg : Args) {

587 if (!IsFirst)

588 OS << ", ";

589 IsFirst = false;

590 Arg->print(OS, MAI);

591 }

592 EmitEOL();

593}

594

595void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) {

596 OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n";

597}

598

599void MCAsmStreamer::emitSubsectionsViaSymbols() {

600 OS << ".subsections_via_symbols\n";

601}

602

603void MCAsmStreamer::emitLinkerOptions(ArrayRefstd::string Options) {

604 assert(Options.empty() && "At least one option is required!");

605 OS << "\t.linker_option \"" << Options[0] << '"';

607 OS << ", " << '"' << Opt << '"';

608 EmitEOL();

609}

610

613 return;

614 switch (Kind) {

620 }

621 EmitEOL();

622}

623

625 switch (Type) {

630 }

632}

633

636 if (SDKVersion.empty())

637 return;

638 OS << '\t' << "sdk_version " << SDKVersion.getMajor();

639 if (auto Minor = SDKVersion.getMinor()) {

640 OS << ", " << *Minor;

641 if (auto Subminor = SDKVersion.getSubminor()) {

642 OS << ", " << *Subminor;

643 }

644 }

645}

646

648 unsigned Minor, unsigned Update,

649 VersionTuple SDKVersion) {

651 if (Update)

652 OS << ", " << Update;

654 EmitEOL();

655}

656

658 switch (Type) {

659#define PLATFORM(platform, id, name, build_name, target, tapi_target, \

660 marketing) \

661 case MachO::PLATFORM_##platform: \

662 return #build_name;

663#include "llvm/BinaryFormat/MachO.def"

664 }

666}

667

668void MCAsmStreamer::emitBuildVersion(unsigned Platform, unsigned Major,

669 unsigned Minor, unsigned Update,

670 VersionTuple SDKVersion) {

672 OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;

673 if (Update)

674 OS << ", " << Update;

676 EmitEOL();

677}

678

679void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(

680 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,

681 VersionTuple SDKVersion) {

682 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);

683}

684

685void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {

687 if (UseSet)

688 OS << ".set ";

689 Symbol->print(OS, MAI);

690 OS << (UseSet ? ", " : " = ");

692

693 EmitEOL();

695}

696

697void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,

698 const MCExpr *Value) {

699 OS << ".lto_set_conditional ";

700 Symbol->print(OS, MAI);

701 OS << ", ";

703 EmitEOL();

704}

705

706void MCAsmStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {

707 OS << ".weakref ";

708 Alias->print(OS, MAI);

709 OS << ", ";

710 Symbol->print(OS, MAI);

711 EmitEOL();

712}

713

714bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,

721 case MCSA_ELF_TypeTLS:

726 return false;

727 OS << "\t.type\t";

728 Symbol->print(OS, MAI);

729 OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');

731 default: return false;

739 }

740 EmitEOL();

741 return true;

744 break;

745 case MCSA_LGlobal: OS << "\t.lglobl\t"; break;

746 case MCSA_Hidden: OS << "\t.hidden\t"; break;

748 case MCSA_Internal: OS << "\t.internal\t"; break;

750 case MCSA_Local: OS << "\t.local\t"; break;

753 return false;

754 OS << "\t.no_dead_strip\t";

755 break;

757 case MCSA_AltEntry: OS << "\t.alt_entry\t"; break;

759 OS << "\t.private_extern\t";

760 break;

764 OS << "\t.extern\t";

765 break;

768 OS << "\t.weak_definition\t";

769 break;

770

774

776

777 return false;

779 OS << "\t.memtag\t";

780 break;

782 OS << "\t.weak_anti_dep\t";

783 break;

784 }

785

786 Symbol->print(OS, MAI);

787 EmitEOL();

788

789 return true;

790}

791

792void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {

793 OS << ".desc" << ' ';

794 Symbol->print(OS, MAI);

795 OS << ',' << DescValue;

796 EmitEOL();

797}

798

799void MCAsmStreamer::emitSyntaxDirective() {

801 OS << "\t.intel_syntax noprefix";

802 EmitEOL();

803 }

804

805

806

807}

808

809void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {

810 OS << "\t.def\t";

811 Symbol->print(OS, MAI);

812 OS << ';';

813 EmitEOL();

814}

815

816void MCAsmStreamer::emitCOFFSymbolStorageClass(int StorageClass) {

818 EmitEOL();

819}

820

821void MCAsmStreamer::emitCOFFSymbolType(int Type) {

822 OS << "\t.type\t" << Type << ';';

823 EmitEOL();

824}

825

826void MCAsmStreamer::endCOFFSymbolDef() {

827 OS << "\t.endef";

828 EmitEOL();

829}

830

831void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {

832 OS << "\t.safeseh\t";

833 Symbol->print(OS, MAI);

834 EmitEOL();

835}

836

837void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {

838 OS << "\t.symidx\t";

839 Symbol->print(OS, MAI);

840 EmitEOL();

841}

842

843void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {

844 OS << "\t.secidx\t";

845 Symbol->print(OS, MAI);

846 EmitEOL();

847}

848

849void MCAsmStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {

850 OS << "\t.secrel32\t";

851 Symbol->print(OS, MAI);

854 EmitEOL();

855}

856

857void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {

858 OS << "\t.rva\t";

859 Symbol->print(OS, MAI);

863 OS << '-' << -Offset;

864 EmitEOL();

865}

866

867void MCAsmStreamer::emitCOFFSecNumber(MCSymbol const *Symbol) {

868 OS << "\t.secnum\t";

869 Symbol->print(OS, MAI);

870 EmitEOL();

871}

872

873void MCAsmStreamer::emitCOFFSecOffset(MCSymbol const *Symbol) {

874 OS << "\t.secoffset\t";

875 Symbol->print(OS, MAI);

876 EmitEOL();

877}

878

879

880

881

882void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,

883 uint64_t Size,

884 MCSymbol *CsectSym,

885 Align Alignment) {

887 "We only support writing log base-2 alignment format with XCOFF.");

888

889 OS << "\t.lcomm\t";

890 LabelSym->print(OS, MAI);

891 OS << ',' << Size << ',';

892 CsectSym->print(OS, MAI);

893 OS << ',' << Log2(Alignment);

894

895 EmitEOL();

896

897

898

899 auto *XSym = static_cast<MCSymbolXCOFF *>(CsectSym);

900 if (XSym->hasRename())

901 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());

902}

903

904void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(

906 auto &Sym = static_cast<MCSymbolXCOFF &>(*Symbol);

910 break;

913 break;

915 OS << "\t.extern\t";

916 break;

918 OS << "\t.lglobl\t";

919 break;

920 default:

922 }

923

924 Symbol->print(OS, MAI);

925

926 switch (Visibility) {

928

929 break;

931 OS << ",hidden";

932 break;

934 OS << ",protected";

935 break;

937 OS << ",exported";

938 break;

939 default:

941 }

942 EmitEOL();

943

944

945

946 if (Sym.hasRename())

947 emitXCOFFRenameDirective(&Sym, Sym.getSymbolTableName());

948}

949

950void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,

951 StringRef Rename) {

952 OS << "\t.rename\t";

953 Name->print(OS, MAI);

954 const char DQ = '"';

955 OS << ',' << DQ;

956 for (char C : Rename) {

957

958 if (C == DQ)

959 OS << DQ;

960 OS << C;

961 }

962 OS << DQ;

963 EmitEOL();

964}

965

966void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {

967 OS << "\t.ref ";

968 Symbol->print(OS, MAI);

969 EmitEOL();

970}

971

972void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,

973 const MCSymbol *Trap,

974 unsigned Lang,

975 unsigned Reason,

976 unsigned FunctionSize,

977 bool hasDebug) {

978 OS << "\t.except\t";

979 Symbol->print(OS, MAI);

980 OS << ", " << Lang << ", " << Reason;

981 EmitEOL();

982}

983

984void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {

985 const char InfoDirective[] = "\t.info ";

986 const char *Separator = ", ";

987 constexpr int WordSize = sizeof(uint32_t);

988

989

990 OS << InfoDirective;

991 PrintQuotedString(Name, OS);

992 OS << Separator;

993

994 size_t MetadataSize = Metadata.size();

995

996

997 OS << format_hex(MetadataSize, 10) << Separator;

998

999

1000 if (MetadataSize == 0) {

1001 EmitEOL();

1002 return;

1003 }

1004

1005

1006

1007

1008

1009

1010 uint32_t PaddedSize = alignTo(MetadataSize, WordSize);

1011 uint32_t PaddingSize = PaddedSize - MetadataSize;

1012

1013

1014

1015

1016

1017

1018 constexpr int WordsPerDirective = 5;

1019

1020

1021 int WordsBeforeNextDirective = 0;

1022 auto PrintWord = [&](const uint8_t *WordPtr) {

1023 if (WordsBeforeNextDirective-- == 0) {

1024 EmitEOL();

1025 OS << InfoDirective;

1026 WordsBeforeNextDirective = WordsPerDirective;

1027 }

1028 OS << Separator;

1031 };

1032

1033 size_t Index = 0;

1034 for (; Index + WordSize <= MetadataSize; Index += WordSize)

1035 PrintWord(reinterpret_cast<const uint8_t *>(Metadata.data()) + Index);

1036

1037

1038

1039 if (PaddingSize) {

1040 assert(PaddedSize - Index == WordSize);

1041 std::array<uint8_t, WordSize> LastWord = {0};

1042 ::memcpy(LastWord.data(), Metadata.data() + Index, MetadataSize - Index);

1043 PrintWord(LastWord.data());

1044 }

1045 EmitEOL();

1046}

1047

1048void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {

1050 OS << "\t.size\t";

1051 Symbol->print(OS, MAI);

1052 OS << ", ";

1054 EmitEOL();

1055}

1056

1057void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,

1058 Align ByteAlignment) {

1059 OS << "\t.comm\t";

1060 Symbol->print(OS, MAI);

1061 OS << ',' << Size;

1062

1065 else

1066 OS << ',' << Log2(ByteAlignment);

1067 EmitEOL();

1068

1069

1070

1072 auto *XSym = static_cast<MCSymbolXCOFF *>(Symbol);

1073 if (XSym && XSym->hasRename())

1074 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());

1075 }

1076}

1077

1078void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,

1079 Align ByteAlign) {

1080 OS << "\t.lcomm\t";

1081 Symbol->print(OS, MAI);

1082 OS << ',' << Size;

1083

1084 if (ByteAlign > 1) {

1089 OS << ',' << ByteAlign.value();

1090 break;

1092 OS << ',' << Log2(ByteAlign);

1093 break;

1094 }

1095 }

1096 EmitEOL();

1097}

1098

1099void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,

1100 uint64_t Size, Align ByteAlignment,

1101 SMLoc Loc) {

1102 if (Symbol)

1103 Symbol->setFragment(&Section->getDummyFragment());

1104

1105

1106 OS << ".zerofill ";

1107

1109 ".zerofill is a Mach-O specific directive");

1110

1111

1112 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);

1114

1115 if (Symbol) {

1116 OS << ',';

1117 Symbol->print(OS, MAI);

1118 OS << ',' << Size;

1119 OS << ',' << Log2(ByteAlignment);

1120 }

1121 EmitEOL();

1122}

1123

1124

1125

1126

1127void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,

1128 uint64_t Size, Align ByteAlignment) {

1129 Symbol->setFragment(&Section->getDummyFragment());

1130

1131

1132

1134 ".zerofill is a Mach-O specific directive");

1135

1136

1137 OS << ".tbss ";

1138 Symbol->print(OS, MAI);

1139 OS << ", " << Size;

1140

1141

1142

1143 if (ByteAlignment > 1)

1144 OS << ", " << Log2(ByteAlignment);

1145

1146 EmitEOL();

1147}

1148

1150 const auto BeginPtr = Data.begin(), EndPtr = Data.end();

1151 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {

1153 return false;

1154 }

1156}

1157

1158static inline char toOctal(int X) { return (X&7)+'0'; }

1159

1162 assert(Data.empty() && "Cannot generate an empty list.");

1163 const auto printCharacterInOctal = [&OS](unsigned char C) {

1164 OS << '0';

1168 };

1169 const auto printOneCharacterFor = [printCharacterInOctal](

1170 auto printOnePrintingCharacter) {

1171 return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {

1173 printOnePrintingCharacter(static_cast<char>(C));

1174 return;

1175 }

1176 printCharacterInOctal(C);

1177 };

1178 };

1179 const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {

1180 const auto BeginPtr = Data.begin(), EndPtr = Data.end();

1181 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {

1182 printOneCharacter(C);

1183 OS << ',';

1184 }

1185 printOneCharacter(*(EndPtr - 1));

1186 };

1187 switch (ACLS) {

1189 printCharacterList(printCharacterInOctal);

1190 return;

1192 printCharacterList(printOneCharacterFor([&OS](char C) {

1193 const char AsmCharLitBuf[2] = {'\'', C};

1194 OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));

1195 }));

1196 return;

1197 }

1199}

1200

1201void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {

1202 OS << '"';

1203

1204 if (MAI->isAIX()) {

1205 for (unsigned char C : Data) {

1206 if (C == '"')

1207 OS << "\"\"";

1208 else

1209 OS << (char)C;

1210 }

1211 } else {

1212 for (unsigned char C : Data) {

1213 if (C == '"' || C == '\\') {

1214 OS << '\\' << (char)C;

1215 continue;

1216 }

1217

1219 OS << (char)C;

1220 continue;

1221 }

1222

1223 switch (C) {

1224 case '\b':

1225 OS << "\\b";

1226 break;

1227 case '\f':

1228 OS << "\\f";

1229 break;

1230 case '\n':

1231 OS << "\\n";

1232 break;

1233 case '\r':

1234 OS << "\\r";

1235 break;

1236 case '\t':

1237 OS << "\\t";

1238 break;

1239 default:

1240 OS << '\\';

1244 break;

1245 }

1246 }

1247 }

1248

1249 OS << '"';

1250}

1251

1252void MCAsmStreamer::emitBytes(StringRef Data) {

1253 assert(getCurrentSectionOnly() &&

1254 "Cannot emit contents before setting section!");

1255 if (Data.empty()) return;

1256

1257 const auto emitAsString = [this](StringRef Data) {

1258 if (MAI->isAIX()) {

1260

1261

1262 if (Data.back() == 0) {

1263 OS << "\t.string\t";

1265 } else {

1266 OS << "\t.byte\t";

1267 }

1268 PrintQuotedString(Data, OS);

1269 } else {

1270 OS << "\t.byte\t";

1272 }

1273 EmitEOL();

1274 return true;

1275 }

1276

1277

1278

1284 } else {

1285 return false;

1286 }

1287

1288 PrintQuotedString(Data, OS);

1289 EmitEOL();

1290 return true;

1291 };

1292

1293 if (Data.size() != 1 && emitAsString(Data))

1294 return;

1295

1296

1297

1298 if (MCTargetStreamer *TS = getTargetStreamer()) {

1299 TS->emitRawBytes(Data);

1300 return;

1301 }

1303 for (const unsigned char C : Data.bytes()) {

1304 OS << Directive << (unsigned)C;

1305 EmitEOL();

1306 }

1307}

1308

1309void MCAsmStreamer::emitBinaryData(StringRef Data) {

1310

1311 const size_t Cols = 4;

1312 for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {

1313 size_t J = I, EJ = std::min(I + Cols, Data.size());

1316 for (; J < EJ - 1; ++J)

1317 OS << format("0x%02x", uint8_t(Data[J])) << ", ";

1318 OS << format("0x%02x", uint8_t(Data[J]));

1319 EmitEOL();

1320 }

1321}

1322

1323void MCAsmStreamer::emitIntValue(uint64_t Value, unsigned Size) {

1325}

1326

1327void MCAsmStreamer::emitIntValueInHex(uint64_t Value, unsigned Size) {

1329}

1330

1331void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t Value,

1332 unsigned Size) {

1334}

1335

1336void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,

1337 SMLoc Loc) {

1338 assert(Size <= 8 && "Invalid size");

1339 assert(getCurrentSectionOnly() &&

1340 "Cannot emit contents before setting section!");

1341 const char *Directive = nullptr;

1342 switch (Size) {

1343 default: break;

1348 }

1349

1350 if (!Directive) {

1351 int64_t IntValue;

1352 if (Value->evaluateAsAbsolute(IntValue))

1354

1355

1356

1357

1358

1360 for (unsigned Emitted = 0; Emitted != Size;) {

1362

1363

1365

1366

1367 unsigned ByteOffset =

1368 IsLittleEndian ? Emitted : (Remaining - EmissionSize);

1369 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);

1370

1371

1372

1373 uint64_t Shift = 64 - EmissionSize * 8;

1374 assert(Shift < static_cast<uint64_t>(

1375 std::numeric_limits::digits) &&

1376 "undefined behavior");

1377 ValueToEmit &= ~0ULL >> Shift;

1378 emitIntValue(ValueToEmit, EmissionSize);

1379 Emitted += EmissionSize;

1380 }

1381 return;

1382 }

1383

1384 assert(Directive && "Invalid size for machine code value!");

1385 OS << Directive;

1386 if (MCTargetStreamer *TS = getTargetStreamer()) {

1387 TS->emitValue(Value);

1388 } else {

1390 EmitEOL();

1391 }

1392}

1393

1394void MCAsmStreamer::emitULEB128Value(const MCExpr *Value) {

1395 int64_t IntValue;

1396 if (Value->evaluateAsAbsolute(IntValue)) {

1397 emitULEB128IntValue(IntValue);

1398 return;

1399 }

1400 OS << "\t.uleb128 ";

1402 EmitEOL();

1403}

1404

1405void MCAsmStreamer::emitSLEB128Value(const MCExpr *Value) {

1406 int64_t IntValue;

1407 if (Value->evaluateAsAbsolute(IntValue)) {

1408 emitSLEB128IntValue(IntValue);

1409 return;

1410 }

1411 OS << "\t.sleb128 ";

1413 EmitEOL();

1414}

1415

1416void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,

1417 SMLoc Loc) {

1418 int64_t IntNumBytes;

1419 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);

1420 if (IsAbsolute && IntNumBytes == 0)

1421 return;

1422

1424 if (!MAI->isAIX() || FillValue == 0) {

1425

1426 OS << ZeroDirective;

1428 if (FillValue != 0)

1429 OS << ',' << (int)FillValue;

1430 EmitEOL();

1431 } else {

1432 if (!IsAbsolute)

1434 "Cannot emit non-absolute expression lengths of fill.");

1435 for (int i = 0; i < IntNumBytes; ++i) {

1437 EmitEOL();

1438 }

1439 }

1440 return;

1441 }

1442

1444}

1445

1446void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,

1447 int64_t Expr, SMLoc Loc) {

1448

1449 OS << "\t.fill\t";

1451 OS << ", " << Size << ", 0x";

1453 EmitEOL();

1454}

1455

1456void MCAsmStreamer::emitAlignmentDirective(uint64_t ByteAlignment,

1457 std::optional<int64_t> Value,

1458 unsigned ValueSize,

1459 unsigned MaxBytesToEmit) {

1460 if (MAI->isAIX()) {

1463 "with .align.");

1464 OS << "\t.align\t";

1465 OS << Log2_64(ByteAlignment);

1466 EmitEOL();

1467 return;

1468 }

1469

1470

1471

1473 switch (ValueSize) {

1474 default:

1476 case 1:

1477 OS << "\t.p2align\t";

1478 break;

1479 case 2:

1480 OS << ".p2alignw ";

1481 break;

1482 case 4:

1483 OS << ".p2alignl ";

1484 break;

1485 case 8:

1487 }

1488

1489 OS << Log2_64(ByteAlignment);

1490

1491 if (Value.has_value() || MaxBytesToEmit) {

1492 if (Value.has_value()) {

1493 OS << ", 0x";

1495 } else {

1496 OS << ", ";

1497 }

1498

1499 if (MaxBytesToEmit)

1500 OS << ", " << MaxBytesToEmit;

1501 }

1502 EmitEOL();

1503 return;

1504 }

1505

1506

1507

1508 switch (ValueSize) {

1509 default: llvm_unreachable("Invalid size for machine code value!");

1510 case 1: OS << ".balign"; break;

1511 case 2: OS << ".balignw"; break;

1512 case 4: OS << ".balignl"; break;

1514 }

1515

1517 if (Value.has_value())

1519 else if (MaxBytesToEmit)

1520 OS << ", ";

1521 if (MaxBytesToEmit)

1522 OS << ", " << MaxBytesToEmit;

1523 EmitEOL();

1524}

1525

1526void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Fill,

1527 uint8_t FillLen,

1528 unsigned MaxBytesToEmit) {

1529 emitAlignmentDirective(Alignment.value(), Fill, FillLen, MaxBytesToEmit);

1530}

1531

1532void MCAsmStreamer::emitCodeAlignment(Align Alignment,

1533 const MCSubtargetInfo *STI,

1534 unsigned MaxBytesToEmit) {

1535

1538 MaxBytesToEmit);

1539 else

1540 emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);

1541}

1542

1543void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,

1544 unsigned char Value,

1545 SMLoc Loc) {

1546

1547 OS << ".org ";

1549 OS << ", " << (unsigned)Value;

1550 EmitEOL();

1551}

1552

1553void MCAsmStreamer::emitFileDirective(StringRef Filename) {

1555 OS << "\t.file\t";

1556 PrintQuotedString(Filename, OS);

1557 EmitEOL();

1558}

1559

1560void MCAsmStreamer::emitFileDirective(StringRef Filename,

1561 StringRef CompilerVersion,

1562 StringRef TimeStamp,

1563 StringRef Description) {

1565 OS << "\t.file\t";

1566 PrintQuotedString(Filename, OS);

1567 bool useTimeStamp = !TimeStamp.empty();

1568 bool useCompilerVersion = !CompilerVersion.empty();

1569 bool useDescription = !Description.empty();

1570 if (useTimeStamp || useCompilerVersion || useDescription) {

1571 OS << ",";

1572 if (useTimeStamp)

1573 PrintQuotedString(TimeStamp, OS);

1574 if (useCompilerVersion || useDescription) {

1575 OS << ",";

1576 if (useCompilerVersion)

1577 PrintQuotedString(CompilerVersion, OS);

1578 if (useDescription) {

1579 OS << ",";

1580 PrintQuotedString(Description, OS);

1581 }

1582 }

1583 }

1584 EmitEOL();

1585}

1586

1587void MCAsmStreamer::printDwarfFileDirective(

1588 unsigned FileNo, StringRef Directory, StringRef Filename,

1589 std::optionalMD5::MD5Result Checksum, std::optional Source,

1590 bool UseDwarfDirectory, raw_svector_ostream &OS) const {

1591 SmallString<128> FullPathName;

1592

1593 if (!UseDwarfDirectory && !Directory.empty()) {

1595 Directory = "";

1596 else {

1597 FullPathName = Directory;

1599 Directory = "";

1601 }

1602 }

1603

1604 OS << "\t.file\t" << FileNo << ' ';

1605 if (!Directory.empty()) {

1606 PrintQuotedString(Directory, OS);

1607 OS << ' ';

1608 }

1609 PrintQuotedString(Filename, OS);

1610 if (Checksum)

1611 OS << " md5 0x" << Checksum->digest();

1612 if (Source) {

1613 OS << " source ";

1614 PrintQuotedString(*Source, OS);

1615 }

1616}

1617

1618Expected MCAsmStreamer::tryEmitDwarfFileDirective(

1619 unsigned FileNo, StringRef Directory, StringRef Filename,

1620 std::optionalMD5::MD5Result Checksum, std::optional Source,

1621 unsigned CUID) {

1622 assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");

1623

1624 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);

1626 Expected FileNoOrErr =

1627 Table.tryGetFile(Directory, Filename, Checksum, Source,

1629 if (!FileNoOrErr)

1631 FileNo = FileNoOrErr.get();

1632

1633

1634

1636 return FileNo;

1637

1638 SmallString<128> Str;

1639 raw_svector_ostream OS1(Str);

1640 printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,

1641 UseDwarfDirectory, OS1);

1642

1643 if (MCTargetStreamer *TS = getTargetStreamer())

1644 TS->emitDwarfFileDirective(OS1.str());

1645 else

1646 emitRawText(OS1.str());

1647

1648 return FileNo;

1649}

1650

1651void MCAsmStreamer::emitDwarfFile0Directive(

1652 StringRef Directory, StringRef Filename,

1653 std::optionalMD5::MD5Result Checksum, std::optional Source,

1654 unsigned CUID) {

1656

1658 return;

1659

1660 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,

1661 Source);

1662

1663

1664 if (MAI->isAIX())

1665 return;

1666

1667 SmallString<128> Str;

1668 raw_svector_ostream OS1(Str);

1669 printDwarfFileDirective(0, Directory, Filename, Checksum, Source,

1670 UseDwarfDirectory, OS1);

1671

1672 if (MCTargetStreamer *TS = getTargetStreamer())

1673 TS->emitDwarfFileDirective(OS1.str());

1674 else

1675 emitRawText(OS1.str());

1676}

1677

1678void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,

1679 unsigned Column, unsigned Flags,

1680 unsigned Isa, unsigned Discriminator,

1681 StringRef FileName,

1682 StringRef Comment) {

1683

1684

1685 if (MAI->isAIX()) {

1686

1687

1690 Discriminator, FileName, Comment);

1691 return;

1692 }

1693

1694 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;

1697 OS << " basic_block";

1699 OS << " prologue_end";

1701 OS << " epilogue_begin";

1702

1703 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();

1705 OS << " is_stmt ";

1706

1708 OS << "1";

1709 else

1710 OS << "0";

1711 }

1712

1713 if (Isa)

1714 OS << " isa " << Isa;

1715 if (Discriminator)

1717 }

1718

1719 if (IsVerboseAsm) {

1723 OS << FileName << ':' << Line << ':' << Column;

1724 else

1726 }

1727 EmitEOL();

1729 Discriminator, FileName, Comment);

1730}

1731

1732void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {

1734 OS << ".loc_label\t" << Name;

1735 EmitEOL();

1736}

1737

1738MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {

1739

1740

1742}

1743

1744bool MCAsmStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,

1745 ArrayRef<uint8_t> Checksum,

1746 unsigned ChecksumKind) {

1747 if (getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,

1748 ChecksumKind))

1749 return false;

1750

1751 OS << "\t.cv_file\t" << FileNo << ' ';

1752 PrintQuotedString(Filename, OS);

1753

1754 if (!ChecksumKind) {

1755 EmitEOL();

1756 return true;

1757 }

1758

1759 OS << ' ';

1760 PrintQuotedString(toHex(Checksum), OS);

1762

1763 EmitEOL();

1764 return true;

1765}

1766

1767bool MCAsmStreamer::emitCVFuncIdDirective(unsigned FuncId) {

1768 OS << "\t.cv_func_id " << FuncId << '\n';

1770}

1771

1772bool MCAsmStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,

1773 unsigned IAFunc,

1774 unsigned IAFile,

1775 unsigned IALine, unsigned IACol,

1776 SMLoc Loc) {

1777 OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc

1778 << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';

1780 IALine, IACol, Loc);

1781}

1782

1783void MCAsmStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,

1784 unsigned Line, unsigned Column,

1785 bool PrologueEnd, bool IsStmt,

1786 StringRef FileName, SMLoc Loc) {

1787

1788 if (!checkCVLocSection(FunctionId, FileNo, Loc))

1789 return;

1790

1791 OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "

1792 << Column;

1793 if (PrologueEnd)

1794 OS << " prologue_end";

1795

1796 if (IsStmt)

1797 OS << " is_stmt 1";

1798

1799 if (IsVerboseAsm) {

1802 << Column;

1803 }

1804 EmitEOL();

1805}

1806

1807void MCAsmStreamer::emitCVLinetableDirective(unsigned FunctionId,

1808 const MCSymbol *FnStart,

1809 const MCSymbol *FnEnd) {

1810 OS << "\t.cv_linetable\t" << FunctionId << ", ";

1811 FnStart->print(OS, MAI);

1812 OS << ", ";

1813 FnEnd->print(OS, MAI);

1814 EmitEOL();

1816}

1817

1818void MCAsmStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,

1819 unsigned SourceFileId,

1820 unsigned SourceLineNum,

1821 const MCSymbol *FnStartSym,

1822 const MCSymbol *FnEndSym) {

1823 OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId

1824 << ' ' << SourceLineNum << ' ';

1825 FnStartSym->print(OS, MAI);

1826 OS << ' ';

1827 FnEndSym->print(OS, MAI);

1828 EmitEOL();

1830 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);

1831}

1832

1833void MCAsmStreamer::PrintCVDefRangePrefix(

1834 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {

1835 OS << "\t.cv_def_range\t";

1836 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {

1837 OS << ' ';

1839 OS << ' ';

1841 }

1842}

1843

1844void MCAsmStreamer::emitCVDefRangeDirective(

1845 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

1846 codeview::DefRangeRegisterRelHeader DRHdr) {

1847 PrintCVDefRangePrefix(Ranges);

1848 OS << ", reg_rel, ";

1849 OS << DRHdr.Register << ", " << DRHdr.Flags << ", "

1851 EmitEOL();

1852}

1853

1854void MCAsmStreamer::emitCVDefRangeDirective(

1855 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

1856 codeview::DefRangeSubfieldRegisterHeader DRHdr) {

1857 PrintCVDefRangePrefix(Ranges);

1858 OS << ", subfield_reg, ";

1860 EmitEOL();

1861}

1862

1863void MCAsmStreamer::emitCVDefRangeDirective(

1864 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

1865 codeview::DefRangeRegisterHeader DRHdr) {

1866 PrintCVDefRangePrefix(Ranges);

1867 OS << ", reg, ";

1869 EmitEOL();

1870}

1871

1872void MCAsmStreamer::emitCVDefRangeDirective(

1873 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,

1874 codeview::DefRangeFramePointerRelHeader DRHdr) {

1875 PrintCVDefRangePrefix(Ranges);

1876 OS << ", frame_ptr_rel, ";

1878 EmitEOL();

1879}

1880

1881void MCAsmStreamer::emitCVStringTableDirective() {

1882 OS << "\t.cv_stringtable";

1883 EmitEOL();

1884}

1885

1886void MCAsmStreamer::emitCVFileChecksumsDirective() {

1887 OS << "\t.cv_filechecksums";

1888 EmitEOL();

1889}

1890

1891void MCAsmStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {

1892 OS << "\t.cv_filechecksumoffset\t" << FileNo;

1893 EmitEOL();

1894}

1895

1896void MCAsmStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {

1897 OS << "\t.cv_fpo_data\t";

1898 ProcSym->print(OS, MAI);

1899 EmitEOL();

1900}

1901

1902void MCAsmStreamer::emitIdent(StringRef IdentString) {

1904 OS << "\t.ident\t";

1905 PrintQuotedString(IdentString, OS);

1906 EmitEOL();

1907}

1908

1909void MCAsmStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {

1911 OS << "\t.cfi_sections ";

1912 bool C = false;

1913 if (EH) {

1914 OS << ".eh_frame";

1915 C = true;

1916 }

1918 if (C)

1919 OS << ", ";

1920 OS << ".debug_frame";

1921 C = true;

1922 }

1923 if (SFrame) {

1924 if (C)

1925 OS << ", ";

1926 OS << ".sframe";

1927 }

1928

1929 EmitEOL();

1930}

1931

1932void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {

1933 OS << "\t.cfi_startproc";

1935 OS << " simple";

1936 EmitEOL();

1937}

1938

1939void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {

1941 OS << "\t.cfi_endproc";

1942 EmitEOL();

1943}

1944

1945void MCAsmStreamer::EmitRegisterName(int64_t Register) {

1947

1948

1949

1950 const MCRegisterInfo *MRI = getContext().getRegisterInfo();

1951 if (std::optional LLVMRegister =

1953 InstPrinter->printRegName(OS, *LLVMRegister);

1954 return;

1955 }

1956 }

1958}

1959

1960void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {

1962 OS << "\t.cfi_def_cfa ";

1964 OS << ", " << Offset;

1965 EmitEOL();

1966}

1967

1968void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {

1970 OS << "\t.cfi_def_cfa_offset " << Offset;

1971 EmitEOL();

1972}

1973

1974void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,

1977 OS << "\t.cfi_llvm_def_aspace_cfa ";

1979 OS << ", " << Offset;

1981 EmitEOL();

1982}

1983

1985 OS << "\t.cfi_escape ";

1986 if (!Values.empty()) {

1987 size_t e = Values.size() - 1;

1988 for (size_t i = 0; i < e; ++i)

1989 OS << format("0x%02x", uint8_t(Values[i])) << ", ";

1991 }

1992}

1993

1994void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {

1997 EmitEOL();

1998}

1999

2000void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {

2002

2003 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };

2005

2006 PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));

2007 EmitEOL();

2008}

2009

2010void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {

2012 OS << "\t.cfi_def_cfa_register ";

2014 EmitEOL();

2015}

2016

2017void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {

2019 OS << "\t.cfi_offset ";

2021 OS << ", " << Offset;

2022 EmitEOL();

2023}

2024

2025void MCAsmStreamer::emitCFIPersonality(const MCSymbol *Sym,

2026 unsigned Encoding) {

2028 OS << "\t.cfi_personality " << Encoding << ", ";

2029 Sym->print(OS, MAI);

2030 EmitEOL();

2031}

2032

2033void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {

2035 OS << "\t.cfi_lsda " << Encoding << ", ";

2036 Sym->print(OS, MAI);

2037 EmitEOL();

2038}

2039

2040void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {

2042 OS << "\t.cfi_remember_state";

2043 EmitEOL();

2044}

2045

2046void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {

2048 OS << "\t.cfi_restore_state";

2049 EmitEOL();

2050}

2051

2052void MCAsmStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {

2054 OS << "\t.cfi_restore ";

2056 EmitEOL();

2057}

2058

2059void MCAsmStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {

2061 OS << "\t.cfi_same_value ";

2063 EmitEOL();

2064}

2065

2066void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset,

2067 SMLoc Loc) {

2069 OS << "\t.cfi_rel_offset ";

2071 OS << ", " << Offset;

2072 EmitEOL();

2073}

2074

2075void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {

2077 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;

2078 EmitEOL();

2079}

2080

2081void MCAsmStreamer::emitCFISignalFrame() {

2083 OS << "\t.cfi_signal_frame";

2084 EmitEOL();

2085}

2086

2087void MCAsmStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {

2089 OS << "\t.cfi_undefined ";

2091 EmitEOL();

2092}

2093

2094void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,

2095 SMLoc Loc) {

2097 OS << "\t.cfi_register ";

2098 EmitRegisterName(Register1);

2099 OS << ", ";

2100 EmitRegisterName(Register2);

2101 EmitEOL();

2102}

2103

2104void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {

2106 OS << "\t.cfi_window_save";

2107 EmitEOL();

2108}

2109

2110void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {

2112 OS << "\t.cfi_negate_ra_state";

2113 EmitEOL();

2114}

2115

2116void MCAsmStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {

2118 OS << "\t.cfi_negate_ra_state_with_pc";

2119 EmitEOL();

2120}

2121

2122void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {

2124 OS << "\t.cfi_return_column ";

2126 EmitEOL();

2127}

2128

2129void MCAsmStreamer::emitCFILabelDirective(SMLoc Loc, StringRef Name) {

2131 OS << "\t.cfi_label " << Name;

2132 EmitEOL();

2133}

2134

2135void MCAsmStreamer::emitCFIBKeyFrame() {

2137 OS << "\t.cfi_b_key_frame";

2138 EmitEOL();

2139}

2140

2141void MCAsmStreamer::emitCFIMTETaggedFrame() {

2143 OS << "\t.cfi_mte_tagged_frame";

2144 EmitEOL();

2145}

2146

2147void MCAsmStreamer::emitCFIValOffset(int64_t Register, int64_t Offset,

2148 SMLoc Loc) {

2150 OS << "\t.cfi_val_offset ";

2152 OS << ", " << Offset;

2153 EmitEOL();

2154}

2155

2156void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {

2158

2159 OS << ".seh_proc ";

2160 Symbol->print(OS, MAI);

2161 EmitEOL();

2162}

2163

2164void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {

2166

2167 OS << "\t.seh_endproc";

2168 EmitEOL();

2169}

2170

2171void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {

2173

2174 OS << "\t.seh_endfunclet";

2175 EmitEOL();

2176}

2177

2178void MCAsmStreamer::emitWinCFIStartChained(SMLoc Loc) {

2180

2181 OS << "\t.seh_startchained";

2182 EmitEOL();

2183}

2184

2185void MCAsmStreamer::emitWinCFIEndChained(SMLoc Loc) {

2187

2188 OS << "\t.seh_endchained";

2189 EmitEOL();

2190}

2191

2192void MCAsmStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind,

2193 bool Except, SMLoc Loc) {

2195

2196 OS << "\t.seh_handler ";

2197 Sym->print(OS, MAI);

2198 char Marker = '@';

2199 const Triple &T = getContext().getTargetTriple();

2201 Marker = '%';

2202 if (Unwind)

2203 OS << ", " << Marker << "unwind";

2204 if (Except)

2205 OS << ", " << Marker << "except";

2206 EmitEOL();

2207}

2208

2209void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {

2211

2212

2213

2214

2215

2216 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();

2217

2218

2219

2220 if (!CurFrame)

2221 return;

2222

2224 MCSection *XData = getAssociatedXDataSection(TextSec);

2225 switchSectionNoPrint(XData);

2226

2227 OS << "\t.seh_handlerdata";

2228 EmitEOL();

2229}

2230

2231void MCAsmStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {

2233

2234 OS << "\t.seh_pushreg ";

2235 InstPrinter->printRegName(OS, Register);

2236 EmitEOL();

2237}

2238

2239void MCAsmStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,

2240 SMLoc Loc) {

2242

2243 OS << "\t.seh_setframe ";

2244 InstPrinter->printRegName(OS, Register);

2245 OS << ", " << Offset;

2246 EmitEOL();

2247}

2248

2249void MCAsmStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {

2251

2252 OS << "\t.seh_stackalloc " << Size;

2253 EmitEOL();

2254}

2255

2256void MCAsmStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,

2257 SMLoc Loc) {

2259

2260 OS << "\t.seh_savereg ";

2261 InstPrinter->printRegName(OS, Register);

2262 OS << ", " << Offset;

2263 EmitEOL();

2264}

2265

2266void MCAsmStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,

2267 SMLoc Loc) {

2269

2270 OS << "\t.seh_savexmm ";

2271 InstPrinter->printRegName(OS, Register);

2272 OS << ", " << Offset;

2273 EmitEOL();

2274}

2275

2276void MCAsmStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {

2278

2279 OS << "\t.seh_pushframe";

2280 if (Code)

2281 OS << " @code";

2282 EmitEOL();

2283}

2284

2285void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {

2287

2288 OS << "\t.seh_endprologue";

2289 EmitEOL();

2290}

2291

2292void MCAsmStreamer::emitWinCFIBeginEpilogue(SMLoc Loc) {

2294

2295 OS << "\t.seh_startepilogue";

2296 EmitEOL();

2297}

2298

2299void MCAsmStreamer::emitWinCFIEndEpilogue(SMLoc Loc) {

2301

2302 OS << "\t.seh_endepilogue";

2303 EmitEOL();

2304}

2305

2306void MCAsmStreamer::emitWinCFIUnwindV2Start(SMLoc Loc) {

2308

2309 OS << "\t.seh_unwindv2start";

2310 EmitEOL();

2311}

2312

2313void MCAsmStreamer::emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc) {

2315

2316 OS << "\t.seh_unwindversion " << (unsigned)Version;

2317 EmitEOL();

2318}

2319

2320void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,

2321 const MCSymbolRefExpr *To,

2322 uint64_t Count) {

2323 OS << "\t.cg_profile ";

2325 OS << ", ";

2327 OS << ", " << Count;

2328 EmitEOL();

2329}

2330

2331void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,

2332 const MCSubtargetInfo &STI) {

2333 raw_ostream &OS = getCommentOS();

2334 SmallString<256> Code;

2336

2337

2338 if (!getAssembler().getEmitterPtr())

2339 return;

2340

2341 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);

2342

2343

2344 bool ForceLE = getContext().getTargetTriple().isRISCV();

2345

2346

2347

2348

2351 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)

2352 FixupMap[i] = 0;

2353

2354 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {

2356 MCFixupKindInfo Info =

2357 getAssembler().getBackend().getFixupKindInfo(F.getKind());

2358 for (unsigned j = 0; j != Info.TargetSize; ++j) {

2359 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;

2360 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");

2361 FixupMap[Index] = 1 + i;

2362 }

2363 }

2364

2365

2366

2367 OS << "encoding: [";

2368 for (unsigned i = 0, e = Code.size(); i != e; ++i) {

2369 if (i)

2370 OS << ',';

2371

2372

2373 uint8_t MapEntry = FixupMap[i * 8 + 0];

2374 for (unsigned j = 1; j != 8; ++j) {

2375 if (FixupMap[i * 8 + j] == MapEntry)

2376 continue;

2377

2378 MapEntry = uint8_t(~0U);

2379 break;

2380 }

2381

2382 if (MapEntry != uint8_t(~0U)) {

2383 if (MapEntry == 0) {

2384 OS << format("0x%02x", uint8_t(Code[i]));

2385 } else {

2386 if (Code[i]) {

2387

2388 OS << format("0x%02x", uint8_t(Code[i])) << '\''

2389 << char('A' + MapEntry - 1) << '\'';

2390 } else

2391 OS << char('A' + MapEntry - 1);

2392 }

2393 } else {

2394

2395 OS << "0b";

2396 for (unsigned j = 8; j--;) {

2397 unsigned Bit = (Code[i] >> j) & 1;

2398

2399 unsigned FixupBit;

2400

2401

2402

2404 FixupBit = i * 8 + j;

2405 else

2406 FixupBit = i * 8 + (7-j);

2407

2408 if (uint8_t MapEntry = FixupMap[FixupBit]) {

2409 assert(Bit == 0 && "Encoder wrote into fixed up bit!");

2410 OS << char('A' + MapEntry - 1);

2411 } else

2412 OS << Bit;

2413 }

2414 }

2415 }

2416 OS << "]\n";

2417

2418 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {

2420 OS << " fixup " << char('A' + i) << " - "

2421 << "offset: " << F.getOffset() << ", value: ";

2423 auto Kind = F.getKind();

2425 OS << ", relocation type: " << Kind;

2426 else {

2427 OS << ", kind: ";

2428 auto Info = getAssembler().getBackend().getFixupKindInfo(Kind);

2429 if (F.isPCRel() && StringRef(Info.Name).starts_with("FK_Data_"))

2430 OS << "FK_PCRel_" << (Info.TargetSize / 8);

2431 else

2432 OS << Info.Name;

2433 }

2434 OS << '\n';

2435 }

2436}

2437

2438void MCAsmStreamer::emitInstruction(const MCInst &Inst,

2439 const MCSubtargetInfo &STI) {

2440 if (CurFrag) {

2441 MCSection *Sec = getCurrentSectionOnly();

2443 }

2444

2445 if (MAI->isAIX() && CurFrag)

2446

2447

2449

2450

2451 AddEncodingComment(Inst, STI);

2452

2453

2454 if (ShowInst) {

2455 Inst.dump_pretty(getCommentOS(), InstPrinter.get(), "\n ");

2456 getCommentOS() << "\n";

2457 }

2458

2459 if(getTargetStreamer())

2460 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);

2461 else

2462 InstPrinter->printInst(&Inst, 0, "", STI, OS);

2463

2464 StringRef Comments = CommentToEmit;

2465 if (Comments.size() && Comments.back() != '\n')

2466 getCommentOS() << "\n";

2467

2468 EmitEOL();

2469}

2470

2471void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,

2472 uint64_t Type, uint64_t Attr,

2473 uint64_t Discriminator,

2475 MCSymbol *FnSym) {

2476 OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;

2477 if (Discriminator)

2479

2480

2481 for (const auto &Site : InlineStack)

2482 OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);

2483

2484 OS << " ";

2485 FnSym->print(OS, MAI);

2486

2487 EmitEOL();

2488}

2489

2490void MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,

2491 const MCExpr *Expr, SMLoc) {

2492 OS << "\t.reloc ";

2494 OS << ", " << Name;

2495 if (Expr) {

2496 OS << ", ";

2498 }

2499 EmitEOL();

2500}

2501

2502void MCAsmStreamer::emitAddrsig() {

2503 OS << "\t.addrsig";

2504 EmitEOL();

2505}

2506

2507void MCAsmStreamer::emitAddrsigSym(const MCSymbol *Sym) {

2508 OS << "\t.addrsig_sym ";

2509 Sym->print(OS, MAI);

2510 EmitEOL();

2511}

2512

2513

2514

2515

2516void MCAsmStreamer::emitRawTextImpl(StringRef String) {

2517 String.consume_back("\n");

2519 EmitEOL();

2520}

2521

2522void MCAsmStreamer::finishImpl() {

2523

2524 if (getContext().getGenDwarfForAssembly())

2526

2527

2528

2529 if (MAI->isAIX()) {

2531 return;

2532 }

2533

2534

2535

2536

2537 const auto &Tables = getContext().getMCDwarfLineTables();

2538 if (!Tables.empty()) {

2539 assert(Tables.size() == 1 && "asm output only supports one line table");

2540 if (auto *Label = Tables.begin()->second.getLabel()) {

2541 switchSection(getContext().getObjectFileInfo()->getDwarfLineSection(), 0);

2542 emitLabel(Label);

2543 }

2544 }

2545}

2546

2547void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {

2548

2549

2550

2551

2552

2553

2554 if (MAI->isAIX())

2555 return;

2557}

2558

2559MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,

2560 const Twine &Comment) {

2561

2562

2563

2564

2565

2566

2567 if (MAI->isAIX())

2568 return getContext().createTempSymbol(Prefix + "_end");

2570}

2571

2572void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {

2573

2574

2575

2576

2577

2578

2580 if (MAI->isAIX()) {

2582

2583 emitLabel(DebugLineSymTmp);

2584

2585

2586

2587 unsigned LengthFieldSize =

2592

2593 emitAssignment(StartSym, OuterSym);

2594 return;

2595 }

2597}

2598

2599void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,

2600 MCSymbol *LastLabel,

2601 MCSymbol *EndLabel) {

2602

2603

2604

2605

2606

2608 ".loc should not be generated together with raw data!");

2609

2611

2612

2613

2614

2616 assert(TextSection->hasEnded() && ".text section is not end!");

2617

2618 if (!EndLabel)

2620 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();

2621 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,

2623}

2624

2625

2626void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,

2627 const MCSymbol *LastLabel,

2628 const MCSymbol *Label,

2629 unsigned PointerSize) {

2631 ".loc/.file don't need raw data in debug line section!");

2632

2633

2634 AddComment("Set address to " + Label->getName());

2635 emitIntValue(dwarf::DW_LNS_extended_op, 1);

2636 emitULEB128IntValue(PointerSize + 1);

2637 emitIntValue(dwarf::DW_LNE_set_address, 1);

2638 emitSymbolValue(Label, PointerSize);

2639

2640 if (!LastLabel) {

2641

2642 AddComment("Start sequence");

2644 return;

2645 }

2646

2647

2648

2650 AddComment("End sequence");

2651 emitIntValue(dwarf::DW_LNS_extended_op, 1);

2652 emitULEB128IntValue(1);

2653 emitIntValue(dwarf::DW_LNE_end_sequence, 1);

2654 return;

2655 }

2656

2657

2658 AddComment("Advance line " + Twine(LineDelta));

2659 emitIntValue(dwarf::DW_LNS_advance_line, 1);

2660 emitSLEB128IntValue(LineDelta);

2661 emitIntValue(dwarf::DW_LNS_copy, 1);

2662}

2663

2665 std::unique_ptr<formatted_raw_ostream> OS,

2666 std::unique_ptr IP,

2667 std::unique_ptr CE,

2668 std::unique_ptr MAB) {

2669 return new MCAsmStreamer(Context, std::move(OS), std::move(IP), std::move(CE),

2670 std::move(MAB));

2671}

unsigned const MachineRegisterInfo * MRI

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

Analysis containing CSE Info

#define LLVM_LIKELY(EXPR)

static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug

static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values)

Definition MCAsmStreamer.cpp:1984

static const char * getVersionMinDirective(MCVersionMinType Type)

Definition MCAsmStreamer.cpp:624

static bool isPrintableString(StringRef Data)

Definition MCAsmStreamer.cpp:1149

static void PrintByteList(StringRef Data, raw_ostream &OS, MCAsmInfo::AsmCharLiteralSyntax ACLS)

Definition MCAsmStreamer.cpp:1160

static char toOctal(int X)

Definition MCAsmStreamer.cpp:1158

static void EmitSDKVersionSuffix(raw_ostream &OS, const VersionTuple &SDKVersion)

Definition MCAsmStreamer.cpp:634

static int64_t truncateToSize(int64_t Value, unsigned Bytes)

Definition MCAsmStreamer.cpp:470

static const char * getPlatformName(MachO::PlatformType Type)

Definition MCAsmStreamer.cpp:657

#define DWARF2_FLAG_IS_STMT

#define DWARF2_FLAG_BASIC_BLOCK

#define DWARF2_FLAG_PROLOGUE_END

#define DWARF2_FLAG_EPILOGUE_BEGIN

Promote Memory to Register

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

This file defines the SmallString class.

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

StringRef getMnemonic(unsigned Opc)

LLVM_ABI void print(raw_ostream &OS) const

Print out the bounds to a stream.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

const char * getLabelSuffix() const

bool hasDotTypeDotSizeDirective() const

bool isLittleEndian() const

True if the target is little endian.

bool doesSupportDataRegionDirectives() const

bool usesSetToEquateSymbol() const

const char * getData32bitsDirective() const

unsigned getAssemblerDialect() const

unsigned getTextAlignFillValue() const

bool useDwarfRegNumForCFI() const

bool supportsExtendedDwarfLocDirective() const

const char * getData8bitsDirective() const

const char * getData64bitsDirective() const

AsmCharLiteralSyntax characterLiteralSyntax() const

LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const

void printExpr(raw_ostream &, const MCExpr &) const

virtual void printSwitchToSection(const MCSection &, uint32_t Subsection, const Triple &, raw_ostream &) const

StringRef getCommentString() const

const char * getAscizDirective() const

const char * getZeroDirective() const

const char * getWeakDirective() const

const char * getData16bitsDirective() const

const char * getSeparatorString() const

bool getCOMMDirectiveAlignmentIsInBytes() const

const char * getGlobalDirective() const

unsigned getCommentColumn() const

bool hasSingleParameterDotFile() const

const char * getAsciiDirective() const

AsmCharLiteralSyntax

Assembly character literal syntax types.

@ ACLS_SingleQuotePrefix

Unknown; character literals not used by LLVM for this target.

const char * getWeakRefDirective() const

bool hasNoDeadStrip() const

bool hasIdentDirective() const

unsigned getCodePointerSize() const

Get the code pointer size in bytes.

static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)

static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)

Context object for machine code objects.

const MCObjectFileInfo * getObjectFileInfo() const

LLVM_ABI MCSymbol * createTempSymbol()

Create a temporary symbol with a unique name.

const MCAsmInfo * getAsmInfo() const

dwarf::DwarfFormat getDwarfFormat() const

static LLVM_ABI void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)

Utility function to emit the encoding to a streamer.

static LLVM_ABI void make(MCStreamer *MCOS, MCSection *Section)

static LLVM_ABI void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)

LLVM_ABI Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)

const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const

static LLVM_ABI void Emit(MCStreamer *MCOS)

LLVM_ABI void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCContext *Ctx=nullptr) const

Dump the MCInst as prettily as possible using the additional MC structures, if given.

MCSection * getTextSection() const

StringRef getSegmentName() const

MCSymbol * getEndSymbol(MCContext &Ctx)

void setHasInstructions(bool Value)

StringRef getName() const

Streaming machine code generation interface.

virtual void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc={})

virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value)

Emit an assignment of Value to Symbol.

virtual void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc={})

virtual void emitWinCFIUnwindVersion(uint8_t Version, SMLoc Loc=SMLoc())

virtual bool emitCVFuncIdDirective(unsigned FunctionId)

Introduces a function id for use with .cv_loc.

virtual void emitCFIBKeyFrame()

virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())

virtual bool popSection()

Restore the current and previous section from the section stack.

virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())

virtual void emitCFISections(bool EH, bool Debug, bool SFrame)

virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name)

This implements the '.loc_label Name' directive.

virtual void emitCFINegateRAStateWithPC(SMLoc Loc={})

virtual void emitCFISameValue(int64_t Register, SMLoc Loc={})

virtual void emitCFIReturnColumn(int64_t Register)

virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)

virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)

Emit a unit length field.

virtual void emitCFIWindowSave(SMLoc Loc={})

virtual void emitWinCFIUnwindV2Start(SMLoc Loc=SMLoc())

virtual void emitWinCFIEndEpilogue(SMLoc Loc=SMLoc())

virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())

virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())

virtual void emitCFIUndefined(int64_t Register, SMLoc Loc={})

virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())

virtual void emitCFINegateRAState(SMLoc Loc={})

virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding)

virtual void emitWinCFIBeginEpilogue(SMLoc Loc=SMLoc())

virtual void emitCFIMTETaggedFrame()

virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc=SMLoc())

virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)

Emit the debug line start label.

virtual void emitCFIEscape(StringRef Values, SMLoc Loc={})

virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())

Emit a label for Symbol into the current section.

virtual void emitCFIRememberState(SMLoc Loc)

virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name)

virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName, StringRef Comment={})

This implements the DWARF2 '.loc fileno lineno ...' assembler directive.

virtual void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)

This implements the CodeView '.cv_linetable' assembler directive.

virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())

virtual void emitWinCFIEndChained(SMLoc Loc=SMLoc())

virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())

virtual void emitWinCFIEndProc(SMLoc Loc=SMLoc())

virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)

virtual void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc={})

virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)

virtual void emitCFIRegister(int64_t Register1, int64_t Register2, SMLoc Loc={})

virtual void emitWinCFIFuncletOrFuncEnd(SMLoc Loc=SMLoc())

This is used on platforms, such as Windows on ARM64, that require function or funclet sizes to be emi...

virtual void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc={})

virtual void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc)

virtual void switchSection(MCSection *Section, uint32_t Subsec=0)

Set the current section where code is being emitted to Section.

virtual void emitCFIRestoreState(SMLoc Loc)

virtual void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc={})

virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())

virtual void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc={})

virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())

virtual void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc={})

virtual bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol, SMLoc Loc)

Introduces an inline call site id for use with .cv_loc.

virtual void emitCFISignalFrame()

virtual void emitWinCFIStartChained(SMLoc Loc=SMLoc())

virtual void emitCFIRestore(int64_t Register, SMLoc Loc={})

virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)

This implements the CodeView '.cv_inline_linetable' assembler directive.

void emitFill(uint64_t NumBytes, uint8_t FillValue)

Emit NumBytes bytes worth of the value specified by FillValue.

virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset, int64_t AddressSpace, SMLoc Loc={})

const MCSymbol & getSymbol() const

static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())

LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const

print - Print the value to the stream OS.

MCSection & getSection() const

Get the section associated with a defined, non-absolute symbol.

void append(StringRef RHS)

Append from a StringRef.

void push_back(const T &Elt)

StringRef - Represent a constant reference to a string, i.e.

std::string str() const

str - Get the contents as an std::string.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

bool starts_with(StringRef Prefix) const

Check if this string starts with the given Prefix.

constexpr bool empty() const

empty - Check if the string is empty.

char back() const

back - Get the last character in the string.

StringRef slice(size_t Start, size_t End) const

Return a reference to the substring from [Start, End).

constexpr size_t size() const

size - Get the string size.

char front() const

front - Get the first character in the string.

size_t find_first_of(char C, size_t From=0) const

Find the first character in the string that is C, or npos if not found.

size_t find(char C, size_t From=0) const

Search for the first character C in the string.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

Represents a version number in the form major[.minor[.subminor[.build]]].

unsigned getMajor() const

Retrieve the major version number.

std::optional< unsigned > getSubminor() const

Retrieve the subminor version number, if provided.

bool empty() const

Determine whether this version information is empty (e.g., all version components are zero).

std::optional< unsigned > getMinor() const

Retrieve the minor version number, if provided.

formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...

formatted_raw_ostream & PadToColumn(unsigned NewCol)

PadToColumn - Align the output to some column number.

This class implements an extremely fast bulk output stream that can only output to a stream.

raw_ostream & write_hex(unsigned long long N)

Output N in hexadecimal, without any prefix or padding.

size_t GetNumBytesInBuffer() const

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

constexpr char Args[]

Key for Kernel::Metadata::mArgs.

@ C

The default llvm calling convention, compatible with C.

void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)

uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)

Get the byte size of the unit length field depending on the DWARF format.

support::ulittle32_t Word

bool isRelocation(MCFixupKind FixupKind)

LLVM_ABI int getDwarfVersion()

@ Emitted

Assigned address, still materializing.

NodeAddr< CodeNode * > Code

Context & getContext() const

uint32_t read32be(const void *P)

LLVM_ABI bool is_absolute(const Twine &path, Style style=Style::native)

Is path absolute?

LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")

Append to path.

This is an optimization pass for GlobalISel generic memory operations.

auto drop_begin(T &&RangeOrContainer, size_t N=1)

Return a range covering RangeOrContainer with the first N elements excluded.

FunctionAddr VTableAddr Value

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

static StringRef MCLOHDirectiveName()

constexpr bool isPowerOf2_64(uint64_t Value)

Return true if the argument is a power of two > 0 (64 bit edition.)

LLVM_ABI MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, std::unique_ptr< MCInstPrinter > InstPrint, std::unique_ptr< MCCodeEmitter > CE, std::unique_ptr< MCAsmBackend > TAB)

Create a machine code streamer which will print out assembly for the native target,...

Definition MCAsmStreamer.cpp:2664

unsigned Log2_64(uint64_t Value)

Return the floor log base 2 of the specified value, -1 if the value is zero.

@ MCDR_DataRegionEnd

.end_data_region

@ MCDR_DataRegion

.data_region

@ MCDR_DataRegionJT8

.data_region jt8

@ MCDR_DataRegionJT32

.data_region jt32

@ MCDR_DataRegionJT16

.data_region jt16

MCLOHDirective::LOHArgs MCLOHArgs

FunctionAddr VTableAddr uintptr_t uintptr_t Version

SmallVector< InlineSite, 8 > MCPseudoProbeInlineStack

@ MCVM_WatchOSVersionMin

.watchos_version_min

@ MCVM_OSXVersionMin

.macosx_version_min

@ MCVM_TvOSVersionMin

.tvos_version_min

@ MCVM_IOSVersionMin

.ios_version_min

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

FunctionAddr VTableAddr Count

LLVM_ABI raw_ostream & nulls()

This returns a reference to a raw_ostream which simply discards output.

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)

format_hex - Output N as a fixed width hexadecimal.

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

static int MCLOHIdToNbArgs(MCLOHType Kind)

FunctionAddr VTableAddr uintptr_t uintptr_t Data

MCLOHType

Linker Optimization Hint Type.

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

ArrayRef(const T &OneElt) -> ArrayRef< T >

void toHex(ArrayRef< uint8_t > Input, bool LowerCase, SmallVectorImpl< char > &Output)

Convert buffer Input to its hexadecimal representation. The returned string is double the size of Inp...

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

bool isPrint(char C)

Checks whether character C is printable.

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.

unsigned Log2(Align A)

Returns the log2 of the alignment.

std::pair< MCSection *, uint32_t > MCSectionSubPair

T bit_floor(T Value)

Returns the largest integral power of two no greater than Value if Value is nonzero.

@ MCSA_WeakDefAutoPrivate

.weak_def_can_be_hidden (MachO)

@ MCSA_Memtag

.memtag (ELF)

@ MCSA_Protected

.protected (ELF)

@ MCSA_Exported

.globl _foo, exported (XCOFF)

@ MCSA_PrivateExtern

.private_extern (MachO)

@ MCSA_Internal

.internal (ELF)

@ MCSA_WeakReference

.weak_reference (MachO)

@ MCSA_AltEntry

.alt_entry (MachO)

@ MCSA_ELF_TypeIndFunction

.type _foo, STT_GNU_IFUNC

@ MCSA_LazyReference

.lazy_reference (MachO)

@ MCSA_ELF_TypeNoType

.type _foo, STT_NOTYPE # aka @notype

@ MCSA_Reference

.reference (MachO)

@ MCSA_SymbolResolver

.symbol_resolver (MachO)

@ MCSA_ELF_TypeTLS

.type _foo, STT_TLS # aka @tls_object

@ MCSA_IndirectSymbol

.indirect_symbol (MachO)

@ MCSA_WeakDefinition

.weak_definition (MachO)

@ MCSA_ELF_TypeCommon

.type _foo, STT_COMMON # aka @common

@ MCSA_Global

.type _foo, @gnu_unique_object

@ MCSA_WeakAntiDep

.weak_anti_dep (COFF)

@ MCSA_Extern

.extern (XCOFF)

@ MCSA_ELF_TypeObject

.type _foo, STT_OBJECT # aka @object

@ MCSA_ELF_TypeGnuUniqueObject

@ MCSA_ELF_TypeFunction

.type _foo, STT_FUNC # aka @function

@ MCSA_Hidden

.hidden (ELF)

@ MCSA_LGlobal

.lglobl (XCOFF)

@ MCSA_Invalid

Not a valid directive.

@ MCSA_NoDeadStrip

.no_dead_strip (MachO)

static StringRef MCLOHIdToName(MCLOHType Kind)

constexpr uint64_t value() const

This is a hole in the type system and should not be abused.

const MCSymbol * Function