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