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