MCAsmStreamer.cpp 85 KB

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