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