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/MCRegister.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSection.h"
28 #include "llvm/MC/MCSectionCOFF.h"
29 #include "llvm/MC/MCSymbol.h"
30 #include "llvm/MC/MCWin64EH.h"
31 #include "llvm/MC/MCWinEH.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MathExtras.h"
36 #include "llvm/Support/raw_ostream.h"
37 #include <cassert>
38 #include <cstdint>
39 #include <cstdlib>
40 #include <utility>
41
42 using namespace llvm;
43
MCTargetStreamer(MCStreamer & S)44 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
45 S.setTargetStreamer(this);
46 }
47
48 // Pin the vtables to this file.
49 MCTargetStreamer::~MCTargetStreamer() = default;
50
emitLabel(MCSymbol * Symbol)51 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
52
finish()53 void MCTargetStreamer::finish() {}
54
changeSection(const MCSection * CurSection,MCSection * Section,const MCExpr * Subsection,raw_ostream & OS)55 void MCTargetStreamer::changeSection(const MCSection *CurSection,
56 MCSection *Section,
57 const MCExpr *Subsection,
58 raw_ostream &OS) {
59 Section->PrintSwitchToSection(
60 *Streamer.getContext().getAsmInfo(),
61 Streamer.getContext().getObjectFileInfo()->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, "invalid symbol redefinition");
418
419 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
420 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
421 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
422 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
423
424 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
425
426 MCTargetStreamer *TS = getTargetStreamer();
427 if (TS)
428 TS->emitLabel(Symbol);
429 }
430
emitCFISections(bool EH,bool Debug)431 void MCStreamer::emitCFISections(bool EH, bool Debug) {
432 assert(EH || Debug);
433 }
434
emitCFIStartProc(bool IsSimple,SMLoc Loc)435 void MCStreamer::emitCFIStartProc(bool IsSimple, SMLoc Loc) {
436 if (hasUnfinishedDwarfFrameInfo())
437 return getContext().reportError(
438 Loc, "starting new .cfi frame before finishing the previous one");
439
440 MCDwarfFrameInfo Frame;
441 Frame.IsSimple = IsSimple;
442 emitCFIStartProcImpl(Frame);
443
444 const MCAsmInfo* MAI = Context.getAsmInfo();
445 if (MAI) {
446 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
447 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
448 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
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
emitCFIOffset(int64_t Register,int64_t Offset)521 void MCStreamer::emitCFIOffset(int64_t Register, int64_t Offset) {
522 MCSymbol *Label = emitCFILabel();
523 MCCFIInstruction Instruction =
524 MCCFIInstruction::createOffset(Label, Register, Offset);
525 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
526 if (!CurFrame)
527 return;
528 CurFrame->Instructions.push_back(Instruction);
529 }
530
emitCFIRelOffset(int64_t Register,int64_t Offset)531 void MCStreamer::emitCFIRelOffset(int64_t Register, int64_t Offset) {
532 MCSymbol *Label = emitCFILabel();
533 MCCFIInstruction Instruction =
534 MCCFIInstruction::createRelOffset(Label, Register, Offset);
535 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
536 if (!CurFrame)
537 return;
538 CurFrame->Instructions.push_back(Instruction);
539 }
540
emitCFIPersonality(const MCSymbol * Sym,unsigned Encoding)541 void MCStreamer::emitCFIPersonality(const MCSymbol *Sym,
542 unsigned Encoding) {
543 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
544 if (!CurFrame)
545 return;
546 CurFrame->Personality = Sym;
547 CurFrame->PersonalityEncoding = Encoding;
548 }
549
emitCFILsda(const MCSymbol * Sym,unsigned Encoding)550 void MCStreamer::emitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
551 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
552 if (!CurFrame)
553 return;
554 CurFrame->Lsda = Sym;
555 CurFrame->LsdaEncoding = Encoding;
556 }
557
emitCFIRememberState()558 void MCStreamer::emitCFIRememberState() {
559 MCSymbol *Label = emitCFILabel();
560 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
561 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
562 if (!CurFrame)
563 return;
564 CurFrame->Instructions.push_back(Instruction);
565 }
566
emitCFIRestoreState()567 void MCStreamer::emitCFIRestoreState() {
568 // FIXME: Error if there is no matching cfi_remember_state.
569 MCSymbol *Label = emitCFILabel();
570 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
571 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
572 if (!CurFrame)
573 return;
574 CurFrame->Instructions.push_back(Instruction);
575 }
576
emitCFISameValue(int64_t Register)577 void MCStreamer::emitCFISameValue(int64_t Register) {
578 MCSymbol *Label = emitCFILabel();
579 MCCFIInstruction Instruction =
580 MCCFIInstruction::createSameValue(Label, Register);
581 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
582 if (!CurFrame)
583 return;
584 CurFrame->Instructions.push_back(Instruction);
585 }
586
emitCFIRestore(int64_t Register)587 void MCStreamer::emitCFIRestore(int64_t Register) {
588 MCSymbol *Label = emitCFILabel();
589 MCCFIInstruction Instruction =
590 MCCFIInstruction::createRestore(Label, Register);
591 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
592 if (!CurFrame)
593 return;
594 CurFrame->Instructions.push_back(Instruction);
595 }
596
emitCFIEscape(StringRef Values)597 void MCStreamer::emitCFIEscape(StringRef Values) {
598 MCSymbol *Label = emitCFILabel();
599 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
600 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
601 if (!CurFrame)
602 return;
603 CurFrame->Instructions.push_back(Instruction);
604 }
605
emitCFIGnuArgsSize(int64_t Size)606 void MCStreamer::emitCFIGnuArgsSize(int64_t Size) {
607 MCSymbol *Label = emitCFILabel();
608 MCCFIInstruction Instruction =
609 MCCFIInstruction::createGnuArgsSize(Label, Size);
610 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
611 if (!CurFrame)
612 return;
613 CurFrame->Instructions.push_back(Instruction);
614 }
615
emitCFISignalFrame()616 void MCStreamer::emitCFISignalFrame() {
617 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
618 if (!CurFrame)
619 return;
620 CurFrame->IsSignalFrame = true;
621 }
622
emitCFIUndefined(int64_t Register)623 void MCStreamer::emitCFIUndefined(int64_t Register) {
624 MCSymbol *Label = emitCFILabel();
625 MCCFIInstruction Instruction =
626 MCCFIInstruction::createUndefined(Label, Register);
627 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
628 if (!CurFrame)
629 return;
630 CurFrame->Instructions.push_back(Instruction);
631 }
632
emitCFIRegister(int64_t Register1,int64_t Register2)633 void MCStreamer::emitCFIRegister(int64_t Register1, int64_t Register2) {
634 MCSymbol *Label = emitCFILabel();
635 MCCFIInstruction Instruction =
636 MCCFIInstruction::createRegister(Label, Register1, Register2);
637 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
638 if (!CurFrame)
639 return;
640 CurFrame->Instructions.push_back(Instruction);
641 }
642
emitCFIWindowSave()643 void MCStreamer::emitCFIWindowSave() {
644 MCSymbol *Label = emitCFILabel();
645 MCCFIInstruction Instruction =
646 MCCFIInstruction::createWindowSave(Label);
647 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
648 if (!CurFrame)
649 return;
650 CurFrame->Instructions.push_back(Instruction);
651 }
652
emitCFINegateRAState()653 void MCStreamer::emitCFINegateRAState() {
654 MCSymbol *Label = emitCFILabel();
655 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
656 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
657 if (!CurFrame)
658 return;
659 CurFrame->Instructions.push_back(Instruction);
660 }
661
emitCFIReturnColumn(int64_t Register)662 void MCStreamer::emitCFIReturnColumn(int64_t Register) {
663 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
664 if (!CurFrame)
665 return;
666 CurFrame->RAReg = Register;
667 }
668
EnsureValidWinFrameInfo(SMLoc Loc)669 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
670 const MCAsmInfo *MAI = Context.getAsmInfo();
671 if (!MAI->usesWindowsCFI()) {
672 getContext().reportError(
673 Loc, ".seh_* directives are not supported on this target");
674 return nullptr;
675 }
676 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
677 getContext().reportError(
678 Loc, ".seh_ directive must appear within an active frame");
679 return nullptr;
680 }
681 return CurrentWinFrameInfo;
682 }
683
EmitWinCFIStartProc(const MCSymbol * Symbol,SMLoc Loc)684 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
685 const MCAsmInfo *MAI = Context.getAsmInfo();
686 if (!MAI->usesWindowsCFI())
687 return getContext().reportError(
688 Loc, ".seh_* directives are not supported on this target");
689 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
690 getContext().reportError(
691 Loc, "Starting a function before ending the previous one!");
692
693 MCSymbol *StartProc = emitCFILabel();
694
695 CurrentProcWinFrameInfoStartIndex = WinFrameInfos.size();
696 WinFrameInfos.emplace_back(
697 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
698 CurrentWinFrameInfo = WinFrameInfos.back().get();
699 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
700 }
701
EmitWinCFIEndProc(SMLoc Loc)702 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
703 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
704 if (!CurFrame)
705 return;
706 if (CurFrame->ChainedParent)
707 getContext().reportError(Loc, "Not all chained regions terminated!");
708
709 MCSymbol *Label = emitCFILabel();
710 CurFrame->End = Label;
711 if (!CurFrame->FuncletOrFuncEnd)
712 CurFrame->FuncletOrFuncEnd = CurFrame->End;
713
714 for (size_t I = CurrentProcWinFrameInfoStartIndex, E = WinFrameInfos.size();
715 I != E; ++I)
716 EmitWindowsUnwindTables(WinFrameInfos[I].get());
717 SwitchSection(CurFrame->TextSection);
718 }
719
EmitWinCFIFuncletOrFuncEnd(SMLoc Loc)720 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
721 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
722 if (!CurFrame)
723 return;
724 if (CurFrame->ChainedParent)
725 getContext().reportError(Loc, "Not all chained regions terminated!");
726
727 MCSymbol *Label = emitCFILabel();
728 CurFrame->FuncletOrFuncEnd = Label;
729 }
730
EmitWinCFIStartChained(SMLoc Loc)731 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
732 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
733 if (!CurFrame)
734 return;
735
736 MCSymbol *StartProc = emitCFILabel();
737
738 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
739 CurFrame->Function, StartProc, CurFrame));
740 CurrentWinFrameInfo = WinFrameInfos.back().get();
741 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
742 }
743
EmitWinCFIEndChained(SMLoc Loc)744 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
745 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
746 if (!CurFrame)
747 return;
748 if (!CurFrame->ChainedParent)
749 return getContext().reportError(
750 Loc, "End of a chained region outside a chained region!");
751
752 MCSymbol *Label = emitCFILabel();
753
754 CurFrame->End = Label;
755 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
756 }
757
EmitWinEHHandler(const MCSymbol * Sym,bool Unwind,bool Except,SMLoc Loc)758 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
759 SMLoc Loc) {
760 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
761 if (!CurFrame)
762 return;
763 if (CurFrame->ChainedParent)
764 return getContext().reportError(
765 Loc, "Chained unwind areas can't have handlers!");
766 CurFrame->ExceptionHandler = Sym;
767 if (!Except && !Unwind)
768 getContext().reportError(Loc, "Don't know what kind of handler this is!");
769 if (Unwind)
770 CurFrame->HandlesUnwind = true;
771 if (Except)
772 CurFrame->HandlesExceptions = true;
773 }
774
EmitWinEHHandlerData(SMLoc Loc)775 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
776 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
777 if (!CurFrame)
778 return;
779 if (CurFrame->ChainedParent)
780 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
781 }
782
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)783 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
784 const MCSymbolRefExpr *To, uint64_t Count) {
785 }
786
getWinCFISection(MCContext & Context,unsigned * NextWinCFIID,MCSection * MainCFISec,const MCSection * TextSec)787 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
788 MCSection *MainCFISec,
789 const MCSection *TextSec) {
790 // If this is the main .text section, use the main unwind info section.
791 if (TextSec == Context.getObjectFileInfo()->getTextSection())
792 return MainCFISec;
793
794 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
795 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
796 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
797
798 // If this section is COMDAT, this unwind section should be COMDAT associative
799 // with its group.
800 const MCSymbol *KeySym = nullptr;
801 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
802 KeySym = TextSecCOFF->getCOMDATSymbol();
803
804 // In a GNU environment, we can't use associative comdats. Instead, do what
805 // GCC does, which is to make plain comdat selectany section named like
806 // ".[px]data$_Z3foov".
807 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
808 std::string SectionName = (MainCFISecCOFF->getName() + "$" +
809 TextSecCOFF->getName().split('$').second)
810 .str();
811 return Context.getCOFFSection(
812 SectionName,
813 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
814 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
815 }
816 }
817
818 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
819 }
820
getAssociatedPDataSection(const MCSection * TextSec)821 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
822 return getWinCFISection(getContext(), &NextWinCFIID,
823 getContext().getObjectFileInfo()->getPDataSection(),
824 TextSec);
825 }
826
getAssociatedXDataSection(const MCSection * TextSec)827 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
828 return getWinCFISection(getContext(), &NextWinCFIID,
829 getContext().getObjectFileInfo()->getXDataSection(),
830 TextSec);
831 }
832
emitSyntaxDirective()833 void MCStreamer::emitSyntaxDirective() {}
834
encodeSEHRegNum(MCContext & Ctx,MCRegister Reg)835 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
836 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
837 }
838
EmitWinCFIPushReg(MCRegister Register,SMLoc Loc)839 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
840 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
841 if (!CurFrame)
842 return;
843
844 MCSymbol *Label = emitCFILabel();
845
846 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
847 Label, encodeSEHRegNum(Context, Register));
848 CurFrame->Instructions.push_back(Inst);
849 }
850
EmitWinCFISetFrame(MCRegister Register,unsigned Offset,SMLoc Loc)851 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
852 SMLoc Loc) {
853 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
854 if (!CurFrame)
855 return;
856 if (CurFrame->LastFrameInst >= 0)
857 return getContext().reportError(
858 Loc, "frame register and offset can be set at most once");
859 if (Offset & 0x0F)
860 return getContext().reportError(Loc, "offset is not a multiple of 16");
861 if (Offset > 240)
862 return getContext().reportError(
863 Loc, "frame offset must be less than or equal to 240");
864
865 MCSymbol *Label = emitCFILabel();
866
867 WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
868 Label, encodeSEHRegNum(getContext(), Register), Offset);
869 CurFrame->LastFrameInst = CurFrame->Instructions.size();
870 CurFrame->Instructions.push_back(Inst);
871 }
872
EmitWinCFIAllocStack(unsigned Size,SMLoc Loc)873 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
874 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
875 if (!CurFrame)
876 return;
877 if (Size == 0)
878 return getContext().reportError(Loc,
879 "stack allocation size must be non-zero");
880 if (Size & 7)
881 return getContext().reportError(
882 Loc, "stack allocation size is not a multiple of 8");
883
884 MCSymbol *Label = emitCFILabel();
885
886 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
887 CurFrame->Instructions.push_back(Inst);
888 }
889
EmitWinCFISaveReg(MCRegister Register,unsigned Offset,SMLoc Loc)890 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
891 SMLoc Loc) {
892 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
893 if (!CurFrame)
894 return;
895
896 if (Offset & 7)
897 return getContext().reportError(
898 Loc, "register save offset is not 8 byte aligned");
899
900 MCSymbol *Label = emitCFILabel();
901
902 WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
903 Label, encodeSEHRegNum(Context, Register), Offset);
904 CurFrame->Instructions.push_back(Inst);
905 }
906
EmitWinCFISaveXMM(MCRegister Register,unsigned Offset,SMLoc Loc)907 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
908 SMLoc Loc) {
909 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
910 if (!CurFrame)
911 return;
912 if (Offset & 0x0F)
913 return getContext().reportError(Loc, "offset is not a multiple of 16");
914
915 MCSymbol *Label = emitCFILabel();
916
917 WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
918 Label, encodeSEHRegNum(Context, Register), Offset);
919 CurFrame->Instructions.push_back(Inst);
920 }
921
EmitWinCFIPushFrame(bool Code,SMLoc Loc)922 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
923 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
924 if (!CurFrame)
925 return;
926 if (!CurFrame->Instructions.empty())
927 return getContext().reportError(
928 Loc, "If present, PushMachFrame must be the first UOP");
929
930 MCSymbol *Label = emitCFILabel();
931
932 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
933 CurFrame->Instructions.push_back(Inst);
934 }
935
EmitWinCFIEndProlog(SMLoc Loc)936 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
937 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
938 if (!CurFrame)
939 return;
940
941 MCSymbol *Label = emitCFILabel();
942
943 CurFrame->PrologEnd = Label;
944 }
945
EmitCOFFSafeSEH(MCSymbol const * Symbol)946 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
947
EmitCOFFSymbolIndex(MCSymbol const * Symbol)948 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
949
EmitCOFFSectionIndex(MCSymbol const * Symbol)950 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
951
EmitCOFFSecRel32(MCSymbol const * Symbol,uint64_t Offset)952 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
953
EmitCOFFImgRel32(MCSymbol const * Symbol,int64_t Offset)954 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
955
956 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
957 /// the specified string in the output .s file. This capability is
958 /// indicated by the hasRawTextSupport() predicate.
emitRawTextImpl(StringRef String)959 void MCStreamer::emitRawTextImpl(StringRef String) {
960 // This is not llvm_unreachable for the sake of out of tree backend
961 // developers who may not have assembly streamers and should serve as a
962 // reminder to not accidentally call EmitRawText in the absence of such.
963 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
964 "it (target backend is likely missing an AsmStreamer "
965 "implementation)");
966 }
967
emitRawText(const Twine & T)968 void MCStreamer::emitRawText(const Twine &T) {
969 SmallString<128> Str;
970 emitRawTextImpl(T.toStringRef(Str));
971 }
972
EmitWindowsUnwindTables()973 void MCStreamer::EmitWindowsUnwindTables() {
974 }
975
EmitWindowsUnwindTables(WinEH::FrameInfo * Frame)976 void MCStreamer::EmitWindowsUnwindTables(WinEH::FrameInfo *Frame) {
977 }
978
Finish(SMLoc EndLoc)979 void MCStreamer::Finish(SMLoc EndLoc) {
980 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
981 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
982 getContext().reportError(EndLoc, "Unfinished frame!");
983 return;
984 }
985
986 MCTargetStreamer *TS = getTargetStreamer();
987 if (TS)
988 TS->finish();
989
990 finishImpl();
991 }
992
emitAssignment(MCSymbol * Symbol,const MCExpr * Value)993 void MCStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
994 visitUsedExpr(*Value);
995 Symbol->setVariableValue(Value);
996
997 MCTargetStreamer *TS = getTargetStreamer();
998 if (TS)
999 TS->emitAssignment(Symbol, Value);
1000 }
1001
prettyPrintAsm(MCInstPrinter & InstPrinter,uint64_t Address,const MCInst & Inst,const MCSubtargetInfo & STI,raw_ostream & OS)1002 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
1003 uint64_t Address, const MCInst &Inst,
1004 const MCSubtargetInfo &STI,
1005 raw_ostream &OS) {
1006 InstPrinter.printInst(&Inst, Address, "", STI, OS);
1007 }
1008
visitUsedSymbol(const MCSymbol & Sym)1009 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
1010 }
1011
visitUsedExpr(const MCExpr & Expr)1012 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
1013 switch (Expr.getKind()) {
1014 case MCExpr::Target:
1015 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
1016 break;
1017
1018 case MCExpr::Constant:
1019 break;
1020
1021 case MCExpr::Binary: {
1022 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
1023 visitUsedExpr(*BE.getLHS());
1024 visitUsedExpr(*BE.getRHS());
1025 break;
1026 }
1027
1028 case MCExpr::SymbolRef:
1029 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1030 break;
1031
1032 case MCExpr::Unary:
1033 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1034 break;
1035 }
1036 }
1037
emitInstruction(const MCInst & Inst,const MCSubtargetInfo &)1038 void MCStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1039 // Scan for values.
1040 for (unsigned i = Inst.getNumOperands(); i--;)
1041 if (Inst.getOperand(i).isExpr())
1042 visitUsedExpr(*Inst.getOperand(i).getExpr());
1043 }
1044
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)1045 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1046 unsigned Size) {
1047 // Get the Hi-Lo expression.
1048 const MCExpr *Diff =
1049 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1050 MCSymbolRefExpr::create(Lo, Context), Context);
1051
1052 const MCAsmInfo *MAI = Context.getAsmInfo();
1053 if (!MAI->doesSetDirectiveSuppressReloc()) {
1054 emitValue(Diff, Size);
1055 return;
1056 }
1057
1058 // Otherwise, emit with .set (aka assignment).
1059 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
1060 emitAssignment(SetLabel, Diff);
1061 emitSymbolValue(SetLabel, Size);
1062 }
1063
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)1064 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1065 const MCSymbol *Lo) {
1066 // Get the Hi-Lo expression.
1067 const MCExpr *Diff =
1068 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1069 MCSymbolRefExpr::create(Lo, Context), Context);
1070
1071 emitULEB128Value(Diff);
1072 }
1073
emitAssemblerFlag(MCAssemblerFlag Flag)1074 void MCStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) {}
emitThumbFunc(MCSymbol * Func)1075 void MCStreamer::emitThumbFunc(MCSymbol *Func) {}
emitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)1076 void MCStreamer::emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
BeginCOFFSymbolDef(const MCSymbol * Symbol)1077 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1078 llvm_unreachable("this directive only supported on COFF targets");
1079 }
EndCOFFSymbolDef()1080 void MCStreamer::EndCOFFSymbolDef() {
1081 llvm_unreachable("this directive only supported on COFF targets");
1082 }
emitFileDirective(StringRef Filename)1083 void MCStreamer::emitFileDirective(StringRef Filename) {}
EmitCOFFSymbolStorageClass(int StorageClass)1084 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1085 llvm_unreachable("this directive only supported on COFF targets");
1086 }
EmitCOFFSymbolType(int Type)1087 void MCStreamer::EmitCOFFSymbolType(int Type) {
1088 llvm_unreachable("this directive only supported on COFF targets");
1089 }
emitXCOFFLocalCommonSymbol(MCSymbol * LabelSym,uint64_t Size,MCSymbol * CsectSym,unsigned ByteAlign)1090 void MCStreamer::emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1091 MCSymbol *CsectSym,
1092 unsigned ByteAlign) {
1093 llvm_unreachable("this directive only supported on XCOFF targets");
1094 }
1095
emitXCOFFSymbolLinkageWithVisibility(MCSymbol * Symbol,MCSymbolAttr Linkage,MCSymbolAttr Visibility)1096 void MCStreamer::emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
1097 MCSymbolAttr Linkage,
1098 MCSymbolAttr Visibility) {
1099 llvm_unreachable("emitXCOFFSymbolLinkageWithVisibility is only supported on "
1100 "XCOFF targets");
1101 }
1102
emitXCOFFRenameDirective(const MCSymbol * Name,StringRef Rename)1103 void MCStreamer::emitXCOFFRenameDirective(const MCSymbol *Name,
1104 StringRef Rename) {
1105 llvm_unreachable("emitXCOFFRenameDirective is only supported on "
1106 "XCOFF targets");
1107 }
1108
emitELFSize(MCSymbol * Symbol,const MCExpr * Value)1109 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
emitELFSymverDirective(StringRef AliasName,const MCSymbol * Aliasee)1110 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1111 const MCSymbol *Aliasee) {}
emitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)1112 void MCStreamer::emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1113 unsigned ByteAlignment) {}
emitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)1114 void MCStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1115 uint64_t Size, unsigned ByteAlignment) {}
changeSection(MCSection *,const MCExpr *)1116 void MCStreamer::changeSection(MCSection *, const MCExpr *) {}
emitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)1117 void MCStreamer::emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
emitBytes(StringRef Data)1118 void MCStreamer::emitBytes(StringRef Data) {}
emitBinaryData(StringRef Data)1119 void MCStreamer::emitBinaryData(StringRef Data) { emitBytes(Data); }
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)1120 void MCStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1121 visitUsedExpr(*Value);
1122 }
emitULEB128Value(const MCExpr * Value)1123 void MCStreamer::emitULEB128Value(const MCExpr *Value) {}
emitSLEB128Value(const MCExpr * Value)1124 void MCStreamer::emitSLEB128Value(const MCExpr *Value) {}
emitFill(const MCExpr & NumBytes,uint64_t Value,SMLoc Loc)1125 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)1126 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1127 SMLoc Loc) {}
emitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)1128 void MCStreamer::emitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1129 unsigned ValueSize,
1130 unsigned MaxBytesToEmit) {}
emitCodeAlignment(unsigned ByteAlignment,unsigned MaxBytesToEmit)1131 void MCStreamer::emitCodeAlignment(unsigned ByteAlignment,
1132 unsigned MaxBytesToEmit) {}
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)1133 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1134 SMLoc Loc) {}
emitBundleAlignMode(unsigned AlignPow2)1135 void MCStreamer::emitBundleAlignMode(unsigned AlignPow2) {}
emitBundleLock(bool AlignToEnd)1136 void MCStreamer::emitBundleLock(bool AlignToEnd) {}
finishImpl()1137 void MCStreamer::finishImpl() {}
emitBundleUnlock()1138 void MCStreamer::emitBundleUnlock() {}
1139
SwitchSection(MCSection * Section,const MCExpr * Subsection)1140 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1141 assert(Section && "Cannot switch to a null section!");
1142 MCSectionSubPair curSection = SectionStack.back().first;
1143 SectionStack.back().second = curSection;
1144 if (MCSectionSubPair(Section, Subsection) != curSection) {
1145 changeSection(Section, Subsection);
1146 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1147 assert(!Section->hasEnded() && "Section already ended");
1148 MCSymbol *Sym = Section->getBeginSymbol();
1149 if (Sym && !Sym->isInSection())
1150 emitLabel(Sym);
1151 }
1152 }
1153
endSection(MCSection * Section)1154 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1155 // TODO: keep track of the last subsection so that this symbol appears in the
1156 // correct place.
1157 MCSymbol *Sym = Section->getEndSymbol(Context);
1158 if (Sym->isInSection())
1159 return Sym;
1160
1161 SwitchSection(Section);
1162 emitLabel(Sym);
1163 return Sym;
1164 }
1165
1166 static VersionTuple
targetVersionOrMinimumSupportedOSVersion(const Triple & Target,VersionTuple TargetVersion)1167 targetVersionOrMinimumSupportedOSVersion(const Triple &Target,
1168 VersionTuple TargetVersion) {
1169 VersionTuple Min = Target.getMinimumSupportedOSVersion();
1170 return !Min.empty() && Min > TargetVersion ? Min : TargetVersion;
1171 }
1172
1173 static MCVersionMinType
getMachoVersionMinLoadCommandType(const Triple & Target)1174 getMachoVersionMinLoadCommandType(const Triple &Target) {
1175 assert(Target.isOSDarwin() && "expected a darwin OS");
1176 switch (Target.getOS()) {
1177 case Triple::MacOSX:
1178 case Triple::Darwin:
1179 return MCVM_OSXVersionMin;
1180 case Triple::IOS:
1181 assert(!Target.isMacCatalystEnvironment() &&
1182 "mac Catalyst should use LC_BUILD_VERSION");
1183 return MCVM_IOSVersionMin;
1184 case Triple::TvOS:
1185 return MCVM_TvOSVersionMin;
1186 case Triple::WatchOS:
1187 return MCVM_WatchOSVersionMin;
1188 default:
1189 break;
1190 }
1191 llvm_unreachable("unexpected OS type");
1192 }
1193
getMachoBuildVersionSupportedOS(const Triple & Target)1194 static VersionTuple getMachoBuildVersionSupportedOS(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 VersionTuple(10, 14);
1200 case Triple::IOS:
1201 // Mac Catalyst always uses the build version load command.
1202 if (Target.isMacCatalystEnvironment())
1203 return VersionTuple();
1204 LLVM_FALLTHROUGH;
1205 case Triple::TvOS:
1206 return VersionTuple(12);
1207 case Triple::WatchOS:
1208 return VersionTuple(5);
1209 default:
1210 break;
1211 }
1212 llvm_unreachable("unexpected OS type");
1213 }
1214
1215 static MachO::PlatformType
getMachoBuildVersionPlatformType(const Triple & Target)1216 getMachoBuildVersionPlatformType(const Triple &Target) {
1217 assert(Target.isOSDarwin() && "expected a darwin OS");
1218 switch (Target.getOS()) {
1219 case Triple::MacOSX:
1220 case Triple::Darwin:
1221 return MachO::PLATFORM_MACOS;
1222 case Triple::IOS:
1223 if (Target.isMacCatalystEnvironment())
1224 return MachO::PLATFORM_MACCATALYST;
1225 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR
1226 : MachO::PLATFORM_IOS;
1227 case Triple::TvOS:
1228 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR
1229 : MachO::PLATFORM_TVOS;
1230 case Triple::WatchOS:
1231 return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR
1232 : MachO::PLATFORM_WATCHOS;
1233 default:
1234 break;
1235 }
1236 llvm_unreachable("unexpected OS type");
1237 }
1238
emitVersionForTarget(const Triple & Target,const VersionTuple & SDKVersion)1239 void MCStreamer::emitVersionForTarget(const Triple &Target,
1240 const VersionTuple &SDKVersion) {
1241 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1242 return;
1243 // Do we even know the version?
1244 if (Target.getOSMajorVersion() == 0)
1245 return;
1246
1247 unsigned Major = 0;
1248 unsigned Minor = 0;
1249 unsigned Update = 0;
1250 switch (Target.getOS()) {
1251 case Triple::MacOSX:
1252 case Triple::Darwin:
1253 Target.getMacOSXVersion(Major, Minor, Update);
1254 break;
1255 case Triple::IOS:
1256 case Triple::TvOS:
1257 Target.getiOSVersion(Major, Minor, Update);
1258 break;
1259 case Triple::WatchOS:
1260 Target.getWatchOSVersion(Major, Minor, Update);
1261 break;
1262 default:
1263 llvm_unreachable("unexpected OS type");
1264 }
1265 assert(Major != 0 && "A non-zero major version is expected");
1266 auto LinkedTargetVersion = targetVersionOrMinimumSupportedOSVersion(
1267 Target, VersionTuple(Major, Minor, Update));
1268 auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target);
1269 if (BuildVersionOSVersion.empty() ||
1270 LinkedTargetVersion >= BuildVersionOSVersion)
1271 return emitBuildVersion(getMachoBuildVersionPlatformType(Target),
1272 LinkedTargetVersion.getMajor(),
1273 *LinkedTargetVersion.getMinor(),
1274 *LinkedTargetVersion.getSubminor(), SDKVersion);
1275
1276 emitVersionMin(getMachoVersionMinLoadCommandType(Target),
1277 LinkedTargetVersion.getMajor(),
1278 *LinkedTargetVersion.getMinor(),
1279 *LinkedTargetVersion.getSubminor(), SDKVersion);
1280 }
1281