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