LLVM 22.0.0git
MCSFrame.cpp
Go to the documentation of this file.
1//===- lib/MC/MCSFrame.cpp - MCSFrame implementation ----------------------===//
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/MCSFrame.h"
11#include "llvm/MC/MCAsmInfo.h"
12#include "llvm/MC/MCContext.h"
15#include "llvm/MC/MCSection.h"
16#include "llvm/MC/MCSymbol.h"
18
19using namespace llvm;
20using namespace sframe;
21
22namespace {
23
24// High-level structure to track info needed to emit a sframe_func_desc_entry
25// and its associated FREs.
26struct SFrameFDE {
27 // Reference to the original dwarf frame to avoid copying.
28 const MCDwarfFrameInfo &DFrame;
29 // Label where this FDE's FREs start.
30 MCSymbol *FREStart;
31
32 SFrameFDE(const MCDwarfFrameInfo &DF, MCSymbol *FRES)
33 : DFrame(DF), FREStart(FRES) {}
34
35 void emit(MCObjectStreamer &S, const MCSymbol *FRESubSectionStart) {
36 MCContext &C = S.getContext();
37
38 // sfde_func_start_address
39 const MCExpr *V = C.getAsmInfo()->getExprForFDESymbol(
40 &(*DFrame.Begin), C.getObjectFileInfo()->getFDEEncoding(), S);
41 S.emitValue(V, sizeof(int32_t));
42
43 // sfde_func_size
44 S.emitAbsoluteSymbolDiff(DFrame.End, DFrame.Begin, sizeof(uint32_t));
45
46 // sfde_func_start_fre_off
47 auto *F = S.getCurrentFragment();
48 const MCExpr *Diff = MCBinaryExpr::createSub(
49 MCSymbolRefExpr::create(FREStart, C),
50 MCSymbolRefExpr::create(FRESubSectionStart, C), C);
51
52 F->addFixup(MCFixup::create(F->getContents().size(), Diff,
54 S.emitInt32(0);
55
56 // sfde_func_start_num_fres
57 S.emitInt32(0);
58
59 // sfde_func_info word
61 I.setFuncInfo(0 /* No pauth key */, FDEType::PCInc, FREType::Addr1);
62 S.emitInt8(I.Info);
63
64 // sfde_func_rep_size. Not relevant in non-PCMASK fdes.
65 S.emitInt8(0);
66
67 // sfde_func_padding2
68 S.emitInt16(0);
69 }
70};
71
72// Emitting these field-by-field, instead of constructing the actual structures
73// lets Streamer do target endian-fixups for free.
74
75class SFrameEmitterImpl {
76 MCObjectStreamer &Streamer;
78 ABI SFrameABI;
79 MCSymbol *FDESubSectionStart;
80 MCSymbol *FRESubSectionStart;
81 MCSymbol *FRESubSectionEnd;
82
83public:
84 SFrameEmitterImpl(MCObjectStreamer &Streamer) : Streamer(Streamer) {
85 assert(Streamer.getContext()
88 .has_value());
89 FDEs.reserve(Streamer.getDwarfFrameInfos().size());
90 SFrameABI = *Streamer.getContext().getObjectFileInfo()->getSFrameABIArch();
91 FDESubSectionStart = Streamer.getContext().createTempSymbol();
92 FRESubSectionStart = Streamer.getContext().createTempSymbol();
93 FRESubSectionEnd = Streamer.getContext().createTempSymbol();
94 }
95
96 void BuildSFDE(const MCDwarfFrameInfo &DF) {
97 FDEs.emplace_back(DF, Streamer.getContext().createTempSymbol());
98 }
99
100 void emitPreamble() {
101 Streamer.emitInt16(Magic);
102 Streamer.emitInt8(static_cast<uint8_t>(Version::V2));
103 Streamer.emitInt8(static_cast<uint8_t>(Flags::FDEFuncStartPCRel));
104 }
105
106 void emitHeader() {
107 emitPreamble();
108 // sfh_abi_arch
109 Streamer.emitInt8(static_cast<uint8_t>(SFrameABI));
110 // sfh_cfa_fixed_fp_offset
111 Streamer.emitInt8(0);
112 // sfh_cfa_fixed_ra_offset
113 Streamer.emitInt8(0);
114 // sfh_auxhdr_len
115 Streamer.emitInt8(0);
116 // shf_num_fdes
117 Streamer.emitInt32(FDEs.size());
118 // shf_num_fres
119 Streamer.emitInt32(0);
120 // shf_fre_len
121 Streamer.emitAbsoluteSymbolDiff(FRESubSectionEnd, FRESubSectionStart,
122 sizeof(int32_t));
123 // shf_fdeoff. With no sfh_auxhdr, these immediately follow this header.
124 Streamer.emitInt32(0);
125 // shf_freoff
126 Streamer.emitAbsoluteSymbolDiff(FRESubSectionStart, FDESubSectionStart,
127 sizeof(uint32_t));
128 }
129
130 void emitFDEs() {
131 Streamer.emitLabel(FDESubSectionStart);
132 for (auto &FDE : FDEs) {
133 FDE.emit(Streamer, FRESubSectionStart);
134 }
135 }
136
137 void emitFREs() {
138 Streamer.emitLabel(FRESubSectionStart);
139 for (auto &FDE : FDEs)
140 Streamer.emitLabel(FDE.FREStart);
141 Streamer.emitLabel(FRESubSectionEnd);
142 }
143};
144
145} // end anonymous namespace
146
148 MCContext &Context = Streamer.getContext();
149 // If this target doesn't support sframes, return now. Gas doesn't warn in
150 // this case, but if we want to, it should be done at option-parsing time,
151 // rather than here.
152 if (!Streamer.getContext()
155 .has_value())
156 return;
157
158 SFrameEmitterImpl Emitter(Streamer);
159 ArrayRef<MCDwarfFrameInfo> FrameArray = Streamer.getDwarfFrameInfos();
160
161 // Both the header itself and the FDEs include various offsets and counts.
162 // Therefore, all of this must be precomputed.
163 for (const auto &DFrame : FrameArray)
164 Emitter.BuildSFDE(DFrame);
165
166 MCSection *Section = Context.getObjectFileInfo()->getSFrameSection();
167 // Not strictly necessary, but gas always aligns to 8, so match that.
168 Section->ensureMinAlignment(Align(8));
169 Streamer.switchSection(Section);
170 MCSymbol *SectionStart = Context.createTempSymbol();
171 Streamer.emitLabel(SectionStart);
172 Emitter.emitHeader();
173 Emitter.emitFDEs();
174 Emitter.emitFREs();
175}
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")
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
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),...
Definition: ArrayRef.h:41
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:428
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:386
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
static MCFixupKind getDataKindForSize(unsigned Size)
Return the generic fixup kind for a value with the given size.
Definition: MCFixup.h:110
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Definition: MCFixup.h:86
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)
Definition: MCSFrame.cpp:147
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:496
MCFragment * getCurrentFragment() const
Definition: MCStreamer.h:432
MCContext & getContext() const
Definition: MCStreamer.h:314
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:178
void emitInt16(uint64_t Value)
Definition: MCStreamer.h:749
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
Definition: MCStreamer.cpp:115
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)
Definition: MCStreamer.h:750
void emitInt8(uint64_t Value)
Definition: MCStreamer.h:748
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
size_t size() const
Definition: SmallVector.h:79
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:938
void reserve(size_type N)
Definition: SmallVector.h:664
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
constexpr uint16_t Magic
Definition: SFrame.h:32
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
MCSymbol * Begin
Definition: MCDwarf.h:772