1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/MC/MCStreamer.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16 #include "llvm/MC/MCAsmBackend.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCCodeView.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCDwarf.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstPrinter.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCPseudoProbe.h"
26 #include "llvm/MC/MCRegister.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCSection.h"
29 #include "llvm/MC/MCSectionCOFF.h"
30 #include "llvm/MC/MCSymbol.h"
31 #include "llvm/MC/MCWin64EH.h"
32 #include "llvm/MC/MCWinEH.h"
33 #include "llvm/Support/Casting.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/LEB128.h"
36 #include "llvm/Support/MathExtras.h"
37 #include "llvm/Support/raw_ostream.h"
38 #include <cassert>
39 #include <cstdint>
40 #include <cstdlib>
41 #include <utility>
42
43 using namespace llvm;
44
MCTargetStreamer(MCStreamer & S)45 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
46 S.setTargetStreamer(this);
47 }
48
49 // Pin the vtables to this file.
50 MCTargetStreamer::~MCTargetStreamer() = default;
51
emitLabel(MCSymbol * Symbol)52 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
53
finish()54 void MCTargetStreamer::finish() {}
55
changeSection(const MCSection * CurSection,MCSection * Section,const MCExpr * Subsection,raw_ostream & OS)56 void MCTargetStreamer::changeSection(const MCSection *CurSection,
57 MCSection *Section,
58 const MCExpr *Subsection,
59 raw_ostream &OS) {
60 Section->PrintSwitchToSection(
61 *Streamer.getContext().getAsmInfo(),
62 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
63 Subsection);
64 }
65
emitDwarfFileDirective(StringRef Directive)66 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
67 Streamer.emitRawText(Directive);
68 }
69
emitValue(const MCExpr * Value)70 void MCTargetStreamer::emitValue(const MCExpr *Value) {
71 SmallString<128> Str;
72 raw_svector_ostream OS(Str);
73
74 Value->print(OS, Streamer.getContext().getAsmInfo());
75 Streamer.emitRawText(OS.str());
76 }
77
emitRawBytes(StringRef Data)78 void MCTargetStreamer::emitRawBytes(StringRef Data) {
79 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
80 const char *Directive = MAI->getData8bitsDirective();
81 for (const unsigned char C : Data.bytes()) {
82 SmallString<128> Str;
83 raw_svector_ostream OS(Str);
84
85 OS << Directive << (unsigned)C;
86 Streamer.emitRawText(OS.str());
87 }
88 }
89
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)90 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
91
MCStreamer(MCContext & Ctx)92 MCStreamer::MCStreamer(MCContext &Ctx)
93 : Context(Ctx), CurrentWinFrameInfo(nullptr),
94 CurrentProcWinFrameInfoStartIndex(0), UseAssemblerInfoForParsing(false) {
95 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
96 }
97
~MCStreamer()98 MCStreamer::~MCStreamer() {}
99
reset()100 void MCStreamer::reset() {
101 DwarfFrameInfos.clear();
102 CurrentWinFrameInfo = nullptr;
103 WinFrameInfos.clear();
104 SymbolOrdering.clear();
105 SectionStack.clear();
106 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
107 }
108
GetCommentOS()109 raw_ostream &MCStreamer::GetCommentOS() {
110 // By default, discard comments.
111 return nulls();
112 }
113
getNumFrameInfos()114 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
getDwarfFrameInfos() const115 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
116 return DwarfFrameInfos;
117 }
118
emitRawComment(const Twine & T,bool TabPrefix)119 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
120
addExplicitComment(const Twine & T)121 void MCStreamer::addExplicitComment(const Twine &T) {}
emitExplicitComments()122 void MCStreamer::emitExplicitComments() {}
123
generateCompactUnwindEncodings(MCAsmBackend * MAB)124 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
125 for (auto &FI : DwarfFrameInfos)
126 FI.CompactUnwindEncoding =
127 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
128 }
129
130 /// EmitIntValue - Special case of EmitValue that avoids the client having to
131 /// pass in a MCExpr for constant integers.
emitIntValue(uint64_t Value,unsigned Size)132 void MCStreamer::emitIntValue(uint64_t Value, unsigned Size) {
133 assert(1 <= Size && Size <= 8 && "Invalid size");
134 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
135 "Invalid size");
136 const bool IsLittleEndian = Context.getAsmInfo()->isLittleEndian();
137 uint64_t Swapped = support::endian::byte_swap(
138 Value, IsLittleEndian ? support::little : support::big);
139 unsigned Index = IsLittleEndian ? 0 : 8 - Size;
140 emitBytes(StringRef(reinterpret_cast<char *>(&Swapped) + Index, Size));
141 }
emitIntValue(APInt Value)142 void MCStreamer::emitIntValue(APInt Value) {
143 if (Value.getNumWords() == 1) {
144 emitIntValue(Value.getLimitedValue(), Value.getBitWidth() / 8);
145 return;
146 }
147
148 const bool IsLittleEndianTarget = Context.getAsmInfo()->isLittleEndian();
149 const bool ShouldSwap = sys::IsLittleEndianHost != IsLittleEndianTarget;
150 const APInt Swapped = ShouldSwap ? Value.byteSwap() : Value;
151 const unsigned Size = Value.getBitWidth() / 8;
152 SmallString<10> Tmp;
153 Tmp.resize(Size);
154 StoreIntToMemory(Swapped, reinterpret_cast<uint8_t *>(Tmp.data()), Size);
155 emitBytes(Tmp.str());
156 }
157
158 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
159 /// client having to pass in a MCExpr for constant integers.
emitULEB128IntValue(uint64_t Value,unsigned PadTo)160 void MCStreamer::emitULEB128IntValue(uint64_t Value, unsigned PadTo) {
161 SmallString<128> Tmp;
162 raw_svector_ostream OSE(Tmp);
163 encodeULEB128(Value, OSE, PadTo);
164 emitBytes(OSE.str());
165 }
166
167 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
168 /// client having to pass in a MCExpr for constant integers.
emitSLEB128IntValue(int64_t Value)169 void MCStreamer::emitSLEB128IntValue(int64_t Value) {
170 SmallString<128> Tmp;
171 raw_svector_ostream OSE(Tmp);
172 encodeSLEB128(Value, OSE);
173 emitBytes(OSE.str());
174 }
175
emitValue(const MCExpr * Value,unsigned Size,SMLoc Loc)176 void MCStreamer::emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
177 emitValueImpl(Value, Size, Loc);
178 }
179
emitSymbolValue(const MCSymbol * Sym,unsigned Size,bool IsSectionRelative)180 void MCStreamer::emitSymbolValue(const MCSymbol *Sym, unsigned Size,
181 bool IsSectionRelative) {
182 assert((!IsSectionRelative || Size == 4) &&
183 "SectionRelative value requires 4-bytes");
184
185 if (!IsSectionRelative)
186 emitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
187 else
188 EmitCOFFSecRel32(Sym, /*Offset=*/0);
189 }
190
emitDTPRel64Value(const MCExpr * Value)191 void MCStreamer::emitDTPRel64Value(const MCExpr *Value) {
192 report_fatal_error("unsupported directive in streamer");
193 }
194
emitDTPRel32Value(const MCExpr * Value)195 void MCStreamer::emitDTPRel32Value(const MCExpr *Value) {
196 report_fatal_error("unsupported directive in streamer");
197 }
198
emitTPRel64Value(const MCExpr * Value)199 void MCStreamer::emitTPRel64Value(const MCExpr *Value) {
200 report_fatal_error("unsupported directive in streamer");
201 }
202
emitTPRel32Value(const MCExpr * Value)203 void MCStreamer::emitTPRel32Value(const MCExpr *Value) {
204 report_fatal_error("unsupported directive in streamer");
205 }
206
emitGPRel64Value(const MCExpr * Value)207 void MCStreamer::emitGPRel64Value(const MCExpr *Value) {
208 report_fatal_error("unsupported directive in streamer");
209 }
210
emitGPRel32Value(const MCExpr * Value)211 void MCStreamer::emitGPRel32Value(const MCExpr *Value) {
212 report_fatal_error("unsupported directive in streamer");
213 }
214
215 /// Emit NumBytes bytes worth of the value specified by FillValue.
216 /// This implements directives such as '.space'.
emitFill(uint64_t NumBytes,uint8_t FillValue)217 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
218 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
219 }
220
emitNops(int64_t NumBytes,int64_t ControlledNopLen,llvm::SMLoc)221 void llvm::MCStreamer::emitNops(int64_t NumBytes, int64_t ControlledNopLen,
222 llvm::SMLoc) {}
223
224 /// The implementation in this class just redirects to emitFill.
emitZeros(uint64_t NumBytes)225 void MCStreamer::emitZeros(uint64_t NumBytes) { emitFill(NumBytes, 0); }
226
227 Expected<unsigned>
tryEmitDwarfFileDirective(unsigned FileNo,StringRef Directory,StringRef Filename,Optional<MD5::MD5Result> Checksum,Optional<StringRef> Source,unsigned CUID)228 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
229 StringRef Filename,
230 Optional<MD5::MD5Result> Checksum,
231 Optional<StringRef> Source,
232 unsigned CUID) {
233 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
234 Source, CUID);
235 }
236
emitDwarfFile0Directive(StringRef Directory,StringRef Filename,Optional<MD5::MD5Result> Checksum,Optional<StringRef> Source,unsigned CUID)237 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
238 StringRef Filename,
239 Optional<MD5::MD5Result> Checksum,
240 Optional<StringRef> Source,
241 unsigned CUID) {
242 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
243 Source);
244 }
245
emitCFIBKeyFrame()246 void MCStreamer::emitCFIBKeyFrame() {
247 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
248 if (!CurFrame)
249 return;
250 CurFrame->IsBKeyFrame = true;
251 }
252
emitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)253 void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
254 unsigned Column, unsigned Flags,
255 unsigned Isa, unsigned Discriminator,
256 StringRef FileName) {
257 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
258 Discriminator);
259 }
260
getDwarfLineTableSymbol(unsigned CUID)261 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
262 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
263 if (!Table.getLabel()) {
264 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
265 Table.setLabel(
266 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
267 }
268 return Table.getLabel();
269 }
270
hasUnfinishedDwarfFrameInfo()271 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
272 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
273 }
274
getCurrentDwarfFrameInfo()275 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
276 if (!hasUnfinishedDwarfFrameInfo()) {
277 getContext().reportError(getStartTokLoc(),
278 "this directive must appear between "
279 ".cfi_startproc and .cfi_endproc directives");
280 return nullptr;
281 }
282 return &DwarfFrameInfos.back();
283 }
284
EmitCVFileDirective(unsigned FileNo,StringRef Filename,ArrayRef<uint8_t> Checksum,unsigned ChecksumKind)285 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
286 ArrayRef<uint8_t> Checksum,
287 unsigned ChecksumKind) {
288 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
289 ChecksumKind);
290 }
291
EmitCVFuncIdDirective(unsigned FunctionId)292 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
293 return getContext().getCVContext().recordFunctionId(FunctionId);
294 }
295
EmitCVInlineSiteIdDirective(unsigned FunctionId,unsigned IAFunc,unsigned IAFile,unsigned IALine,unsigned IACol,SMLoc Loc)296 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
297 unsigned IAFunc, unsigned IAFile,
298 unsigned IALine, unsigned IACol,
299 SMLoc Loc) {
300 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
301 getContext().reportError(Loc, "parent function id not introduced by "
302 ".cv_func_id or .cv_inline_site_id");
303 return true;
304 }
305
306 return getContext().getCVContext().recordInlinedCallSiteId(
307 FunctionId, IAFunc, IAFile, IALine, IACol);
308 }
309
emitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)310 void MCStreamer::emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
311 unsigned Line, unsigned Column,
312 bool PrologueEnd, bool IsStmt,
313 StringRef FileName, SMLoc Loc) {}
314
checkCVLocSection(unsigned FuncId,unsigned FileNo,SMLoc Loc)315 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
316 SMLoc Loc) {
317 CodeViewContext &CVC = getContext().getCVContext();
318 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
319 if (!FI) {
320 getContext().reportError(
321 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
322 return false;
323 }
324
325 // Track the section
326 if (FI->Section == nullptr)
327 FI->Section = getCurrentSectionOnly();
328 else if (FI->Section != getCurrentSectionOnly()) {
329 getContext().reportError(
330 Loc,
331 "all .cv_loc directives for a function must be in the same section");
332 return false;
333 }
334 return true;
335 }
336
emitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)337 void MCStreamer::emitCVLinetableDirective(unsigned FunctionId,
338 const MCSymbol *Begin,
339 const MCSymbol *End) {}
340
emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)341 void MCStreamer::emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
342 unsigned SourceFileId,
343 unsigned SourceLineNum,
344 const MCSymbol *FnStartSym,
345 const MCSymbol *FnEndSym) {}
346
347 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
348 /// structs composed of them.
349 template <typename T>
copyBytesForDefRange(SmallString<20> & BytePrefix,codeview::SymbolKind SymKind,const T & DefRangeHeader)350 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
351 codeview::SymbolKind SymKind,
352 const T &DefRangeHeader) {
353 BytePrefix.resize(2 + sizeof(T));
354 codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
355 memcpy(&BytePrefix[0], &SymKindLE, 2);
356 memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
357 }
358
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)359 void MCStreamer::emitCVDefRangeDirective(
360 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
361 StringRef FixedSizePortion) {}
362
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterRelHeader DRHdr)363 void MCStreamer::emitCVDefRangeDirective(
364 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
365 codeview::DefRangeRegisterRelHeader DRHdr) {
366 SmallString<20> BytePrefix;
367 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
368 emitCVDefRangeDirective(Ranges, BytePrefix);
369 }
370
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeSubfieldRegisterHeader DRHdr)371 void MCStreamer::emitCVDefRangeDirective(
372 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
373 codeview::DefRangeSubfieldRegisterHeader DRHdr) {
374 SmallString<20> BytePrefix;
375 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
376 DRHdr);
377 emitCVDefRangeDirective(Ranges, BytePrefix);
378 }
379
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterHeader DRHdr)380 void MCStreamer::emitCVDefRangeDirective(
381 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
382 codeview::DefRangeRegisterHeader DRHdr) {
383 SmallString<20> BytePrefix;
384 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
385 emitCVDefRangeDirective(Ranges, BytePrefix);
386 }
387
emitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeFramePointerRelHeader DRHdr)388 void MCStreamer::emitCVDefRangeDirective(
389 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
390 codeview::DefRangeFramePointerRelHeader DRHdr) {
391 SmallString<20> BytePrefix;
392 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
393 DRHdr);
394 emitCVDefRangeDirective(Ranges, BytePrefix);
395 }
396
emitEHSymAttributes(const MCSymbol * Symbol,MCSymbol * EHSymbol)397 void MCStreamer::emitEHSymAttributes(const MCSymbol *Symbol,
398 MCSymbol *EHSymbol) {
399 }
400
InitSections(bool NoExecStack)401 void MCStreamer::InitSections(bool NoExecStack) {
402 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
403 }
404
AssignFragment(MCSymbol * Symbol,MCFragment * Fragment)405 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
406 assert(Fragment);
407 Symbol->setFragment(Fragment);
408
409 // As we emit symbols into a section, track the order so that they can
410 // be sorted upon later. Zero is reserved to mean 'unemitted'.
411 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
412 }
413
emitLabel(MCSymbol * Symbol,SMLoc Loc)414 void MCStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
415 Symbol->redefineIfPossible();
416
417 if (!Symbol->isUndefined() || Symbol->isVariable())
418 return getContext().reportError(Loc, "invalid symbol redefinition");
419
420 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
421 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
422 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
423 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
424
425 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
426
427 MCTargetStreamer *TS = getTargetStreamer();
428 if (TS)
429 TS->emitLabel(Symbol);
430 }
431
emitCFISections(bool EH,bool Debug)432 void MCStreamer::emitCFISections(bool EH, bool Debug) {
433 assert(EH || Debug);
434 }
435
emitCFIStartProc(bool IsSimple,SMLoc Loc)436 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
437 if (hasUnfinishedDwarfFrameInfo())
438 return getContext().reportError(
439 Loc, "starting new .cfi frame before finishing the previous one");
440
441 MCDwarfFrameInfo Frame;
442 Frame.IsSimple = IsSimple;
443 emitCFIStartProcImpl(Frame);
444
445 const MCAsmInfo* MAI = Context.getAsmInfo();
446 if (MAI) {
447 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
448 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
449 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
450 Frame.CurrentCfaRegister = Inst.getRegister();
451 }
452 }
453 }
454
455 DwarfFrameInfos.push_back(Frame);
456 }
457
emitCFIStartProcImpl(MCDwarfFrameInfo & Frame)458 void MCStreamer::emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
459 }
460
emitCFIEndProc()461 void MCStreamer::emitCFIEndProc() {
462 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
463 if (!CurFrame)
464 return;
465 emitCFIEndProcImpl(*CurFrame);
466 }
467
emitCFIEndProcImpl(MCDwarfFrameInfo & Frame)468 void MCStreamer::emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
469 // Put a dummy non-null value in Frame.End to mark that this frame has been
470 // closed.
471 Frame.End = (MCSymbol *)1;
472 }
473
emitCFILabel()474 MCSymbol *MCStreamer::emitCFILabel() {
475 // Return a dummy non-null value so that label fields appear filled in when
476 // generating textual assembly.
477 return (MCSymbol *)1;
478 }
479
emitCFIDefCfa(int64_t Register,int64_t Offset)480 void MCStreamer::emitCFIDefCfa(int64_t Register, int64_t Offset) {
481 MCSymbol *Label = emitCFILabel();
482 MCCFIInstruction Instruction =
483 MCCFIInstruction::cfiDefCfa(Label, Register, Offset);
484 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
485 if (!CurFrame)
486 return;
487 CurFrame->Instructions.push_back(Instruction);
488 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
489 }
490
emitCFIDefCfaOffset(int64_t Offset)491 void MCStreamer::emitCFIDefCfaOffset(int64_t Offset) {
492 MCSymbol *Label = emitCFILabel();
493 MCCFIInstruction Instruction =
494 MCCFIInstruction::cfiDefCfaOffset(Label, Offset);
495 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
496 if (!CurFrame)
497 return;
498 CurFrame->Instructions.push_back(Instruction);
499 }
500
emitCFIAdjustCfaOffset(int64_t Adjustment)501 void MCStreamer::emitCFIAdjustCfaOffset(int64_t Adjustment) {
502 MCSymbol *Label = emitCFILabel();
503 MCCFIInstruction Instruction =
504 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
505 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
506 if (!CurFrame)
507 return;
508 CurFrame->Instructions.push_back(Instruction);
509 }
510
emitCFIDefCfaRegister(int64_t Register)511 void MCStreamer::emitCFIDefCfaRegister(int64_t Register) {
512 MCSymbol *Label = emitCFILabel();
513 MCCFIInstruction Instruction =
514 MCCFIInstruction::createDefCfaRegister(Label, Register);
515 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
516 if (!CurFrame)
517 return;
518 CurFrame->Instructions.push_back(Instruction);
519 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
520 }
521
emitCFIOffset(int64_t Register,int64_t Offset)522 void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
523 MCSymbol *Label = emitCFILabel();
524 MCCFIInstruction Instruction =
525 MCCFIInstruction::createOffset(Label, Register, Offset);
526 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
527 if (!CurFrame)
528 return;
529 CurFrame->Instructions.push_back(Instruction);
530 }
531
emitCFIRelOffset(int64_t Register,int64_t Offset)532 void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
533 MCSymbol *Label = emitCFILabel();
534 MCCFIInstruction Instruction =
535 MCCFIInstruction::createRelOffset(Label, Register, Offset);
536 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
537 if (!CurFrame)
538 return;
539 CurFrame->Instructions.push_back(Instruction);
540 }
541
emitCFIPersonality(const MCSymbol * Sym,unsigned Encoding)542 void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
543 unsigned Encoding) {
544 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
545 if (!CurFrame)
546 return;
547 CurFrame->Personality = Sym;
548 CurFrame->PersonalityEncoding = Encoding;
549 }
550
emitCFILsda(const MCSymbol * Sym,unsigned Encoding)551 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
552 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
553 if (!CurFrame)
554 return;
555 CurFrame->Lsda = Sym;
556 CurFrame->LsdaEncoding = Encoding;
557 }
558
emitCFIRememberState()559 void MCStreamer::emitCFIRememberState() {
560 MCSymbol *Label = emitCFILabel();
561 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
562 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
563 if (!CurFrame)
564 return;
565 CurFrame->Instructions.push_back(Instruction);
566 }
567
emitCFIRestoreState()568 void MCStreamer::emitCFIRestoreState() {
569 // FIXME: Error if there is no matching cfi_remember_state.
570 MCSymbol *Label = emitCFILabel();
571 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
572 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
573 if (!CurFrame)
574 return;
575 CurFrame->Instructions.push_back(Instruction);
576 }
577
emitCFISameValue(int64_t Register)578 void MCStreamer::emitCFISameValue(int64_t Register) {
579 MCSymbol *Label = emitCFILabel();
580 MCCFIInstruction Instruction =
581 MCCFIInstruction::createSameValue(Label, Register);
582 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
583 if (!CurFrame)
584 return;
585 CurFrame->Instructions.push_back(Instruction);
586 }
587
emitCFIRestore(int64_t Register)588 void MCStreamer::emitCFIRestore(int64_t Register) {
589 MCSymbol *Label = emitCFILabel();
590 MCCFIInstruction Instruction =
591 MCCFIInstruction::createRestore(Label, Register);
592 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
593 if (!CurFrame)
594 return;
595 CurFrame->Instructions.push_back(Instruction);
596 }
597
emitCFIEscape(StringRef Values)598 void MCStreamer::emitCFIEscape(StringRef Values) {
599 MCSymbol *Label = emitCFILabel();
600 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
601 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
602 if (!CurFrame)
603 return;
604 CurFrame->Instructions.push_back(Instruction);
605 }
606
emitCFIGnuArgsSize(int64_t Size)607 void MCStreamer::emitCFIGnuArgsSize(int64_t Size) {
608 MCSymbol *Label = emitCFILabel();
609 MCCFIInstruction Instruction =
610 MCCFIInstruction::createGnuArgsSize(Label, Size);
611 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
612 if (!CurFrame)
613 return;
614 CurFrame->Instructions.push_back(Instruction);
615 }
616
emitCFISignalFrame()617 void MCStreamer::emitCFISignalFrame() {
618 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
619 if (!CurFrame)
620 return;
621 CurFrame->IsSignalFrame = true;
622 }
623
emitCFIUndefined(int64_t Register)624 void MCStreamer::emitCFIUndefined(int64_t Register) {
625 MCSymbol *Label = emitCFILabel();
626 MCCFIInstruction Instruction =
627 MCCFIInstruction::createUndefined(Label, Register);
628 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
629 if (!CurFrame)
630 return;
631 CurFrame->Instructions.push_back(Instruction);
632 }
633
emitCFIRegister(int64_t Register1,int64_t Register2)634 void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
635 MCSymbol *Label = emitCFILabel();
636 MCCFIInstruction Instruction =
637 MCCFIInstruction::createRegister(Label, Register1, Register2);
638 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
639 if (!CurFrame)
640 return;
641 CurFrame->Instructions.push_back(Instruction);
642 }
643
emitCFIWindowSave()644 void MCStreamer::emitCFIWindowSave() {
645 MCSymbol *Label = emitCFILabel();
646 MCCFIInstruction Instruction =
647 MCCFIInstruction::createWindowSave(Label);
648 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
649 if (!CurFrame)
650 return;
651 CurFrame->Instructions.push_back(Instruction);
652 }
653
emitCFINegateRAState()654 void MCStreamer::emitCFINegateRAState() {
655 MCSymbol *Label = emitCFILabel();
656 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
657 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
658 if (!CurFrame)
659 return;
660 CurFrame->Instructions.push_back(Instruction);
661 }
662
emitCFIReturnColumn(int64_t Register)663 void MCStreamer::emitCFIReturnColumn(int64_t Register) {
664 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
665 if (!CurFrame)
666 return;
667 CurFrame->RAReg = Register;
668 }
669
EnsureValidWinFrameInfo(SMLoc Loc)670 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
671 const MCAsmInfo *MAI = Context.getAsmInfo();
672 if (!MAI->usesWindowsCFI()) {
673 getContext().reportError(
674 Loc, ".seh_* directives are not supported on this target");
675 return nullptr;
676 }
677 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
678 getContext().reportError(
679 Loc, ".seh_ directive must appear within an active frame");
680 return nullptr;
681 }
682 return CurrentWinFrameInfo;
683 }
684
EmitWinCFIStartProc(const MCSymbol * Symbol,SMLoc Loc)685 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
686 const MCAsmInfo *MAI = Context.getAsmInfo();
687 if (!MAI->usesWindowsCFI())
688 return getContext().reportError(
689 Loc, ".seh_* directives are not supported on this target");
690 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
691 getContext().reportError(
692 Loc, "Starting a function before ending the previous one!");
693
694 MCSymbol *StartProc = emitCFILabel();
695
696 CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
697 WinFrameInfos.emplace_back(
698 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
699 CurrentWinFrameInfo = WinFrameInfos.back().get();
700 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
701 }
702
EmitWinCFIEndProc(SMLoc Loc)703 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
704 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
705 if (!CurFrame)
706 return;
707 if (CurFrame->ChainedParent)
708 getContext().reportError(Loc, "Not all chained regions terminated!");
709
710 MCSymbol *Label = emitCFILabel();
711 CurFrame->End = Label;
712 if (!CurFrame->FuncletOrFuncEnd)
713 CurFrame->FuncletOrFuncEnd = CurFrame->End;
714
715 for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
716 I != E; ++I)
717 EmitWindowsUnwindTables(WinFrameInfos[I].get());
718 SwitchSection(CurFrame->TextSection);
719 }
720
EmitWinCFIFuncletOrFuncEnd(SMLoc Loc)721 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
722 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
723 if (!CurFrame)
724 return;
725 if (CurFrame->ChainedParent)
726 getContext().reportError(Loc, "Not all chained regions terminated!");
727
728 MCSymbol *Label = emitCFILabel();
729 CurFrame->FuncletOrFuncEnd = Label;
730 }
731
EmitWinCFIStartChained(SMLoc Loc)732 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
733 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
734 if (!CurFrame)
735 return;
736
737 MCSymbol *StartProc = emitCFILabel();
738
739 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
740 CurFrame->Function, StartProc, CurFrame));
741 CurrentWinFrameInfo = WinFrameInfos.back().get();
742 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
743 }
744
EmitWinCFIEndChained(SMLoc Loc)745 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
746 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
747 if (!CurFrame)
748 return;
749 if (!CurFrame->ChainedParent)
750 return getContext().reportError(
751 Loc, "End of a chained region outside a chained region!");
752
753 MCSymbol *Label = emitCFILabel();
754
755 CurFrame->End = Label;
756 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
757 }
758
EmitWinEHHandler(const MCSymbol * Sym,bool Unwind,bool Except,SMLoc Loc)759 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
760 SMLoc Loc) {
761 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
762 if (!CurFrame)
763 return;
764 if (CurFrame->ChainedParent)
765 return getContext().reportError(
766 Loc, "Chained unwind areas can't have handlers!");
767 CurFrame->ExceptionHandler = Sym;
768 if (!Except && !Unwind)
769 getContext().reportError(Loc, "Don't know what kind of handler this is!");
770 if (Unwind)
771 CurFrame->HandlesUnwind = true;
772 if (Except)
773 CurFrame->HandlesExceptions = true;
774 }
775
EmitWinEHHandlerData(SMLoc Loc)776 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
777 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
778 if (!CurFrame)
779 return;
780 if (CurFrame->ChainedParent)
781 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
782 }
783
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)784 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
785 const MCSymbolRefExpr *To, uint64_t Count) {
786 }
787
getWinCFISection(MCContext & Context,unsigned * NextWinCFIID,MCSection * MainCFISec,const MCSection * TextSec)788 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
789 MCSection *MainCFISec,
790 const MCSection *TextSec) {
791 // If this is the main .text section, use the main unwind info section.
792 if (TextSec == Context.getObjectFileInfo()->getTextSection())
793 return MainCFISec;
794
795 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
796 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
797 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
798
799 // If this section is COMDAT, this unwind section should be COMDAT associative
800 // with its group.
801 const MCSymbol *KeySym = nullptr;
802 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
803 KeySym = TextSecCOFF->getCOMDATSymbol();
804
805 // In a GNU environment, we can't use associative comdats. Instead, do what
806 // GCC does, which is to make plain comdat selectany section named like
807 // ".[px]data$_Z3foov".
808 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
809 std::string SectionName = (MainCFISecCOFF->getName() + "$" +
810 TextSecCOFF->getName().split('$').second)
811 .str();
812 return Context.getCOFFSection(
813 SectionName,
814 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
815 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
816 }
817 }
818
819 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
820 }
821
getAssociatedPDataSection(const MCSection * TextSec)822 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
823 return getWinCFISection(getContext(), &NextWinCFIID,
824 getContext().getObjectFileInfo()->getPDataSection(),
825 TextSec);
826 }
827
getAssociatedXDataSection(const MCSection * TextSec)828 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
829 return getWinCFISection(getContext(), &NextWinCFIID,
830 getContext().getObjectFileInfo()->getXDataSection(),
831 TextSec);
832 }
833
emitSyntaxDirective()834 void MCStreamer::emitSyntaxDirective() {}
835
encodeSEHRegNum(MCContext & Ctx,MCRegister Reg)836 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
837 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
838 }
839
EmitWinCFIPushReg(MCRegister Register,SMLoc Loc)840 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
841 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
842 if (!CurFrame)
843 return;
844
845 MCSymbol *Label = emitCFILabel();
846
847 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
848 Label, encodeSEHRegNum(Context, Register));
849 CurFrame->Instructions.push_back(Inst);
850 }
851
EmitWinCFISetFrame(MCRegister Register,unsigned Offset,SMLoc Loc)852 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
853 SMLoc Loc) {
854 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
855 if (!CurFrame)
856 return;
857 if (CurFrame->LastFrameInst >= 0)
858 return getContext().reportError(
859 Loc, "frame register and offset can be set at most once");
860 if (Offset & 0x0F)
861 return getContext().reportError(Loc, "offset is not a multiple of 16");
862 if (Offset > 240)
863 return getContext().reportError(
864 Loc, "frame offset must be less than or equal to 240");
865
866 MCSymbol *Label = emitCFILabel();
867
868 WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
869 Label, encodeSEHRegNum(getContext(), Register), Offset);
870 CurFrame->LastFrameInst = CurFrame->Instructions.size();
871 CurFrame->Instructions.push_back(Inst);
872 }
873
EmitWinCFIAllocStack(unsigned Size,SMLoc Loc)874 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
875 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
876 if (!CurFrame)
877 return;
878 if (Size == 0)
879 return getContext().reportError(Loc,
880 "stack allocation size must be non-zero");
881 if (Size & 7)
882 return getContext().reportError(
883 Loc, "stack allocation size is not a multiple of 8");
884
885 MCSymbol *Label = emitCFILabel();
886
887 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
888 CurFrame->Instructions.push_back(Inst);
889 }
890
EmitWinCFISaveReg(MCRegister Register,unsigned Offset,SMLoc Loc)891 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
892 SMLoc Loc) {
893 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
894 if (!CurFrame)
895 return;
896
897 if (Offset & 7)
898 return getContext().reportError(
899 Loc, "register save offset is not 8 byte aligned");
900
901 MCSymbol *Label = emitCFILabel();
902
903 WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
904 Label, encodeSEHRegNum(Context, Register), Offset);
905 CurFrame->Instructions.push_back(Inst);
906 }
907
EmitWinCFISaveXMM(MCRegister Register,unsigned Offset,SMLoc Loc)908 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
909 SMLoc Loc) {
910 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
911 if (!CurFrame)
912 return;
913 if (Offset & 0x0F)
914 return getContext().reportError(Loc, "offset is not a multiple of 16");
915
916 MCSymbol *Label = emitCFILabel();
917
918 WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
919 Label, encodeSEHRegNum(Context, Register), Offset);
920 CurFrame->Instructions.push_back(Inst);
921 }
922
EmitWinCFIPushFrame(bool Code,SMLoc Loc)923 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
924 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
925 if (!CurFrame)
926 return;
927 if (!CurFrame->Instructions.empty())
928 return getContext().reportError(
929 Loc, "If present, PushMachFrame must be the first UOP");
930
931 MCSymbol *Label = emitCFILabel();
932
933 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
934 CurFrame->Instructions.push_back(Inst);
935 }
936
EmitWinCFIEndProlog(SMLoc Loc)937 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
938 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
939 if (!CurFrame)
940 return;
941
942 MCSymbol *Label = emitCFILabel();
943
944 CurFrame->PrologEnd = Label;
945 }
946
EmitCOFFSafeSEH(MCSymbol const * Symbol)947 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
948
EmitCOFFSymbolIndex(MCSymbol const * Symbol)949 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
950
EmitCOFFSectionIndex(MCSymbol const * Symbol)951 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
952
EmitCOFFSecRel32(MCSymbol const * Symbol,uint64_t Offset)953 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
954
EmitCOFFImgRel32(MCSymbol const * Symbol,int64_t Offset)955 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
956
957 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
958 /// the specified string in the output .s file. This capability is
959 /// indicated by the hasRawTextSupport() predicate.
emitRawTextImpl(StringRef String)960 void MCStreamer::emitRawTextImpl(StringRef String) {
961 // This is not llvm_unreachable for the sake of out of tree backend
962 // developers who may not have assembly streamers and should serve as a
963 // reminder to not accidentally call EmitRawText in the absence of such.
964 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
965 "it (target backend is likely missing an AsmStreamer "
966 "implementation)");
967 }
968
emitRawText(const Twine & T)969 void MCStreamer::emitRawText(const Twine &T) {
970 SmallString<128> Str;
971 emitRawTextImpl(T.toStringRef(Str));
972 }
973
EmitWindowsUnwindTables()974 void MCStreamer::EmitWindowsUnwindTables() {
975 }
976
EmitWindowsUnwindTables(WinEH::FrameInfo * Frame)977 void MCStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
978 }
979
Finish(SMLoc EndLoc)980 void MCStreamer::Finish(SMLoc EndLoc) {
981 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
982 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
983 getContext().reportError(EndLoc, "Unfinished frame!");
984 return;
985 }
986
987 MCTargetStreamer *TS = getTargetStreamer();
988 if (TS)
989 TS->finish();
990
991 finishImpl();
992 }
993
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)994 void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
995 visitUsedExpr(*Value);
996 Symbol->setVariableValue(Value);
997
998 MCTargetStreamer *TS = getTargetStreamer();
999 if (TS)
1000 TS->emitAssignment(Symbol, Value);
1001 }
1002
prettyPrintAsm(MCInstPrinter & InstPrinter,uint64_t Address,const MCInst & Inst,const MCSubtargetInfo & STI,raw_ostream & OS)1003 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
1004 uint64_t Address, const MCInst &Inst,
1005 const MCSubtargetInfo &STI,
1006 raw_ostream &OS) {
1007 InstPrinter.printInst(&Inst, Address, "", STI, OS);
1008 }
1009
visitUsedSymbol(const MCSymbol & Sym)1010 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
1011 }
1012
visitUsedExpr(const MCExpr & Expr)1013 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
1014 switch (Expr.getKind()) {
1015 case MCExpr::Target:
1016 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
1017 break;
1018
1019 case MCExpr::Constant:
1020 break;
1021
1022 case MCExpr::Binary: {
1023 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
1024 visitUsedExpr(*BE.getLHS());
1025 visitUsedExpr(*BE.getRHS());
1026 break;
1027 }
1028
1029 case MCExpr::SymbolRef:
1030 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1031 break;
1032
1033 case MCExpr::Unary:
1034 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1035 break;
1036 }
1037 }
1038
emitInstruction(const MCInst & Inst,const MCSubtargetInfo &)1039 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1040 // Scan for values.
1041 for (unsigned i = Inst.getNumOperands(); i--;)
1042 if (Inst.getOperand(i).isExpr())
1043 visitUsedExpr(*Inst.getOperand(i).getExpr());
1044 }
1045
emitPseudoProbe(uint64_t Guid,uint64_t Index,uint64_t Type,uint64_t Attr,const MCPseudoProbeInlineStack & InlineStack)1046 void MCStreamer::emitPseudoProbe(uint64_t Guid, uint64_t Index, uint64_t Type,
1047 uint64_t Attr,
1048 const MCPseudoProbeInlineStack &InlineStack) {
1049 auto &Context = getContext();
1050
1051 // Create a symbol at in the current section for use in the probe.
1052 MCSymbol *ProbeSym = Context.createTempSymbol();
1053
1054 // Set the value of the symbol to use for the MCPseudoProbe.
1055 emitLabel(ProbeSym);
1056
1057 // Create a (local) probe entry with the symbol.
1058 MCPseudoProbe Probe(ProbeSym, Guid, Index, Type, Attr);
1059
1060 // Add the probe entry to this section's entries.
1061 Context.getMCPseudoProbeTable().getProbeSections().addPseudoProbe(
1062 getCurrentSectionOnly(), Probe, InlineStack);
1063 }
1064
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)1065 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1066 unsigned Size) {
1067 // Get the Hi-Lo expression.
1068 const MCExpr *Diff =
1069 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1070 MCSymbolRefExpr::create(Lo, Context), Context);
1071
1072 const MCAsmInfo *MAI = Context.getAsmInfo();
1073 if (!MAI->doesSetDirectiveSuppressReloc()) {
1074 emitValue(Diff, Size);
1075 return;
1076 }
1077
1078 // Otherwise, emit with .set (aka assignment).
1079 MCSymbol *SetLabel = Context.createTempSymbol("set");
1080 emitAssignment(SetLabel, Diff);
1081 emitSymbolValue(SetLabel, Size);
1082 }
1083
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)1084 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1085 const MCSymbol *Lo) {
1086 // Get the Hi-Lo expression.
1087 const MCExpr *Diff =
1088 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1089 MCSymbolRefExpr::create(Lo, Context), Context);
1090
1091 emitULEB128Value(Diff);
1092 }
1093
emitAssemblerFlag(MCAssemblerFlag Flag)1094 void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {}
emitThumbFunc(MCSymbol * Func)1095 void MCStreamer::emitThumbFunc(MCSymbol *Func) {}
emitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)1096 void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
BeginCOFFSymbolDef(const MCSymbol * Symbol)1097 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1098 llvm_unreachable("this directive only supported on COFF targets");
1099 }
EndCOFFSymbolDef()1100 void MCStreamer::EndCOFFSymbolDef() {
1101 llvm_unreachable("this directive only supported on COFF targets");
1102 }
emitFileDirective(StringRef Filename)1103 void MCStreamer::emitFileDirective(StringRef Filename) {}
EmitCOFFSymbolStorageClass(int StorageClass)1104 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1105 llvm_unreachable("this directive only supported on COFF targets");
1106 }
EmitCOFFSymbolType(int Type)1107 void MCStreamer::EmitCOFFSymbolType(int Type) {
1108 llvm_unreachable("this directive only supported on COFF targets");
1109 }
emitXCOFFLocalCommonSymbol(MCSymbol * LabelSym,uint64_t Size,MCSymbol * CsectSym,unsigned ByteAlign)1110 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1111 MCSymbol *CsectSym,
1112 unsigned ByteAlign) {
1113 llvm_unreachable("this directive only supported on XCOFF targets");
1114 }
1115
emitXCOFFSymbolLinkageWithVisibility(MCSymbol * Symbol,MCSymbolAttr Linkage,MCSymbolAttr Visibility)1116 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
1117 MCSymbolAttr Linkage,
1118 MCSymbolAttr Visibility) {
1119 llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1120 "XCOFF targets");
1121 }
1122
emitXCOFFRenameDirective(const MCSymbol * Name,StringRef Rename)1123 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
1124 StringRef Rename) {
1125 llvm_unreachable("emitXCOFFRenameDirective is only supported on "
1126 "XCOFF targets");
1127 }
1128
emitELFSize(MCSymbol * Symbol,const MCExpr * Value)1129 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
emitELFSymverDirective(StringRef AliasName,const MCSymbol * Aliasee)1130 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1131 const MCSymbol *Aliasee) {}
emitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)1132 void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1133 unsigned ByteAlignment) {}
emitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)1134 void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1135 uint64_t Size, unsigned ByteAlignment) {}
changeSection(MCSection *,const MCExpr *)1136 void MCStreamer::changeSection(MCSection *, const MCExpr *) {}
emitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)1137 void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
emitBytes(StringRef Data)1138 void MCStreamer::emitBytes(StringRef Data) {}
emitBinaryData(StringRef Data)1139 void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)1140 void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1141 visitUsedExpr(*Value);
1142 }
emitULEB128Value(const MCExpr * Value)1143 void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
emitSLEB128Value(const MCExpr * Value)1144 void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
emitFill(const MCExpr & NumBytes,uint64_t Value,SMLoc Loc)1145 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)1146 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1147 SMLoc Loc) {}
emitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)1148 void MCStreamer::emitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1149 unsigned ValueSize,
1150 unsigned MaxBytesToEmit) {}
emitCodeAlignment(unsigned ByteAlignment,unsigned MaxBytesToEmit)1151 void MCStreamer::emitCodeAlignment(unsigned ByteAlignment,
1152 unsigned MaxBytesToEmit) {}
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)1153 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1154 SMLoc Loc) {}
emitBundleAlignMode(unsigned AlignPow2)1155 void MCStreamer::emitBundleAlignMode(unsigned AlignPow2) {}
emitBundleLock(bool AlignToEnd)1156 void MCStreamer::emitBundleLock(bool AlignToEnd) {}
finishImpl()1157 void MCStreamer::finishImpl() {}
emitBundleUnlock()1158 void MCStreamer::emitBundleUnlock() {}
1159
SwitchSection(MCSection * Section,const MCExpr * Subsection)1160 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1161 assert(Section && "Cannot switch to a null section!");
1162 MCSectionSubPair curSection = SectionStack.back().first;
1163 SectionStack.back().second = curSection;
1164 if (MCSectionSubPair(Section, Subsection) != curSection) {
1165 changeSection(Section, Subsection);
1166 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1167 assert(!Section->hasEnded() && "Section already ended");
1168 MCSymbol *Sym = Section->getBeginSymbol();
1169 if (Sym && !Sym->isInSection())
1170 emitLabel(Sym);
1171 }
1172 }
1173
endSection(MCSection * Section)1174 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1175 // TODO: keep track of the last subsection so that this symbol appears in the
1176 // correct place.
1177 MCSymbol *Sym = Section->getEndSymbol(Context);
1178 if (Sym->isInSection())
1179 return Sym;
1180
1181 SwitchSection(Section);
1182 emitLabel(Sym);
1183 return Sym;
1184 }
1185
1186 static VersionTuple
targetVersionOrMinimumSupportedOSVersion(const Triple & Target,VersionTuple TargetVersion)1187 targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
1188 VersionTuple TargetVersion) {
1189 VersionTuple Min = Target.getMinimumSupportedOSVersion();
1190 return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
1191 }
1192
1193 static MCVersionMinType
getMachoVersionMinLoadCommandType(const Triple & Target)1194 getMachoVersionMinLoadCommandType(const Triple &Target) {
1195 assert(Target.isOSDarwin() && "expected a darwin OS");
1196 switch (Target.getOS()) {
1197 case Triple::MacOSX:
1198 case Triple::Darwin:
1199 return MCVM_OSXVersionMin;
1200 case Triple::IOS:
1201 assert(!Target.isMacCatalystEnvironment() &&
1202 "mac Catalyst should use LC_BUILD_VERSION");
1203 return MCVM_IOSVersionMin;
1204 case Triple::TvOS:
1205 return MCVM_TvOSVersionMin;
1206 case Triple::WatchOS:
1207 return MCVM_WatchOSVersionMin;
1208 default:
1209 break;
1210 }
1211 llvm_unreachable("unexpected OS type");
1212 }
1213
getMachoBuildVersionSupportedOS(const Triple & Target)1214 static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) {
1215 assert(Target.isOSDarwin() && "expected a darwin OS");
1216 switch (Target.getOS()) {
1217 case Triple::MacOSX:
1218 case Triple::Darwin:
1219 return VersionTuple(10, 14);
1220 case Triple::IOS:
1221 // Mac Catalyst always uses the build version load command.
1222 if (Target.isMacCatalystEnvironment())
1223 return VersionTuple();
1224 LLVM_FALLTHROUGH;
1225 case Triple::TvOS:
1226 return VersionTuple(12);
1227 case Triple::WatchOS:
1228 return VersionTuple(5);
1229 default:
1230 break;
1231 }
1232 llvm_unreachable("unexpected OS type");
1233 }
1234
1235 static MachO::PlatformType
getMachoBuildVersionPlatformType(const Triple & Target)1236 getMachoBuildVersionPlatformType(const Triple &Target) {
1237 assert(Target.isOSDarwin() && "expected a darwin OS");
1238 switch (Target.getOS()) {
1239 case Triple::MacOSX:
1240 case Triple::Darwin:
1241 return MachO::PLATFORM_MACOS;
1242 case Triple::IOS:
1243 if (Target.isMacCatalystEnvironment())
1244 return MachO::PLATFORM_MACCATALYST;
1245 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1246 : MachO::PLATFORM_IOS;
1247 case Triple::TvOS:
1248 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1249 : MachO::PLATFORM_TVOS;
1250 case Triple::WatchOS:
1251 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1252 : MachO::PLATFORM_WATCHOS;
1253 default:
1254 break;
1255 }
1256 llvm_unreachable("unexpected OS type");
1257 }
1258
emitVersionForTarget(const Triple & Target,const VersionTuple & SDKVersion)1259 void MCStreamer::emitVersionForTarget(const Triple &Target,
1260 const VersionTuple &SDKVersion) {
1261 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1262 return;
1263 // Do we even know the version?
1264 if (Target.getOSMajorVersion() == 0)
1265 return;
1266
1267 unsigned Major = 0;
1268 unsigned Minor = 0;
1269 unsigned Update = 0;
1270 switch (Target.getOS()) {
1271 case Triple::MacOSX:
1272 case Triple::Darwin:
1273 Target.getMacOSXVersion(Major, Minor, Update);
1274 break;
1275 case Triple::IOS:
1276 case Triple::TvOS:
1277 Target.getiOSVersion(Major, Minor, Update);
1278 break;
1279 case Triple::WatchOS:
1280 Target.getWatchOSVersion(Major, Minor, Update);
1281 break;
1282 default:
1283 llvm_unreachable("unexpected OS type");
1284 }
1285 assert(Major != 0 && "A non-zero major version is expected");
1286 auto LinkedTargetVersion = targetVersionOrMinimumSupportedOSVersion(
1287 Target, VersionTuple(Major, Minor, Update));
1288 auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
1289 if (BuildVersionOSVersion.empty() ||
1290 LinkedTargetVersion >= BuildVersionOSVersion)
1291 return emitBuildVersion(getMachoBuildVersionPlatformType(Target),
1292 LinkedTargetVersion.getMajor(),
1293 *LinkedTargetVersion.getMinor(),
1294 *LinkedTargetVersion.getSubminor(), SDKVersion);
1295
1296 emitVersionMin(getMachoVersionMinLoadCommandType(Target),
1297 LinkedTargetVersion.getMajor(),
1298 *LinkedTargetVersion.getMinor(),
1299 *LinkedTargetVersion.getSubminor(), SDKVersion);
1300 }
1301