Skip to content

Commit 3415154

Browse files
Address comments.
1 parent 8b54030 commit 3415154

File tree

3 files changed

+64
-80
lines changed

3 files changed

+64
-80
lines changed

llvm/lib/MC/MCSFrame.cpp

Lines changed: 55 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ namespace {
2424
// High-level structure to track info needed to emit a
2525
// sframe_frame_row_entry_addrX. On disk these have both a fixed portion of type
2626
// sframe_frame_row_entry_addrX and trailing data of X * S bytes, where X is the
27-
// datum size, and S is 1, 2, or 3 depending on which of Cfa, SP, and FP are
27+
// datum size, and S is 1, 2, or 3 depending on which of CFA, SP, and FP are
2828
// being tracked.
2929
struct SFrameFRE {
3030
// An FRE describes how to find the registers when the PC is at this
3131
// Label from function start.
3232
const MCSymbol *Label = nullptr;
33-
size_t CfaOffset = 0;
33+
size_t CFAOffset = 0;
3434
size_t FPOffset = 0;
3535
size_t RAOffset = 0;
3636
bool FromFP = false;
37-
bool CfaRegSet = false;
37+
bool CFARegSet = false;
3838

3939
SFrameFRE(const MCSymbol *Start) : Label(Start) {}
4040
};
@@ -46,13 +46,11 @@ struct SFrameFDE {
4646
const MCDwarfFrameInfo &DFrame;
4747
// Label where this FDE's FREs start.
4848
MCSymbol *FREStart;
49-
// True when unwind info can't be described with an Sframe FDE.
50-
bool Invalid;
5149
// Unwinding fres
5250
SmallVector<SFrameFRE> FREs;
5351

5452
SFrameFDE(const MCDwarfFrameInfo &DF, MCSymbol *FRES)
55-
: DFrame(DF), FREStart(FRES), Invalid(false) {}
53+
: DFrame(DF), FREStart(FRES) {}
5654

5755
void emit(MCObjectStreamer &S, const MCSymbol *FRESubSectionStart) {
5856
MCContext &C = S.getContext();
@@ -109,91 +107,81 @@ class SFrameEmitterImpl {
109107
MCSymbol *FRESubSectionStart;
110108
MCSymbol *FRESubSectionEnd;
111109

112-
113-
bool setCfaRegister(SFrameFDE &FDE, SFrameFRE &FRE, const MCCFIInstruction &I) {
110+
bool setCFARegister(SFrameFRE &FRE, const MCCFIInstruction &I) {
114111
if (I.getRegister() == SPReg) {
115-
FRE.CfaRegSet = true;
112+
FRE.CFARegSet = true;
116113
FRE.FromFP = false;
117114
return true;
118-
} else if (I.getRegister() == FPReg) {
119-
FRE.CfaRegSet = true;
115+
}
116+
if (I.getRegister() == FPReg) {
117+
FRE.CFARegSet = true;
120118
FRE.FromFP = true;
121119
return true;
122120
}
123121
Streamer.getContext().reportWarning(
124122
I.getLoc(), "Canonical Frame Address not in stack- or frame-pointer. "
125123
"Omitting SFrame unwind info for this function.");
126-
FDE.Invalid = true;
127124
return false;
128125
}
129126

130-
bool isCfaRegisterSet(SFrameFDE &FDE, SFrameFRE &FRE,
131-
const MCCFIInstruction &I) {
132-
if (FRE.CfaRegSet)
133-
return true;
134-
135-
Streamer.getContext().reportWarning(
136-
I.getLoc(), "Adjusting CFA offset without a base register. "
137-
"Omitting SFrame unwind info for this function.");
138-
FDE.Invalid = true;
139-
return false;
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.");
132+
return false;
133+
}
134+
FRE.CFAOffset = Offset;
135+
return true;
140136
}
141137

142138
// Add the effects of CFI to the current FDE, creating a new FRE when
143139
// necessary.
144-
void handleCFI(SFrameFDE &FDE, SFrameFRE &FRE, const MCCFIInstruction &CFI) {
140+
bool handleCFI(SFrameFDE &FDE, SFrameFRE &FRE, const MCCFIInstruction &CFI) {
145141
switch (CFI.getOperation()) {
146142
case MCCFIInstruction::OpDefCfaRegister:
147-
setCfaRegister(FDE, FRE, CFI);
148-
return;
143+
return setCFARegister(FRE, CFI);
149144
case MCCFIInstruction::OpDefCfa:
150145
case MCCFIInstruction::OpLLVMDefAspaceCfa:
151-
if (!setCfaRegister(FDE, FRE, CFI))
152-
return;
153-
FRE.CfaOffset = CFI.getOffset();
154-
return;
146+
if (!setCFARegister(FRE, CFI))
147+
return false;
148+
setCFAOffset(FRE, CFI.getLoc(), CFI.getOffset());
149+
return true;
155150
case MCCFIInstruction::OpOffset:
156151
if (CFI.getRegister() == FPReg)
157152
FRE.FPOffset = CFI.getOffset();
158153
else if (CFI.getRegister() == RAReg)
159154
FRE.RAOffset = CFI.getOffset();
160-
return;
155+
return true;
161156
case MCCFIInstruction::OpRelOffset:
162157
if (CFI.getRegister() == FPReg)
163158
FRE.FPOffset += CFI.getOffset();
164159
else if (CFI.getRegister() == RAReg)
165160
FRE.RAOffset += CFI.getOffset();
166-
return;
161+
return true;
167162
case MCCFIInstruction::OpDefCfaOffset:
168-
if (!isCfaRegisterSet(FDE, FRE, CFI))
169-
return;
170-
FRE.CfaOffset = CFI.getOffset();
171-
return;
163+
return setCFAOffset(FRE, CFI.getLoc(), CFI.getOffset());
172164
case MCCFIInstruction::OpAdjustCfaOffset:
173-
if (!isCfaRegisterSet(FDE, FRE, CFI))
174-
return;
175-
FRE.CfaOffset += CFI.getOffset();
176-
return;
165+
return setCFAOffset(FRE, CFI.getLoc(), FRE.CFAOffset + CFI.getOffset());
177166
case MCCFIInstruction::OpRememberState:
178-
// TODO: Implement
179-
return;
167+
// TODO: Implement. Will use FDE.
168+
return true;
180169
case MCCFIInstruction::OpRestore:
181-
// TODO: Implement
182-
return;
170+
// TODO: Implement. Will use FDE.
171+
return true;
183172
case MCCFIInstruction::OpRestoreState:
184-
// TODO: Implement
185-
return;
173+
// TODO: Implement. Will use FDE.
174+
return true;
186175
case MCCFIInstruction::OpEscape:
187-
// TODO: Implement
188-
return;
176+
// TODO: Implement. Will use FDE.
177+
return true;
189178
default:
190-
// Instructions that don't affect the Cfa, RA, and SP can be safely
179+
// Instructions that don't affect the CFA, RA, and SP can be safely
191180
// ignored.
192-
return;
181+
return true;
193182
}
194183
}
195184

196-
197185
public:
198186
SFrameEmitterImpl(MCObjectStreamer &Streamer) : Streamer(Streamer) {
199187
assert(Streamer.getContext()
@@ -230,13 +218,14 @@ class SFrameEmitterImpl {
230218
}
231219

232220
bool equalIgnoringLocation(const SFrameFRE &Left, const SFrameFRE &Right) {
233-
return Left.CfaOffset == Right.CfaOffset &&
221+
return Left.CFAOffset == Right.CFAOffset &&
234222
Left.FPOffset == Right.FPOffset && Left.RAOffset == Right.RAOffset &&
235-
Left.FromFP == Right.FromFP && Left.CfaRegSet == Right.CfaRegSet;
223+
Left.FromFP == Right.FromFP && Left.CFARegSet == Right.CFARegSet;
236224
}
237225

238226
void buildSFDE(const MCDwarfFrameInfo &DF) {
239-
auto &FDE = FDEs.emplace_back(DF, Streamer.getContext().createTempSymbol());
227+
bool Valid = true;
228+
SFrameFDE FDE(DF, Streamer.getContext().createTempSymbol());
240229
// This would have been set via ".cfi_return_column", but
241230
// MCObjectStreamer doesn't emit an MCCFIInstruction for that. It just
242231
// sets the DF.RAReg.
@@ -245,18 +234,18 @@ class SFrameEmitterImpl {
245234
// hand-written assembly.
246235
if (DF.RAReg != RAReg) {
247236
Streamer.getContext().reportWarning(
248-
SMLoc(), "Non-default RA register " + Twine(DF.RAReg) +
237+
SMLoc(), "Non-default RA register in .cfi_return_column " +
238+
Twine(DF.RAReg) +
249239
". Omitting SFrame unwind info for this function.");
250-
// Continue with the FDE to find any addtional errors. Discard it at
251-
// the end.
252-
FDE.Invalid = true;
240+
Valid = false;
253241
}
254-
MCSymbol *BaseLabel = DF.Begin;
255-
SFrameFRE BaseFRE(BaseLabel);
242+
MCSymbol *LastLabel = DF.Begin;
243+
SFrameFRE BaseFRE(LastLabel);
256244
if (!DF.IsSimple) {
257245
for (const auto &CFI :
258246
Streamer.getContext().getAsmInfo()->getInitialFrameState())
259-
handleCFI(FDE, BaseFRE, CFI);
247+
if (!handleCFI(FDE, BaseFRE, CFI))
248+
Valid = false;
260249
}
261250
FDE.FREs.push_back(BaseFRE);
262251

@@ -269,24 +258,25 @@ class SFrameEmitterImpl {
269258
continue;
270259

271260
SFrameFRE FRE = FDE.FREs.back();
272-
handleCFI(FDE, FRE, CFI);
261+
if (!handleCFI(FDE, FRE, CFI))
262+
Valid = false;
273263

274264
// If nothing relevant but the location changed, don't add the FRE.
275265
if (equalIgnoringLocation(FRE, FDE.FREs.back()))
276266
continue;
277267

278268
// If the location stayed the same, then update the current
279269
// row. Otherwise, add a new one.
280-
if (atSameLocation(BaseLabel, L))
270+
if (atSameLocation(LastLabel, L))
281271
FDE.FREs.back() = FRE;
282272
else {
283273
FDE.FREs.push_back(FRE);
284274
FDE.FREs.back().Label = L;
285-
BaseLabel = L;
275+
LastLabel = L;
286276
}
287277
}
288-
if (FDE.Invalid)
289-
FDEs.pop_back();
278+
if (Valid)
279+
FDEs.push_back(FDE);
290280
}
291281

292282
void emitPreamble() {
@@ -309,8 +299,6 @@ class SFrameEmitterImpl {
309299
Streamer.emitInt32(FDEs.size());
310300
// shf_num_fres
311301
uint32_t TotalFREs = 0;
312-
// for (auto &FDE : FDEs)
313-
// TotalFREs += FDE.FREs.size();
314302
Streamer.emitInt32(TotalFREs);
315303

316304
// shf_fre_len
Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,31 @@
11
// TODO: Add other architectures as they gain sframe support
22
// REQUIRES: x86-registered-target
3-
// RUN: llvm-mc --assemble --filetype=obj --gsframe -triple x86_64 %s -o %t.o 2>&1 | FileCheck %s
3+
// RUN: llvm-mc --assemble --filetype=obj -triple x86_64 %s -o %t.o 2>&1 | FileCheck %s
44
// RUN: llvm-readelf --sframe %t.o | FileCheck --check-prefix=CHECK-NOFDES %s
55

66

77
.cfi_sections .sframe
88
f1:
99
.cfi_startproc simple
10+
// CHECK: Non-default RA register {{.*}}
11+
.cfi_return_column 0
1012
nop
11-
.cfi_def_cfa_offset 16 // No base register yet
12-
nop
13-
.cfi_adjust_cfa_offset 16 // No base register yet
13+
// CHECK: {{.*}} Adjusting CFA offset without a base register.{{.*}}
14+
.cfi_def_cfa_offset 16 // no line number reported here.
1415
nop
15-
.cfi_return_column 0
16+
// CHECK: [[@LINE+1]]:{{.*}} Adjusting CFA offset without a base register.{{.*}}
17+
.cfi_adjust_cfa_offset 16
1618
nop
1719
.cfi_endproc
1820

1921
f2:
2022
.cfi_startproc
2123
nop
24+
// CHECK: Canonical Frame Address not in stack- or frame-pointer. {{.*}}
2225
.cfi_def_cfa 0, 4
2326
nop
2427

2528
.cfi_endproc
2629

27-
// CHECK: Non-default RA register {{.*}}
28-
// asm parser doesn't give a location with .cfi_def_cfa_offset
29-
// CHECK: :0:{{.*}} Adjusting CFA offset without a base register.{{.*}}
30-
// .cfi_adjust_cfa_offset
31-
// CHECK: :13:{{.*}} Adjusting CFA offset without a base register. {{.*}}
32-
// CHECK: Canonical Frame Address not in stack- or frame-pointer. {{.*}}
33-
3430
// CHECK-NOFDES: Num FDEs: 0
3531
// CHECK-NOFDES: Num FREs: 0

llvm/test/MC/ELF/cfi-sframe.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ f1:
1616
nop
1717
.cfi_register 0, 1 // Uninteresting register. No new FRE.
1818
nop
19-
19+
2020
.cfi_endproc
2121

2222
f2:

0 commit comments

Comments
 (0)