-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[SFrames] Implement .cfi_restore, remember_state, and restore_state #159832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SFrames] Implement .cfi_restore, remember_state, and restore_state #159832
Conversation
…re_state As in the description. Very straightforward.
|
@llvm/pr-subscribers-llvm-mc Author: None (Sterling-Augustine) ChangesAs in the description. Very straightforward. Full diff: https://github.com/llvm/llvm-project/pull/159832.diff 2 Files Affected:
diff --git a/llvm/lib/MC/MCSFrame.cpp b/llvm/lib/MC/MCSFrame.cpp
index 066d1a34e1548..ef6700fb1dccf 100644
--- a/llvm/lib/MC/MCSFrame.cpp
+++ b/llvm/lib/MC/MCSFrame.cpp
@@ -111,6 +111,8 @@ struct SFrameFDE {
MCFragment *Frag;
// Unwinding fres
SmallVector<SFrameFRE> FREs;
+ // .cfi_remember_state stack
+ SmallVector<SFrameFRE> SaveState;
SFrameFDE(const MCDwarfFrameInfo &DF, MCSymbol *FRES)
: DFrame(DF), FREStart(FRES), Frag(nullptr) {}
@@ -237,13 +239,31 @@ class SFrameEmitterImpl {
case MCCFIInstruction::OpAdjustCfaOffset:
return setCFAOffset(FRE, CFI.getLoc(), FRE.CFAOffset + CFI.getOffset());
case MCCFIInstruction::OpRememberState:
- // TODO: Implement. Will use FDE.
+ if (FDE.FREs.size() == 1) {
+ // Error for gas compatibility: If the initial FRE isn't complete,
+ // then any state is incomplete. FIXME: Dwarf doesn't error here.
+ // Why should sframe?
+ Streamer.getContext().reportWarning(
+ CFI.getLoc(), "skipping SFrame FDE; .cfi_remember_state without "
+ "prior SFrame FRE state");
+ return false;
+ }
+ FDE.SaveState.push_back(FRE);
return true;
case MCCFIInstruction::OpRestore:
- // TODO: Implement. Will use FDE.
+ // The first FRE generated has the original state.
+ if (CFI.getRegister() == FPReg)
+ FRE.FPOffset = FDE.FREs.front().FPOffset;
+ else if (CFI.getRegister() == RAReg)
+ FRE.RAOffset = FDE.FREs.front().RAOffset;
return true;
case MCCFIInstruction::OpRestoreState:
- // TODO: Implement. Will use FDE.
+ // The cfi parser will have caught unbalanced directives earlier, so a
+ // mismatch here is an implementation error.
+ assert(!FDE.SaveState.empty() &&
+ "cfi_restore_state without cfi_save_state");
+ FRE = FDE.SaveState.back();
+ FDE.SaveState.pop_back();
return true;
case MCCFIInstruction::OpEscape:
// TODO: Implement. Will use FDE.
@@ -394,8 +414,8 @@ class SFrameEmitterImpl {
// shf_fdeoff. With no sfh_auxhdr, these immediately follow this header.
Streamer.emitInt32(0);
// shf_freoff
- Streamer.emitAbsoluteSymbolDiff(FRESubSectionStart, FDESubSectionStart,
- sizeof(uint32_t));
+ Streamer.emitInt32(FDEs.size() *
+ sizeof(sframe::FuncDescEntry<endianness::native>));
}
void emitFDEs() {
diff --git a/llvm/test/MC/ELF/cfi-sframe-fre-cases.s b/llvm/test/MC/ELF/cfi-sframe-fre-cases.s
index 6d9e8c1b6480f..eeaa4021ceefd 100644
--- a/llvm/test/MC/ELF/cfi-sframe-fre-cases.s
+++ b/llvm/test/MC/ELF/cfi-sframe-fre-cases.s
@@ -17,7 +17,7 @@ fde4_fre_offset_sizes:
# CHECK: FuncDescEntry [0] {
# CHECK: Start FRE Offset: 0
# CHECK: FRE Type: Addr1 (0x0)
- .cfi_startproc
+ .cfi_startproc
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x0
# CHECK-NEXT: Return Address Signed: No
@@ -27,9 +27,9 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: RA Offset: -8
.long 0
# Uninteresting register no new fre, no effect on cfa
- .cfi_offset 0, 8
+ .cfi_offset 0, 8
.long 0
- .cfi_def_cfa_offset 0x78
+ .cfi_def_cfa_offset 0x78
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x8
# CHECK-NEXT: Return Address Signed: No
@@ -37,11 +37,11 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: SP (0x1)
# CHECK-NEXT: CFA Offset: 120
# CHECK-NEXT: RA Offset: -8
- .long 0
+ .long 0
# Uninteresting register no new fre, no effect on cfa
.cfi_rel_offset 1, 8
.long 0
- .cfi_def_cfa_offset 0x80
+ .cfi_def_cfa_offset 0x80
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x10
# CHECK-NEXT: Return Address Signed: No
@@ -49,11 +49,11 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: SP (0x1)
# CHECK-NEXT: CFA Offset: 128
# CHECK-NEXT: RA Offset: -8
- .long 0
+ .long 0
# Uninteresting register no new fre, no effect on cfa
.cfi_val_offset 1, 8
.long 0
- .cfi_def_cfa_offset 0x7FFF
+ .cfi_def_cfa_offset 0x7FFF
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x18
# CHECK-NEXT: Return Address Signed: No
@@ -61,8 +61,8 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: SP (0x1)
# CHECK-NEXT: CFA Offset: 32767
# CHECK-NEXT: RA Offset: -8
- .long 0
- .cfi_def_cfa_offset 0x8000
+ .long 0
+ .cfi_def_cfa_offset 0x8000
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x1C
# CHECK-NEXT: Return Address Signed: No
@@ -70,8 +70,8 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: SP (0x1)
# CHECK-NEXT: CFA Offset: 32768
# CHECK-NEXT: RA Offset: -8
- .long 0
- .cfi_def_cfa_offset 0x8
+ .long 0
+ .cfi_def_cfa_offset 0x8
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x20
# CHECK-NEXT: Return Address Signed: No
@@ -79,8 +79,8 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: SP (0x1)
# CHECK-NEXT: CFA Offset: 8
# CHECK-NEXT: RA Offset: -8
- .long 0
- .cfi_adjust_cfa_offset 0x8
+ .long 0
+ .cfi_adjust_cfa_offset 0x8
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x24
# CHECK-NEXT: Return Address Signed: No
@@ -88,8 +88,8 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: SP (0x1)
# CHECK-NEXT: CFA Offset: 16
# CHECK-NEXT: RA Offset: -8
- .long 0
- .cfi_def_cfa_register 6 # switch to fp
+ .long 0
+ .cfi_def_cfa_register 6 # switch to fp
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x28
# CHECK-NEXT: Return Address Signed: No
@@ -97,10 +97,10 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: Base Register: FP (0x0)
# CHECK-NEXT: CFA Offset: 16
# CHECK-NEXT: RA Offset: -8
- .long 0
- .cfi_offset 7, 32
- # sp not the cfa but with large offset still changes encoding.
- .cfi_offset 6, 0x7FF8
+ .long 0
+ .cfi_offset 7, 32
+ # sp not the cfa but with large offset still changes encoding.
+ .cfi_offset 6, 0x7FF8
# CHECK: Frame Row Entry {
# CHECK-NEXT: Start Address: 0x2C
# CHECK-NEXT: Return Address Signed: No
@@ -109,5 +109,75 @@ fde4_fre_offset_sizes:
# CHECK-NEXT: CFA Offset: 16
# CHECK-NEXT: RA Offset: -8
# CHECK-NEXT: FP Offset: 32760
- .long 0
+ .long 0
+ .cfi_endproc
+
+ .align 1024
+restore_reg:
+# CHECK: FuncDescEntry [1] {
+# CHECK: Start FRE Offset: 0x23
+# CHECK-NEXT: Num FREs: 3
+ .cfi_startproc
+# CHECK: Frame Row Entry {
+# CHECK-NEXT: Start Address: 0x400
+# CHECK-NOT FP Offset{{.*}}
+# CHECK: }
+ .long 0
+ .cfi_offset 6, 32
+# CHECK Frame Row Entry {
+# CHECK-NEXT Start Address: 0x404
+# CHECK: FP Offset: 32
+ .long 0
+ .cfi_restore 6
+# CHECK: Frame Row Entry {
+# CHECK-NEXT: Start Address: 0x408
+# CHECK-NOT FP Offset{{.*}}
+# CHECK: }
+ .long 0
+ .cfi_endproc
+
+ .align 1024
+remember_restore_state:
+# CHECK: FuncDescEntry [2] {
+# CHECK: Start FRE Offset: 0x2D
+# CHECK-NEXT: Num FREs: 4
+ .cfi_startproc
+# CHECK: Frame Row Entry {
+# CHECK-NEXT: Start Address: 0x800
+# CHECK-NOT FP Offset{{.*}}
+# CHECK: }
+ .long 0
+ .cfi_offset 6, 8
+ .cfi_offset 7, 16
+ .cfi_offset 8, 24
+# CHECK: Frame Row Entry {
+# CHECK-NEXT: Start Address: 0x804
+# CHECK: Base Register: SP (0x1)
+# CHECK-NEXT: CFA Offset: 8
+# CHECK-NEXT: RA Offset: -8
+# CHECK-NEXT: FP Offset: 8
+# CHECK-NEXT: }
+ .long 0
+ .cfi_remember_state
+# CHECK: Frame Row Entry {
+# CHECK-NEXT: Start Address: 0x808
+# CHECK: Base Register: SP (0x1)
+# CHECK-NEXT: CFA Offset: 8
+# CHECK-NEXT: RA Offset: -8
+# CHECK-NEXT: FP Offset: 32
+# CHECK-NEXT: }
+ .cfi_offset 6, 32
+ .cfi_offset 7, 40
+ .cfi_offset 8, 48
+ .long 0
+# CHECK: Frame Row Entry {
+# CHECK-NEXT: Start Address: 0x80C
+# CHECK: Base Register: SP (0x1)
+# CHECK-NEXT: CFA Offset: 8
+# CHECK-NEXT: RA Offset: -8
+# CHECK-NEXT: FP Offset: 8
+# CHECK-NEXT: }
+ .cfi_restore_state
+ .long 0
+
.cfi_endproc
|
|
The build failures here are unrelated: 4 tests failed Clang |
weiguozhi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
…lvm#159832) As in the description. Very straightforward.
As in the description. Very straightforward.