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