1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCStreamer.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"
41 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
42 S.setTargetStreamer(this);
45 // Pin the vtables to this file.
46 MCTargetStreamer::~MCTargetStreamer() = default;
48 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
50 void MCTargetStreamer::finish() {}
52 void MCTargetStreamer::changeSection(const MCSection *CurSection,
54 const MCExpr *Subsection,
56 Section->PrintSwitchToSection(
57 *Streamer.getContext().getAsmInfo(),
58 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
62 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
63 Streamer.EmitRawText(Directive);
66 void MCTargetStreamer::emitValue(const MCExpr *Value) {
68 raw_svector_ostream OS(Str);
70 Value->print(OS, Streamer.getContext().getAsmInfo());
71 Streamer.EmitRawText(OS.str());
74 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
76 MCStreamer::MCStreamer(MCContext &Ctx)
77 : Context(Ctx), CurrentWinFrameInfo(nullptr) {
78 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
81 MCStreamer::~MCStreamer() {}
83 void MCStreamer::reset() {
84 DwarfFrameInfos.clear();
85 CurrentWinFrameInfo = nullptr;
86 WinFrameInfos.clear();
87 SymbolOrdering.clear();
89 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
92 raw_ostream &MCStreamer::GetCommentOS() {
93 // By default, discard comments.
97 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
99 void MCStreamer::addExplicitComment(const Twine &T) {}
100 void MCStreamer::emitExplicitComments() {}
102 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
103 for (auto &FI : DwarfFrameInfos)
104 FI.CompactUnwindEncoding =
105 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
108 /// EmitIntValue - Special case of EmitValue that avoids the client having to
109 /// pass in a MCExpr for constant integers.
110 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
111 assert(1 <= Size && Size <= 8 && "Invalid size");
112 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
115 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
116 for (unsigned i = 0; i != Size; ++i) {
117 unsigned index = isLittleEndian ? i : (Size - i - 1);
118 buf[i] = uint8_t(Value >> (index * 8));
120 EmitBytes(StringRef(buf, Size));
123 /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
124 /// client having to pass in a MCExpr for constant integers.
125 void MCStreamer::EmitPaddedULEB128IntValue(uint64_t Value, unsigned PadTo) {
126 SmallString<128> Tmp;
127 raw_svector_ostream OSE(Tmp);
128 encodeULEB128(Value, OSE, PadTo);
129 EmitBytes(OSE.str());
132 void MCStreamer::EmitULEB128IntValue(uint64_t Value) {
133 EmitPaddedULEB128IntValue(Value, 0);
136 /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
137 /// client having to pass in a MCExpr for constant integers.
138 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
139 SmallString<128> Tmp;
140 raw_svector_ostream OSE(Tmp);
141 encodeSLEB128(Value, OSE);
142 EmitBytes(OSE.str());
145 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
146 EmitValueImpl(Value, Size, Loc);
149 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
150 bool IsSectionRelative) {
151 assert((!IsSectionRelative || Size == 4) &&
152 "SectionRelative value requires 4-bytes");
154 if (!IsSectionRelative)
155 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
157 EmitCOFFSecRel32(Sym, /*Offset=*/0);
160 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
161 report_fatal_error("unsupported directive in streamer");
164 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
165 report_fatal_error("unsupported directive in streamer");
168 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
169 report_fatal_error("unsupported directive in streamer");
172 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
173 report_fatal_error("unsupported directive in streamer");
176 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
177 report_fatal_error("unsupported directive in streamer");
180 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
181 report_fatal_error("unsupported directive in streamer");
184 /// Emit NumBytes bytes worth of the value specified by FillValue.
185 /// This implements directives such as '.space'.
186 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
187 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
190 void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
191 int64_t NonZeroSize = Size > 4 ? 4 : Size;
192 Expr &= ~0ULL >> (64 - NonZeroSize * 8);
193 for (uint64_t i = 0, e = NumValues; i != e; ++i) {
194 EmitIntValue(Expr, NonZeroSize);
195 if (NonZeroSize < Size)
196 EmitIntValue(0, Size - NonZeroSize);
200 /// The implementation in this class just redirects to emitFill.
201 void MCStreamer::EmitZeros(uint64_t NumBytes) {
202 emitFill(NumBytes, 0);
205 unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
207 StringRef Filename, unsigned CUID) {
208 return getContext().getDwarfFile(Directory, Filename, FileNo, CUID);
211 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
212 unsigned Column, unsigned Flags,
214 unsigned Discriminator,
215 StringRef FileName) {
216 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
220 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
221 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
222 if (!Table.getLabel()) {
223 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
225 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
227 return Table.getLabel();
230 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
231 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
234 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
235 if (!hasUnfinishedDwarfFrameInfo()) {
236 getContext().reportError(SMLoc(), "this directive must appear between "
237 ".cfi_startproc and .cfi_endproc "
241 return &DwarfFrameInfos.back();
244 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
245 ArrayRef<uint8_t> Checksum,
246 unsigned ChecksumKind) {
247 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
251 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
252 return getContext().getCVContext().recordFunctionId(FunctionId);
255 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
256 unsigned IAFunc, unsigned IAFile,
257 unsigned IALine, unsigned IACol,
259 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
260 getContext().reportError(Loc, "parent function id not introduced by "
261 ".cv_func_id or .cv_inline_site_id");
265 return getContext().getCVContext().recordInlinedCallSiteId(
266 FunctionId, IAFunc, IAFile, IALine, IACol);
269 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
270 unsigned Line, unsigned Column,
271 bool PrologueEnd, bool IsStmt,
272 StringRef FileName, SMLoc Loc) {
273 CodeViewContext &CVC = getContext().getCVContext();
274 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FunctionId);
276 return getContext().reportError(
277 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
280 if (FI->Section == nullptr)
281 FI->Section = getCurrentSectionOnly();
282 else if (FI->Section != getCurrentSectionOnly())
283 return getContext().reportError(
285 "all .cv_loc directives for a function must be in the same section");
287 CVC.setCurrentCVLoc(FunctionId, FileNo, Line, Column, PrologueEnd, IsStmt);
290 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
291 const MCSymbol *Begin,
292 const MCSymbol *End) {}
294 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
295 unsigned SourceFileId,
296 unsigned SourceLineNum,
297 const MCSymbol *FnStartSym,
298 const MCSymbol *FnEndSym) {}
300 void MCStreamer::EmitCVDefRangeDirective(
301 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
302 StringRef FixedSizePortion) {}
304 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
305 MCSymbol *EHSymbol) {
308 void MCStreamer::InitSections(bool NoExecStack) {
309 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
312 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
314 Symbol->setFragment(Fragment);
316 // As we emit symbols into a section, track the order so that they can
317 // be sorted upon later. Zero is reserved to mean 'unemitted'.
318 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
321 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
322 Symbol->redefineIfPossible();
324 if (!Symbol->isUndefined() || Symbol->isVariable())
325 return getContext().reportError(Loc, "invalid symbol redefinition");
327 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
328 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
329 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
330 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
332 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
334 MCTargetStreamer *TS = getTargetStreamer();
336 TS->emitLabel(Symbol);
339 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
343 void MCStreamer::EmitCFIStartProc(bool IsSimple) {
344 if (hasUnfinishedDwarfFrameInfo())
345 getContext().reportError(
346 SMLoc(), "starting new .cfi frame before finishing the previous one");
348 MCDwarfFrameInfo Frame;
349 Frame.IsSimple = IsSimple;
350 EmitCFIStartProcImpl(Frame);
352 const MCAsmInfo* MAI = Context.getAsmInfo();
354 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
355 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
356 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
357 Frame.CurrentCfaRegister = Inst.getRegister();
362 DwarfFrameInfos.push_back(Frame);
365 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
368 void MCStreamer::EmitCFIEndProc() {
369 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
372 EmitCFIEndProcImpl(*CurFrame);
375 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
376 // Put a dummy non-null value in Frame.End to mark that this frame has been
378 Frame.End = (MCSymbol *)1;
381 MCSymbol *MCStreamer::EmitCFILabel() {
382 // Return a dummy non-null value so that label fields appear filled in when
383 // generating textual assembly.
384 return (MCSymbol *)1;
387 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
388 MCSymbol *Label = EmitCFILabel();
389 MCCFIInstruction Instruction =
390 MCCFIInstruction::createDefCfa(Label, Register, Offset);
391 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
394 CurFrame->Instructions.push_back(Instruction);
395 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
398 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
399 MCSymbol *Label = EmitCFILabel();
400 MCCFIInstruction Instruction =
401 MCCFIInstruction::createDefCfaOffset(Label, Offset);
402 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
405 CurFrame->Instructions.push_back(Instruction);
408 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
409 MCSymbol *Label = EmitCFILabel();
410 MCCFIInstruction Instruction =
411 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
412 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
415 CurFrame->Instructions.push_back(Instruction);
418 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
419 MCSymbol *Label = EmitCFILabel();
420 MCCFIInstruction Instruction =
421 MCCFIInstruction::createDefCfaRegister(Label, Register);
422 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
425 CurFrame->Instructions.push_back(Instruction);
426 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
429 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
430 MCSymbol *Label = EmitCFILabel();
431 MCCFIInstruction Instruction =
432 MCCFIInstruction::createOffset(Label, Register, Offset);
433 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
436 CurFrame->Instructions.push_back(Instruction);
439 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
440 MCSymbol *Label = EmitCFILabel();
441 MCCFIInstruction Instruction =
442 MCCFIInstruction::createRelOffset(Label, Register, Offset);
443 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
446 CurFrame->Instructions.push_back(Instruction);
449 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
451 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
454 CurFrame->Personality = Sym;
455 CurFrame->PersonalityEncoding = Encoding;
458 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
459 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
462 CurFrame->Lsda = Sym;
463 CurFrame->LsdaEncoding = Encoding;
466 void MCStreamer::EmitCFIRememberState() {
467 MCSymbol *Label = EmitCFILabel();
468 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
469 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
472 CurFrame->Instructions.push_back(Instruction);
475 void MCStreamer::EmitCFIRestoreState() {
476 // FIXME: Error if there is no matching cfi_remember_state.
477 MCSymbol *Label = EmitCFILabel();
478 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
479 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
482 CurFrame->Instructions.push_back(Instruction);
485 void MCStreamer::EmitCFISameValue(int64_t Register) {
486 MCSymbol *Label = EmitCFILabel();
487 MCCFIInstruction Instruction =
488 MCCFIInstruction::createSameValue(Label, Register);
489 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
492 CurFrame->Instructions.push_back(Instruction);
495 void MCStreamer::EmitCFIRestore(int64_t Register) {
496 MCSymbol *Label = EmitCFILabel();
497 MCCFIInstruction Instruction =
498 MCCFIInstruction::createRestore(Label, Register);
499 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
502 CurFrame->Instructions.push_back(Instruction);
505 void MCStreamer::EmitCFIEscape(StringRef Values) {
506 MCSymbol *Label = EmitCFILabel();
507 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
508 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
511 CurFrame->Instructions.push_back(Instruction);
514 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
515 MCSymbol *Label = EmitCFILabel();
516 MCCFIInstruction Instruction =
517 MCCFIInstruction::createGnuArgsSize(Label, Size);
518 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
521 CurFrame->Instructions.push_back(Instruction);
524 void MCStreamer::EmitCFISignalFrame() {
525 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
528 CurFrame->IsSignalFrame = true;
531 void MCStreamer::EmitCFIUndefined(int64_t Register) {
532 MCSymbol *Label = EmitCFILabel();
533 MCCFIInstruction Instruction =
534 MCCFIInstruction::createUndefined(Label, Register);
535 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
538 CurFrame->Instructions.push_back(Instruction);
541 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
542 MCSymbol *Label = EmitCFILabel();
543 MCCFIInstruction Instruction =
544 MCCFIInstruction::createRegister(Label, Register1, Register2);
545 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
548 CurFrame->Instructions.push_back(Instruction);
551 void MCStreamer::EmitCFIWindowSave() {
552 MCSymbol *Label = EmitCFILabel();
553 MCCFIInstruction Instruction =
554 MCCFIInstruction::createWindowSave(Label);
555 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
558 CurFrame->Instructions.push_back(Instruction);
561 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
562 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
565 CurFrame->RAReg = Register;
568 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
569 const MCAsmInfo *MAI = Context.getAsmInfo();
570 if (!MAI->usesWindowsCFI()) {
571 getContext().reportError(
572 Loc, ".seh_* directives are not supported on this target");
575 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
576 getContext().reportError(
577 Loc, ".seh_ directive must appear within an active frame");
580 return CurrentWinFrameInfo;
583 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
584 const MCAsmInfo *MAI = Context.getAsmInfo();
585 if (!MAI->usesWindowsCFI())
586 return getContext().reportError(
587 Loc, ".seh_* directives are not supported on this target");
588 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
589 getContext().reportError(
590 Loc, "Starting a function before ending the previous one!");
592 MCSymbol *StartProc = EmitCFILabel();
594 WinFrameInfos.emplace_back(
595 llvm::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
596 CurrentWinFrameInfo = WinFrameInfos.back().get();
597 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
600 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
601 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
604 if (CurFrame->ChainedParent)
605 getContext().reportError(Loc, "Not all chained regions terminated!");
607 MCSymbol *Label = EmitCFILabel();
608 CurFrame->End = Label;
611 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
612 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
616 MCSymbol *StartProc = EmitCFILabel();
618 WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>(
619 CurFrame->Function, StartProc, CurFrame));
620 CurrentWinFrameInfo = WinFrameInfos.back().get();
621 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
624 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
625 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
628 if (!CurFrame->ChainedParent)
629 return getContext().reportError(
630 Loc, "End of a chained region outside a chained region!");
632 MCSymbol *Label = EmitCFILabel();
634 CurFrame->End = Label;
635 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
638 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
640 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
643 if (CurFrame->ChainedParent)
644 return getContext().reportError(
645 Loc, "Chained unwind areas can't have handlers!");
646 CurFrame->ExceptionHandler = Sym;
647 if (!Except && !Unwind)
648 getContext().reportError(Loc, "Don't know what kind of handler this is!");
650 CurFrame->HandlesUnwind = true;
652 CurFrame->HandlesExceptions = true;
655 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
656 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
659 if (CurFrame->ChainedParent)
660 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
663 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
664 MCSection *MainCFISec,
665 const MCSection *TextSec) {
666 // If this is the main .text section, use the main unwind info section.
667 if (TextSec == Context.getObjectFileInfo()->getTextSection())
670 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
671 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
673 // If this section is COMDAT, this unwind section should be COMDAT associative
675 const MCSymbol *KeySym = nullptr;
676 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)
677 KeySym = TextSecCOFF->getCOMDATSymbol();
679 return Context.getAssociativeCOFFSection(cast<MCSectionCOFF>(MainCFISec),
683 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
684 return getWinCFISection(getContext(), &NextWinCFIID,
685 getContext().getObjectFileInfo()->getPDataSection(),
689 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
690 return getWinCFISection(getContext(), &NextWinCFIID,
691 getContext().getObjectFileInfo()->getXDataSection(),
695 void MCStreamer::EmitSyntaxDirective() {}
697 void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
698 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
702 MCSymbol *Label = EmitCFILabel();
704 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
705 CurFrame->Instructions.push_back(Inst);
708 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
710 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
713 if (CurFrame->LastFrameInst >= 0)
714 return getContext().reportError(
715 Loc, "frame register and offset can be set at most once");
717 return getContext().reportError(Loc, "offset is not a multiple of 16");
719 return getContext().reportError(
720 Loc, "frame offset must be less than or equal to 240");
722 MCSymbol *Label = EmitCFILabel();
724 WinEH::Instruction Inst =
725 Win64EH::Instruction::SetFPReg(Label, Register, Offset);
726 CurFrame->LastFrameInst = CurFrame->Instructions.size();
727 CurFrame->Instructions.push_back(Inst);
730 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
731 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
735 return getContext().reportError(Loc,
736 "stack allocation size must be non-zero");
738 return getContext().reportError(
739 Loc, "stack allocation size is not a multiple of 8");
741 MCSymbol *Label = EmitCFILabel();
743 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
744 CurFrame->Instructions.push_back(Inst);
747 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
749 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
754 return getContext().reportError(
755 Loc, "register save offset is not 8 byte aligned");
757 MCSymbol *Label = EmitCFILabel();
759 WinEH::Instruction Inst =
760 Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
761 CurFrame->Instructions.push_back(Inst);
764 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
766 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
770 return getContext().reportError(Loc, "offset is not a multiple of 16");
772 MCSymbol *Label = EmitCFILabel();
774 WinEH::Instruction Inst =
775 Win64EH::Instruction::SaveXMM(Label, Register, Offset);
776 CurFrame->Instructions.push_back(Inst);
779 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
780 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
783 if (!CurFrame->Instructions.empty())
784 return getContext().reportError(
785 Loc, "If present, PushMachFrame must be the first UOP");
787 MCSymbol *Label = EmitCFILabel();
789 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
790 CurFrame->Instructions.push_back(Inst);
793 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
794 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
798 MCSymbol *Label = EmitCFILabel();
800 CurFrame->PrologEnd = Label;
803 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
806 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {
809 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
811 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
812 /// the specified string in the output .s file. This capability is
813 /// indicated by the hasRawTextSupport() predicate.
814 void MCStreamer::EmitRawTextImpl(StringRef String) {
815 errs() << "EmitRawText called on an MCStreamer that doesn't support it, "
816 " something must not be fully mc'ized\n";
820 void MCStreamer::EmitRawText(const Twine &T) {
821 SmallString<128> Str;
822 EmitRawTextImpl(T.toStringRef(Str));
825 void MCStreamer::EmitWindowsUnwindTables() {
828 void MCStreamer::Finish() {
829 if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
830 getContext().reportError(SMLoc(), "Unfinished frame!");
831 if (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)
832 getContext().reportError(SMLoc(), "Unfinished frame!");
834 MCTargetStreamer *TS = getTargetStreamer();
841 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
842 visitUsedExpr(*Value);
843 Symbol->setVariableValue(Value);
845 MCTargetStreamer *TS = getTargetStreamer();
847 TS->emitAssignment(Symbol, Value);
850 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS,
851 const MCInst &Inst, const MCSubtargetInfo &STI) {
852 InstPrinter.printInst(&Inst, OS, "", STI);
855 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
858 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
859 switch (Expr.getKind()) {
861 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
864 case MCExpr::Constant:
867 case MCExpr::Binary: {
868 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
869 visitUsedExpr(*BE.getLHS());
870 visitUsedExpr(*BE.getRHS());
874 case MCExpr::SymbolRef:
875 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
879 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
884 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
887 for (unsigned i = Inst.getNumOperands(); i--;)
888 if (Inst.getOperand(i).isExpr())
889 visitUsedExpr(*Inst.getOperand(i).getExpr());
892 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
894 // Get the Hi-Lo expression.
896 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
897 MCSymbolRefExpr::create(Lo, Context), Context);
899 const MCAsmInfo *MAI = Context.getAsmInfo();
900 if (!MAI->doesSetDirectiveSuppressReloc()) {
901 EmitValue(Diff, Size);
905 // Otherwise, emit with .set (aka assignment).
906 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
907 EmitAssignment(SetLabel, Diff);
908 EmitSymbolValue(SetLabel, Size);
911 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
912 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
913 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
914 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
915 llvm_unreachable("this directive only supported on COFF targets");
917 void MCStreamer::EndCOFFSymbolDef() {
918 llvm_unreachable("this directive only supported on COFF targets");
920 void MCStreamer::EmitFileDirective(StringRef Filename) {}
921 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
922 llvm_unreachable("this directive only supported on COFF targets");
924 void MCStreamer::EmitCOFFSymbolType(int Type) {
925 llvm_unreachable("this directive only supported on COFF targets");
927 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
928 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
929 const MCSymbol *Aliasee) {}
930 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
931 unsigned ByteAlignment) {}
932 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
933 uint64_t Size, unsigned ByteAlignment) {}
934 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
935 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
936 void MCStreamer::EmitBytes(StringRef Data) {}
937 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
938 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
939 visitUsedExpr(*Value);
941 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
942 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
943 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
944 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
946 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
948 unsigned MaxBytesToEmit) {}
949 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
950 unsigned MaxBytesToEmit) {}
951 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
953 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
954 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
955 void MCStreamer::FinishImpl() {}
956 void MCStreamer::EmitBundleUnlock() {}
958 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
959 assert(Section && "Cannot switch to a null section!");
960 MCSectionSubPair curSection = SectionStack.back().first;
961 SectionStack.back().second = curSection;
962 if (MCSectionSubPair(Section, Subsection) != curSection) {
963 ChangeSection(Section, Subsection);
964 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
965 assert(!Section->hasEnded() && "Section already ended");
966 MCSymbol *Sym = Section->getBeginSymbol();
967 if (Sym && !Sym->isInSection())
972 MCSymbol *MCStreamer::endSection(MCSection *Section) {
973 // TODO: keep track of the last subsection so that this symbol appears in the
975 MCSymbol *Sym = Section->getEndSymbol(Context);
976 if (Sym->isInSection())
979 SwitchSection(Section);
984 void MCStreamer::EmitVersionForTarget(const Triple &Target) {
985 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
987 // Do we even know the version?
988 if (Target.getOSMajorVersion() == 0)
994 MCVersionMinType VersionType;
995 if (Target.isWatchOS()) {
996 VersionType = MCVM_WatchOSVersionMin;
997 Target.getWatchOSVersion(Major, Minor, Update);
998 } else if (Target.isTvOS()) {
999 VersionType = MCVM_TvOSVersionMin;
1000 Target.getiOSVersion(Major, Minor, Update);
1001 } else if (Target.isMacOSX()) {
1002 VersionType = MCVM_OSXVersionMin;
1003 if (!Target.getMacOSXVersion(Major, Minor, Update))
1006 VersionType = MCVM_IOSVersionMin;
1007 Target.getiOSVersion(Major, Minor, Update);
1010 EmitVersionMin(VersionType, Major, Minor, Update);