LLVM 20.0.0git
MCAsmStreamer.cpp
Go to the documentation of this file.
1//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/ADT/Twine.h"
14#include "llvm/MC/MCAsmInfo.h"
15#include "llvm/MC/MCAssembler.h"
17#include "llvm/MC/MCCodeView.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCInst.h"
26#include "llvm/MC/MCRegister.h"
29#include "llvm/MC/MCStreamer.h"
34#include "llvm/Support/Format.h"
36#include "llvm/Support/LEB128.h"
38#include "llvm/Support/Path.h"
39#include <algorithm>
40#include <optional>
41
42using namespace llvm;
43
44namespace {
45
46class MCAsmStreamer final : public MCStreamer {
47 std::unique_ptr<formatted_raw_ostream> OSOwner;
49 const MCAsmInfo *MAI;
50 std::unique_ptr<MCInstPrinter> InstPrinter;
51 std::unique_ptr<MCAssembler> Assembler;
52
53 SmallString<128> ExplicitCommentToEmit;
54 SmallString<128> CommentToEmit;
55 raw_svector_ostream CommentStream;
56 raw_null_ostream NullStream;
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::optional<MD5::MD5Result> Checksum,
67 std::optional<StringRef> 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 MCInstPrinter *printer, std::unique_ptr<MCCodeEmitter> emitter,
76 std::unique_ptr<MCAsmBackend> asmbackend)
77 : MCStreamer(Context), OSOwner(std::move(os)), OS(*OSOwner),
78 MAI(Context.getAsmInfo()), InstPrinter(printer),
79 Assembler(std::make_unique<MCAssembler>(
80 Context, std::move(asmbackend), std::move(emitter),
81 (asmbackend) ? asmbackend->createObjectWriter(NullStream)
82 : nullptr)),
83 CommentStream(CommentToEmit) {
84 assert(InstPrinter);
85 if (Assembler->getBackendPtr())
86 setAllowAutoPadding(Assembler->getBackend().allowAutoPadding());
87
88 Context.setUseNamesOnTempLabels(true);
89
90 auto *TO = Context.getTargetOptions();
91 if (!TO)
92 return;
93 IsVerboseAsm = TO->AsmVerbose;
94 if (IsVerboseAsm)
95 InstPrinter->setCommentStream(CommentStream);
96 ShowInst = TO->ShowMCInst;
97 switch (TO->MCUseDwarfDirectory) {
99 UseDwarfDirectory = false;
100 break;
102 UseDwarfDirectory = true;
103 break;
105 UseDwarfDirectory =
107 break;
108 }
109 }
110
111 MCAssembler &getAssembler() { return *Assembler; }
112 MCAssembler *getAssemblerPtr() override { return nullptr; }
113
114 inline void EmitEOL() {
115 // Dump Explicit Comments here.
117 // If we don't have any comments, just emit a \n.
118 if (!IsVerboseAsm) {
119 OS << '\n';
120 return;
121 }
122 EmitCommentsAndEOL();
123 }
124
125 void emitSyntaxDirective() override;
126
127 void EmitCommentsAndEOL();
128
129 /// Return true if this streamer supports verbose assembly at all.
130 bool isVerboseAsm() const override { return IsVerboseAsm; }
131
132 /// Do we support EmitRawText?
133 bool hasRawTextSupport() const override { return true; }
134
135 /// Add a comment that can be emitted to the generated .s file to make the
136 /// output of the compiler more readable. This only affects the MCAsmStreamer
137 /// and only when verbose assembly output is enabled.
138 void AddComment(const Twine &T, bool EOL = true) override;
139
140 /// Add a comment showing the encoding of an instruction.
141 void AddEncodingComment(const MCInst &Inst, const MCSubtargetInfo &);
142
143 /// Return a raw_ostream that comments can be written to.
144 /// Unlike AddComment, you are required to terminate comments with \n if you
145 /// use this method.
146 raw_ostream &getCommentOS() override {
147 if (!IsVerboseAsm)
148 return nulls(); // Discard comments unless in verbose asm mode.
149 return CommentStream;
150 }
151
152 void emitRawComment(const Twine &T, bool TabPrefix = true) override;
153
154 void addExplicitComment(const Twine &T) override;
155 void emitExplicitComments() override;
156
157 /// Emit a blank line to a .s file to pretty it up.
158 void addBlankLine() override { EmitEOL(); }
159
160 /// @name MCStreamer Interface
161 /// @{
162
163 void changeSection(MCSection *Section, uint32_t Subsection) override;
164
165 void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name,
166 bool KeepOriginalSym) override;
167
168 void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
169
170 void emitGNUAttribute(unsigned Tag, unsigned Value) override;
171
172 StringRef getMnemonic(const MCInst &MI) const override {
173 auto [Ptr, Bits] = InstPrinter->getMnemonic(MI);
174 assert((Bits != 0 || Ptr == nullptr) &&
175 "Invalid char pointer for instruction with no mnemonic");
176 return Ptr;
177 }
178
179 void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
180
181 void emitAssemblerFlag(MCAssemblerFlag Flag) override;
183 void emitDataRegion(MCDataRegionType Kind) override;
184 void emitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
185 unsigned Update, VersionTuple SDKVersion) override;
186 void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
187 unsigned Update, VersionTuple SDKVersion) override;
188 void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major,
189 unsigned Minor, unsigned Update,
190 VersionTuple SDKVersion) override;
191 void emitThumbFunc(MCSymbol *Func) override;
192
193 void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
195 const MCExpr *Value) override;
196 void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
197 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
198
199 void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
200 void beginCOFFSymbolDef(const MCSymbol *Symbol) override;
201 void emitCOFFSymbolStorageClass(int StorageClass) override;
202 void emitCOFFSymbolType(int Type) override;
203 void endCOFFSymbolDef() override;
204 void emitCOFFSafeSEH(MCSymbol const *Symbol) override;
205 void emitCOFFSymbolIndex(MCSymbol const *Symbol) override;
206 void emitCOFFSectionIndex(MCSymbol const *Symbol) override;
207 void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
208 void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
210 MCSymbol *CsectSym, Align Alignment) override;
212 MCSymbolAttr Linkage,
213 MCSymbolAttr Visibility) override;
215 StringRef Rename) override;
216
217 void emitXCOFFRefDirective(const MCSymbol *Symbol) override;
218
219 void emitXCOFFExceptDirective(const MCSymbol *Symbol,
220 const MCSymbol *Trap,
221 unsigned Lang, unsigned Reason,
222 unsigned FunctionSize, bool hasDebug) override;
224
225 void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
227 Align ByteAlignment) override;
228
229 /// Emit a local common (.lcomm) symbol.
230 ///
231 /// @param Symbol - The common symbol to emit.
232 /// @param Size - The size of the common symbol.
233 /// @param ByteAlignment - The alignment of the common symbol in bytes.
235 Align ByteAlignment) override;
236
237 void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
238 uint64_t Size = 0, Align ByteAlignment = Align(1),
239 SMLoc Loc = SMLoc()) override;
240
241 void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
242 Align ByteAlignment = Align(1)) override;
243
244 void emitBinaryData(StringRef Data) override;
245
246 void emitBytes(StringRef Data) override;
247
248 void emitValueImpl(const MCExpr *Value, unsigned Size,
249 SMLoc Loc = SMLoc()) override;
250 void emitIntValue(uint64_t Value, unsigned Size) override;
251 void emitIntValueInHex(uint64_t Value, unsigned Size) override;
252 void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size) override;
253
254 void emitULEB128Value(const MCExpr *Value) override;
255
256 void emitSLEB128Value(const MCExpr *Value) override;
257
258 void emitDTPRel32Value(const MCExpr *Value) override;
259 void emitDTPRel64Value(const MCExpr *Value) override;
260 void emitTPRel32Value(const MCExpr *Value) override;
261 void emitTPRel64Value(const MCExpr *Value) override;
262
263 void emitGPRel64Value(const MCExpr *Value) override;
264
265 void emitGPRel32Value(const MCExpr *Value) override;
266
267 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
268 SMLoc Loc = SMLoc()) override;
269
270 void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
271 SMLoc Loc = SMLoc()) override;
272
273 void emitAlignmentDirective(uint64_t ByteAlignment,
274 std::optional<int64_t> Value, unsigned ValueSize,
275 unsigned MaxBytesToEmit);
276
277 void emitValueToAlignment(Align Alignment, int64_t Value = 0,
278 unsigned ValueSize = 1,
279 unsigned MaxBytesToEmit = 0) override;
280
281 void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI,
282 unsigned MaxBytesToEmit = 0) override;
283
284 void emitValueToOffset(const MCExpr *Offset,
285 unsigned char Value,
286 SMLoc Loc) override;
287
288 void emitFileDirective(StringRef Filename) override;
289 void emitFileDirective(StringRef Filename, StringRef CompilerVersion,
290 StringRef TimeStamp, StringRef Description) override;
292 unsigned FileNo, StringRef Directory, StringRef Filename,
293 std::optional<MD5::MD5Result> Checksum = std::nullopt,
294 std::optional<StringRef> Source = std::nullopt,
295 unsigned CUID = 0) override;
296 void emitDwarfFile0Directive(StringRef Directory, StringRef Filename,
297 std::optional<MD5::MD5Result> Checksum,
298 std::optional<StringRef> Source,
299 unsigned CUID = 0) override;
300 void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
301 unsigned Flags, unsigned Isa,
302 unsigned Discriminator,
303 StringRef FileName) override;
304 virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override;
305
306 MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
307
308 bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
309 ArrayRef<uint8_t> Checksum,
310 unsigned ChecksumKind) override;
311 bool emitCVFuncIdDirective(unsigned FuncId) override;
312 bool emitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
313 unsigned IAFile, unsigned IALine,
314 unsigned IACol, SMLoc Loc) override;
315 void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
316 unsigned Column, bool PrologueEnd, bool IsStmt,
317 StringRef FileName, SMLoc Loc) override;
318 void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart,
319 const MCSymbol *FnEnd) override;
320 void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
321 unsigned SourceFileId,
322 unsigned SourceLineNum,
323 const MCSymbol *FnStartSym,
324 const MCSymbol *FnEndSym) override;
325
326 void PrintCVDefRangePrefix(
327 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges);
328
330 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
332
334 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
336
338 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
339 codeview::DefRangeRegisterHeader DRHdr) override;
340
342 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
344
345 void emitCVStringTableDirective() override;
346 void emitCVFileChecksumsDirective() override;
347 void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
348 void emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
349
350 void emitIdent(StringRef IdentString) override;
351 void emitCFIBKeyFrame() override;
352 void emitCFIMTETaggedFrame() override;
353 void emitCFISections(bool EH, bool Debug) override;
354 void emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) override;
355 void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) override;
356 void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) override;
357 void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
358 int64_t AddressSpace, SMLoc Loc) override;
359 void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
360 void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding) override;
361 void emitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
362 void emitCFIRememberState(SMLoc Loc) override;
363 void emitCFIRestoreState(SMLoc Loc) override;
364 void emitCFIRestore(int64_t Register, SMLoc Loc) override;
365 void emitCFISameValue(int64_t Register, SMLoc Loc) override;
366 void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
367 void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) override;
368 void emitCFIEscape(StringRef Values, SMLoc Loc) override;
369 void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) override;
370 void emitCFISignalFrame() override;
371 void emitCFIUndefined(int64_t Register, SMLoc Loc) override;
372 void emitCFIRegister(int64_t Register1, int64_t Register2,
373 SMLoc Loc) override;
374 void emitCFIWindowSave(SMLoc Loc) override;
375 void emitCFINegateRAState(SMLoc Loc) override;
376 void emitCFINegateRAStateWithPC(SMLoc Loc) override;
377 void emitCFIReturnColumn(int64_t Register) override;
378 void emitCFILabelDirective(SMLoc Loc, StringRef Name) override;
379 void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc) override;
380
381 void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
382 void emitWinCFIEndProc(SMLoc Loc) override;
383 void emitWinCFIFuncletOrFuncEnd(SMLoc Loc) override;
384 void emitWinCFIStartChained(SMLoc Loc) override;
385 void emitWinCFIEndChained(SMLoc Loc) override;
386 void emitWinCFIPushReg(MCRegister Register, SMLoc Loc) override;
388 SMLoc Loc) override;
389 void emitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
391 SMLoc Loc) override;
393 SMLoc Loc) override;
394 void emitWinCFIPushFrame(bool Code, SMLoc Loc) override;
395 void emitWinCFIEndProlog(SMLoc Loc) override;
396
397 void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
398 SMLoc Loc) override;
399 void emitWinEHHandlerData(SMLoc Loc) override;
400
402 const MCSymbolRefExpr *To, uint64_t Count) override;
403
404 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
405
407 uint64_t Attr, uint64_t Discriminator,
408 const MCPseudoProbeInlineStack &InlineStack,
409 MCSymbol *FnSym) override;
410
411 void emitBundleAlignMode(Align Alignment) override;
412 void emitBundleLock(bool AlignToEnd) override;
413 void emitBundleUnlock() override;
414
415 std::optional<std::pair<bool, std::string>>
417 SMLoc Loc, const MCSubtargetInfo &STI) override;
418
419 void emitAddrsig() override;
420 void emitAddrsigSym(const MCSymbol *Sym) override;
421
422 /// If this file is backed by an assembly streamer, this dumps the specified
423 /// string in the output .s file. This capability is indicated by the
424 /// hasRawTextSupport() predicate.
425 void emitRawTextImpl(StringRef String) override;
426
427 void finishImpl() override;
428
429 void emitDwarfUnitLength(uint64_t Length, const Twine &Comment) override;
430
431 MCSymbol *emitDwarfUnitLength(const Twine &Prefix,
432 const Twine &Comment) override;
433
434 void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
435
436 void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
437 MCSymbol *EndLabel = nullptr) override;
438
439 void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
440 const MCSymbol *Label,
441 unsigned PointerSize) override;
442
443 void doFinalizationAtSectionEnd(MCSection *Section) override;
444};
445
446} // end anonymous namespace.
447
448void MCAsmStreamer::AddComment(const Twine &T, bool EOL) {
449 if (!IsVerboseAsm) return;
450
451 T.toVector(CommentToEmit);
452
453 if (EOL)
454 CommentToEmit.push_back('\n'); // Place comment in a new line.
455}
456
457void MCAsmStreamer::EmitCommentsAndEOL() {
458 if (CommentToEmit.empty() && CommentStream.GetNumBytesInBuffer() == 0) {
459 OS << '\n';
460 return;
461 }
462
463 StringRef Comments = CommentToEmit;
464
465 assert(Comments.back() == '\n' &&
466 "Comment array not newline terminated");
467 do {
468 // Emit a line of comments.
469 OS.PadToColumn(MAI->getCommentColumn());
470 size_t Position = Comments.find('\n');
471 OS << MAI->getCommentString() << ' ' << Comments.substr(0, Position) <<'\n';
472
473 Comments = Comments.substr(Position+1);
474 } while (!Comments.empty());
475
476 CommentToEmit.clear();
477}
478
479static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) {
480 assert(Bytes > 0 && Bytes <= 8 && "Invalid size!");
481 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8));
482}
483
484void MCAsmStreamer::emitRawComment(const Twine &T, bool TabPrefix) {
485 if (TabPrefix)
486 OS << '\t';
487 OS << MAI->getCommentString() << T;
488 EmitEOL();
489}
490
491void MCAsmStreamer::addExplicitComment(const Twine &T) {
492 StringRef c = T.getSingleStringRef();
493 if (c == MAI->getSeparatorString())
494 return;
495 if (c.starts_with(StringRef("//"))) {
496 ExplicitCommentToEmit.append("\t");
497 ExplicitCommentToEmit.append(MAI->getCommentString());
498 // drop //
499 ExplicitCommentToEmit.append(c.substr(2).str());
500 } else if (c.starts_with(StringRef("/*"))) {
501 size_t p = 2, len = c.size() - 2;
502 // emit each line in comment as separate newline.
503 do {
504 size_t newp = std::min(len, c.find_first_of("\r\n", p));
505 ExplicitCommentToEmit.append("\t");
506 ExplicitCommentToEmit.append(MAI->getCommentString());
507 ExplicitCommentToEmit.append(c.slice(p, newp).str());
508 // If we have another line in this comment add line
509 if (newp < len)
510 ExplicitCommentToEmit.append("\n");
511 p = newp + 1;
512 } while (p < len);
513 } else if (c.starts_with(StringRef(MAI->getCommentString()))) {
514 ExplicitCommentToEmit.append("\t");
515 ExplicitCommentToEmit.append(c.str());
516 } else if (c.front() == '#') {
517
518 ExplicitCommentToEmit.append("\t");
519 ExplicitCommentToEmit.append(MAI->getCommentString());
520 ExplicitCommentToEmit.append(c.substr(1).str());
521 } else
522 assert(false && "Unexpected Assembly Comment");
523 // full line comments immediately output
524 if (c.back() == '\n')
525 emitExplicitComments();
526}
527
528void MCAsmStreamer::emitExplicitComments() {
529 StringRef Comments = ExplicitCommentToEmit;
530 if (!Comments.empty())
531 OS << Comments;
532 ExplicitCommentToEmit.clear();
533}
534
535void MCAsmStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
536 if (MCTargetStreamer *TS = getTargetStreamer()) {
537 TS->changeSection(getCurrentSection().first, Section, Subsection, OS);
538 } else {
539 Section->printSwitchToSection(*MAI, getContext().getTargetTriple(), OS,
540 Subsection);
541 }
542 MCStreamer::changeSection(Section, Subsection);
543}
544
545void MCAsmStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
547 bool KeepOriginalSym) {
548 OS << ".symver ";
549 OriginalSym->print(OS, MAI);
550 OS << ", " << Name;
551 if (!KeepOriginalSym && !Name.contains("@@@"))
552 OS << ", remove";
553 EmitEOL();
554}
555
556void MCAsmStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
557 MCStreamer::emitLabel(Symbol, Loc);
558
559 Symbol->print(OS, MAI);
560 OS << MAI->getLabelSuffix();
561
562 EmitEOL();
563}
564
565void MCAsmStreamer::emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
566 StringRef str = MCLOHIdToName(Kind);
567
568#ifndef NDEBUG
569 int NbArgs = MCLOHIdToNbArgs(Kind);
570 assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
571 assert(str != "" && "Invalid LOH name");
572#endif
573
574 OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
575 bool IsFirst = true;
576 for (const MCSymbol *Arg : Args) {
577 if (!IsFirst)
578 OS << ", ";
579 IsFirst = false;
580 Arg->print(OS, MAI);
581 }
582 EmitEOL();
583}
584
585void MCAsmStreamer::emitGNUAttribute(unsigned Tag, unsigned Value) {
586 OS << "\t.gnu_attribute " << Tag << ", " << Value << "\n";
587}
588
589void MCAsmStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {
590 switch (Flag) {
591 case MCAF_SyntaxUnified: OS << "\t.syntax unified"; break;
592 case MCAF_SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break;
593 case MCAF_Code16: OS << '\t'<< MAI->getCode16Directive();break;
594 case MCAF_Code32: OS << '\t'<< MAI->getCode32Directive();break;
595 case MCAF_Code64: OS << '\t'<< MAI->getCode64Directive();break;
596 }
597 EmitEOL();
598}
599
600void MCAsmStreamer::emitLinkerOptions(ArrayRef<std::string> Options) {
601 assert(!Options.empty() && "At least one option is required!");
602 OS << "\t.linker_option \"" << Options[0] << '"';
603 for (const std::string &Opt : llvm::drop_begin(Options))
604 OS << ", " << '"' << Opt << '"';
605 EmitEOL();
606}
607
608void MCAsmStreamer::emitDataRegion(MCDataRegionType Kind) {
610 return;
611 switch (Kind) {
612 case MCDR_DataRegion: OS << "\t.data_region"; break;
613 case MCDR_DataRegionJT8: OS << "\t.data_region jt8"; break;
614 case MCDR_DataRegionJT16: OS << "\t.data_region jt16"; break;
615 case MCDR_DataRegionJT32: OS << "\t.data_region jt32"; break;
616 case MCDR_DataRegionEnd: OS << "\t.end_data_region"; break;
617 }
618 EmitEOL();
619}
620
622 switch (Type) {
623 case MCVM_WatchOSVersionMin: return ".watchos_version_min";
624 case MCVM_TvOSVersionMin: return ".tvos_version_min";
625 case MCVM_IOSVersionMin: return ".ios_version_min";
626 case MCVM_OSXVersionMin: return ".macosx_version_min";
627 }
628 llvm_unreachable("Invalid MC version min type");
629}
630
632 const VersionTuple &SDKVersion) {
633 if (SDKVersion.empty())
634 return;
635 OS << '\t' << "sdk_version " << SDKVersion.getMajor();
636 if (auto Minor = SDKVersion.getMinor()) {
637 OS << ", " << *Minor;
638 if (auto Subminor = SDKVersion.getSubminor()) {
639 OS << ", " << *Subminor;
640 }
641 }
642}
643
644void MCAsmStreamer::emitVersionMin(MCVersionMinType Type, unsigned Major,
645 unsigned Minor, unsigned Update,
646 VersionTuple SDKVersion) {
647 OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
648 if (Update)
649 OS << ", " << Update;
650 EmitSDKVersionSuffix(OS, SDKVersion);
651 EmitEOL();
652}
653
655 switch (Type) {
656#define PLATFORM(platform, id, name, build_name, target, tapi_target, \
657 marketing) \
658 case MachO::PLATFORM_##platform: \
659 return #build_name;
660#include "llvm/BinaryFormat/MachO.def"
661 }
662 llvm_unreachable("Invalid Mach-O platform type");
663}
664
665void MCAsmStreamer::emitBuildVersion(unsigned Platform, unsigned Major,
666 unsigned Minor, unsigned Update,
667 VersionTuple SDKVersion) {
668 const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
669 OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
670 if (Update)
671 OS << ", " << Update;
672 EmitSDKVersionSuffix(OS, SDKVersion);
673 EmitEOL();
674}
675
676void MCAsmStreamer::emitDarwinTargetVariantBuildVersion(
677 unsigned Platform, unsigned Major, unsigned Minor, unsigned Update,
678 VersionTuple SDKVersion) {
679 emitBuildVersion(Platform, Major, Minor, Update, SDKVersion);
680}
681
682void MCAsmStreamer::emitThumbFunc(MCSymbol *Func) {
683 // This needs to emit to a temporary string to get properly quoted
684 // MCSymbols when they have spaces in them.
685 OS << "\t.thumb_func";
686 // Only Mach-O hasSubsectionsViaSymbols()
687 if (MAI->hasSubsectionsViaSymbols()) {
688 OS << '\t';
689 Func->print(OS, MAI);
690 }
691 EmitEOL();
692}
693
694void MCAsmStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
695 // Do not emit a .set on inlined target assignments.
696 bool EmitSet = true;
697 if (auto *E = dyn_cast<MCTargetExpr>(Value))
698 if (E->inlineAssignedExpr())
699 EmitSet = false;
700 if (EmitSet) {
701 OS << ".set ";
702 Symbol->print(OS, MAI);
703 OS << ", ";
704 Value->print(OS, MAI);
705
706 EmitEOL();
707 }
708
710}
711
712void MCAsmStreamer::emitConditionalAssignment(MCSymbol *Symbol,
713 const MCExpr *Value) {
714 OS << ".lto_set_conditional ";
715 Symbol->print(OS, MAI);
716 OS << ", ";
717 Value->print(OS, MAI);
718 EmitEOL();
719}
720
721void MCAsmStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {
722 OS << ".weakref ";
723 Alias->print(OS, MAI);
724 OS << ", ";
725 Symbol->print(OS, MAI);
726 EmitEOL();
727}
728
729bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol,
731 switch (Attribute) {
732 case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute");
733 case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function
734 case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC
735 case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object
736 case MCSA_ELF_TypeTLS: /// .type _foo, STT_TLS # aka @tls_object
737 case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common
738 case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype
739 case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object
740 if (!MAI->hasDotTypeDotSizeDirective())
741 return false; // Symbol attribute not supported
742 OS << "\t.type\t";
743 Symbol->print(OS, MAI);
744 OS << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%');
745 switch (Attribute) {
746 default: return false;
747 case MCSA_ELF_TypeFunction: OS << "function"; break;
748 case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break;
749 case MCSA_ELF_TypeObject: OS << "object"; break;
750 case MCSA_ELF_TypeTLS: OS << "tls_object"; break;
751 case MCSA_ELF_TypeCommon: OS << "common"; break;
752 case MCSA_ELF_TypeNoType: OS << "notype"; break;
753 case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break;
754 }
755 EmitEOL();
756 return true;
757 case MCSA_Global: // .globl/.global
758 OS << MAI->getGlobalDirective();
759 break;
760 case MCSA_LGlobal: OS << "\t.lglobl\t"; break;
761 case MCSA_Hidden: OS << "\t.hidden\t"; break;
762 case MCSA_IndirectSymbol: OS << "\t.indirect_symbol\t"; break;
763 case MCSA_Internal: OS << "\t.internal\t"; break;
764 case MCSA_LazyReference: OS << "\t.lazy_reference\t"; break;
765 case MCSA_Local: OS << "\t.local\t"; break;
766 case MCSA_NoDeadStrip:
767 if (!MAI->hasNoDeadStrip())
768 return false;
769 OS << "\t.no_dead_strip\t";
770 break;
771 case MCSA_SymbolResolver: OS << "\t.symbol_resolver\t"; break;
772 case MCSA_AltEntry: OS << "\t.alt_entry\t"; break;
774 OS << "\t.private_extern\t";
775 break;
776 case MCSA_Protected: OS << "\t.protected\t"; break;
777 case MCSA_Reference: OS << "\t.reference\t"; break;
778 case MCSA_Extern:
779 OS << "\t.extern\t";
780 break;
781 case MCSA_Weak: OS << MAI->getWeakDirective(); break;
783 OS << "\t.weak_definition\t";
784 break;
785 // .weak_reference
786 case MCSA_WeakReference: OS << MAI->getWeakRefDirective(); break;
787 case MCSA_WeakDefAutoPrivate: OS << "\t.weak_def_can_be_hidden\t"; break;
788 case MCSA_Cold:
789 // Assemblers currently do not support a .cold directive.
790 case MCSA_Exported:
791 // Non-AIX assemblers currently do not support exported visibility.
792 return false;
793 case MCSA_Memtag:
794 OS << "\t.memtag\t";
795 break;
796 case MCSA_WeakAntiDep:
797 OS << "\t.weak_anti_dep\t";
798 break;
799 }
800
801 Symbol->print(OS, MAI);
802 EmitEOL();
803
804 return true;
805}
806
807void MCAsmStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
808 OS << ".desc" << ' ';
809 Symbol->print(OS, MAI);
810 OS << ',' << DescValue;
811 EmitEOL();
812}
813
814void MCAsmStreamer::emitSyntaxDirective() {
815 if (MAI->getAssemblerDialect() == 1) {
816 OS << "\t.intel_syntax noprefix";
817 EmitEOL();
818 }
819 // FIXME: Currently emit unprefix'ed registers.
820 // The intel_syntax directive has one optional argument
821 // with may have a value of prefix or noprefix.
822}
823
824void MCAsmStreamer::beginCOFFSymbolDef(const MCSymbol *Symbol) {
825 OS << "\t.def\t";
826 Symbol->print(OS, MAI);
827 OS << ';';
828 EmitEOL();
829}
830
831void MCAsmStreamer::emitCOFFSymbolStorageClass(int StorageClass) {
832 OS << "\t.scl\t" << StorageClass << ';';
833 EmitEOL();
834}
835
836void MCAsmStreamer::emitCOFFSymbolType(int Type) {
837 OS << "\t.type\t" << Type << ';';
838 EmitEOL();
839}
840
841void MCAsmStreamer::endCOFFSymbolDef() {
842 OS << "\t.endef";
843 EmitEOL();
844}
845
846void MCAsmStreamer::emitCOFFSafeSEH(MCSymbol const *Symbol) {
847 OS << "\t.safeseh\t";
848 Symbol->print(OS, MAI);
849 EmitEOL();
850}
851
852void MCAsmStreamer::emitCOFFSymbolIndex(MCSymbol const *Symbol) {
853 OS << "\t.symidx\t";
854 Symbol->print(OS, MAI);
855 EmitEOL();
856}
857
858void MCAsmStreamer::emitCOFFSectionIndex(MCSymbol const *Symbol) {
859 OS << "\t.secidx\t";
860 Symbol->print(OS, MAI);
861 EmitEOL();
862}
863
864void MCAsmStreamer::emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {
865 OS << "\t.secrel32\t";
866 Symbol->print(OS, MAI);
867 if (Offset != 0)
868 OS << '+' << Offset;
869 EmitEOL();
870}
871
872void MCAsmStreamer::emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {
873 OS << "\t.rva\t";
874 Symbol->print(OS, MAI);
875 if (Offset > 0)
876 OS << '+' << Offset;
877 else if (Offset < 0)
878 OS << '-' << -Offset;
879 EmitEOL();
880}
881
882// We need an XCOFF-specific version of this directive as the AIX syntax
883// requires a QualName argument identifying the csect name and storage mapping
884// class to appear before the alignment if we are specifying it.
885void MCAsmStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym,
887 MCSymbol *CsectSym,
888 Align Alignment) {
890 "We only support writing log base-2 alignment format with XCOFF.");
891
892 OS << "\t.lcomm\t";
893 LabelSym->print(OS, MAI);
894 OS << ',' << Size << ',';
895 CsectSym->print(OS, MAI);
896 OS << ',' << Log2(Alignment);
897
898 EmitEOL();
899
900 // Print symbol's rename (original name contains invalid character(s)) if
901 // there is one.
902 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(CsectSym);
903 if (XSym->hasRename())
904 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
905}
906
907void MCAsmStreamer::emitXCOFFSymbolLinkageWithVisibility(
908 MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility) {
909
910 switch (Linkage) {
911 case MCSA_Global:
912 OS << MAI->getGlobalDirective();
913 break;
914 case MCSA_Weak:
915 OS << MAI->getWeakDirective();
916 break;
917 case MCSA_Extern:
918 OS << "\t.extern\t";
919 break;
920 case MCSA_LGlobal:
921 OS << "\t.lglobl\t";
922 break;
923 default:
924 report_fatal_error("unhandled linkage type");
925 }
926
927 Symbol->print(OS, MAI);
928
929 switch (Visibility) {
930 case MCSA_Invalid:
931 // Nothing to do.
932 break;
933 case MCSA_Hidden:
934 OS << ",hidden";
935 break;
936 case MCSA_Protected:
937 OS << ",protected";
938 break;
939 case MCSA_Exported:
940 OS << ",exported";
941 break;
942 default:
943 report_fatal_error("unexpected value for Visibility type");
944 }
945 EmitEOL();
946
947 // Print symbol's rename (original name contains invalid character(s)) if
948 // there is one.
949 if (cast<MCSymbolXCOFF>(Symbol)->hasRename())
950 emitXCOFFRenameDirective(Symbol,
951 cast<MCSymbolXCOFF>(Symbol)->getSymbolTableName());
952}
953
954void MCAsmStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
955 StringRef Rename) {
956 OS << "\t.rename\t";
957 Name->print(OS, MAI);
958 const char DQ = '"';
959 OS << ',' << DQ;
960 for (char C : Rename) {
961 // To escape a double quote character, the character should be doubled.
962 if (C == DQ)
963 OS << DQ;
964 OS << C;
965 }
966 OS << DQ;
967 EmitEOL();
968}
969
970void MCAsmStreamer::emitXCOFFRefDirective(const MCSymbol *Symbol) {
971 OS << "\t.ref ";
972 Symbol->print(OS, MAI);
973 EmitEOL();
974}
975
976void MCAsmStreamer::emitXCOFFExceptDirective(const MCSymbol *Symbol,
977 const MCSymbol *Trap,
978 unsigned Lang,
979 unsigned Reason,
980 unsigned FunctionSize,
981 bool hasDebug) {
982 OS << "\t.except\t";
983 Symbol->print(OS, MAI);
984 OS << ", " << Lang << ", " << Reason;
985 EmitEOL();
986}
987
988void MCAsmStreamer::emitXCOFFCInfoSym(StringRef Name, StringRef Metadata) {
989 const char InfoDirective[] = "\t.info ";
990 const char *Separator = ", ";
991 constexpr int WordSize = sizeof(uint32_t);
992
993 // Start by emitting the .info pseudo-op and C_INFO symbol name.
994 OS << InfoDirective;
995 PrintQuotedString(Name, OS);
996 OS << Separator;
997
998 size_t MetadataSize = Metadata.size();
999
1000 // Emit the 4-byte length of the metadata.
1001 OS << format_hex(MetadataSize, 10) << Separator;
1002
1003 // Nothing left to do if there's no metadata.
1004 if (MetadataSize == 0) {
1005 EmitEOL();
1006 return;
1007 }
1008
1009 // Metadata needs to be padded out to an even word size when generating
1010 // assembly because the .info pseudo-op can only generate words of data. We
1011 // apply the same restriction to the object case for consistency, however the
1012 // linker doesn't require padding, so it will only save bytes specified by the
1013 // length and discard any padding.
1014 uint32_t PaddedSize = alignTo(MetadataSize, WordSize);
1015 uint32_t PaddingSize = PaddedSize - MetadataSize;
1016
1017 // Write out the payload a word at a time.
1018 //
1019 // The assembler has a limit on the number of operands in an expression,
1020 // so we need multiple .info pseudo-ops. We choose a small number of words
1021 // per pseudo-op to keep the assembly readable.
1022 constexpr int WordsPerDirective = 5;
1023 // Force emitting a new directive to keep the first directive purely about the
1024 // name and size of the note.
1025 int WordsBeforeNextDirective = 0;
1026 auto PrintWord = [&](const uint8_t *WordPtr) {
1027 if (WordsBeforeNextDirective-- == 0) {
1028 EmitEOL();
1029 OS << InfoDirective;
1030 WordsBeforeNextDirective = WordsPerDirective;
1031 }
1032 OS << Separator;
1034 OS << format_hex(Word, 10);
1035 };
1036
1037 size_t Index = 0;
1038 for (; Index + WordSize <= MetadataSize; Index += WordSize)
1039 PrintWord(reinterpret_cast<const uint8_t *>(Metadata.data()) + Index);
1040
1041 // If there is padding, then we have at least one byte of payload left
1042 // to emit.
1043 if (PaddingSize) {
1044 assert(PaddedSize - Index == WordSize);
1045 std::array<uint8_t, WordSize> LastWord = {0};
1046 ::memcpy(LastWord.data(), Metadata.data() + Index, MetadataSize - Index);
1047 PrintWord(LastWord.data());
1048 }
1049 EmitEOL();
1050}
1051
1052void MCAsmStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {
1054 OS << "\t.size\t";
1055 Symbol->print(OS, MAI);
1056 OS << ", ";
1057 Value->print(OS, MAI);
1058 EmitEOL();
1059}
1060
1061void MCAsmStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1062 Align ByteAlignment) {
1063 OS << "\t.comm\t";
1064 Symbol->print(OS, MAI);
1065 OS << ',' << Size;
1066
1068 OS << ',' << ByteAlignment.value();
1069 else
1070 OS << ',' << Log2(ByteAlignment);
1071 EmitEOL();
1072
1073 // Print symbol's rename (original name contains invalid character(s)) if
1074 // there is one.
1075 MCSymbolXCOFF *XSym = dyn_cast<MCSymbolXCOFF>(Symbol);
1076 if (XSym && XSym->hasRename())
1077 emitXCOFFRenameDirective(XSym, XSym->getSymbolTableName());
1078}
1079
1080void MCAsmStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1081 Align ByteAlign) {
1082 OS << "\t.lcomm\t";
1083 Symbol->print(OS, MAI);
1084 OS << ',' << Size;
1085
1086 if (ByteAlign > 1) {
1087 switch (MAI->getLCOMMDirectiveAlignmentType()) {
1088 case LCOMM::NoAlignment:
1089 llvm_unreachable("alignment not supported on .lcomm!");
1091 OS << ',' << ByteAlign.value();
1092 break;
1094 OS << ',' << Log2(ByteAlign);
1095 break;
1096 }
1097 }
1098 EmitEOL();
1099}
1100
1101void MCAsmStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
1102 uint64_t Size, Align ByteAlignment,
1103 SMLoc Loc) {
1104 if (Symbol)
1105 Symbol->setFragment(&Section->getDummyFragment());
1106
1107 // Note: a .zerofill directive does not switch sections.
1108 OS << ".zerofill ";
1109
1110 assert(Section->getVariant() == MCSection::SV_MachO &&
1111 ".zerofill is a Mach-O specific directive");
1112 // This is a mach-o specific directive.
1113
1114 const MCSectionMachO *MOSection = ((const MCSectionMachO*)Section);
1115 OS << MOSection->getSegmentName() << "," << MOSection->getName();
1116
1117 if (Symbol) {
1118 OS << ',';
1119 Symbol->print(OS, MAI);
1120 OS << ',' << Size;
1121 OS << ',' << Log2(ByteAlignment);
1122 }
1123 EmitEOL();
1124}
1125
1126// .tbss sym, size, align
1127// This depends that the symbol has already been mangled from the original,
1128// e.g. _a.
1129void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1130 uint64_t Size, Align ByteAlignment) {
1131 Symbol->setFragment(&Section->getDummyFragment());
1132
1133 // Instead of using the Section we'll just use the shortcut.
1134
1135 assert(Section->getVariant() == MCSection::SV_MachO &&
1136 ".zerofill is a Mach-O specific directive");
1137 // This is a mach-o specific directive and section.
1138
1139 OS << ".tbss ";
1140 Symbol->print(OS, MAI);
1141 OS << ", " << Size;
1142
1143 // Output align if we have it. We default to 1 so don't bother printing
1144 // that.
1145 if (ByteAlignment > 1)
1146 OS << ", " << Log2(ByteAlignment);
1147
1148 EmitEOL();
1149}
1150
1151static inline bool isPrintableString(StringRef Data) {
1152 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1153 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1154 if (!isPrint(C))
1155 return false;
1156 }
1157 return isPrint(Data.back()) || Data.back() == 0;
1158}
1159
1160static inline char toOctal(int X) { return (X&7)+'0'; }
1161
1164 assert(!Data.empty() && "Cannot generate an empty list.");
1165 const auto printCharacterInOctal = [&OS](unsigned char C) {
1166 OS << '0';
1167 OS << toOctal(C >> 6);
1168 OS << toOctal(C >> 3);
1169 OS << toOctal(C >> 0);
1170 };
1171 const auto printOneCharacterFor = [printCharacterInOctal](
1172 auto printOnePrintingCharacter) {
1173 return [printCharacterInOctal, printOnePrintingCharacter](unsigned char C) {
1174 if (isPrint(C)) {
1175 printOnePrintingCharacter(static_cast<char>(C));
1176 return;
1177 }
1178 printCharacterInOctal(C);
1179 };
1180 };
1181 const auto printCharacterList = [Data, &OS](const auto &printOneCharacter) {
1182 const auto BeginPtr = Data.begin(), EndPtr = Data.end();
1183 for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) {
1184 printOneCharacter(C);
1185 OS << ',';
1186 }
1187 printOneCharacter(*(EndPtr - 1));
1188 };
1189 switch (ACLS) {
1191 printCharacterList(printCharacterInOctal);
1192 return;
1194 printCharacterList(printOneCharacterFor([&OS](char C) {
1195 const char AsmCharLitBuf[2] = {'\'', C};
1196 OS << StringRef(AsmCharLitBuf, sizeof(AsmCharLitBuf));
1197 }));
1198 return;
1199 }
1200 llvm_unreachable("Invalid AsmCharLiteralSyntax value!");
1201}
1202
1203void MCAsmStreamer::PrintQuotedString(StringRef Data, raw_ostream &OS) const {
1204 OS << '"';
1205
1207 for (unsigned char C : Data) {
1208 if (C == '"')
1209 OS << "\"\"";
1210 else
1211 OS << (char)C;
1212 }
1213 } else {
1214 for (unsigned char C : Data) {
1215 if (C == '"' || C == '\\') {
1216 OS << '\\' << (char)C;
1217 continue;
1218 }
1219
1220 if (isPrint((unsigned char)C)) {
1221 OS << (char)C;
1222 continue;
1223 }
1224
1225 switch (C) {
1226 case '\b':
1227 OS << "\\b";
1228 break;
1229 case '\f':
1230 OS << "\\f";
1231 break;
1232 case '\n':
1233 OS << "\\n";
1234 break;
1235 case '\r':
1236 OS << "\\r";
1237 break;
1238 case '\t':
1239 OS << "\\t";
1240 break;
1241 default:
1242 OS << '\\';
1243 OS << toOctal(C >> 6);
1244 OS << toOctal(C >> 3);
1245 OS << toOctal(C >> 0);
1246 break;
1247 }
1248 }
1249 }
1250
1251 OS << '"';
1252}
1253
1254void MCAsmStreamer::emitBytes(StringRef Data) {
1255 assert(getCurrentSectionOnly() &&
1256 "Cannot emit contents before setting section!");
1257 if (Data.empty()) return;
1258
1259 const auto emitAsString = [this](StringRef Data) {
1260 // If the data ends with 0 and the target supports .asciz, use it, otherwise
1261 // use .ascii or a byte-list directive
1262 if (MAI->getAscizDirective() && Data.back() == 0) {
1263 OS << MAI->getAscizDirective();
1264 Data = Data.substr(0, Data.size() - 1);
1265 } else if (LLVM_LIKELY(MAI->getAsciiDirective())) {
1266 OS << MAI->getAsciiDirective();
1267 } else if (MAI->hasPairedDoubleQuoteStringConstants() &&
1268 isPrintableString(Data)) {
1269 // For target with DoubleQuoteString constants, .string and .byte are used
1270 // as replacement of .asciz and .ascii.
1272 "hasPairedDoubleQuoteStringConstants target must support "
1273 "PlainString Directive");
1275 "hasPairedDoubleQuoteStringConstants target must support ByteList "
1276 "Directive");
1277 if (Data.back() == 0) {
1278 OS << MAI->getPlainStringDirective();
1279 Data = Data.substr(0, Data.size() - 1);
1280 } else {
1281 OS << MAI->getByteListDirective();
1282 }
1283 } else if (MAI->getByteListDirective()) {
1284 OS << MAI->getByteListDirective();
1286 EmitEOL();
1287 return true;
1288 } else {
1289 return false;
1290 }
1291
1292 PrintQuotedString(Data, OS);
1293 EmitEOL();
1294 return true;
1295 };
1296
1297 if (Data.size() != 1 && emitAsString(Data))
1298 return;
1299
1300 // Only single byte is provided or no ascii, asciz, or byte-list directives
1301 // are applicable. Emit as vector of individual 8bits data elements.
1302 if (MCTargetStreamer *TS = getTargetStreamer()) {
1303 TS->emitRawBytes(Data);
1304 return;
1305 }
1306 const char *Directive = MAI->getData8bitsDirective();
1307 for (const unsigned char C : Data.bytes()) {
1308 OS << Directive << (unsigned)C;
1309 EmitEOL();
1310 }
1311}
1312
1313void MCAsmStreamer::emitBinaryData(StringRef Data) {
1314 // This is binary data. Print it in a grid of hex bytes for readability.
1315 const size_t Cols = 4;
1316 for (size_t I = 0, EI = alignTo(Data.size(), Cols); I < EI; I += Cols) {
1317 size_t J = I, EJ = std::min(I + Cols, Data.size());
1318 assert(EJ > 0);
1319 OS << MAI->getData8bitsDirective();
1320 for (; J < EJ - 1; ++J)
1321 OS << format("0x%02x", uint8_t(Data[J])) << ", ";
1322 OS << format("0x%02x", uint8_t(Data[J]));
1323 EmitEOL();
1324 }
1325}
1326
1327void MCAsmStreamer::emitIntValue(uint64_t Value, unsigned Size) {
1328 emitValue(MCConstantExpr::create(Value, getContext()), Size);
1329}
1330
1331void MCAsmStreamer::emitIntValueInHex(uint64_t Value, unsigned Size) {
1332 emitValue(MCConstantExpr::create(Value, getContext(), true), Size);
1333}
1334
1335void MCAsmStreamer::emitIntValueInHexWithPadding(uint64_t Value,
1336 unsigned Size) {
1337 emitValue(MCConstantExpr::create(Value, getContext(), true, Size), Size);
1338}
1339
1340void MCAsmStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
1341 SMLoc Loc) {
1342 assert(Size <= 8 && "Invalid size");
1343 assert(getCurrentSectionOnly() &&
1344 "Cannot emit contents before setting section!");
1345 const char *Directive = nullptr;
1346 switch (Size) {
1347 default: break;
1348 case 1: Directive = MAI->getData8bitsDirective(); break;
1349 case 2: Directive = MAI->getData16bitsDirective(); break;
1350 case 4: Directive = MAI->getData32bitsDirective(); break;
1351 case 8: Directive = MAI->getData64bitsDirective(); break;
1352 }
1353
1354 if (!Directive) {
1355 int64_t IntValue;
1356 if (!Value->evaluateAsAbsolute(IntValue))
1357 report_fatal_error("Don't know how to emit this value.");
1358
1359 // We couldn't handle the requested integer size so we fallback by breaking
1360 // the request down into several, smaller, integers.
1361 // Since sizes greater or equal to "Size" are invalid, we use the greatest
1362 // power of 2 that is less than "Size" as our largest piece of granularity.
1363 bool IsLittleEndian = MAI->isLittleEndian();
1364 for (unsigned Emitted = 0; Emitted != Size;) {
1365 unsigned Remaining = Size - Emitted;
1366 // The size of our partial emission must be a power of two less than
1367 // Size.
1368 unsigned EmissionSize = llvm::bit_floor(std::min(Remaining, Size - 1));
1369 // Calculate the byte offset of our partial emission taking into account
1370 // the endianness of the target.
1371 unsigned ByteOffset =
1372 IsLittleEndian ? Emitted : (Remaining - EmissionSize);
1373 uint64_t ValueToEmit = IntValue >> (ByteOffset * 8);
1374 // We truncate our partial emission to fit within the bounds of the
1375 // emission domain. This produces nicer output and silences potential
1376 // truncation warnings when round tripping through another assembler.
1377 uint64_t Shift = 64 - EmissionSize * 8;
1378 assert(Shift < static_cast<uint64_t>(
1379 std::numeric_limits<unsigned long long>::digits) &&
1380 "undefined behavior");
1381 ValueToEmit &= ~0ULL >> Shift;
1382 emitIntValue(ValueToEmit, EmissionSize);
1383 Emitted += EmissionSize;
1384 }
1385 return;
1386 }
1387
1388 assert(Directive && "Invalid size for machine code value!");
1389 OS << Directive;
1390 if (MCTargetStreamer *TS = getTargetStreamer()) {
1391 TS->emitValue(Value);
1392 } else {
1393 Value->print(OS, MAI);
1394 EmitEOL();
1395 }
1396}
1397
1398void MCAsmStreamer::emitULEB128Value(const MCExpr *Value) {
1399 int64_t IntValue;
1400 if (Value->evaluateAsAbsolute(IntValue)) {
1401 emitULEB128IntValue(IntValue);
1402 return;
1403 }
1404 OS << "\t.uleb128 ";
1405 Value->print(OS, MAI);
1406 EmitEOL();
1407}
1408
1409void MCAsmStreamer::emitSLEB128Value(const MCExpr *Value) {
1410 int64_t IntValue;
1411 if (Value->evaluateAsAbsolute(IntValue)) {
1412 emitSLEB128IntValue(IntValue);
1413 return;
1414 }
1415 OS << "\t.sleb128 ";
1416 Value->print(OS, MAI);
1417 EmitEOL();
1418}
1419
1420void MCAsmStreamer::emitDTPRel64Value(const MCExpr *Value) {
1421 assert(MAI->getDTPRel64Directive() != nullptr);
1422 OS << MAI->getDTPRel64Directive();
1423 Value->print(OS, MAI);
1424 EmitEOL();
1425}
1426
1427void MCAsmStreamer::emitDTPRel32Value(const MCExpr *Value) {
1428 assert(MAI->getDTPRel32Directive() != nullptr);
1429 OS << MAI->getDTPRel32Directive();
1430 Value->print(OS, MAI);
1431 EmitEOL();
1432}
1433
1434void MCAsmStreamer::emitTPRel64Value(const MCExpr *Value) {
1435 assert(MAI->getTPRel64Directive() != nullptr);
1436 OS << MAI->getTPRel64Directive();
1437 Value->print(OS, MAI);
1438 EmitEOL();
1439}
1440
1441void MCAsmStreamer::emitTPRel32Value(const MCExpr *Value) {
1442 assert(MAI->getTPRel32Directive() != nullptr);
1443 OS << MAI->getTPRel32Directive();
1444 Value->print(OS, MAI);
1445 EmitEOL();
1446}
1447
1448void MCAsmStreamer::emitGPRel64Value(const MCExpr *Value) {
1449 assert(MAI->getGPRel64Directive() != nullptr);
1450 OS << MAI->getGPRel64Directive();
1451 Value->print(OS, MAI);
1452 EmitEOL();
1453}
1454
1455void MCAsmStreamer::emitGPRel32Value(const MCExpr *Value) {
1456 assert(MAI->getGPRel32Directive() != nullptr);
1457 OS << MAI->getGPRel32Directive();
1458 Value->print(OS, MAI);
1459 EmitEOL();
1460}
1461
1462void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
1463 SMLoc Loc) {
1464 int64_t IntNumBytes;
1465 const bool IsAbsolute = NumBytes.evaluateAsAbsolute(IntNumBytes);
1466 if (IsAbsolute && IntNumBytes == 0)
1467 return;
1468
1469 if (const char *ZeroDirective = MAI->getZeroDirective()) {
1470 if (MAI->doesZeroDirectiveSupportNonZeroValue() || FillValue == 0) {
1471 // FIXME: Emit location directives
1472 OS << ZeroDirective;
1473 NumBytes.print(OS, MAI);
1474 if (FillValue != 0)
1475 OS << ',' << (int)FillValue;
1476 EmitEOL();
1477 } else {
1478 if (!IsAbsolute)
1480 "Cannot emit non-absolute expression lengths of fill.");
1481 for (int i = 0; i < IntNumBytes; ++i) {
1482 OS << MAI->getData8bitsDirective() << (int)FillValue;
1483 EmitEOL();
1484 }
1485 }
1486 return;
1487 }
1488
1489 MCStreamer::emitFill(NumBytes, FillValue);
1490}
1491
1492void MCAsmStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
1493 int64_t Expr, SMLoc Loc) {
1494 // FIXME: Emit location directives
1495 OS << "\t.fill\t";
1496 NumValues.print(OS, MAI);
1497 OS << ", " << Size << ", 0x";
1498 OS.write_hex(truncateToSize(Expr, 4));
1499 EmitEOL();
1500}
1501
1502void MCAsmStreamer::emitAlignmentDirective(uint64_t ByteAlignment,
1503 std::optional<int64_t> Value,
1504 unsigned ValueSize,
1505 unsigned MaxBytesToEmit) {
1506 if (MAI->useDotAlignForAlignment()) {
1507 if (!isPowerOf2_64(ByteAlignment))
1508 report_fatal_error("Only power-of-two alignments are supported "
1509 "with .align.");
1510 OS << "\t.align\t";
1511 OS << Log2_64(ByteAlignment);
1512 EmitEOL();
1513 return;
1514 }
1515
1516 // Some assemblers don't support non-power of two alignments, so we always
1517 // emit alignments as a power of two if possible.
1518 if (isPowerOf2_64(ByteAlignment)) {
1519 switch (ValueSize) {
1520 default:
1521 llvm_unreachable("Invalid size for machine code value!");
1522 case 1:
1523 OS << "\t.p2align\t";
1524 break;
1525 case 2:
1526 OS << ".p2alignw ";
1527 break;
1528 case 4:
1529 OS << ".p2alignl ";
1530 break;
1531 case 8:
1532 llvm_unreachable("Unsupported alignment size!");
1533 }
1534
1535 OS << Log2_64(ByteAlignment);
1536
1537 if (Value.has_value() || MaxBytesToEmit) {
1538 if (Value.has_value()) {
1539 OS << ", 0x";
1540 OS.write_hex(truncateToSize(*Value, ValueSize));
1541 } else {
1542 OS << ", ";
1543 }
1544
1545 if (MaxBytesToEmit)
1546 OS << ", " << MaxBytesToEmit;
1547 }
1548 EmitEOL();
1549 return;
1550 }
1551
1552 // Non-power of two alignment. This is not widely supported by assemblers.
1553 // FIXME: Parameterize this based on MAI.
1554 switch (ValueSize) {
1555 default: llvm_unreachable("Invalid size for machine code value!");
1556 case 1: OS << ".balign"; break;
1557 case 2: OS << ".balignw"; break;
1558 case 4: OS << ".balignl"; break;
1559 case 8: llvm_unreachable("Unsupported alignment size!");
1560 }
1561
1562 OS << ' ' << ByteAlignment;
1563 if (Value.has_value())
1564 OS << ", " << truncateToSize(*Value, ValueSize);
1565 else if (MaxBytesToEmit)
1566 OS << ", ";
1567 if (MaxBytesToEmit)
1568 OS << ", " << MaxBytesToEmit;
1569 EmitEOL();
1570}
1571
1572void MCAsmStreamer::emitValueToAlignment(Align Alignment, int64_t Value,
1573 unsigned ValueSize,
1574 unsigned MaxBytesToEmit) {
1575 emitAlignmentDirective(Alignment.value(), Value, ValueSize, MaxBytesToEmit);
1576}
1577
1578void MCAsmStreamer::emitCodeAlignment(Align Alignment,
1579 const MCSubtargetInfo *STI,
1580 unsigned MaxBytesToEmit) {
1581 // Emit with a text fill value.
1582 if (MAI->getTextAlignFillValue())
1583 emitAlignmentDirective(Alignment.value(), MAI->getTextAlignFillValue(), 1,
1584 MaxBytesToEmit);
1585 else
1586 emitAlignmentDirective(Alignment.value(), std::nullopt, 1, MaxBytesToEmit);
1587}
1588
1589void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
1590 unsigned char Value,
1591 SMLoc Loc) {
1592 // FIXME: Verify that Offset is associated with the current section.
1593 OS << ".org ";
1594 Offset->print(OS, MAI);
1595 OS << ", " << (unsigned)Value;
1596 EmitEOL();
1597}
1598
1599void MCAsmStreamer::emitFileDirective(StringRef Filename) {
1601 OS << "\t.file\t";
1602 PrintQuotedString(Filename, OS);
1603 EmitEOL();
1604}
1605
1606void MCAsmStreamer::emitFileDirective(StringRef Filename,
1607 StringRef CompilerVersion,
1608 StringRef TimeStamp,
1609 StringRef Description) {
1611 OS << "\t.file\t";
1612 PrintQuotedString(Filename, OS);
1613 bool useTimeStamp = !TimeStamp.empty();
1614 bool useCompilerVersion = !CompilerVersion.empty();
1615 bool useDescription = !Description.empty();
1616 if (useTimeStamp || useCompilerVersion || useDescription) {
1617 OS << ",";
1618 if (useTimeStamp)
1619 PrintQuotedString(TimeStamp, OS);
1620 if (useCompilerVersion || useDescription) {
1621 OS << ",";
1622 if (useCompilerVersion)
1623 PrintQuotedString(CompilerVersion, OS);
1624 if (useDescription) {
1625 OS << ",";
1626 PrintQuotedString(Description, OS);
1627 }
1628 }
1629 }
1630 EmitEOL();
1631}
1632
1633void MCAsmStreamer::printDwarfFileDirective(
1634 unsigned FileNo, StringRef Directory, StringRef Filename,
1635 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1636 bool UseDwarfDirectory, raw_svector_ostream &OS) const {
1637 SmallString<128> FullPathName;
1638
1639 if (!UseDwarfDirectory && !Directory.empty()) {
1640 if (sys::path::is_absolute(Filename))
1641 Directory = "";
1642 else {
1643 FullPathName = Directory;
1644 sys::path::append(FullPathName, Filename);
1645 Directory = "";
1646 Filename = FullPathName;
1647 }
1648 }
1649
1650 OS << "\t.file\t" << FileNo << ' ';
1651 if (!Directory.empty()) {
1652 PrintQuotedString(Directory, OS);
1653 OS << ' ';
1654 }
1655 PrintQuotedString(Filename, OS);
1656 if (Checksum)
1657 OS << " md5 0x" << Checksum->digest();
1658 if (Source) {
1659 OS << " source ";
1660 PrintQuotedString(*Source, OS);
1661 }
1662}
1663
1664Expected<unsigned> MCAsmStreamer::tryEmitDwarfFileDirective(
1665 unsigned FileNo, StringRef Directory, StringRef Filename,
1666 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1667 unsigned CUID) {
1668 assert(CUID == 0 && "multiple CUs not supported by MCAsmStreamer");
1669
1670 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
1671 unsigned NumFiles = Table.getMCDwarfFiles().size();
1672 Expected<unsigned> FileNoOrErr =
1673 Table.tryGetFile(Directory, Filename, Checksum, Source,
1674 getContext().getDwarfVersion(), FileNo);
1675 if (!FileNoOrErr)
1676 return FileNoOrErr.takeError();
1677 FileNo = FileNoOrErr.get();
1678
1679 // Return early if this file is already emitted before or if target doesn't
1680 // support .file directive.
1681 if (NumFiles == Table.getMCDwarfFiles().size() ||
1683 return FileNo;
1684
1685 SmallString<128> Str;
1686 raw_svector_ostream OS1(Str);
1687 printDwarfFileDirective(FileNo, Directory, Filename, Checksum, Source,
1688 UseDwarfDirectory, OS1);
1689
1690 if (MCTargetStreamer *TS = getTargetStreamer())
1691 TS->emitDwarfFileDirective(OS1.str());
1692 else
1693 emitRawText(OS1.str());
1694
1695 return FileNo;
1696}
1697
1698void MCAsmStreamer::emitDwarfFile0Directive(
1699 StringRef Directory, StringRef Filename,
1700 std::optional<MD5::MD5Result> Checksum, std::optional<StringRef> Source,
1701 unsigned CUID) {
1702 assert(CUID == 0);
1703 // .file 0 is new for DWARF v5.
1704 if (getContext().getDwarfVersion() < 5)
1705 return;
1706 // Inform MCDwarf about the root file.
1707 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
1708 Source);
1709
1710 // Target doesn't support .loc/.file directives, return early.
1712 return;
1713
1714 SmallString<128> Str;
1715 raw_svector_ostream OS1(Str);
1716 printDwarfFileDirective(0, Directory, Filename, Checksum, Source,
1717 UseDwarfDirectory, OS1);
1718
1719 if (MCTargetStreamer *TS = getTargetStreamer())
1720 TS->emitDwarfFileDirective(OS1.str());
1721 else
1722 emitRawText(OS1.str());
1723}
1724
1725void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
1726 unsigned Column, unsigned Flags,
1727 unsigned Isa, unsigned Discriminator,
1728 StringRef FileName) {
1729 // If target doesn't support .loc/.file directive, we need to record the lines
1730 // same way like we do in object mode.
1731 if (!MAI->usesDwarfFileAndLocDirectives()) {
1732 // In case we see two .loc directives in a row, make sure the
1733 // first one gets a line entry.
1734 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
1735 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1736 Discriminator, FileName);
1737 return;
1738 }
1739
1740 OS << "\t.loc\t" << FileNo << " " << Line << " " << Column;
1742 if (Flags & DWARF2_FLAG_BASIC_BLOCK)
1743 OS << " basic_block";
1744 if (Flags & DWARF2_FLAG_PROLOGUE_END)
1745 OS << " prologue_end";
1746 if (Flags & DWARF2_FLAG_EPILOGUE_BEGIN)
1747 OS << " epilogue_begin";
1748
1749 unsigned OldFlags = getContext().getCurrentDwarfLoc().getFlags();
1750 if ((Flags & DWARF2_FLAG_IS_STMT) != (OldFlags & DWARF2_FLAG_IS_STMT)) {
1751 OS << " is_stmt ";
1752
1753 if (Flags & DWARF2_FLAG_IS_STMT)
1754 OS << "1";
1755 else
1756 OS << "0";
1757 }
1758
1759 if (Isa)
1760 OS << " isa " << Isa;
1761 if (Discriminator)
1762 OS << " discriminator " << Discriminator;
1763 }
1764
1765 if (IsVerboseAsm) {
1766 OS.PadToColumn(MAI->getCommentColumn());
1767 OS << MAI->getCommentString() << ' ' << FileName << ':'
1768 << Line << ':' << Column;
1769 }
1770 EmitEOL();
1771 this->MCStreamer::emitDwarfLocDirective(FileNo, Line, Column, Flags, Isa,
1772 Discriminator, FileName);
1773}
1774
1775void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
1777 OS << ".loc_label\t" << Name;
1778 EmitEOL();
1779}
1780
1781MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
1782 // Always use the zeroth line table, since asm syntax only supports one line
1783 // table for now.
1785}
1786
1787bool MCAsmStreamer::emitCVFileDirective(unsigned FileNo, StringRef Filename,
1788 ArrayRef<uint8_t> Checksum,
1789 unsigned ChecksumKind) {
1790 if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
1791 ChecksumKind))
1792 return false;
1793
1794 OS << "\t.cv_file\t" << FileNo << ' ';
1795 PrintQuotedString(Filename, OS);
1796
1797 if (!ChecksumKind) {
1798 EmitEOL();
1799 return true;
1800 }
1801
1802 OS << ' ';
1803 PrintQuotedString(toHex(Checksum), OS);
1804 OS << ' ' << ChecksumKind;
1805
1806 EmitEOL();
1807 return true;
1808}
1809
1810bool MCAsmStreamer::emitCVFuncIdDirective(unsigned FuncId) {
1811 OS << "\t.cv_func_id " << FuncId << '\n';
1813}
1814
1815bool MCAsmStreamer::emitCVInlineSiteIdDirective(unsigned FunctionId,
1816 unsigned IAFunc,
1817 unsigned IAFile,
1818 unsigned IALine, unsigned IACol,
1819 SMLoc Loc) {
1820 OS << "\t.cv_inline_site_id " << FunctionId << " within " << IAFunc
1821 << " inlined_at " << IAFile << ' ' << IALine << ' ' << IACol << '\n';
1823 IALine, IACol, Loc);
1824}
1825
1826void MCAsmStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
1827 unsigned Line, unsigned Column,
1828 bool PrologueEnd, bool IsStmt,
1829 StringRef FileName, SMLoc Loc) {
1830 // Validate the directive.
1831 if (!checkCVLocSection(FunctionId, FileNo, Loc))
1832 return;
1833
1834 OS << "\t.cv_loc\t" << FunctionId << " " << FileNo << " " << Line << " "
1835 << Column;
1836 if (PrologueEnd)
1837 OS << " prologue_end";
1838
1839 if (IsStmt)
1840 OS << " is_stmt 1";
1841
1842 if (IsVerboseAsm) {
1843 OS.PadToColumn(MAI->getCommentColumn());
1844 OS << MAI->getCommentString() << ' ' << FileName << ':' << Line << ':'
1845 << Column;
1846 }
1847 EmitEOL();
1848}
1849
1850void MCAsmStreamer::emitCVLinetableDirective(unsigned FunctionId,
1851 const MCSymbol *FnStart,
1852 const MCSymbol *FnEnd) {
1853 OS << "\t.cv_linetable\t" << FunctionId << ", ";
1854 FnStart->print(OS, MAI);
1855 OS << ", ";
1856 FnEnd->print(OS, MAI);
1857 EmitEOL();
1858 this->MCStreamer::emitCVLinetableDirective(FunctionId, FnStart, FnEnd);
1859}
1860
1861void MCAsmStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
1862 unsigned SourceFileId,
1863 unsigned SourceLineNum,
1864 const MCSymbol *FnStartSym,
1865 const MCSymbol *FnEndSym) {
1866 OS << "\t.cv_inline_linetable\t" << PrimaryFunctionId << ' ' << SourceFileId
1867 << ' ' << SourceLineNum << ' ';
1868 FnStartSym->print(OS, MAI);
1869 OS << ' ';
1870 FnEndSym->print(OS, MAI);
1871 EmitEOL();
1873 PrimaryFunctionId, SourceFileId, SourceLineNum, FnStartSym, FnEndSym);
1874}
1875
1876void MCAsmStreamer::PrintCVDefRangePrefix(
1877 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges) {
1878 OS << "\t.cv_def_range\t";
1879 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Ranges) {
1880 OS << ' ';
1881 Range.first->print(OS, MAI);
1882 OS << ' ';
1883 Range.second->print(OS, MAI);
1884 }
1885}
1886
1887void MCAsmStreamer::emitCVDefRangeDirective(
1888 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1890 PrintCVDefRangePrefix(Ranges);
1891 OS << ", reg_rel, ";
1892 OS << DRHdr.Register << ", " << DRHdr.Flags << ", "
1893 << DRHdr.BasePointerOffset;
1894 EmitEOL();
1895}
1896
1897void MCAsmStreamer::emitCVDefRangeDirective(
1898 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1900 PrintCVDefRangePrefix(Ranges);
1901 OS << ", subfield_reg, ";
1902 OS << DRHdr.Register << ", " << DRHdr.OffsetInParent;
1903 EmitEOL();
1904}
1905
1906void MCAsmStreamer::emitCVDefRangeDirective(
1907 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1909 PrintCVDefRangePrefix(Ranges);
1910 OS << ", reg, ";
1911 OS << DRHdr.Register;
1912 EmitEOL();
1913}
1914
1915void MCAsmStreamer::emitCVDefRangeDirective(
1916 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
1918 PrintCVDefRangePrefix(Ranges);
1919 OS << ", frame_ptr_rel, ";
1920 OS << DRHdr.Offset;
1921 EmitEOL();
1922}
1923
1924void MCAsmStreamer::emitCVStringTableDirective() {
1925 OS << "\t.cv_stringtable";
1926 EmitEOL();
1927}
1928
1929void MCAsmStreamer::emitCVFileChecksumsDirective() {
1930 OS << "\t.cv_filechecksums";
1931 EmitEOL();
1932}
1933
1934void MCAsmStreamer::emitCVFileChecksumOffsetDirective(unsigned FileNo) {
1935 OS << "\t.cv_filechecksumoffset\t" << FileNo;
1936 EmitEOL();
1937}
1938
1939void MCAsmStreamer::emitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
1940 OS << "\t.cv_fpo_data\t";
1941 ProcSym->print(OS, MAI);
1942 EmitEOL();
1943}
1944
1945void MCAsmStreamer::emitIdent(StringRef IdentString) {
1946 assert(MAI->hasIdentDirective() && ".ident directive not supported");
1947 OS << "\t.ident\t";
1948 PrintQuotedString(IdentString, OS);
1949 EmitEOL();
1950}
1951
1952void MCAsmStreamer::emitCFISections(bool EH, bool Debug) {
1954 OS << "\t.cfi_sections ";
1955 if (EH) {
1956 OS << ".eh_frame";
1957 if (Debug)
1958 OS << ", .debug_frame";
1959 } else if (Debug) {
1960 OS << ".debug_frame";
1961 }
1962
1963 EmitEOL();
1964}
1965
1966void MCAsmStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
1967 OS << "\t.cfi_startproc";
1968 if (Frame.IsSimple)
1969 OS << " simple";
1970 EmitEOL();
1971}
1972
1973void MCAsmStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
1975 OS << "\t.cfi_endproc";
1976 EmitEOL();
1977}
1978
1979void MCAsmStreamer::EmitRegisterName(int64_t Register) {
1980 if (!MAI->useDwarfRegNumForCFI()) {
1981 // User .cfi_* directives can use arbitrary DWARF register numbers, not
1982 // just ones that map to LLVM register numbers and have known names.
1983 // Fall back to using the original number directly if no name is known.
1984 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1985 if (std::optional<MCRegister> LLVMRegister =
1986 MRI->getLLVMRegNum(Register, true)) {
1987 InstPrinter->printRegName(OS, *LLVMRegister);
1988 return;
1989 }
1990 }
1991 OS << Register;
1992}
1993
1994void MCAsmStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset, SMLoc Loc) {
1996 OS << "\t.cfi_def_cfa ";
1997 EmitRegisterName(Register);
1998 OS << ", " << Offset;
1999 EmitEOL();
2000}
2001
2002void MCAsmStreamer::emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc) {
2004 OS << "\t.cfi_def_cfa_offset " << Offset;
2005 EmitEOL();
2006}
2007
2008void MCAsmStreamer::emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset,
2009 int64_t AddressSpace, SMLoc Loc) {
2011 OS << "\t.cfi_llvm_def_aspace_cfa ";
2012 EmitRegisterName(Register);
2013 OS << ", " << Offset;
2014 OS << ", " << AddressSpace;
2015 EmitEOL();
2016}
2017
2019 OS << "\t.cfi_escape ";
2020 if (!Values.empty()) {
2021 size_t e = Values.size() - 1;
2022 for (size_t i = 0; i < e; ++i)
2023 OS << format("0x%02x", uint8_t(Values[i])) << ", ";
2024 OS << format("0x%02x", uint8_t(Values[e]));
2025 }
2026}
2027
2028void MCAsmStreamer::emitCFIEscape(StringRef Values, SMLoc Loc) {
2029 MCStreamer::emitCFIEscape(Values, Loc);
2030 PrintCFIEscape(OS, Values);
2031 EmitEOL();
2032}
2033
2034void MCAsmStreamer::emitCFIGnuArgsSize(int64_t Size, SMLoc Loc) {
2036
2037 uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
2038 unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
2039
2040 PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
2041 EmitEOL();
2042}
2043
2044void MCAsmStreamer::emitCFIDefCfaRegister(int64_t Register, SMLoc Loc) {
2046 OS << "\t.cfi_def_cfa_register ";
2047 EmitRegisterName(Register);
2048 EmitEOL();
2049}
2050
2051void MCAsmStreamer::emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc) {
2053 OS << "\t.cfi_offset ";
2054 EmitRegisterName(Register);
2055 OS << ", " << Offset;
2056 EmitEOL();
2057}
2058
2059void MCAsmStreamer::emitCFIPersonality(const MCSymbol *Sym,
2060 unsigned Encoding) {
2062 OS << "\t.cfi_personality " << Encoding << ", ";
2063 Sym->print(OS, MAI);
2064 EmitEOL();
2065}
2066
2067void MCAsmStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
2068 MCStreamer::emitCFILsda(Sym, Encoding);
2069 OS << "\t.cfi_lsda " << Encoding << ", ";
2070 Sym->print(OS, MAI);
2071 EmitEOL();
2072}
2073
2074void MCAsmStreamer::emitCFIRememberState(SMLoc Loc) {
2076 OS << "\t.cfi_remember_state";
2077 EmitEOL();
2078}
2079
2080void MCAsmStreamer::emitCFIRestoreState(SMLoc Loc) {
2082 OS << "\t.cfi_restore_state";
2083 EmitEOL();
2084}
2085
2086void MCAsmStreamer::emitCFIRestore(int64_t Register, SMLoc Loc) {
2088 OS << "\t.cfi_restore ";
2089 EmitRegisterName(Register);
2090 EmitEOL();
2091}
2092
2093void MCAsmStreamer::emitCFISameValue(int64_t Register, SMLoc Loc) {
2095 OS << "\t.cfi_same_value ";
2096 EmitRegisterName(Register);
2097 EmitEOL();
2098}
2099
2100void MCAsmStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset,
2101 SMLoc Loc) {
2103 OS << "\t.cfi_rel_offset ";
2104 EmitRegisterName(Register);
2105 OS << ", " << Offset;
2106 EmitEOL();
2107}
2108
2109void MCAsmStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc) {
2110 MCStreamer::emitCFIAdjustCfaOffset(Adjustment, Loc);
2111 OS << "\t.cfi_adjust_cfa_offset " << Adjustment;
2112 EmitEOL();
2113}
2114
2115void MCAsmStreamer::emitCFISignalFrame() {
2117 OS << "\t.cfi_signal_frame";
2118 EmitEOL();
2119}
2120
2121void MCAsmStreamer::emitCFIUndefined(int64_t Register, SMLoc Loc) {
2123 OS << "\t.cfi_undefined ";
2124 EmitRegisterName(Register);
2125 EmitEOL();
2126}
2127
2128void MCAsmStreamer::emitCFIRegister(int64_t Register1, int64_t Register2,
2129 SMLoc Loc) {
2130 MCStreamer::emitCFIRegister(Register1, Register2, Loc);
2131 OS << "\t.cfi_register ";
2132 EmitRegisterName(Register1);
2133 OS << ", ";
2134 EmitRegisterName(Register2);
2135 EmitEOL();
2136}
2137
2138void MCAsmStreamer::emitCFIWindowSave(SMLoc Loc) {
2140 OS << "\t.cfi_window_save";
2141 EmitEOL();
2142}
2143
2144void MCAsmStreamer::emitCFINegateRAState(SMLoc Loc) {
2146 OS << "\t.cfi_negate_ra_state";
2147 EmitEOL();
2148}
2149
2150void MCAsmStreamer::emitCFINegateRAStateWithPC(SMLoc Loc) {
2152 OS << "\t.cfi_negate_ra_state_with_pc";
2153 EmitEOL();
2154}
2155
2156void MCAsmStreamer::emitCFIReturnColumn(int64_t Register) {
2158 OS << "\t.cfi_return_column ";
2159 EmitRegisterName(Register);
2160 EmitEOL();
2161}
2162
2163void MCAsmStreamer::emitCFILabelDirective(SMLoc Loc, StringRef Name) {
2165 OS << "\t.cfi_label " << Name;
2166 EmitEOL();
2167}
2168
2169void MCAsmStreamer::emitCFIBKeyFrame() {
2171 OS << "\t.cfi_b_key_frame";
2172 EmitEOL();
2173}
2174
2175void MCAsmStreamer::emitCFIMTETaggedFrame() {
2177 OS << "\t.cfi_mte_tagged_frame";
2178 EmitEOL();
2179}
2180
2181void MCAsmStreamer::emitCFIValOffset(int64_t Register, int64_t Offset,
2182 SMLoc Loc) {
2184 OS << "\t.cfi_val_offset ";
2185 EmitRegisterName(Register);
2186 OS << ", " << Offset;
2187 EmitEOL();
2188}
2189
2190void MCAsmStreamer::emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
2192
2193 OS << ".seh_proc ";
2194 Symbol->print(OS, MAI);
2195 EmitEOL();
2196}
2197
2198void MCAsmStreamer::emitWinCFIEndProc(SMLoc Loc) {
2200
2201 OS << "\t.seh_endproc";
2202 EmitEOL();
2203}
2204
2205void MCAsmStreamer::emitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
2207
2208 OS << "\t.seh_endfunclet";
2209 EmitEOL();
2210}
2211
2212void MCAsmStreamer::emitWinCFIStartChained(SMLoc Loc) {
2214
2215 OS << "\t.seh_startchained";
2216 EmitEOL();
2217}
2218
2219void MCAsmStreamer::emitWinCFIEndChained(SMLoc Loc) {
2221
2222 OS << "\t.seh_endchained";
2223 EmitEOL();
2224}
2225
2226void MCAsmStreamer::emitWinEHHandler(const MCSymbol *Sym, bool Unwind,
2227 bool Except, SMLoc Loc) {
2228 MCStreamer::emitWinEHHandler(Sym, Unwind, Except, Loc);
2229
2230 OS << "\t.seh_handler ";
2231 Sym->print(OS, MAI);
2232 char Marker = '@';
2233 const Triple &T = getContext().getTargetTriple();
2234 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
2235 Marker = '%';
2236 if (Unwind)
2237 OS << ", " << Marker << "unwind";
2238 if (Except)
2239 OS << ", " << Marker << "except";
2240 EmitEOL();
2241}
2242
2243void MCAsmStreamer::emitWinEHHandlerData(SMLoc Loc) {
2245
2246 // Switch sections. Don't call switchSection directly, because that will
2247 // cause the section switch to be visible in the emitted assembly.
2248 // We only do this so the section switch that terminates the handler
2249 // data block is visible.
2250 WinEH::FrameInfo *CurFrame = getCurrentWinFrameInfo();
2251
2252 // Do nothing if no frame is open. MCStreamer should've already reported an
2253 // error.
2254 if (!CurFrame)
2255 return;
2256
2257 MCSection *TextSec = &CurFrame->Function->getSection();
2258 MCSection *XData = getAssociatedXDataSection(TextSec);
2259 switchSectionNoPrint(XData);
2260
2261 OS << "\t.seh_handlerdata";
2262 EmitEOL();
2263}
2264
2265void MCAsmStreamer::emitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
2267
2268 OS << "\t.seh_pushreg ";
2269 InstPrinter->printRegName(OS, Register);
2270 EmitEOL();
2271}
2272
2273void MCAsmStreamer::emitWinCFISetFrame(MCRegister Register, unsigned Offset,
2274 SMLoc Loc) {
2276
2277 OS << "\t.seh_setframe ";
2278 InstPrinter->printRegName(OS, Register);
2279 OS << ", " << Offset;
2280 EmitEOL();
2281}
2282
2283void MCAsmStreamer::emitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
2285
2286 OS << "\t.seh_stackalloc " << Size;
2287 EmitEOL();
2288}
2289
2290void MCAsmStreamer::emitWinCFISaveReg(MCRegister Register, unsigned Offset,
2291 SMLoc Loc) {
2293
2294 OS << "\t.seh_savereg ";
2295 InstPrinter->printRegName(OS, Register);
2296 OS << ", " << Offset;
2297 EmitEOL();
2298}
2299
2300void MCAsmStreamer::emitWinCFISaveXMM(MCRegister Register, unsigned Offset,
2301 SMLoc Loc) {
2303
2304 OS << "\t.seh_savexmm ";
2305 InstPrinter->printRegName(OS, Register);
2306 OS << ", " << Offset;
2307 EmitEOL();
2308}
2309
2310void MCAsmStreamer::emitWinCFIPushFrame(bool Code, SMLoc Loc) {
2312
2313 OS << "\t.seh_pushframe";
2314 if (Code)
2315 OS << " @code";
2316 EmitEOL();
2317}
2318
2319void MCAsmStreamer::emitWinCFIEndProlog(SMLoc Loc) {
2321
2322 OS << "\t.seh_endprologue";
2323 EmitEOL();
2324}
2325
2326void MCAsmStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
2327 const MCSymbolRefExpr *To,
2328 uint64_t Count) {
2329 OS << "\t.cg_profile ";
2330 From->getSymbol().print(OS, MAI);
2331 OS << ", ";
2332 To->getSymbol().print(OS, MAI);
2333 OS << ", " << Count;
2334 EmitEOL();
2335}
2336
2337void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
2338 const MCSubtargetInfo &STI) {
2339 raw_ostream &OS = getCommentOS();
2342
2343 // If we have no code emitter, don't emit code.
2344 if (!getAssembler().getEmitterPtr())
2345 return;
2346
2347 getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI);
2348
2349 // If we are showing fixups, create symbolic markers in the encoded
2350 // representation. We do this by making a per-bit map to the fixup item index,
2351 // then trying to display it as nicely as possible.
2352 SmallVector<uint8_t, 64> FixupMap;
2353 FixupMap.resize(Code.size() * 8);
2354 for (unsigned i = 0, e = Code.size() * 8; i != e; ++i)
2355 FixupMap[i] = 0;
2356
2357 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
2358 MCFixup &F = Fixups[i];
2359 const MCFixupKindInfo &Info =
2360 getAssembler().getBackend().getFixupKindInfo(F.getKind());
2361 for (unsigned j = 0; j != Info.TargetSize; ++j) {
2362 unsigned Index = F.getOffset() * 8 + Info.TargetOffset + j;
2363 assert(Index < Code.size() * 8 && "Invalid offset in fixup!");
2364 FixupMap[Index] = 1 + i;
2365 }
2366 }
2367
2368 // FIXME: Note the fixup comments for Thumb2 are completely bogus since the
2369 // high order halfword of a 32-bit Thumb2 instruction is emitted first.
2370 OS << "encoding: [";
2371 for (unsigned i = 0, e = Code.size(); i != e; ++i) {
2372 if (i)
2373 OS << ',';
2374
2375 // See if all bits are the same map entry.
2376 uint8_t MapEntry = FixupMap[i * 8 + 0];
2377 for (unsigned j = 1; j != 8; ++j) {
2378 if (FixupMap[i * 8 + j] == MapEntry)
2379 continue;
2380
2381 MapEntry = uint8_t(~0U);
2382 break;
2383 }
2384
2385 if (MapEntry != uint8_t(~0U)) {
2386 if (MapEntry == 0) {
2387 OS << format("0x%02x", uint8_t(Code[i]));
2388 } else {
2389 if (Code[i]) {
2390 // FIXME: Some of the 8 bits require fix up.
2391 OS << format("0x%02x", uint8_t(Code[i])) << '\''
2392 << char('A' + MapEntry - 1) << '\'';
2393 } else
2394 OS << char('A' + MapEntry - 1);
2395 }
2396 } else {
2397 // Otherwise, write out in binary.
2398 OS << "0b";
2399 for (unsigned j = 8; j--;) {
2400 unsigned Bit = (Code[i] >> j) & 1;
2401
2402 unsigned FixupBit;
2403 if (MAI->isLittleEndian())
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) {
2419 MCFixup &F = Fixups[i];
2420 const MCFixupKindInfo &Info =
2421 getAssembler().getBackend().getFixupKindInfo(F.getKind());
2422 OS << " fixup " << char('A' + i) << " - "
2423 << "offset: " << F.getOffset() << ", value: ";
2424 F.getValue()->print(OS, MAI);
2425 OS << ", kind: " << Info.Name << "\n";
2426 }
2427}
2428
2429void MCAsmStreamer::emitInstruction(const MCInst &Inst,
2430 const MCSubtargetInfo &STI) {
2431 if (!MAI->usesDwarfFileAndLocDirectives() && CurFrag)
2432 // Now that a machine instruction has been assembled into this section, make
2433 // a line entry for any .loc directive that has been seen.
2434 MCDwarfLineEntry::make(this, getCurrentSectionOnly());
2435
2436 // Show the encoding in a comment if we have a code emitter.
2437 AddEncodingComment(Inst, STI);
2438
2439 // Show the MCInst if enabled.
2440 if (ShowInst) {
2441 Inst.dump_pretty(getCommentOS(), InstPrinter.get(), "\n ");
2442 getCommentOS() << "\n";
2443 }
2444
2445 if(getTargetStreamer())
2446 getTargetStreamer()->prettyPrintAsm(*InstPrinter, 0, Inst, STI, OS);
2447 else
2448 InstPrinter->printInst(&Inst, 0, "", STI, OS);
2449
2450 StringRef Comments = CommentToEmit;
2451 if (Comments.size() && Comments.back() != '\n')
2452 getCommentOS() << "\n";
2453
2454 EmitEOL();
2455}
2456
2457void MCAsmStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index,
2458 uint64_t Type, uint64_t Attr,
2459 uint64_t Discriminator,
2460 const MCPseudoProbeInlineStack &InlineStack,
2461 MCSymbol *FnSym) {
2462 OS << "\t.pseudoprobe\t" << Guid << " " << Index << " " << Type << " " << Attr;
2463 if (Discriminator)
2464 OS << " " << Discriminator;
2465 // Emit inline stack like
2466 // @ GUIDmain:3 @ GUIDCaller:1 @ GUIDDirectCaller:11
2467 for (const auto &Site : InlineStack)
2468 OS << " @ " << std::get<0>(Site) << ":" << std::get<1>(Site);
2469
2470 OS << " " << FnSym->getName();
2471
2472 EmitEOL();
2473}
2474
2475void MCAsmStreamer::emitBundleAlignMode(Align Alignment) {
2476 OS << "\t.bundle_align_mode " << Log2(Alignment);
2477 EmitEOL();
2478}
2479
2480void MCAsmStreamer::emitBundleLock(bool AlignToEnd) {
2481 OS << "\t.bundle_lock";
2482 if (AlignToEnd)
2483 OS << " align_to_end";
2484 EmitEOL();
2485}
2486
2487void MCAsmStreamer::emitBundleUnlock() {
2488 OS << "\t.bundle_unlock";
2489 EmitEOL();
2490}
2491
2492std::optional<std::pair<bool, std::string>>
2493MCAsmStreamer::emitRelocDirective(const MCExpr &Offset, StringRef Name,
2494 const MCExpr *Expr, SMLoc,
2495 const MCSubtargetInfo &STI) {
2496 OS << "\t.reloc ";
2497 Offset.print(OS, MAI);
2498 OS << ", " << Name;
2499 if (Expr) {
2500 OS << ", ";
2501 Expr->print(OS, MAI);
2502 }
2503 EmitEOL();
2504 return std::nullopt;
2505}
2506
2507void MCAsmStreamer::emitAddrsig() {
2508 OS << "\t.addrsig";
2509 EmitEOL();
2510}
2511
2512void MCAsmStreamer::emitAddrsigSym(const MCSymbol *Sym) {
2513 OS << "\t.addrsig_sym ";
2514 Sym->print(OS, MAI);
2515 EmitEOL();
2516}
2517
2518/// EmitRawText - If this file is backed by an assembly streamer, this dumps
2519/// the specified string in the output .s file. This capability is
2520/// indicated by the hasRawTextSupport() predicate.
2521void MCAsmStreamer::emitRawTextImpl(StringRef String) {
2522 String.consume_back("\n");
2523 OS << String;
2524 EmitEOL();
2525}
2526
2527void MCAsmStreamer::finishImpl() {
2528 // If we are generating dwarf for assembly source files dump out the sections.
2529 if (getContext().getGenDwarfForAssembly())
2531
2532 // Now it is time to emit debug line sections if target doesn't support .loc
2533 // and .line directives.
2534 if (!MAI->usesDwarfFileAndLocDirectives()) {
2535 MCDwarfLineTable::emit(this, getAssembler().getDWARFLinetableParams());
2536 return;
2537 }
2538
2539 // Emit the label for the line table, if requested - since the rest of the
2540 // line table will be defined by .loc/.file directives, and not emitted
2541 // directly, the label is the only work required here.
2542 const auto &Tables = getContext().getMCDwarfLineTables();
2543 if (!Tables.empty()) {
2544 assert(Tables.size() == 1 && "asm output only supports one line table");
2545 if (auto *Label = Tables.begin()->second.getLabel()) {
2546 switchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
2547 emitLabel(Label);
2548 }
2549 }
2550}
2551
2552void MCAsmStreamer::emitDwarfUnitLength(uint64_t Length, const Twine &Comment) {
2553 // If the assembler on some target fills in the DWARF unit length, we
2554 // don't want to emit the length in the compiler. For example, the AIX
2555 // assembler requires the assembly file with the unit length omitted from
2556 // the debug section headers. In such cases, any label we placed occurs
2557 // after the implied length field. We need to adjust the reference here
2558 // to account for the offset introduced by the inserted length field.
2560 return;
2562}
2563
2564MCSymbol *MCAsmStreamer::emitDwarfUnitLength(const Twine &Prefix,
2565 const Twine &Comment) {
2566 // If the assembler on some target fills in the DWARF unit length, we
2567 // don't want to emit the length in the compiler. For example, the AIX
2568 // assembler requires the assembly file with the unit length omitted from
2569 // the debug section headers. In such cases, any label we placed occurs
2570 // after the implied length field. We need to adjust the reference here
2571 // to account for the offset introduced by the inserted length field.
2573 return getContext().createTempSymbol(Prefix + "_end");
2574 return MCStreamer::emitDwarfUnitLength(Prefix, Comment);
2575}
2576
2577void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
2578 // If the assembler on some target fills in the DWARF unit length, we
2579 // don't want to emit the length in the compiler. For example, the AIX
2580 // assembler requires the assembly file with the unit length omitted from
2581 // the debug section headers. In such cases, any label we placed occurs
2582 // after the implied length field. We need to adjust the reference here
2583 // to account for the offset introduced by the inserted length field.
2584 MCContext &Ctx = getContext();
2585 if (!MAI->needsDwarfSectionSizeInHeader()) {
2586 MCSymbol *DebugLineSymTmp = Ctx.createTempSymbol("debug_line_");
2587 // Emit the symbol which does not contain the unit length field.
2588 emitLabel(DebugLineSymTmp);
2589
2590 // Adjust the outer reference to account for the offset introduced by the
2591 // inserted length field.
2592 unsigned LengthFieldSize =
2594 const MCExpr *EntrySize = MCConstantExpr::create(LengthFieldSize, Ctx);
2595 const MCExpr *OuterSym = MCBinaryExpr::createSub(
2596 MCSymbolRefExpr::create(DebugLineSymTmp, Ctx), EntrySize, Ctx);
2597
2598 emitAssignment(StartSym, OuterSym);
2599 return;
2600 }
2602}
2603
2604void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
2605 MCSymbol *LastLabel,
2606 MCSymbol *EndLabel) {
2607 // If the targets write the raw debug line data for assembly output (We can
2608 // not switch to Section and add the end symbol there for assembly output)
2609 // we currently use the .text end label as any section end. This will not
2610 // impact the debugability as we will jump to the caller of the last function
2611 // in the section before we come into the .text end address.
2613 ".loc should not be generated together with raw data!");
2614
2615 MCContext &Ctx = getContext();
2616
2617 // FIXME: use section end symbol as end of the Section. We need to consider
2618 // the explicit sections and -ffunction-sections when we try to generate or
2619 // find section end symbol for the Section.
2620 MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
2621 assert(TextSection->hasEnded() && ".text section is not end!");
2622
2623 if (!EndLabel)
2624 EndLabel = TextSection->getEndSymbol(Ctx);
2625 const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
2626 emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,
2627 AsmInfo->getCodePointerSize());
2628}
2629
2630// Generate DWARF line sections for assembly mode without .loc/.file
2631void MCAsmStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
2632 const MCSymbol *LastLabel,
2633 const MCSymbol *Label,
2634 unsigned PointerSize) {
2636 ".loc/.file don't need raw data in debug line section!");
2637
2638 // Set to new address.
2639 AddComment("Set address to " + Label->getName());
2640 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2641 emitULEB128IntValue(PointerSize + 1);
2642 emitIntValue(dwarf::DW_LNE_set_address, 1);
2643 emitSymbolValue(Label, PointerSize);
2644
2645 if (!LastLabel) {
2646 // Emit the sequence for the LineDelta (from 1) and a zero address delta.
2647 AddComment("Start sequence");
2648 MCDwarfLineAddr::Emit(this, MCDwarfLineTableParams(), LineDelta, 0);
2649 return;
2650 }
2651
2652 // INT64_MAX is a signal of the end of the section. Emit DW_LNE_end_sequence
2653 // for the end of the section.
2654 if (LineDelta == INT64_MAX) {
2655 AddComment("End sequence");
2656 emitIntValue(dwarf::DW_LNS_extended_op, 1);
2657 emitULEB128IntValue(1);
2658 emitIntValue(dwarf::DW_LNE_end_sequence, 1);
2659 return;
2660 }
2661
2662 // Advance line.
2663 AddComment("Advance line " + Twine(LineDelta));
2664 emitIntValue(dwarf::DW_LNS_advance_line, 1);
2665 emitSLEB128IntValue(LineDelta);
2666 emitIntValue(dwarf::DW_LNS_copy, 1);
2667}
2668
2669void MCAsmStreamer::doFinalizationAtSectionEnd(MCSection *Section) {
2670 // Emit section end. This is used to tell the debug line section where the end
2671 // is for a text section if we don't use .loc to represent the debug line.
2673 return;
2674
2675 switchSectionNoPrint(Section);
2676
2677 MCSymbol *Sym = getCurrentSectionOnly()->getEndSymbol(getContext());
2678
2679 if (!Sym->isInSection())
2680 emitLabel(Sym);
2681}
2682
2684 std::unique_ptr<formatted_raw_ostream> OS,
2685 MCInstPrinter *IP,
2686 std::unique_ptr<MCCodeEmitter> &&CE,
2687 std::unique_ptr<MCAsmBackend> &&MAB) {
2688 return new MCAsmStreamer(Context, std::move(OS), IP, std::move(CE),
2689 std::move(MAB));
2690}
unsigned const MachineRegisterInfo * MRI
BlockVerifier::State From
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_LIKELY(EXPR)
Definition: Compiler.h:319
dxil pretty printer
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
Definition: Debug.cpp:108
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
static LVOptions Options
Definition: LVOptions.cpp:25
static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values)
static const char * getVersionMinDirective(MCVersionMinType Type)
static bool isPrintableString(StringRef Data)
static void PrintByteList(StringRef Data, raw_ostream &OS, MCAsmInfo::AsmCharLiteralSyntax ACLS)
static char toOctal(int X)
static void EmitSDKVersionSuffix(raw_ostream &OS, const VersionTuple &SDKVersion)
static int64_t truncateToSize(int64_t Value, unsigned Bytes)
static const char * getPlatformName(MachO::PlatformType Type)
#define DWARF2_FLAG_IS_STMT
Definition: MCDwarf.h:117
#define DWARF2_FLAG_BASIC_BLOCK
Definition: MCDwarf.h:118
#define DWARF2_FLAG_PROLOGUE_END
Definition: MCDwarf.h:119
#define DWARF2_FLAG_EPILOGUE_BEGIN
Definition: MCDwarf.h:120
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Profile::FuncID FuncId
Definition: Profile.cpp:321
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file contains some functions that are useful when dealing with strings.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
void print(raw_ostream &OS) const
Print out the bounds to a stream.
Tagged union holding either a T or a Error.
Definition: Error.h:481
Error takeError()
Take ownership of the stored error.
Definition: Error.h:608
reference get()
Returns a reference to the stored T value.
Definition: Error.h:578
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
const char * getPlainStringDirective() const
Definition: MCAsmInfo.h:683
const char * getLabelSuffix() const
Definition: MCAsmInfo.h:623
bool hasDotTypeDotSizeDirective() const
Definition: MCAsmInfo.h:710
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:527
bool doesSupportDataRegionDirectives() const
Definition: MCAsmInfo.h:663
const char * getTPRel64Directive() const
Definition: MCAsmInfo.h:545
const char * getData32bitsDirective() const
Definition: MCAsmInfo.h:538
bool hasFourStringsDotFile() const
Definition: MCAsmInfo.h:712
unsigned getAssemblerDialect() const
Definition: MCAsmInfo.h:646
unsigned getTextAlignFillValue() const
Definition: MCAsmInfo.h:688
bool useDwarfRegNumForCFI() const
Definition: MCAsmInfo.h:770
bool supportsExtendedDwarfLocDirective() const
Definition: MCAsmInfo.h:775
const char * getData8bitsDirective() const
Definition: MCAsmInfo.h:536
const char * getTPRel32Directive() const
Definition: MCAsmInfo.h:546
const char * getData64bitsDirective() const
Definition: MCAsmInfo.h:539
AsmCharLiteralSyntax characterLiteralSyntax() const
Definition: MCAsmInfo.h:684
const char * getByteListDirective() const
Definition: MCAsmInfo.h:682
const char * getCode16Directive() const
Definition: MCAsmInfo.h:643
const char * getGPRel64Directive() const
Definition: MCAsmInfo.h:541
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const
Definition: MCAsmInfo.h:699
StringRef getCommentString() const
Definition: MCAsmInfo.h:615
const char * getAscizDirective() const
Definition: MCAsmInfo.h:681
const char * getDTPRel64Directive() const
Definition: MCAsmInfo.h:543
const char * getZeroDirective() const
Definition: MCAsmInfo.h:676
const char * getWeakDirective() const
Definition: MCAsmInfo.h:715
bool hasSubsectionsViaSymbols() const
Definition: MCAsmInfo.h:532
const char * getData16bitsDirective() const
Definition: MCAsmInfo.h:537
const char * getSeparatorString() const
Definition: MCAsmInfo.h:610
bool getCOMMDirectiveAlignmentIsInBytes() const
Definition: MCAsmInfo.h:695
bool hasPairedDoubleQuoteStringConstants() const
Definition: MCAsmInfo.h:706
bool needsDwarfSectionSizeInHeader() const
Definition: MCAsmInfo.h:783
const char * getGlobalDirective() const
Definition: MCAsmInfo.h:689
const char * getCode32Directive() const
Definition: MCAsmInfo.h:644
unsigned getCommentColumn() const
Definition: MCAsmInfo.h:612
const char * getCode64Directive() const
Definition: MCAsmInfo.h:645
bool hasSingleParameterDotFile() const
Definition: MCAsmInfo.h:711
bool doesZeroDirectiveSupportNonZeroValue() const
Definition: MCAsmInfo.h:677
const char * getAsciiDirective() const
Definition: MCAsmInfo.h:680
AsmCharLiteralSyntax
Assembly character literal syntax types.
Definition: MCAsmInfo.h:59
@ ACLS_SingleQuotePrefix
Unknown; character literals not used by LLVM for this target.
Definition: MCAsmInfo.h:62
bool useDotAlignForAlignment() const
Definition: MCAsmInfo.h:667
const char * getGPRel32Directive() const
Definition: MCAsmInfo.h:542
const char * getWeakRefDirective() const
Definition: MCAsmInfo.h:716
const char * getDTPRel32Directive() const
Definition: MCAsmInfo.h:544
bool hasNoDeadStrip() const
Definition: MCAsmInfo.h:714
bool enableDwarfFileDirectoryDefault() const
Definition: MCAsmInfo.h:787
bool usesDwarfFileAndLocDirectives() const
Definition: MCAsmInfo.h:779
bool hasIdentDirective() const
Definition: MCAsmInfo.h:713
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:518
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:622
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:412
const MCTargetOptions * getTargetOptions() const
Definition: MCContext.h:420
void setUseNamesOnTempLabels(bool Value)
Definition: MCContext.h:424
dwarf::DwarfFormat getDwarfFormat() const
Definition: MCContext.h:799
static void Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
Definition: MCDwarf.cpp:701
static void make(MCStreamer *MCOS, MCSection *Section)
Definition: MCDwarf.cpp:91
static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params)
Definition: MCDwarf.cpp:286
Expected< unsigned > tryGetFile(StringRef &Directory, StringRef &FileName, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, uint16_t DwarfVersion, unsigned FileNumber=0)
Definition: MCDwarf.cpp:602
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles() const
Definition: MCDwarf.h:433
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:40
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
static void Emit(MCStreamer *MCOS)
Definition: MCDwarf.cpp:1170
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:46
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition: MCInst.cpp:84
MCSection * getTextSection() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
This represents a section on a Mach-O system (used by Mac OS X).
StringRef getSegmentName() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:36
MCSymbol * getEndSymbol(MCContext &Ctx)
Definition: MCSection.cpp:32
StringRef getName() const
Definition: MCSection.h:130
bool hasEnded() const
Definition: MCSection.cpp:38
Streaming machine code generation interface.
Definition: MCStreamer.h:213
virtual void emitCFIGnuArgsSize(int64_t Size, SMLoc Loc={})
Definition: MCStreamer.cpp:648
virtual void emitAddrsig()
Definition: MCStreamer.h:1076
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={})
Definition: MCStreamer.cpp:506
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:387
virtual bool emitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
Definition: MCStreamer.cpp:307
virtual void finishImpl()
Streamer specific finalization.
virtual void emitDTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (64-bit DTP relative) value.
Definition: MCStreamer.cpp:194
virtual void emitCFIBKeyFrame()
Definition: MCStreamer.cpp:248
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitSyntaxDirective()
Definition: MCStreamer.cpp:903
virtual void emitWinCFIPushReg(MCRegister Register, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:909
virtual void emitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
virtual void emitGNUAttribute(unsigned Tag, unsigned Value)
Emit a .gnu_attribute directive.
Definition: MCStreamer.h:641
virtual raw_ostream & getCommentOS()
Return a raw_ostream that comments can be written to.
Definition: MCStreamer.cpp:110
virtual void emitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:828
virtual void emitBundleLock(bool AlignToEnd)
The following instructions are a bundle-locked group.
virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name)
This implements the '.loc_label Name' directive.
Definition: MCStreamer.cpp:270
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitCFINegateRAStateWithPC(SMLoc Loc={})
Definition: MCStreamer.cpp:705
virtual void emitGPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a gprel64 (64-bit GP relative) value.
Definition: MCStreamer.cpp:210
virtual void emitCFISameValue(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:618
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
virtual bool emitCVFileDirective(unsigned FileNo, StringRef Filename, ArrayRef< uint8_t > Checksum, unsigned ChecksumKind)
Associate a filename with a specified logical file number, and also specify that file's checksum info...
Definition: MCStreamer.cpp:300
virtual void emitCFIReturnColumn(int64_t Register)
Definition: MCStreamer.cpp:715
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:580
virtual void emitDwarfUnitLength(uint64_t Length, const Twine &Comment)
Emit a unit length field.
virtual void emitCFIWindowSave(SMLoc Loc={})
Definition: MCStreamer.cpp:686
virtual void emitCOFFSymbolIndex(MCSymbol const *Symbol)
Emits the symbol table index of a Symbol into the current section.
virtual void emitCVStringTableDirective()
This implements the CodeView '.cv_stringtable' assembler directive.
Definition: MCStreamer.h:978
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
Definition: MCStreamer.h:347
virtual void emitIntValueInHex(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h:715
virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName)
This implements the DWARF2 '.loc fileno lineno ...' assembler directive.
Definition: MCStreamer.cpp:262
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
Definition: MCStreamer.h:343
virtual void emitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset)
Emits a COFF image relative relocation.
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
virtual void emitWinCFIPushFrame(bool Code, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:992
virtual void emitWinEHHandlerData(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:845
virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)=0
Emit a common symbol.
virtual MCAssembler * getAssemblerPtr()
Definition: MCStreamer.h:304
virtual void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol, MCSymbolAttr Linkage, MCSymbolAttr Visibility)
Emit a symbol's linkage and visibility with a linkage directive for XCOFF.
virtual void emitCFIUndefined(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:665
virtual void emitWinCFISaveXMM(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:977
virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame)
Definition: MCStreamer.cpp:469
virtual void emitCVFileChecksumOffsetDirective(unsigned FileNo)
This implements the CodeView '.cv_filechecksumoffset' assembler directive.
Definition: MCStreamer.h:985
virtual void emitCFINegateRAState(SMLoc Loc={})
Definition: MCStreamer.cpp:695
virtual void emitGPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a gprel32 (32-bit GP relative) value.
Definition: MCStreamer.cpp:214
virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding)
Definition: MCStreamer.cpp:589
virtual void emitBundleUnlock()
Ends a bundle-locked group.
virtual Expected< unsigned > tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt, unsigned CUID=0)
Associate a filename with a specified logical file number.
Definition: MCStreamer.cpp:231
virtual void addExplicitComment(const Twine &T)
Add explicit comment T.
Definition: MCStreamer.cpp:122
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:366
virtual void emitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc={})
This implements the CodeView '.cv_fpo_data' assembler directive.
Definition: MCStreamer.h:988
virtual void emitELFSize(MCSymbol *Symbol, const MCExpr *Value)
Emit an ELF .size directive.
virtual void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size, MCSymbol *CsectSym, Align Alignment)
Emits an lcomm directive with XCOFF csect information.
virtual void emitCFIMTETaggedFrame()
Definition: MCStreamer.cpp:255
virtual void emitTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (32-bit TP relative) value.
Definition: MCStreamer.cpp:206
virtual void emitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
virtual void doFinalizationAtSectionEnd(MCSection *Section)
Do finalization for the streamer at the end of a section.
Definition: MCStreamer.h:1142
virtual void emitRawComment(const Twine &T, bool TabPrefix=true)
Print T and prefix it with the comment string (normally #) and optionally a tab.
Definition: MCStreamer.cpp:120
virtual std::optional< std::pair< bool, std::string > > emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc, const MCSubtargetInfo &STI)
Record a relocation described by the .reloc directive.
Definition: MCStreamer.h:1071
virtual void emitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:754
virtual void emitIdent(StringRef IdentString)
Emit the "identifiers" directive.
Definition: MCStreamer.h:878
virtual StringRef getMnemonic(const MCInst &MI) const
Returns the mnemonic for MI, if the streamer has access to a instruction printer and returns an empty...
Definition: MCStreamer.h:446
virtual void emitCVFileChecksumsDirective()
This implements the CodeView '.cv_filechecksums' assembler directive.
Definition: MCStreamer.h:981
virtual void emitDwarfLineStartLabel(MCSymbol *StartSym)
Emit the debug line start label.
virtual void emitCFIEscape(StringRef Values, SMLoc Loc={})
Definition: MCStreamer.cpp:638
virtual void emitXCOFFExceptDirective(const MCSymbol *Symbol, const MCSymbol *Trap, unsigned Lang, unsigned Reason, unsigned FunctionSize, bool hasDebug)
Emit an XCOFF .except directive which adds information about a trap instruction to the object file ex...
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:420
virtual void emitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
void setAllowAutoPadding(bool v)
Definition: MCStreamer.h:313
virtual void emitCFIRememberState(SMLoc Loc)
Definition: MCStreamer.cpp:597
virtual void emitCFILabelDirective(SMLoc Loc, StringRef Name)
Definition: MCStreamer.cpp:722
virtual void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
Definition: MCStreamer.cpp:352
virtual void emitTPRel64Value(const MCExpr *Value)
Emit the expression Value into the output as a tprel (64-bit TP relative) value.
Definition: MCStreamer.cpp:202
virtual void emitCFISections(bool EH, bool Debug)
Definition: MCStreamer.cpp:442
virtual void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers & p...
Definition: MCStreamer.h:727
virtual void emitAssemblerFlag(MCAssemblerFlag Flag)
Note in the output the specified Flag.
virtual void emitDarwinTargetVariantBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Definition: MCStreamer.h:483
virtual void emitValueToAlignment(Align Alignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:133
virtual void emitWinCFISaveReg(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:960
virtual void emitWinCFIEndChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:814
virtual void emitWinCFIEndProlog(SMLoc Loc=SMLoc())
virtual void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
If targets does not support representing debug line section by .loc/.file directives in assembly outp...
Definition: MCStreamer.h:1136
virtual void emitWinCFIEndProc(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:772
virtual void emitCodeAlignment(Align Alignment, const MCSubtargetInfo *STI, unsigned MaxBytesToEmit=0)
Emit nops until the byte alignment ByteAlignment is reached.
virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame)
Definition: MCStreamer.cpp:480
virtual void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue)
Set the DescValue for the Symbol.
virtual void emitCFIDefCfaRegister(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:537
virtual void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment)
Emit a local common (.lcomm) symbol.
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
Definition: MCStreamer.cpp:276
virtual void emitCFIRegister(int64_t Register1, int64_t Register2, SMLoc Loc={})
Definition: MCStreamer.cpp:675
virtual void emitCOFFSafeSEH(MCSymbol const *Symbol)
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...
Definition: MCStreamer.cpp:790
virtual void emitXCOFFRenameDirective(const MCSymbol *Name, StringRef Rename)
Emit a XCOFF .rename directive which creates a synonym for an illegal or undesirable name.
virtual void emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type, uint64_t Attr, uint64_t Discriminator, const MCPseudoProbeInlineStack &InlineStack, MCSymbol *FnSym)
Emit the a pseudo probe into the current section.
virtual void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count)
Definition: MCStreamer.cpp:853
virtual void emitDataRegion(MCDataRegionType Kind)
Note in the output the specified region Kind.
Definition: MCStreamer.h:470
virtual void emitCFIAdjustCfaOffset(int64_t Adjustment, SMLoc Loc={})
Definition: MCStreamer.cpp:527
virtual void emitULEB128Value(const MCExpr *Value)
virtual void emitCFIRelOffset(int64_t Register, int64_t Offset, SMLoc Loc)
Definition: MCStreamer.cpp:570
virtual void emitLinkerOptions(ArrayRef< std::string > Kind)
Emit the given list Options of strings as linker options into the output.
Definition: MCStreamer.h:467
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value, SMLoc Loc)
Emit some number of copies of Value until the byte offset Offset is reached.
virtual void emitExplicitComments()
Emit added explicit comments.
Definition: MCStreamer.cpp:123
virtual void emitThumbFunc(MCSymbol *Func)
Note in the output that the specified Func is a Thumb mode function (ARM target only).
virtual void emitCFIRestoreState(SMLoc Loc)
Definition: MCStreamer.cpp:607
virtual void emitXCOFFRefDirective(const MCSymbol *Symbol)
Emit a XCOFF .ref directive which creates R_REF type entry in the relocation table for one or more sy...
virtual void emitCVDefRangeDirective(ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > Ranges, StringRef FixedSizePortion)
This implements the CodeView '.cv_def_range' assembler directive.
Definition: MCStreamer.cpp:374
virtual void emitCFIOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:560
virtual void emitWinCFISetFrame(MCRegister Register, unsigned Offset, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:921
virtual void emitDTPRel32Value(const MCExpr *Value)
Emit the expression Value into the output as a dtprel (32-bit DTP relative) value.
Definition: MCStreamer.cpp:198
virtual void emitCFIDefCfaOffset(int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:517
virtual void emitZerofill(MCSection *Section, MCSymbol *Symbol=nullptr, uint64_t Size=0, Align ByteAlignment=Align(1), SMLoc Loc=SMLoc())=0
Emit the zerofill section and an optional symbol.
virtual void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc)
This implements the CodeView '.cv_loc' assembler directive.
Definition: MCStreamer.cpp:325
virtual void emitWinCFIAllocStack(unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:943
virtual void emitFileDirective(StringRef Filename)
Switch to a new logical file.
virtual void emitSLEB128Value(const MCExpr *Value)
virtual void emitCFIValOffset(int64_t Register, int64_t Offset, SMLoc Loc={})
Definition: MCStreamer.cpp:729
virtual void emitELFSymverDirective(const MCSymbol *OriginalSym, StringRef Name, bool KeepOriginalSym)
Emit an ELF .symver directive.
virtual void emitXCOFFCInfoSym(StringRef Name, StringRef Metadata)
Emit a C_INFO symbol with XCOFF embedded metadata to the .info section.
virtual void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Emit the expression Value into the output as a native integer of the given Size bytes.
virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, MCSymbol *EndLabel=nullptr)
Emit the debug line end entry.
Definition: MCStreamer.h:1130
virtual void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args)
Emit a Linker Optimization Hint (LOH) directive.
Definition: MCStreamer.h:638
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.
Definition: MCStreamer.cpp:311
virtual void emitCFISignalFrame()
Definition: MCStreamer.cpp:658
virtual void emitVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Specify the Mach-O minimum deployment target version.
Definition: MCStreamer.h:473
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
virtual void emitConditionalAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol, but only if Value is also emitted.
Definition: MCStreamer.cpp:439
virtual void emitWinCFIStartChained(SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:801
virtual void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, Align ByteAlignment=Align(1))
Emit a thread local bss (.tbss) symbol.
virtual void emitCFIRestore(int64_t Register, SMLoc Loc={})
Definition: MCStreamer.cpp:628
virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
This implements the CodeView '.cv_inline_linetable' assembler directive.
Definition: MCStreamer.cpp:356
void emitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
Definition: MCStreamer.cpp:220
virtual void emitBundleAlignMode(Align Alignment)
Set the bundle alignment mode from now on in the section.
virtual void emitRawTextImpl(StringRef String)
EmitRawText - If this file is backed by an assembly streamer, this dumps the specified string in the ...
virtual void emitBytes(StringRef Data)
Emit the bytes in Data into the output.
virtual void emitAddrsigSym(const MCSymbol *Sym)
Definition: MCStreamer.h:1077
virtual void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol)
Emit an weak reference from Alias to Symbol.
virtual void emitDwarfFile0Directive(StringRef Directory, StringRef Filename, std::optional< MD5::MD5Result > Checksum, std::optional< StringRef > Source, unsigned CUID=0)
Specify the "root" file of the compilation, using the ".file 0" extension.
Definition: MCStreamer.cpp:239
virtual void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
Emit/Specify Mach-O build version command.
Definition: MCStreamer.h:479
virtual void changeSection(MCSection *, uint32_t)
This is called by popSection and switchSection, if the current section changes.
virtual void emitCFILLVMDefAspaceCfa(int64_t Register, int64_t Offset, int64_t AddressSpace, SMLoc Loc={})
Definition: MCStreamer.cpp:548
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:411
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
StringRef getSymbolTableName() const
Definition: MCSymbolXCOFF.h:68
bool hasRename() const
Definition: MCSymbolXCOFF.h:61
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:269
Target specific streamer interface.
Definition: MCStreamer.h:94
Root of the metadata hierarchy.
Definition: Metadata.h:62
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
void append(StringRef RHS)
Append from a StringRef.
Definition: SmallString.h:68
bool empty() const
Definition: SmallVector.h:81
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void resize(size_type N)
Definition: SmallVector.h:638
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:571
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:265
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
char back() const
back - Get the last character in the string.
Definition: StringRef.h:159
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:684
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
char front() const
front - Get the first character in the string.
Definition: StringRef.h:153
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.
Definition: StringRef.h:377
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:297
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:5061
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
unsigned getMajor() const
Retrieve the major version number.
Definition: VersionTuple.h:71
std::optional< unsigned > getSubminor() const
Retrieve the subminor version number, if provided.
Definition: VersionTuple.h:81
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero).
Definition: VersionTuple.h:66
std::optional< unsigned > getMinor() const
Retrieve the minor version number, if provided.
Definition: VersionTuple.h:74
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
A raw_ostream that discards all output.
Definition: raw_ostream.h:731
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
size_t GetNumBytesInBuffer() const
Definition: raw_ostream.h:190
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:691
This class represents a function that is read from a sample profile.
Definition: FunctionId.h:36
#define INT64_MAX
Definition: DataTypes.h:71
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ ByteAlignment
Definition: MCAsmInfo.h:50
@ Log2Alignment
Definition: MCAsmInfo.h:50
PlatformType
Definition: MachO.h:500
StorageClass
Definition: XCOFF.h:170
uint8_t getUnitLengthFieldByteSize(DwarfFormat Format)
Get the byte size of the unit length field depending on the DWARF format.
Definition: Dwarf.h:1110
support::ulittle32_t Word
Definition: IRSymtab.h:52
@ ChecksumKind
Definition: LLToken.h:492
int getDwarfVersion()
@ Emitted
Assigned address, still materializing.
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
NodeAddr< CodeNode * > Code
Definition: RDFGraph.h:388
uint32_t read32be(const void *P)
Definition: Endian.h:434
bool isPrint(int c)
Definition: Locale.cpp:13
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:671
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:456
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
@ Length
Definition: DWP.cpp:480
MCStreamer * createAsmStreamer(MCContext &Ctx, std::unique_ptr< formatted_raw_ostream > OS, 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,...
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.)
Definition: MathExtras.h:296
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:346
MCDataRegionType
Definition: MCDirectives.h:61
@ MCDR_DataRegionEnd
.end_data_region
Definition: MCDirectives.h:66
@ MCDR_DataRegion
.data_region
Definition: MCDirectives.h:62
@ MCDR_DataRegionJT8
.data_region jt8
Definition: MCDirectives.h:63
@ MCDR_DataRegionJT32
.data_region jt32
Definition: MCDirectives.h:65
@ MCDR_DataRegionJT16
.data_region jt16
Definition: MCDirectives.h:64
MCVersionMinType
Definition: MCDirectives.h:69
@ MCVM_WatchOSVersionMin
.watchos_version_min
Definition: MCDirectives.h:73
@ MCVM_OSXVersionMin
.macosx_version_min
Definition: MCDirectives.h:71
@ MCVM_TvOSVersionMin
.tvos_version_min
Definition: MCDirectives.h:72
@ MCVM_IOSVersionMin
.ios_version_min
Definition: MCDirectives.h:70
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
raw_ostream & nulls()
This returns a reference to a raw_ostream which simply discards output.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:187
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
static int MCLOHIdToNbArgs(MCLOHType Kind)
MCAssemblerFlag
Definition: MCDirectives.h:53
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:54
@ MCAF_Code64
.code64 (X86)
Definition: MCDirectives.h:58
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:56
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:57
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:55
MCLOHType
Linker Optimization Hint Type.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
unsigned Log2(Align A)
Returns the log2 of the alignment.
Definition: Alignment.h:208
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:38
@ MCSA_WeakDefAutoPrivate
.weak_def_can_be_hidden (MachO)
Definition: MCDirectives.h:48
@ MCSA_Memtag
.memtag (ELF)
Definition: MCDirectives.h:50
@ MCSA_Protected
.protected (ELF)
Definition: MCDirectives.h:43
@ MCSA_Exported
.globl _foo, exported (XCOFF)
Definition: MCDirectives.h:34
@ MCSA_PrivateExtern
.private_extern (MachO)
Definition: MCDirectives.h:42
@ MCSA_Internal
.internal (ELF)
Definition: MCDirectives.h:36
@ MCSA_WeakReference
.weak_reference (MachO)
Definition: MCDirectives.h:47
@ MCSA_AltEntry
.alt_entry (MachO)
Definition: MCDirectives.h:41
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
Definition: MCDirectives.h:24
@ MCSA_LazyReference
.lazy_reference (MachO)
Definition: MCDirectives.h:37
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
Definition: MCDirectives.h:28
@ MCSA_Reference
.reference (MachO)
Definition: MCDirectives.h:44
@ MCSA_SymbolResolver
.symbol_resolver (MachO)
Definition: MCDirectives.h:40
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
Definition: MCDirectives.h:26
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
Definition: MCDirectives.h:35
@ MCSA_WeakDefinition
.weak_definition (MachO)
Definition: MCDirectives.h:46
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
Definition: MCDirectives.h:27
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
Definition: MCDirectives.h:49
@ MCSA_Extern
.extern (XCOFF)
Definition: MCDirectives.h:32
@ MCSA_Cold
.cold (MachO)
Definition: MCDirectives.h:22
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
Definition: MCDirectives.h:25
@ MCSA_ELF_TypeGnuUniqueObject
Definition: MCDirectives.h:29
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
@ MCSA_LGlobal
.lglobl (XCOFF)
Definition: MCDirectives.h:31
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
@ MCSA_NoDeadStrip
.no_dead_strip (MachO)
Definition: MCDirectives.h:39
static StringRef MCLOHIdToName(MCLOHType Kind)
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Target independent information on a fixup kind.
const MCSymbol * Function
Definition: MCWinEH.h:44