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