37 bool CFARegSet =
false;
39 SFrameFRE(
const MCSymbol *Start) : Label(
Start) {}
46 const MCDwarfFrameInfo &DFrame;
52 SFrameFDE(
const MCDwarfFrameInfo &
DF, MCSymbol *FRES)
53 : DFrame(
DF), FREStart(FRES) {}
55 void emit(MCObjectStreamer &S,
const MCSymbol *FRESubSectionStart) {
59 const MCExpr *
V =
C.getAsmInfo()->getExprForFDESymbol(
60 &(*DFrame.Begin),
C.getObjectFileInfo()->getFDEEncoding(), S);
81 FDEInfo<endianness::native>
I;
82 I.setFuncInfo(0 , FDEType::PCInc, FREType::Addr1);
96class SFrameEmitterImpl {
97 MCObjectStreamer &Streamer;
110 bool setCFARegister(SFrameFRE &FRE,
const MCCFIInstruction &
I) {
111 if (
I.getRegister() == SPReg) {
112 FRE.CFARegSet =
true;
116 if (
I.getRegister() == FPReg) {
117 FRE.CFARegSet =
true;
121 Streamer.getContext().reportWarning(
122 I.getLoc(),
"canonical Frame Address not in stack- or frame-pointer. "
123 "Omitting SFrame unwind info for this function");
127 bool setCFAOffset(SFrameFRE &FRE,
const SMLoc &Loc,
size_t Offset) {
128 if (!
FRE.CFARegSet) {
129 Streamer.getContext().reportWarning(
130 Loc,
"adjusting CFA offset without a base register. "
131 "Omitting SFrame unwind info for this function");
140 bool handleCFI(SFrameFDE &FDE, SFrameFRE &FRE,
const MCCFIInstruction &CFI) {
143 return setCFARegister(FRE, CFI);
146 if (!setCFARegister(FRE, CFI))
185 SFrameEmitterImpl(MCObjectStreamer &Streamer) : Streamer(Streamer) {
186 assert(Streamer.getContext()
190 FDEs.reserve(Streamer.getDwarfFrameInfos().size());
191 SFrameABI = *Streamer.getContext().getObjectFileInfo()->getSFrameABIArch();
193 case ABI::AArch64EndianBig:
194 case ABI::AArch64EndianLittle:
199 case ABI::AMD64EndianLittle:
203 RAReg =
static_cast<unsigned>(INT_MAX);
208 FDESubSectionStart = Streamer.getContext().createTempSymbol();
209 FRESubSectionStart = Streamer.getContext().createTempSymbol();
210 FRESubSectionEnd = Streamer.getContext().createTempSymbol();
213 bool atSameLocation(
const MCSymbol *
Left,
const MCSymbol *
Right) {
214 return Left !=
nullptr &&
Right !=
nullptr &&
215 Left->getFragment() ==
Right->getFragment() &&
219 bool equalIgnoringLocation(
const SFrameFRE &
Left,
const SFrameFRE &
Right) {
220 return Left.CFAOffset ==
Right.CFAOffset &&
225 void buildSFDE(
const MCDwarfFrameInfo &
DF) {
227 SFrameFDE FDE(
DF, Streamer.getContext().createTempSymbol());
234 if (
DF.RAReg != RAReg) {
235 Streamer.getContext().reportWarning(
236 SMLoc(),
"non-default RA register in .cfi_return_column " +
238 ". Omitting SFrame unwind info for this function");
242 SFrameFRE BaseFRE(LastLabel);
244 for (
const auto &CFI :
245 Streamer.getContext().getAsmInfo()->getInitialFrameState())
246 if (!handleCFI(FDE, BaseFRE, CFI))
249 FDE.FREs.push_back(BaseFRE);
251 for (
const auto &CFI :
DF.Instructions) {
259 if (L && !
L->isDefined())
262 SFrameFRE
FRE = FDE.FREs.back();
263 if (!handleCFI(FDE, FRE, CFI))
267 if (equalIgnoringLocation(FRE, FDE.FREs.back()))
272 if (atSameLocation(LastLabel, L))
273 FDE.FREs.back() =
FRE;
275 FDE.FREs.push_back(FRE);
276 FDE.FREs.back().Label =
L;
284 void emitPreamble() {
285 Streamer.emitInt16(
Magic);
286 Streamer.emitInt8(
static_cast<uint8_t
>(Version::V2));
287 Streamer.emitInt8(
static_cast<uint8_t
>(Flags::FDEFuncStartPCRel));
293 Streamer.emitInt8(
static_cast<uint8_t
>(SFrameABI));
295 Streamer.emitInt8(0);
297 Streamer.emitInt8(0);
299 Streamer.emitInt8(0);
301 Streamer.emitInt32(FDEs.size());
303 uint32_t TotalFREs = 0;
304 Streamer.emitInt32(TotalFREs);
307 Streamer.emitAbsoluteSymbolDiff(FRESubSectionEnd, FRESubSectionStart,
310 Streamer.emitInt32(0);
312 Streamer.emitAbsoluteSymbolDiff(FRESubSectionStart, FDESubSectionStart,
317 Streamer.emitLabel(FDESubSectionStart);
318 for (
auto &FDE : FDEs) {
319 FDE.emit(Streamer, FRESubSectionStart);
324 Streamer.emitLabel(FRESubSectionStart);
325 for (
auto &FDE : FDEs)
326 Streamer.emitLabel(FDE.FREStart);
327 Streamer.emitLabel(FRESubSectionEnd);
344 SFrameEmitterImpl
Emitter(Streamer);
349 for (
const auto &DFrame : FrameArray)
352 MCSection *Section = Context.getObjectFileInfo()->getSFrameSection();
354 Section->ensureMinAlignment(
Align(8));
356 MCSymbol *SectionStart = Context.createTempSymbol();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file contains data-structure definitions and constants to support unwinding based on ....
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
MCSymbol * getLabel() const
unsigned getRegister() const
OpType getOperation() const
int64_t getOffset() const
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
static MCFixupKind getDataKindForSize(unsigned Size)
Return the generic fixup kind for a value with the given size.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
std::optional< sframe::ABI > getSFrameABIArch() const
Streaming object file generation interface.
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) override
Emit the absolute difference between two symbols if possible.
static void emit(MCObjectStreamer &Streamer)
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCFragment * getCurrentFragment() const
MCContext & getContext() const
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
void emitInt16(uint64_t Value)
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
void emitInt32(uint64_t Value)
void emitInt8(uint64_t Value)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
@ C
The default llvm calling convention, compatible with C.
@ FRE
Reciprocal estimate instructions (unary FP ops).
This is an optimization pass for GlobalISel generic memory operations.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
This struct is a compact representation of a valid (non-zero power of two) alignment.