aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCSFrame.cpp
diff options
context:
space:
mode:
authorZhaoQi <zhaoqi01@loongson.cn>2025-09-26 10:45:29 +0800
committerGitHub <noreply@github.com>2025-09-26 10:45:29 +0800
commit4321d4fe8039a745796726dfe145e5e699b928b3 (patch)
tree589d406b275c99425ea9c7ee22776e9920d7de4f /llvm/lib/MC/MCSFrame.cpp
parentd516d07c268f260e245690f89ab0f3e727389cb5 (diff)
parentef876268b97d664a90dc0d9a044f518557270e3d (diff)
downloadllvm-users/zhaoqi5/override-isxxxcheap-hooks.zip
llvm-users/zhaoqi5/override-isxxxcheap-hooks.tar.gz
llvm-users/zhaoqi5/override-isxxxcheap-hooks.tar.bz2
Merge branch 'users/zhaoqi5/test-isxxxcheap' into users/zhaoqi5/override-isxxxcheap-hooksusers/zhaoqi5/override-isxxxcheap-hooks
Diffstat (limited to 'llvm/lib/MC/MCSFrame.cpp')
-rw-r--r--llvm/lib/MC/MCSFrame.cpp29
1 files changed, 24 insertions, 5 deletions
diff --git a/llvm/lib/MC/MCSFrame.cpp b/llvm/lib/MC/MCSFrame.cpp
index 066d1a3..910fcab 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,30 @@ 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.pop_back_val();
return true;
case MCCFIInstruction::OpEscape:
// TODO: Implement. Will use FDE.
@@ -394,8 +413,8 @@ public:
// 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() {