1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
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
7 //===----------------------------------------------------------------------===//
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"
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::emitRawBytes(StringRef Data
) {
75 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
76 const char *Directive
= MAI
->getData8bitsDirective();
77 for (const unsigned char C
: Data
.bytes()) {
79 raw_svector_ostream
OS(Str
);
81 OS
<< Directive
<< (unsigned)C
;
82 Streamer
.EmitRawText(OS
.str());
86 void MCTargetStreamer::emitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
88 MCStreamer::MCStreamer(MCContext
&Ctx
)
89 : Context(Ctx
), CurrentWinFrameInfo(nullptr),
90 UseAssemblerInfoForParsing(false) {
91 SectionStack
.push_back(std::pair
<MCSectionSubPair
, MCSectionSubPair
>());
94 MCStreamer::~MCStreamer() {}
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
>());
105 raw_ostream
&MCStreamer::GetCommentOS() {
106 // By default, discard comments.
110 void MCStreamer::emitRawComment(const Twine
&T
, bool TabPrefix
) {}
112 void MCStreamer::addExplicitComment(const Twine
&T
) {}
113 void MCStreamer::emitExplicitComments() {}
115 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend
*MAB
) {
116 for (auto &FI
: DwarfFrameInfos
)
117 FI
.CompactUnwindEncoding
=
118 (MAB
? MAB
->generateCompactUnwindEncoding(FI
.Instructions
) : 0);
121 /// EmitIntValue - Special case of EmitValue that avoids the client having to
122 /// pass in a MCExpr for constant integers.
123 void MCStreamer::EmitIntValue(uint64_t Value
, unsigned Size
) {
124 assert(1 <= Size
&& Size
<= 8 && "Invalid size");
125 assert((isUIntN(8 * Size
, Value
) || isIntN(8 * Size
, Value
)) &&
128 const bool isLittleEndian
= Context
.getAsmInfo()->isLittleEndian();
129 for (unsigned i
= 0; i
!= Size
; ++i
) {
130 unsigned index
= isLittleEndian
? i
: (Size
- i
- 1);
131 buf
[i
] = uint8_t(Value
>> (index
* 8));
133 EmitBytes(StringRef(buf
, Size
));
136 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
137 /// client having to pass in a MCExpr for constant integers.
138 void MCStreamer::EmitULEB128IntValue(uint64_t Value
) {
139 SmallString
<128> Tmp
;
140 raw_svector_ostream
OSE(Tmp
);
141 encodeULEB128(Value
, OSE
);
142 EmitBytes(OSE
.str());
145 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
146 /// client having to pass in a MCExpr for constant integers.
147 void MCStreamer::EmitSLEB128IntValue(int64_t Value
) {
148 SmallString
<128> Tmp
;
149 raw_svector_ostream
OSE(Tmp
);
150 encodeSLEB128(Value
, OSE
);
151 EmitBytes(OSE
.str());
154 void MCStreamer::EmitValue(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
155 EmitValueImpl(Value
, Size
, Loc
);
158 void MCStreamer::EmitSymbolValue(const MCSymbol
*Sym
, unsigned Size
,
159 bool IsSectionRelative
) {
160 assert((!IsSectionRelative
|| Size
== 4) &&
161 "SectionRelative value requires 4-bytes");
163 if (!IsSectionRelative
)
164 EmitValueImpl(MCSymbolRefExpr::create(Sym
, getContext()), Size
);
166 EmitCOFFSecRel32(Sym
, /*Offset=*/0);
169 void MCStreamer::EmitDTPRel64Value(const MCExpr
*Value
) {
170 report_fatal_error("unsupported directive in streamer");
173 void MCStreamer::EmitDTPRel32Value(const MCExpr
*Value
) {
174 report_fatal_error("unsupported directive in streamer");
177 void MCStreamer::EmitTPRel64Value(const MCExpr
*Value
) {
178 report_fatal_error("unsupported directive in streamer");
181 void MCStreamer::EmitTPRel32Value(const MCExpr
*Value
) {
182 report_fatal_error("unsupported directive in streamer");
185 void MCStreamer::EmitGPRel64Value(const MCExpr
*Value
) {
186 report_fatal_error("unsupported directive in streamer");
189 void MCStreamer::EmitGPRel32Value(const MCExpr
*Value
) {
190 report_fatal_error("unsupported directive in streamer");
193 /// Emit NumBytes bytes worth of the value specified by FillValue.
194 /// This implements directives such as '.space'.
195 void MCStreamer::emitFill(uint64_t NumBytes
, uint8_t FillValue
) {
196 emitFill(*MCConstantExpr::create(NumBytes
, getContext()), FillValue
);
199 /// The implementation in this class just redirects to emitFill.
200 void MCStreamer::EmitZeros(uint64_t NumBytes
) {
201 emitFill(NumBytes
, 0);
205 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo
, StringRef Directory
,
207 MD5::MD5Result
*Checksum
,
208 Optional
<StringRef
> Source
,
210 return getContext().getDwarfFile(Directory
, Filename
, FileNo
, Checksum
,
214 void MCStreamer::emitDwarfFile0Directive(StringRef Directory
,
216 MD5::MD5Result
*Checksum
,
217 Optional
<StringRef
> Source
,
219 getContext().setMCLineTableRootFile(CUID
, Directory
, Filename
, Checksum
,
223 void MCStreamer::EmitCFIBKeyFrame() {
224 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
227 CurFrame
->IsBKeyFrame
= true;
230 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
231 unsigned Column
, unsigned Flags
,
233 unsigned Discriminator
,
234 StringRef FileName
) {
235 getContext().setCurrentDwarfLoc(FileNo
, Line
, Column
, Flags
, Isa
,
239 MCSymbol
*MCStreamer::getDwarfLineTableSymbol(unsigned CUID
) {
240 MCDwarfLineTable
&Table
= getContext().getMCDwarfLineTable(CUID
);
241 if (!Table
.getLabel()) {
242 StringRef Prefix
= Context
.getAsmInfo()->getPrivateGlobalPrefix();
244 Context
.getOrCreateSymbol(Prefix
+ "line_table_start" + Twine(CUID
)));
246 return Table
.getLabel();
249 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
250 return !DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
;
253 MCDwarfFrameInfo
*MCStreamer::getCurrentDwarfFrameInfo() {
254 if (!hasUnfinishedDwarfFrameInfo()) {
255 getContext().reportError(SMLoc(), "this directive must appear between "
256 ".cfi_startproc and .cfi_endproc "
260 return &DwarfFrameInfos
.back();
263 bool MCStreamer::EmitCVFileDirective(unsigned FileNo
, StringRef Filename
,
264 ArrayRef
<uint8_t> Checksum
,
265 unsigned ChecksumKind
) {
266 return getContext().getCVContext().addFile(*this, FileNo
, Filename
, Checksum
,
270 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId
) {
271 return getContext().getCVContext().recordFunctionId(FunctionId
);
274 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId
,
275 unsigned IAFunc
, unsigned IAFile
,
276 unsigned IALine
, unsigned IACol
,
278 if (getContext().getCVContext().getCVFunctionInfo(IAFunc
) == nullptr) {
279 getContext().reportError(Loc
, "parent function id not introduced by "
280 ".cv_func_id or .cv_inline_site_id");
284 return getContext().getCVContext().recordInlinedCallSiteId(
285 FunctionId
, IAFunc
, IAFile
, IALine
, IACol
);
288 void MCStreamer::EmitCVLocDirective(unsigned FunctionId
, unsigned FileNo
,
289 unsigned Line
, unsigned Column
,
290 bool PrologueEnd
, bool IsStmt
,
291 StringRef FileName
, SMLoc Loc
) {}
293 bool MCStreamer::checkCVLocSection(unsigned FuncId
, unsigned FileNo
,
295 CodeViewContext
&CVC
= getContext().getCVContext();
296 MCCVFunctionInfo
*FI
= CVC
.getCVFunctionInfo(FuncId
);
298 getContext().reportError(
299 Loc
, "function id not introduced by .cv_func_id or .cv_inline_site_id");
304 if (FI
->Section
== nullptr)
305 FI
->Section
= getCurrentSectionOnly();
306 else if (FI
->Section
!= getCurrentSectionOnly()) {
307 getContext().reportError(
309 "all .cv_loc directives for a function must be in the same section");
315 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId
,
316 const MCSymbol
*Begin
,
317 const MCSymbol
*End
) {}
319 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId
,
320 unsigned SourceFileId
,
321 unsigned SourceLineNum
,
322 const MCSymbol
*FnStartSym
,
323 const MCSymbol
*FnEndSym
) {}
325 void MCStreamer::EmitCVDefRangeDirective(
326 ArrayRef
<std::pair
<const MCSymbol
*, const MCSymbol
*>> Ranges
,
327 StringRef FixedSizePortion
) {}
329 void MCStreamer::EmitEHSymAttributes(const MCSymbol
*Symbol
,
330 MCSymbol
*EHSymbol
) {
333 void MCStreamer::InitSections(bool NoExecStack
) {
334 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
337 void MCStreamer::AssignFragment(MCSymbol
*Symbol
, MCFragment
*Fragment
) {
339 Symbol
->setFragment(Fragment
);
341 // As we emit symbols into a section, track the order so that they can
342 // be sorted upon later. Zero is reserved to mean 'unemitted'.
343 SymbolOrdering
[Symbol
] = 1 + SymbolOrdering
.size();
346 void MCStreamer::EmitLabel(MCSymbol
*Symbol
, SMLoc Loc
) {
347 Symbol
->redefineIfPossible();
349 if (!Symbol
->isUndefined() || Symbol
->isVariable())
350 return getContext().reportError(Loc
, "invalid symbol redefinition");
352 assert(!Symbol
->isVariable() && "Cannot emit a variable symbol!");
353 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
354 assert(!Symbol
->getFragment() && "Unexpected fragment on symbol data!");
355 assert(Symbol
->isUndefined() && "Cannot define a symbol twice!");
357 Symbol
->setFragment(&getCurrentSectionOnly()->getDummyFragment());
359 MCTargetStreamer
*TS
= getTargetStreamer();
361 TS
->emitLabel(Symbol
);
364 void MCStreamer::EmitCFISections(bool EH
, bool Debug
) {
368 void MCStreamer::EmitCFIStartProc(bool IsSimple
, SMLoc Loc
) {
369 if (hasUnfinishedDwarfFrameInfo())
370 return getContext().reportError(
371 Loc
, "starting new .cfi frame before finishing the previous one");
373 MCDwarfFrameInfo Frame
;
374 Frame
.IsSimple
= IsSimple
;
375 EmitCFIStartProcImpl(Frame
);
377 const MCAsmInfo
* MAI
= Context
.getAsmInfo();
379 for (const MCCFIInstruction
& Inst
: MAI
->getInitialFrameState()) {
380 if (Inst
.getOperation() == MCCFIInstruction::OpDefCfa
||
381 Inst
.getOperation() == MCCFIInstruction::OpDefCfaRegister
) {
382 Frame
.CurrentCfaRegister
= Inst
.getRegister();
387 DwarfFrameInfos
.push_back(Frame
);
390 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) {
393 void MCStreamer::EmitCFIEndProc() {
394 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
397 EmitCFIEndProcImpl(*CurFrame
);
400 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) {
401 // Put a dummy non-null value in Frame.End to mark that this frame has been
403 Frame
.End
= (MCSymbol
*)1;
406 MCSymbol
*MCStreamer::EmitCFILabel() {
407 // Return a dummy non-null value so that label fields appear filled in when
408 // generating textual assembly.
409 return (MCSymbol
*)1;
412 void MCStreamer::EmitCFIDefCfa(int64_t Register
, int64_t Offset
) {
413 MCSymbol
*Label
= EmitCFILabel();
414 MCCFIInstruction Instruction
=
415 MCCFIInstruction::createDefCfa(Label
, Register
, Offset
);
416 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
419 CurFrame
->Instructions
.push_back(Instruction
);
420 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
423 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset
) {
424 MCSymbol
*Label
= EmitCFILabel();
425 MCCFIInstruction Instruction
=
426 MCCFIInstruction::createDefCfaOffset(Label
, Offset
);
427 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
430 CurFrame
->Instructions
.push_back(Instruction
);
433 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment
) {
434 MCSymbol
*Label
= EmitCFILabel();
435 MCCFIInstruction Instruction
=
436 MCCFIInstruction::createAdjustCfaOffset(Label
, Adjustment
);
437 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
440 CurFrame
->Instructions
.push_back(Instruction
);
443 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register
) {
444 MCSymbol
*Label
= EmitCFILabel();
445 MCCFIInstruction Instruction
=
446 MCCFIInstruction::createDefCfaRegister(Label
, Register
);
447 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
450 CurFrame
->Instructions
.push_back(Instruction
);
451 CurFrame
->CurrentCfaRegister
= static_cast<unsigned>(Register
);
454 void MCStreamer::EmitCFIOffset(int64_t Register
, int64_t Offset
) {
455 MCSymbol
*Label
= EmitCFILabel();
456 MCCFIInstruction Instruction
=
457 MCCFIInstruction::createOffset(Label
, Register
, Offset
);
458 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
461 CurFrame
->Instructions
.push_back(Instruction
);
464 void MCStreamer::EmitCFIRelOffset(int64_t Register
, int64_t Offset
) {
465 MCSymbol
*Label
= EmitCFILabel();
466 MCCFIInstruction Instruction
=
467 MCCFIInstruction::createRelOffset(Label
, Register
, Offset
);
468 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
471 CurFrame
->Instructions
.push_back(Instruction
);
474 void MCStreamer::EmitCFIPersonality(const MCSymbol
*Sym
,
476 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
479 CurFrame
->Personality
= Sym
;
480 CurFrame
->PersonalityEncoding
= Encoding
;
483 void MCStreamer::EmitCFILsda(const MCSymbol
*Sym
, unsigned Encoding
) {
484 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
487 CurFrame
->Lsda
= Sym
;
488 CurFrame
->LsdaEncoding
= Encoding
;
491 void MCStreamer::EmitCFIRememberState() {
492 MCSymbol
*Label
= EmitCFILabel();
493 MCCFIInstruction Instruction
= MCCFIInstruction::createRememberState(Label
);
494 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
497 CurFrame
->Instructions
.push_back(Instruction
);
500 void MCStreamer::EmitCFIRestoreState() {
501 // FIXME: Error if there is no matching cfi_remember_state.
502 MCSymbol
*Label
= EmitCFILabel();
503 MCCFIInstruction Instruction
= MCCFIInstruction::createRestoreState(Label
);
504 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
507 CurFrame
->Instructions
.push_back(Instruction
);
510 void MCStreamer::EmitCFISameValue(int64_t Register
) {
511 MCSymbol
*Label
= EmitCFILabel();
512 MCCFIInstruction Instruction
=
513 MCCFIInstruction::createSameValue(Label
, Register
);
514 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
517 CurFrame
->Instructions
.push_back(Instruction
);
520 void MCStreamer::EmitCFIRestore(int64_t Register
) {
521 MCSymbol
*Label
= EmitCFILabel();
522 MCCFIInstruction Instruction
=
523 MCCFIInstruction::createRestore(Label
, Register
);
524 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
527 CurFrame
->Instructions
.push_back(Instruction
);
530 void MCStreamer::EmitCFIEscape(StringRef Values
) {
531 MCSymbol
*Label
= EmitCFILabel();
532 MCCFIInstruction Instruction
= MCCFIInstruction::createEscape(Label
, Values
);
533 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
536 CurFrame
->Instructions
.push_back(Instruction
);
539 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size
) {
540 MCSymbol
*Label
= EmitCFILabel();
541 MCCFIInstruction Instruction
=
542 MCCFIInstruction::createGnuArgsSize(Label
, Size
);
543 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
546 CurFrame
->Instructions
.push_back(Instruction
);
549 void MCStreamer::EmitCFISignalFrame() {
550 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
553 CurFrame
->IsSignalFrame
= true;
556 void MCStreamer::EmitCFIUndefined(int64_t Register
) {
557 MCSymbol
*Label
= EmitCFILabel();
558 MCCFIInstruction Instruction
=
559 MCCFIInstruction::createUndefined(Label
, Register
);
560 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
563 CurFrame
->Instructions
.push_back(Instruction
);
566 void MCStreamer::EmitCFIRegister(int64_t Register1
, int64_t Register2
) {
567 MCSymbol
*Label
= EmitCFILabel();
568 MCCFIInstruction Instruction
=
569 MCCFIInstruction::createRegister(Label
, Register1
, Register2
);
570 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
573 CurFrame
->Instructions
.push_back(Instruction
);
576 void MCStreamer::EmitCFIWindowSave() {
577 MCSymbol
*Label
= EmitCFILabel();
578 MCCFIInstruction Instruction
=
579 MCCFIInstruction::createWindowSave(Label
);
580 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
583 CurFrame
->Instructions
.push_back(Instruction
);
586 void MCStreamer::EmitCFINegateRAState() {
587 MCSymbol
*Label
= EmitCFILabel();
588 MCCFIInstruction Instruction
= MCCFIInstruction::createNegateRAState(Label
);
589 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
592 CurFrame
->Instructions
.push_back(Instruction
);
595 void MCStreamer::EmitCFIReturnColumn(int64_t Register
) {
596 MCDwarfFrameInfo
*CurFrame
= getCurrentDwarfFrameInfo();
599 CurFrame
->RAReg
= Register
;
602 WinEH::FrameInfo
*MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc
) {
603 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
604 if (!MAI
->usesWindowsCFI()) {
605 getContext().reportError(
606 Loc
, ".seh_* directives are not supported on this target");
609 if (!CurrentWinFrameInfo
|| CurrentWinFrameInfo
->End
) {
610 getContext().reportError(
611 Loc
, ".seh_ directive must appear within an active frame");
614 return CurrentWinFrameInfo
;
617 void MCStreamer::EmitWinCFIStartProc(const MCSymbol
*Symbol
, SMLoc Loc
) {
618 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
619 if (!MAI
->usesWindowsCFI())
620 return getContext().reportError(
621 Loc
, ".seh_* directives are not supported on this target");
622 if (CurrentWinFrameInfo
&& !CurrentWinFrameInfo
->End
)
623 getContext().reportError(
624 Loc
, "Starting a function before ending the previous one!");
626 MCSymbol
*StartProc
= EmitCFILabel();
628 WinFrameInfos
.emplace_back(
629 llvm::make_unique
<WinEH::FrameInfo
>(Symbol
, StartProc
));
630 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
631 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
634 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc
) {
635 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
638 if (CurFrame
->ChainedParent
)
639 getContext().reportError(Loc
, "Not all chained regions terminated!");
641 MCSymbol
*Label
= EmitCFILabel();
642 CurFrame
->End
= Label
;
645 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc
) {
646 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
649 if (CurFrame
->ChainedParent
)
650 getContext().reportError(Loc
, "Not all chained regions terminated!");
652 MCSymbol
*Label
= EmitCFILabel();
653 CurFrame
->FuncletOrFuncEnd
= Label
;
656 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc
) {
657 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
661 MCSymbol
*StartProc
= EmitCFILabel();
663 WinFrameInfos
.emplace_back(llvm::make_unique
<WinEH::FrameInfo
>(
664 CurFrame
->Function
, StartProc
, CurFrame
));
665 CurrentWinFrameInfo
= WinFrameInfos
.back().get();
666 CurrentWinFrameInfo
->TextSection
= getCurrentSectionOnly();
669 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc
) {
670 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
673 if (!CurFrame
->ChainedParent
)
674 return getContext().reportError(
675 Loc
, "End of a chained region outside a chained region!");
677 MCSymbol
*Label
= EmitCFILabel();
679 CurFrame
->End
= Label
;
680 CurrentWinFrameInfo
= const_cast<WinEH::FrameInfo
*>(CurFrame
->ChainedParent
);
683 void MCStreamer::EmitWinEHHandler(const MCSymbol
*Sym
, bool Unwind
, bool Except
,
685 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
688 if (CurFrame
->ChainedParent
)
689 return getContext().reportError(
690 Loc
, "Chained unwind areas can't have handlers!");
691 CurFrame
->ExceptionHandler
= Sym
;
692 if (!Except
&& !Unwind
)
693 getContext().reportError(Loc
, "Don't know what kind of handler this is!");
695 CurFrame
->HandlesUnwind
= true;
697 CurFrame
->HandlesExceptions
= true;
700 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc
) {
701 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
704 if (CurFrame
->ChainedParent
)
705 getContext().reportError(Loc
, "Chained unwind areas can't have handlers!");
708 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr
*From
,
709 const MCSymbolRefExpr
*To
, uint64_t Count
) {
712 static MCSection
*getWinCFISection(MCContext
&Context
, unsigned *NextWinCFIID
,
713 MCSection
*MainCFISec
,
714 const MCSection
*TextSec
) {
715 // If this is the main .text section, use the main unwind info section.
716 if (TextSec
== Context
.getObjectFileInfo()->getTextSection())
719 const auto *TextSecCOFF
= cast
<MCSectionCOFF
>(TextSec
);
720 auto *MainCFISecCOFF
= cast
<MCSectionCOFF
>(MainCFISec
);
721 unsigned UniqueID
= TextSecCOFF
->getOrAssignWinCFISectionID(NextWinCFIID
);
723 // If this section is COMDAT, this unwind section should be COMDAT associative
725 const MCSymbol
*KeySym
= nullptr;
726 if (TextSecCOFF
->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT
) {
727 KeySym
= TextSecCOFF
->getCOMDATSymbol();
729 // In a GNU environment, we can't use associative comdats. Instead, do what
730 // GCC does, which is to make plain comdat selectany section named like
731 // ".[px]data$_Z3foov".
732 if (!Context
.getAsmInfo()->hasCOFFAssociativeComdats()) {
733 std::string SectionName
=
734 (MainCFISecCOFF
->getSectionName() + "$" +
735 TextSecCOFF
->getSectionName().split('$').second
)
737 return Context
.getCOFFSection(
739 MainCFISecCOFF
->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT
,
740 MainCFISecCOFF
->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY
);
744 return Context
.getAssociativeCOFFSection(MainCFISecCOFF
, KeySym
, UniqueID
);
747 MCSection
*MCStreamer::getAssociatedPDataSection(const MCSection
*TextSec
) {
748 return getWinCFISection(getContext(), &NextWinCFIID
,
749 getContext().getObjectFileInfo()->getPDataSection(),
753 MCSection
*MCStreamer::getAssociatedXDataSection(const MCSection
*TextSec
) {
754 return getWinCFISection(getContext(), &NextWinCFIID
,
755 getContext().getObjectFileInfo()->getXDataSection(),
759 void MCStreamer::EmitSyntaxDirective() {}
761 void MCStreamer::EmitWinCFIPushReg(unsigned Register
, SMLoc Loc
) {
762 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
766 MCSymbol
*Label
= EmitCFILabel();
768 WinEH::Instruction Inst
= Win64EH::Instruction::PushNonVol(Label
, Register
);
769 CurFrame
->Instructions
.push_back(Inst
);
772 void MCStreamer::EmitWinCFISetFrame(unsigned Register
, unsigned Offset
,
774 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
777 if (CurFrame
->LastFrameInst
>= 0)
778 return getContext().reportError(
779 Loc
, "frame register and offset can be set at most once");
781 return getContext().reportError(Loc
, "offset is not a multiple of 16");
783 return getContext().reportError(
784 Loc
, "frame offset must be less than or equal to 240");
786 MCSymbol
*Label
= EmitCFILabel();
788 WinEH::Instruction Inst
=
789 Win64EH::Instruction::SetFPReg(Label
, Register
, Offset
);
790 CurFrame
->LastFrameInst
= CurFrame
->Instructions
.size();
791 CurFrame
->Instructions
.push_back(Inst
);
794 void MCStreamer::EmitWinCFIAllocStack(unsigned Size
, SMLoc Loc
) {
795 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
799 return getContext().reportError(Loc
,
800 "stack allocation size must be non-zero");
802 return getContext().reportError(
803 Loc
, "stack allocation size is not a multiple of 8");
805 MCSymbol
*Label
= EmitCFILabel();
807 WinEH::Instruction Inst
= Win64EH::Instruction::Alloc(Label
, Size
);
808 CurFrame
->Instructions
.push_back(Inst
);
811 void MCStreamer::EmitWinCFISaveReg(unsigned Register
, unsigned Offset
,
813 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
818 return getContext().reportError(
819 Loc
, "register save offset is not 8 byte aligned");
821 MCSymbol
*Label
= EmitCFILabel();
823 WinEH::Instruction Inst
=
824 Win64EH::Instruction::SaveNonVol(Label
, Register
, Offset
);
825 CurFrame
->Instructions
.push_back(Inst
);
828 void MCStreamer::EmitWinCFISaveXMM(unsigned Register
, unsigned Offset
,
830 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
834 return getContext().reportError(Loc
, "offset is not a multiple of 16");
836 MCSymbol
*Label
= EmitCFILabel();
838 WinEH::Instruction Inst
=
839 Win64EH::Instruction::SaveXMM(Label
, Register
, Offset
);
840 CurFrame
->Instructions
.push_back(Inst
);
843 void MCStreamer::EmitWinCFIPushFrame(bool Code
, SMLoc Loc
) {
844 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
847 if (!CurFrame
->Instructions
.empty())
848 return getContext().reportError(
849 Loc
, "If present, PushMachFrame must be the first UOP");
851 MCSymbol
*Label
= EmitCFILabel();
853 WinEH::Instruction Inst
= Win64EH::Instruction::PushMachFrame(Label
, Code
);
854 CurFrame
->Instructions
.push_back(Inst
);
857 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc
) {
858 WinEH::FrameInfo
*CurFrame
= EnsureValidWinFrameInfo(Loc
);
862 MCSymbol
*Label
= EmitCFILabel();
864 CurFrame
->PrologEnd
= Label
;
867 void MCStreamer::EmitCOFFSafeSEH(MCSymbol
const *Symbol
) {}
869 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol
const *Symbol
) {}
871 void MCStreamer::EmitCOFFSectionIndex(MCSymbol
const *Symbol
) {}
873 void MCStreamer::EmitCOFFSecRel32(MCSymbol
const *Symbol
, uint64_t Offset
) {}
875 void MCStreamer::EmitCOFFImgRel32(MCSymbol
const *Symbol
, int64_t Offset
) {}
877 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
878 /// the specified string in the output .s file. This capability is
879 /// indicated by the hasRawTextSupport() predicate.
880 void MCStreamer::EmitRawTextImpl(StringRef String
) {
881 // This is not llvm_unreachable for the sake of out of tree backend
882 // developers who may not have assembly streamers and should serve as a
883 // reminder to not accidentally call EmitRawText in the absence of such.
884 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
885 "it (target backend is likely missing an AsmStreamer "
889 void MCStreamer::EmitRawText(const Twine
&T
) {
890 SmallString
<128> Str
;
891 EmitRawTextImpl(T
.toStringRef(Str
));
894 void MCStreamer::EmitWindowsUnwindTables() {
897 void MCStreamer::Finish() {
898 if ((!DwarfFrameInfos
.empty() && !DwarfFrameInfos
.back().End
) ||
899 (!WinFrameInfos
.empty() && !WinFrameInfos
.back()->End
)) {
900 getContext().reportError(SMLoc(), "Unfinished frame!");
904 MCTargetStreamer
*TS
= getTargetStreamer();
911 void MCStreamer::EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) {
912 visitUsedExpr(*Value
);
913 Symbol
->setVariableValue(Value
);
915 MCTargetStreamer
*TS
= getTargetStreamer();
917 TS
->emitAssignment(Symbol
, Value
);
920 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter
&InstPrinter
,
921 raw_ostream
&OS
, const MCInst
&Inst
,
922 const MCSubtargetInfo
&STI
) {
923 InstPrinter
.printInst(&Inst
, OS
, "", STI
);
926 void MCStreamer::visitUsedSymbol(const MCSymbol
&Sym
) {
929 void MCStreamer::visitUsedExpr(const MCExpr
&Expr
) {
930 switch (Expr
.getKind()) {
932 cast
<MCTargetExpr
>(Expr
).visitUsedExpr(*this);
935 case MCExpr::Constant
:
938 case MCExpr::Binary
: {
939 const MCBinaryExpr
&BE
= cast
<MCBinaryExpr
>(Expr
);
940 visitUsedExpr(*BE
.getLHS());
941 visitUsedExpr(*BE
.getRHS());
945 case MCExpr::SymbolRef
:
946 visitUsedSymbol(cast
<MCSymbolRefExpr
>(Expr
).getSymbol());
950 visitUsedExpr(*cast
<MCUnaryExpr
>(Expr
).getSubExpr());
955 void MCStreamer::EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
&) {
957 for (unsigned i
= Inst
.getNumOperands(); i
--;)
958 if (Inst
.getOperand(i
).isExpr())
959 visitUsedExpr(*Inst
.getOperand(i
).getExpr());
962 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol
*Hi
, const MCSymbol
*Lo
,
964 // Get the Hi-Lo expression.
966 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
967 MCSymbolRefExpr::create(Lo
, Context
), Context
);
969 const MCAsmInfo
*MAI
= Context
.getAsmInfo();
970 if (!MAI
->doesSetDirectiveSuppressReloc()) {
971 EmitValue(Diff
, Size
);
975 // Otherwise, emit with .set (aka assignment).
976 MCSymbol
*SetLabel
= Context
.createTempSymbol("set", true);
977 EmitAssignment(SetLabel
, Diff
);
978 EmitSymbolValue(SetLabel
, Size
);
981 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol
*Hi
,
982 const MCSymbol
*Lo
) {
983 // Get the Hi-Lo expression.
985 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi
, Context
),
986 MCSymbolRefExpr::create(Lo
, Context
), Context
);
988 EmitULEB128Value(Diff
);
991 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag
) {}
992 void MCStreamer::EmitThumbFunc(MCSymbol
*Func
) {}
993 void MCStreamer::EmitSymbolDesc(MCSymbol
*Symbol
, unsigned DescValue
) {}
994 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol
*Symbol
) {
995 llvm_unreachable("this directive only supported on COFF targets");
997 void MCStreamer::EndCOFFSymbolDef() {
998 llvm_unreachable("this directive only supported on COFF targets");
1000 void MCStreamer::EmitFileDirective(StringRef Filename
) {}
1001 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass
) {
1002 llvm_unreachable("this directive only supported on COFF targets");
1004 void MCStreamer::EmitCOFFSymbolType(int Type
) {
1005 llvm_unreachable("this directive only supported on COFF targets");
1007 void MCStreamer::emitELFSize(MCSymbol
*Symbol
, const MCExpr
*Value
) {}
1008 void MCStreamer::emitELFSymverDirective(StringRef AliasName
,
1009 const MCSymbol
*Aliasee
) {}
1010 void MCStreamer::EmitLocalCommonSymbol(MCSymbol
*Symbol
, uint64_t Size
,
1011 unsigned ByteAlignment
) {}
1012 void MCStreamer::EmitTBSSSymbol(MCSection
*Section
, MCSymbol
*Symbol
,
1013 uint64_t Size
, unsigned ByteAlignment
) {}
1014 void MCStreamer::ChangeSection(MCSection
*, const MCExpr
*) {}
1015 void MCStreamer::EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) {}
1016 void MCStreamer::EmitBytes(StringRef Data
) {}
1017 void MCStreamer::EmitBinaryData(StringRef Data
) { EmitBytes(Data
); }
1018 void MCStreamer::EmitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) {
1019 visitUsedExpr(*Value
);
1021 void MCStreamer::EmitULEB128Value(const MCExpr
*Value
) {}
1022 void MCStreamer::EmitSLEB128Value(const MCExpr
*Value
) {}
1023 void MCStreamer::emitFill(const MCExpr
&NumBytes
, uint64_t Value
, SMLoc Loc
) {}
1024 void MCStreamer::emitFill(const MCExpr
&NumValues
, int64_t Size
, int64_t Expr
,
1026 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
,
1028 unsigned MaxBytesToEmit
) {}
1029 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment
,
1030 unsigned MaxBytesToEmit
) {}
1031 void MCStreamer::emitValueToOffset(const MCExpr
*Offset
, unsigned char Value
,
1033 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2
) {}
1034 void MCStreamer::EmitBundleLock(bool AlignToEnd
) {}
1035 void MCStreamer::FinishImpl() {}
1036 void MCStreamer::EmitBundleUnlock() {}
1038 void MCStreamer::SwitchSection(MCSection
*Section
, const MCExpr
*Subsection
) {
1039 assert(Section
&& "Cannot switch to a null section!");
1040 MCSectionSubPair curSection
= SectionStack
.back().first
;
1041 SectionStack
.back().second
= curSection
;
1042 if (MCSectionSubPair(Section
, Subsection
) != curSection
) {
1043 ChangeSection(Section
, Subsection
);
1044 SectionStack
.back().first
= MCSectionSubPair(Section
, Subsection
);
1045 assert(!Section
->hasEnded() && "Section already ended");
1046 MCSymbol
*Sym
= Section
->getBeginSymbol();
1047 if (Sym
&& !Sym
->isInSection())
1052 MCSymbol
*MCStreamer::endSection(MCSection
*Section
) {
1053 // TODO: keep track of the last subsection so that this symbol appears in the
1055 MCSymbol
*Sym
= Section
->getEndSymbol(Context
);
1056 if (Sym
->isInSection())
1059 SwitchSection(Section
);
1064 void MCStreamer::EmitVersionForTarget(const Triple
&Target
,
1065 const VersionTuple
&SDKVersion
) {
1066 if (!Target
.isOSBinFormatMachO() || !Target
.isOSDarwin())
1068 // Do we even know the version?
1069 if (Target
.getOSMajorVersion() == 0)
1075 MCVersionMinType VersionType
;
1076 if (Target
.isWatchOS()) {
1077 VersionType
= MCVM_WatchOSVersionMin
;
1078 Target
.getWatchOSVersion(Major
, Minor
, Update
);
1079 } else if (Target
.isTvOS()) {
1080 VersionType
= MCVM_TvOSVersionMin
;
1081 Target
.getiOSVersion(Major
, Minor
, Update
);
1082 } else if (Target
.isMacOSX()) {
1083 VersionType
= MCVM_OSXVersionMin
;
1084 if (!Target
.getMacOSXVersion(Major
, Minor
, Update
))
1087 VersionType
= MCVM_IOSVersionMin
;
1088 Target
.getiOSVersion(Major
, Minor
, Update
);
1091 EmitVersionMin(VersionType
, Major
, Minor
, Update
, SDKVersion
);