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