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