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