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