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 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 char buf[8];
136 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
137 for (unsigned i = 0; i != Size; ++i) {
138 unsigned index = isLittleEndian ? i : (Size - i - 1);
139 buf[i] = uint8_t(Value >> (index * 8));
140 }
141 EmitBytes(StringRef(buf, Size));
142 }
143
144 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
145 /// client having to pass in a MCExpr for constant integers.
EmitULEB128IntValue(uint64_t Value,unsigned PadTo)146 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) {
147 SmallString<128> Tmp;
148 raw_svector_ostream OSE(Tmp);
149 encodeULEB128(Value, OSE, PadTo);
150 EmitBytes(OSE.str());
151 }
152
153 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
154 /// client having to pass in a MCExpr for constant integers.
EmitSLEB128IntValue(int64_t Value)155 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
156 SmallString<128> Tmp;
157 raw_svector_ostream OSE(Tmp);
158 encodeSLEB128(Value, OSE);
159 EmitBytes(OSE.str());
160 }
161
EmitValue(const MCExpr * Value,unsigned Size,SMLoc Loc)162 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
163 EmitValueImpl(Value, Size, Loc);
164 }
165
EmitSymbolValue(const MCSymbol * Sym,unsigned Size,bool IsSectionRelative)166 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
167 bool IsSectionRelative) {
168 assert((!IsSectionRelative || Size == 4) &&
169 "SectionRelative value requires 4-bytes");
170
171 if (!IsSectionRelative)
172 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
173 else
174 EmitCOFFSecRel32(Sym, /*Offset=*/0);
175 }
176
EmitDTPRel64Value(const MCExpr * Value)177 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
178 report_fatal_error("unsupported directive in streamer");
179 }
180
EmitDTPRel32Value(const MCExpr * Value)181 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
182 report_fatal_error("unsupported directive in streamer");
183 }
184
EmitTPRel64Value(const MCExpr * Value)185 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
186 report_fatal_error("unsupported directive in streamer");
187 }
188
EmitTPRel32Value(const MCExpr * Value)189 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
190 report_fatal_error("unsupported directive in streamer");
191 }
192
EmitGPRel64Value(const MCExpr * Value)193 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
194 report_fatal_error("unsupported directive in streamer");
195 }
196
EmitGPRel32Value(const MCExpr * Value)197 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
198 report_fatal_error("unsupported directive in streamer");
199 }
200
201 /// Emit NumBytes bytes worth of the value specified by FillValue.
202 /// This implements directives such as '.space'.
emitFill(uint64_t NumBytes,uint8_t FillValue)203 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
204 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
205 }
206
207 /// The implementation in this class just redirects to emitFill.
EmitZeros(uint64_t NumBytes)208 void MCStreamer::EmitZeros(uint64_t NumBytes) {
209 emitFill(NumBytes, 0);
210 }
211
212 Expected<unsigned>
tryEmitDwarfFileDirective(unsigned FileNo,StringRef Directory,StringRef Filename,Optional<MD5::MD5Result> Checksum,Optional<StringRef> Source,unsigned CUID)213 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
214 StringRef Filename,
215 Optional<MD5::MD5Result> Checksum,
216 Optional<StringRef> Source,
217 unsigned CUID) {
218 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
219 Source, CUID);
220 }
221
emitDwarfFile0Directive(StringRef Directory,StringRef Filename,Optional<MD5::MD5Result> Checksum,Optional<StringRef> Source,unsigned CUID)222 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
223 StringRef Filename,
224 Optional<MD5::MD5Result> Checksum,
225 Optional<StringRef> Source,
226 unsigned CUID) {
227 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
228 Source);
229 }
230
EmitCFIBKeyFrame()231 void MCStreamer::EmitCFIBKeyFrame() {
232 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
233 if (!CurFrame)
234 return;
235 CurFrame->IsBKeyFrame = true;
236 }
237
EmitDwarfLocDirective(unsigned FileNo,unsigned Line,unsigned Column,unsigned Flags,unsigned Isa,unsigned Discriminator,StringRef FileName)238 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
239 unsigned Column, unsigned Flags,
240 unsigned Isa,
241 unsigned Discriminator,
242 StringRef FileName) {
243 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
244 Discriminator);
245 }
246
getDwarfLineTableSymbol(unsigned CUID)247 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
248 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
249 if (!Table.getLabel()) {
250 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
251 Table.setLabel(
252 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
253 }
254 return Table.getLabel();
255 }
256
hasUnfinishedDwarfFrameInfo()257 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
258 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
259 }
260
getCurrentDwarfFrameInfo()261 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
262 if (!hasUnfinishedDwarfFrameInfo()) {
263 getContext().reportError(SMLoc(), "this directive must appear between "
264 ".cfi_startproc and .cfi_endproc "
265 "directives");
266 return nullptr;
267 }
268 return &DwarfFrameInfos.back();
269 }
270
EmitCVFileDirective(unsigned FileNo,StringRef Filename,ArrayRef<uint8_t> Checksum,unsigned ChecksumKind)271 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
272 ArrayRef<uint8_t> Checksum,
273 unsigned ChecksumKind) {
274 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
275 ChecksumKind);
276 }
277
EmitCVFuncIdDirective(unsigned FunctionId)278 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
279 return getContext().getCVContext().recordFunctionId(FunctionId);
280 }
281
EmitCVInlineSiteIdDirective(unsigned FunctionId,unsigned IAFunc,unsigned IAFile,unsigned IALine,unsigned IACol,SMLoc Loc)282 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
283 unsigned IAFunc, unsigned IAFile,
284 unsigned IALine, unsigned IACol,
285 SMLoc Loc) {
286 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
287 getContext().reportError(Loc, "parent function id not introduced by "
288 ".cv_func_id or .cv_inline_site_id");
289 return true;
290 }
291
292 return getContext().getCVContext().recordInlinedCallSiteId(
293 FunctionId, IAFunc, IAFile, IALine, IACol);
294 }
295
EmitCVLocDirective(unsigned FunctionId,unsigned FileNo,unsigned Line,unsigned Column,bool PrologueEnd,bool IsStmt,StringRef FileName,SMLoc Loc)296 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
297 unsigned Line, unsigned Column,
298 bool PrologueEnd, bool IsStmt,
299 StringRef FileName, SMLoc Loc) {}
300
checkCVLocSection(unsigned FuncId,unsigned FileNo,SMLoc Loc)301 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
302 SMLoc Loc) {
303 CodeViewContext &CVC = getContext().getCVContext();
304 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
305 if (!FI) {
306 getContext().reportError(
307 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
308 return false;
309 }
310
311 // Track the section
312 if (FI->Section == nullptr)
313 FI->Section = getCurrentSectionOnly();
314 else if (FI->Section != getCurrentSectionOnly()) {
315 getContext().reportError(
316 Loc,
317 "all .cv_loc directives for a function must be in the same section");
318 return false;
319 }
320 return true;
321 }
322
EmitCVLinetableDirective(unsigned FunctionId,const MCSymbol * Begin,const MCSymbol * End)323 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
324 const MCSymbol *Begin,
325 const MCSymbol *End) {}
326
EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,unsigned SourceFileId,unsigned SourceLineNum,const MCSymbol * FnStartSym,const MCSymbol * FnEndSym)327 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
328 unsigned SourceFileId,
329 unsigned SourceLineNum,
330 const MCSymbol *FnStartSym,
331 const MCSymbol *FnEndSym) {}
332
333 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
334 /// structs composed of them.
335 template <typename T>
copyBytesForDefRange(SmallString<20> & BytePrefix,codeview::SymbolKind SymKind,const T & DefRangeHeader)336 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
337 codeview::SymbolKind SymKind,
338 const T &DefRangeHeader) {
339 BytePrefix.resize(2 + sizeof(T));
340 codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
341 memcpy(&BytePrefix[0], &SymKindLE, 2);
342 memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
343 }
344
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,StringRef FixedSizePortion)345 void MCStreamer::EmitCVDefRangeDirective(
346 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
347 StringRef FixedSizePortion) {}
348
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterRelHeader DRHdr)349 void MCStreamer::EmitCVDefRangeDirective(
350 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
351 codeview::DefRangeRegisterRelHeader DRHdr) {
352 SmallString<20> BytePrefix;
353 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
354 EmitCVDefRangeDirective(Ranges, BytePrefix);
355 }
356
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeSubfieldRegisterHeader DRHdr)357 void MCStreamer::EmitCVDefRangeDirective(
358 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
359 codeview::DefRangeSubfieldRegisterHeader DRHdr) {
360 SmallString<20> BytePrefix;
361 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
362 DRHdr);
363 EmitCVDefRangeDirective(Ranges, BytePrefix);
364 }
365
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeRegisterHeader DRHdr)366 void MCStreamer::EmitCVDefRangeDirective(
367 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
368 codeview::DefRangeRegisterHeader DRHdr) {
369 SmallString<20> BytePrefix;
370 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
371 EmitCVDefRangeDirective(Ranges, BytePrefix);
372 }
373
EmitCVDefRangeDirective(ArrayRef<std::pair<const MCSymbol *,const MCSymbol * >> Ranges,codeview::DefRangeFramePointerRelHeader DRHdr)374 void MCStreamer::EmitCVDefRangeDirective(
375 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
376 codeview::DefRangeFramePointerRelHeader DRHdr) {
377 SmallString<20> BytePrefix;
378 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
379 DRHdr);
380 EmitCVDefRangeDirective(Ranges, BytePrefix);
381 }
382
EmitEHSymAttributes(const MCSymbol * Symbol,MCSymbol * EHSymbol)383 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
384 MCSymbol *EHSymbol) {
385 }
386
InitSections(bool NoExecStack)387 void MCStreamer::InitSections(bool NoExecStack) {
388 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
389 }
390
AssignFragment(MCSymbol * Symbol,MCFragment * Fragment)391 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
392 assert(Fragment);
393 Symbol->setFragment(Fragment);
394
395 // As we emit symbols into a section, track the order so that they can
396 // be sorted upon later. Zero is reserved to mean 'unemitted'.
397 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
398 }
399
EmitLabel(MCSymbol * Symbol,SMLoc Loc)400 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
401 Symbol->redefineIfPossible();
402
403 if (!Symbol->isUndefined() || Symbol->isVariable())
404 return getContext().reportError(Loc, "invalid symbol redefinition");
405
406 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
407 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
408 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
409 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
410
411 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
412
413 MCTargetStreamer *TS = getTargetStreamer();
414 if (TS)
415 TS->emitLabel(Symbol);
416 }
417
EmitCFISections(bool EH,bool Debug)418 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
419 assert(EH || Debug);
420 }
421
EmitCFIStartProc(bool IsSimple,SMLoc Loc)422 void MCStreamer::EmitCFIStartProc(bool IsSimple, SMLoc Loc) {
423 if (hasUnfinishedDwarfFrameInfo())
424 return getContext().reportError(
425 Loc, "starting new .cfi frame before finishing the previous one");
426
427 MCDwarfFrameInfo Frame;
428 Frame.IsSimple = IsSimple;
429 EmitCFIStartProcImpl(Frame);
430
431 const MCAsmInfo* MAI = Context.getAsmInfo();
432 if (MAI) {
433 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
434 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
435 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
436 Frame.CurrentCfaRegister = Inst.getRegister();
437 }
438 }
439 }
440
441 DwarfFrameInfos.push_back(Frame);
442 }
443
EmitCFIStartProcImpl(MCDwarfFrameInfo & Frame)444 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
445 }
446
EmitCFIEndProc()447 void MCStreamer::EmitCFIEndProc() {
448 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
449 if (!CurFrame)
450 return;
451 EmitCFIEndProcImpl(*CurFrame);
452 }
453
EmitCFIEndProcImpl(MCDwarfFrameInfo & Frame)454 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
455 // Put a dummy non-null value in Frame.End to mark that this frame has been
456 // closed.
457 Frame.End = (MCSymbol *)1;
458 }
459
EmitCFILabel()460 MCSymbol *MCStreamer::EmitCFILabel() {
461 // Return a dummy non-null value so that label fields appear filled in when
462 // generating textual assembly.
463 return (MCSymbol *)1;
464 }
465
EmitCFIDefCfa(int64_t Register,int64_t Offset)466 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
467 MCSymbol *Label = EmitCFILabel();
468 MCCFIInstruction Instruction =
469 MCCFIInstruction::createDefCfa(Label, Register, Offset);
470 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
471 if (!CurFrame)
472 return;
473 CurFrame->Instructions.push_back(Instruction);
474 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
475 }
476
EmitCFIDefCfaOffset(int64_t Offset)477 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
478 MCSymbol *Label = EmitCFILabel();
479 MCCFIInstruction Instruction =
480 MCCFIInstruction::createDefCfaOffset(Label, Offset);
481 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
482 if (!CurFrame)
483 return;
484 CurFrame->Instructions.push_back(Instruction);
485 }
486
EmitCFIAdjustCfaOffset(int64_t Adjustment)487 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
488 MCSymbol *Label = EmitCFILabel();
489 MCCFIInstruction Instruction =
490 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
491 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
492 if (!CurFrame)
493 return;
494 CurFrame->Instructions.push_back(Instruction);
495 }
496
EmitCFIDefCfaRegister(int64_t Register)497 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
498 MCSymbol *Label = EmitCFILabel();
499 MCCFIInstruction Instruction =
500 MCCFIInstruction::createDefCfaRegister(Label, Register);
501 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
502 if (!CurFrame)
503 return;
504 CurFrame->Instructions.push_back(Instruction);
505 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
506 }
507
EmitCFIOffset(int64_t Register,int64_t Offset)508 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
509 MCSymbol *Label = EmitCFILabel();
510 MCCFIInstruction Instruction =
511 MCCFIInstruction::createOffset(Label, Register, Offset);
512 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
513 if (!CurFrame)
514 return;
515 CurFrame->Instructions.push_back(Instruction);
516 }
517
EmitCFIRelOffset(int64_t Register,int64_t Offset)518 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
519 MCSymbol *Label = EmitCFILabel();
520 MCCFIInstruction Instruction =
521 MCCFIInstruction::createRelOffset(Label, Register, Offset);
522 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
523 if (!CurFrame)
524 return;
525 CurFrame->Instructions.push_back(Instruction);
526 }
527
EmitCFIPersonality(const MCSymbol * Sym,unsigned Encoding)528 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
529 unsigned Encoding) {
530 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
531 if (!CurFrame)
532 return;
533 CurFrame->Personality = Sym;
534 CurFrame->PersonalityEncoding = Encoding;
535 }
536
EmitCFILsda(const MCSymbol * Sym,unsigned Encoding)537 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
538 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
539 if (!CurFrame)
540 return;
541 CurFrame->Lsda = Sym;
542 CurFrame->LsdaEncoding = Encoding;
543 }
544
EmitCFIRememberState()545 void MCStreamer::EmitCFIRememberState() {
546 MCSymbol *Label = EmitCFILabel();
547 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
548 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
549 if (!CurFrame)
550 return;
551 CurFrame->Instructions.push_back(Instruction);
552 }
553
EmitCFIRestoreState()554 void MCStreamer::EmitCFIRestoreState() {
555 // FIXME: Error if there is no matching cfi_remember_state.
556 MCSymbol *Label = EmitCFILabel();
557 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
558 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
559 if (!CurFrame)
560 return;
561 CurFrame->Instructions.push_back(Instruction);
562 }
563
EmitCFISameValue(int64_t Register)564 void MCStreamer::EmitCFISameValue(int64_t Register) {
565 MCSymbol *Label = EmitCFILabel();
566 MCCFIInstruction Instruction =
567 MCCFIInstruction::createSameValue(Label, Register);
568 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
569 if (!CurFrame)
570 return;
571 CurFrame->Instructions.push_back(Instruction);
572 }
573
EmitCFIRestore(int64_t Register)574 void MCStreamer::EmitCFIRestore(int64_t Register) {
575 MCSymbol *Label = EmitCFILabel();
576 MCCFIInstruction Instruction =
577 MCCFIInstruction::createRestore(Label, Register);
578 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
579 if (!CurFrame)
580 return;
581 CurFrame->Instructions.push_back(Instruction);
582 }
583
EmitCFIEscape(StringRef Values)584 void MCStreamer::EmitCFIEscape(StringRef Values) {
585 MCSymbol *Label = EmitCFILabel();
586 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
587 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
588 if (!CurFrame)
589 return;
590 CurFrame->Instructions.push_back(Instruction);
591 }
592
EmitCFIGnuArgsSize(int64_t Size)593 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
594 MCSymbol *Label = EmitCFILabel();
595 MCCFIInstruction Instruction =
596 MCCFIInstruction::createGnuArgsSize(Label, Size);
597 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
598 if (!CurFrame)
599 return;
600 CurFrame->Instructions.push_back(Instruction);
601 }
602
EmitCFISignalFrame()603 void MCStreamer::EmitCFISignalFrame() {
604 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
605 if (!CurFrame)
606 return;
607 CurFrame->IsSignalFrame = true;
608 }
609
EmitCFIUndefined(int64_t Register)610 void MCStreamer::EmitCFIUndefined(int64_t Register) {
611 MCSymbol *Label = EmitCFILabel();
612 MCCFIInstruction Instruction =
613 MCCFIInstruction::createUndefined(Label, Register);
614 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
615 if (!CurFrame)
616 return;
617 CurFrame->Instructions.push_back(Instruction);
618 }
619
EmitCFIRegister(int64_t Register1,int64_t Register2)620 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
621 MCSymbol *Label = EmitCFILabel();
622 MCCFIInstruction Instruction =
623 MCCFIInstruction::createRegister(Label, Register1, Register2);
624 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
625 if (!CurFrame)
626 return;
627 CurFrame->Instructions.push_back(Instruction);
628 }
629
EmitCFIWindowSave()630 void MCStreamer::EmitCFIWindowSave() {
631 MCSymbol *Label = EmitCFILabel();
632 MCCFIInstruction Instruction =
633 MCCFIInstruction::createWindowSave(Label);
634 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
635 if (!CurFrame)
636 return;
637 CurFrame->Instructions.push_back(Instruction);
638 }
639
EmitCFINegateRAState()640 void MCStreamer::EmitCFINegateRAState() {
641 MCSymbol *Label = EmitCFILabel();
642 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
643 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
644 if (!CurFrame)
645 return;
646 CurFrame->Instructions.push_back(Instruction);
647 }
648
EmitCFIReturnColumn(int64_t Register)649 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
650 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
651 if (!CurFrame)
652 return;
653 CurFrame->RAReg = Register;
654 }
655
EnsureValidWinFrameInfo(SMLoc Loc)656 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
657 const MCAsmInfo *MAI = Context.getAsmInfo();
658 if (!MAI->usesWindowsCFI()) {
659 getContext().reportError(
660 Loc, ".seh_* directives are not supported on this target");
661 return nullptr;
662 }
663 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
664 getContext().reportError(
665 Loc, ".seh_ directive must appear within an active frame");
666 return nullptr;
667 }
668 return CurrentWinFrameInfo;
669 }
670
EmitWinCFIStartProc(const MCSymbol * Symbol,SMLoc Loc)671 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
672 const MCAsmInfo *MAI = Context.getAsmInfo();
673 if (!MAI->usesWindowsCFI())
674 return getContext().reportError(
675 Loc, ".seh_* directives are not supported on this target");
676 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
677 getContext().reportError(
678 Loc, "Starting a function before ending the previous one!");
679
680 MCSymbol *StartProc = EmitCFILabel();
681
682 WinFrameInfos.emplace_back(
683 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
684 CurrentWinFrameInfo = WinFrameInfos.back().get();
685 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
686 }
687
EmitWinCFIEndProc(SMLoc Loc)688 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
689 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
690 if (!CurFrame)
691 return;
692 if (CurFrame->ChainedParent)
693 getContext().reportError(Loc, "Not all chained regions terminated!");
694
695 MCSymbol *Label = EmitCFILabel();
696 CurFrame->End = Label;
697 }
698
EmitWinCFIFuncletOrFuncEnd(SMLoc Loc)699 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
700 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
701 if (!CurFrame)
702 return;
703 if (CurFrame->ChainedParent)
704 getContext().reportError(Loc, "Not all chained regions terminated!");
705
706 MCSymbol *Label = EmitCFILabel();
707 CurFrame->FuncletOrFuncEnd = Label;
708 }
709
EmitWinCFIStartChained(SMLoc Loc)710 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
711 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
712 if (!CurFrame)
713 return;
714
715 MCSymbol *StartProc = EmitCFILabel();
716
717 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
718 CurFrame->Function, StartProc, CurFrame));
719 CurrentWinFrameInfo = WinFrameInfos.back().get();
720 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
721 }
722
EmitWinCFIEndChained(SMLoc Loc)723 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
724 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
725 if (!CurFrame)
726 return;
727 if (!CurFrame->ChainedParent)
728 return getContext().reportError(
729 Loc, "End of a chained region outside a chained region!");
730
731 MCSymbol *Label = EmitCFILabel();
732
733 CurFrame->End = Label;
734 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
735 }
736
EmitWinEHHandler(const MCSymbol * Sym,bool Unwind,bool Except,SMLoc Loc)737 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
738 SMLoc Loc) {
739 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
740 if (!CurFrame)
741 return;
742 if (CurFrame->ChainedParent)
743 return getContext().reportError(
744 Loc, "Chained unwind areas can't have handlers!");
745 CurFrame->ExceptionHandler = Sym;
746 if (!Except && !Unwind)
747 getContext().reportError(Loc, "Don't know what kind of handler this is!");
748 if (Unwind)
749 CurFrame->HandlesUnwind = true;
750 if (Except)
751 CurFrame->HandlesExceptions = true;
752 }
753
EmitWinEHHandlerData(SMLoc Loc)754 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
755 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
756 if (!CurFrame)
757 return;
758 if (CurFrame->ChainedParent)
759 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
760 }
761
emitCGProfileEntry(const MCSymbolRefExpr * From,const MCSymbolRefExpr * To,uint64_t Count)762 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
763 const MCSymbolRefExpr *To, uint64_t Count) {
764 }
765
getWinCFISection(MCContext & Context,unsigned * NextWinCFIID,MCSection * MainCFISec,const MCSection * TextSec)766 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
767 MCSection *MainCFISec,
768 const MCSection *TextSec) {
769 // If this is the main .text section, use the main unwind info section.
770 if (TextSec == Context.getObjectFileInfo()->getTextSection())
771 return MainCFISec;
772
773 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
774 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
775 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
776
777 // If this section is COMDAT, this unwind section should be COMDAT associative
778 // with its group.
779 const MCSymbol *KeySym = nullptr;
780 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
781 KeySym = TextSecCOFF->getCOMDATSymbol();
782
783 // In a GNU environment, we can't use associative comdats. Instead, do what
784 // GCC does, which is to make plain comdat selectany section named like
785 // ".[px]data$_Z3foov".
786 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
787 std::string SectionName =
788 (MainCFISecCOFF->getSectionName() + "$" +
789 TextSecCOFF->getSectionName().split('$').second)
790 .str();
791 return Context.getCOFFSection(
792 SectionName,
793 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
794 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
795 }
796 }
797
798 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
799 }
800
getAssociatedPDataSection(const MCSection * TextSec)801 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
802 return getWinCFISection(getContext(), &NextWinCFIID,
803 getContext().getObjectFileInfo()->getPDataSection(),
804 TextSec);
805 }
806
getAssociatedXDataSection(const MCSection * TextSec)807 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
808 return getWinCFISection(getContext(), &NextWinCFIID,
809 getContext().getObjectFileInfo()->getXDataSection(),
810 TextSec);
811 }
812
EmitSyntaxDirective()813 void MCStreamer::EmitSyntaxDirective() {}
814
encodeSEHRegNum(MCContext & Ctx,MCRegister Reg)815 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
816 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
817 }
818
EmitWinCFIPushReg(MCRegister Register,SMLoc Loc)819 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
820 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
821 if (!CurFrame)
822 return;
823
824 MCSymbol *Label = EmitCFILabel();
825
826 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
827 Label, encodeSEHRegNum(Context, Register));
828 CurFrame->Instructions.push_back(Inst);
829 }
830
EmitWinCFISetFrame(MCRegister Register,unsigned Offset,SMLoc Loc)831 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
832 SMLoc Loc) {
833 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
834 if (!CurFrame)
835 return;
836 if (CurFrame->LastFrameInst >= 0)
837 return getContext().reportError(
838 Loc, "frame register and offset can be set at most once");
839 if (Offset & 0x0F)
840 return getContext().reportError(Loc, "offset is not a multiple of 16");
841 if (Offset > 240)
842 return getContext().reportError(
843 Loc, "frame offset must be less than or equal to 240");
844
845 MCSymbol *Label = EmitCFILabel();
846
847 WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
848 Label, encodeSEHRegNum(getContext(), Register), Offset);
849 CurFrame->LastFrameInst = CurFrame->Instructions.size();
850 CurFrame->Instructions.push_back(Inst);
851 }
852
EmitWinCFIAllocStack(unsigned Size,SMLoc Loc)853 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
854 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
855 if (!CurFrame)
856 return;
857 if (Size == 0)
858 return getContext().reportError(Loc,
859 "stack allocation size must be non-zero");
860 if (Size & 7)
861 return getContext().reportError(
862 Loc, "stack allocation size is not a multiple of 8");
863
864 MCSymbol *Label = EmitCFILabel();
865
866 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
867 CurFrame->Instructions.push_back(Inst);
868 }
869
EmitWinCFISaveReg(MCRegister Register,unsigned Offset,SMLoc Loc)870 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
871 SMLoc Loc) {
872 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
873 if (!CurFrame)
874 return;
875
876 if (Offset & 7)
877 return getContext().reportError(
878 Loc, "register save offset is not 8 byte aligned");
879
880 MCSymbol *Label = EmitCFILabel();
881
882 WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
883 Label, encodeSEHRegNum(Context, Register), Offset);
884 CurFrame->Instructions.push_back(Inst);
885 }
886
EmitWinCFISaveXMM(MCRegister Register,unsigned Offset,SMLoc Loc)887 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
888 SMLoc Loc) {
889 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
890 if (!CurFrame)
891 return;
892 if (Offset & 0x0F)
893 return getContext().reportError(Loc, "offset is not a multiple of 16");
894
895 MCSymbol *Label = EmitCFILabel();
896
897 WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
898 Label, encodeSEHRegNum(Context, Register), Offset);
899 CurFrame->Instructions.push_back(Inst);
900 }
901
EmitWinCFIPushFrame(bool Code,SMLoc Loc)902 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
903 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
904 if (!CurFrame)
905 return;
906 if (!CurFrame->Instructions.empty())
907 return getContext().reportError(
908 Loc, "If present, PushMachFrame must be the first UOP");
909
910 MCSymbol *Label = EmitCFILabel();
911
912 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
913 CurFrame->Instructions.push_back(Inst);
914 }
915
EmitWinCFIEndProlog(SMLoc Loc)916 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
917 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
918 if (!CurFrame)
919 return;
920
921 MCSymbol *Label = EmitCFILabel();
922
923 CurFrame->PrologEnd = Label;
924 }
925
EmitCOFFSafeSEH(MCSymbol const * Symbol)926 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
927
EmitCOFFSymbolIndex(MCSymbol const * Symbol)928 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
929
EmitCOFFSectionIndex(MCSymbol const * Symbol)930 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
931
EmitCOFFSecRel32(MCSymbol const * Symbol,uint64_t Offset)932 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
933
EmitCOFFImgRel32(MCSymbol const * Symbol,int64_t Offset)934 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
935
936 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
937 /// the specified string in the output .s file. This capability is
938 /// indicated by the hasRawTextSupport() predicate.
EmitRawTextImpl(StringRef String)939 void MCStreamer::EmitRawTextImpl(StringRef String) {
940 // This is not llvm_unreachable for the sake of out of tree backend
941 // developers who may not have assembly streamers and should serve as a
942 // reminder to not accidentally call EmitRawText in the absence of such.
943 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
944 "it (target backend is likely missing an AsmStreamer "
945 "implementation)");
946 }
947
EmitRawText(const Twine & T)948 void MCStreamer::EmitRawText(const Twine &T) {
949 SmallString<128> Str;
950 EmitRawTextImpl(T.toStringRef(Str));
951 }
952
EmitWindowsUnwindTables()953 void MCStreamer::EmitWindowsUnwindTables() {
954 }
955
Finish()956 void MCStreamer::Finish() {
957 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
958 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
959 getContext().reportError(SMLoc(), "Unfinished frame!");
960 return;
961 }
962
963 MCTargetStreamer *TS = getTargetStreamer();
964 if (TS)
965 TS->finish();
966
967 FinishImpl();
968 }
969
EmitAssignment(MCSymbol * Symbol,const MCExpr * Value)970 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
971 visitUsedExpr(*Value);
972 Symbol->setVariableValue(Value);
973
974 MCTargetStreamer *TS = getTargetStreamer();
975 if (TS)
976 TS->emitAssignment(Symbol, Value);
977 }
978
prettyPrintAsm(MCInstPrinter & InstPrinter,uint64_t Address,const MCInst & Inst,const MCSubtargetInfo & STI,raw_ostream & OS)979 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
980 uint64_t Address, const MCInst &Inst,
981 const MCSubtargetInfo &STI,
982 raw_ostream &OS) {
983 InstPrinter.printInst(&Inst, Address, "", STI, OS);
984 }
985
visitUsedSymbol(const MCSymbol & Sym)986 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
987 }
988
visitUsedExpr(const MCExpr & Expr)989 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
990 switch (Expr.getKind()) {
991 case MCExpr::Target:
992 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
993 break;
994
995 case MCExpr::Constant:
996 break;
997
998 case MCExpr::Binary: {
999 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
1000 visitUsedExpr(*BE.getLHS());
1001 visitUsedExpr(*BE.getRHS());
1002 break;
1003 }
1004
1005 case MCExpr::SymbolRef:
1006 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1007 break;
1008
1009 case MCExpr::Unary:
1010 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1011 break;
1012 }
1013 }
1014
EmitInstruction(const MCInst & Inst,const MCSubtargetInfo &)1015 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1016 // Scan for values.
1017 for (unsigned i = Inst.getNumOperands(); i--;)
1018 if (Inst.getOperand(i).isExpr())
1019 visitUsedExpr(*Inst.getOperand(i).getExpr());
1020 }
1021
emitAbsoluteSymbolDiff(const MCSymbol * Hi,const MCSymbol * Lo,unsigned Size)1022 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1023 unsigned Size) {
1024 // Get the Hi-Lo expression.
1025 const MCExpr *Diff =
1026 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1027 MCSymbolRefExpr::create(Lo, Context), Context);
1028
1029 const MCAsmInfo *MAI = Context.getAsmInfo();
1030 if (!MAI->doesSetDirectiveSuppressReloc()) {
1031 EmitValue(Diff, Size);
1032 return;
1033 }
1034
1035 // Otherwise, emit with .set (aka assignment).
1036 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
1037 EmitAssignment(SetLabel, Diff);
1038 EmitSymbolValue(SetLabel, Size);
1039 }
1040
emitAbsoluteSymbolDiffAsULEB128(const MCSymbol * Hi,const MCSymbol * Lo)1041 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1042 const MCSymbol *Lo) {
1043 // Get the Hi-Lo expression.
1044 const MCExpr *Diff =
1045 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1046 MCSymbolRefExpr::create(Lo, Context), Context);
1047
1048 EmitULEB128Value(Diff);
1049 }
1050
EmitAssemblerFlag(MCAssemblerFlag Flag)1051 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
EmitThumbFunc(MCSymbol * Func)1052 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
EmitSymbolDesc(MCSymbol * Symbol,unsigned DescValue)1053 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
BeginCOFFSymbolDef(const MCSymbol * Symbol)1054 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1055 llvm_unreachable("this directive only supported on COFF targets");
1056 }
EndCOFFSymbolDef()1057 void MCStreamer::EndCOFFSymbolDef() {
1058 llvm_unreachable("this directive only supported on COFF targets");
1059 }
EmitFileDirective(StringRef Filename)1060 void MCStreamer::EmitFileDirective(StringRef Filename) {}
EmitCOFFSymbolStorageClass(int StorageClass)1061 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1062 llvm_unreachable("this directive only supported on COFF targets");
1063 }
EmitCOFFSymbolType(int Type)1064 void MCStreamer::EmitCOFFSymbolType(int Type) {
1065 llvm_unreachable("this directive only supported on COFF targets");
1066 }
EmitXCOFFLocalCommonSymbol(MCSymbol * LabelSym,uint64_t Size,MCSymbol * CsectSym,unsigned ByteAlign)1067 void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
1068 MCSymbol *CsectSym,
1069 unsigned ByteAlign) {
1070 llvm_unreachable("this directive only supported on XCOFF targets");
1071 }
emitELFSize(MCSymbol * Symbol,const MCExpr * Value)1072 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
emitELFSymverDirective(StringRef AliasName,const MCSymbol * Aliasee)1073 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1074 const MCSymbol *Aliasee) {}
EmitLocalCommonSymbol(MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)1075 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1076 unsigned ByteAlignment) {}
EmitTBSSSymbol(MCSection * Section,MCSymbol * Symbol,uint64_t Size,unsigned ByteAlignment)1077 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1078 uint64_t Size, unsigned ByteAlignment) {}
ChangeSection(MCSection *,const MCExpr *)1079 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
EmitWeakReference(MCSymbol * Alias,const MCSymbol * Symbol)1080 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
EmitBytes(StringRef Data)1081 void MCStreamer::EmitBytes(StringRef Data) {}
EmitBinaryData(StringRef Data)1082 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
EmitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)1083 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1084 visitUsedExpr(*Value);
1085 }
EmitULEB128Value(const MCExpr * Value)1086 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
EmitSLEB128Value(const MCExpr * Value)1087 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
emitFill(const MCExpr & NumBytes,uint64_t Value,SMLoc Loc)1088 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
emitFill(const MCExpr & NumValues,int64_t Size,int64_t Expr,SMLoc Loc)1089 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1090 SMLoc Loc) {}
EmitValueToAlignment(unsigned ByteAlignment,int64_t Value,unsigned ValueSize,unsigned MaxBytesToEmit)1091 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1092 unsigned ValueSize,
1093 unsigned MaxBytesToEmit) {}
EmitCodeAlignment(unsigned ByteAlignment,unsigned MaxBytesToEmit)1094 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1095 unsigned MaxBytesToEmit) {}
emitValueToOffset(const MCExpr * Offset,unsigned char Value,SMLoc Loc)1096 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1097 SMLoc Loc) {}
EmitBundleAlignMode(unsigned AlignPow2)1098 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
EmitBundleLock(bool AlignToEnd)1099 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
FinishImpl()1100 void MCStreamer::FinishImpl() {}
EmitBundleUnlock()1101 void MCStreamer::EmitBundleUnlock() {}
1102
SwitchSection(MCSection * Section,const MCExpr * Subsection)1103 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1104 assert(Section && "Cannot switch to a null section!");
1105 MCSectionSubPair curSection = SectionStack.back().first;
1106 SectionStack.back().second = curSection;
1107 if (MCSectionSubPair(Section, Subsection) != curSection) {
1108 ChangeSection(Section, Subsection);
1109 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1110 assert(!Section->hasEnded() && "Section already ended");
1111 MCSymbol *Sym = Section->getBeginSymbol();
1112 if (Sym && !Sym->isInSection())
1113 EmitLabel(Sym);
1114 }
1115 }
1116
endSection(MCSection * Section)1117 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1118 // TODO: keep track of the last subsection so that this symbol appears in the
1119 // correct place.
1120 MCSymbol *Sym = Section->getEndSymbol(Context);
1121 if (Sym->isInSection())
1122 return Sym;
1123
1124 SwitchSection(Section);
1125 EmitLabel(Sym);
1126 return Sym;
1127 }
1128
EmitVersionForTarget(const Triple & Target,const VersionTuple & SDKVersion)1129 void MCStreamer::EmitVersionForTarget(const Triple &Target,
1130 const VersionTuple &SDKVersion) {
1131 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1132 return;
1133 // Do we even know the version?
1134 if (Target.getOSMajorVersion() == 0)
1135 return;
1136
1137 unsigned Major;
1138 unsigned Minor;
1139 unsigned Update;
1140 if (Target.isMacCatalystEnvironment()) {
1141 // Mac Catalyst always uses the build version load command.
1142 Target.getiOSVersion(Major, Minor, Update);
1143 assert(Major && "A non-zero major version is expected");
1144 EmitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update,
1145 SDKVersion);
1146 return;
1147 }
1148
1149 MCVersionMinType VersionType;
1150 if (Target.isWatchOS()) {
1151 VersionType = MCVM_WatchOSVersionMin;
1152 Target.getWatchOSVersion(Major, Minor, Update);
1153 } else if (Target.isTvOS()) {
1154 VersionType = MCVM_TvOSVersionMin;
1155 Target.getiOSVersion(Major, Minor, Update);
1156 } else if (Target.isMacOSX()) {
1157 VersionType = MCVM_OSXVersionMin;
1158 if (!Target.getMacOSXVersion(Major, Minor, Update))
1159 Major = 0;
1160 } else {
1161 VersionType = MCVM_IOSVersionMin;
1162 Target.getiOSVersion(Major, Minor, Update);
1163 }
1164 if (Major != 0)
1165 EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion);
1166 }
1167