aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCWin64EH.cpp
diff options
context:
space:
mode:
authorDaniel Paoliello <danpao@microsoft.com>2025-08-29 09:00:01 -0700
committerGitHub <noreply@github.com>2025-08-29 09:00:01 -0700
commit95657630bda3e73c19d190e25fd9d92b07fc3455 (patch)
treeea9d1305eda8f28a3615e8375743be6dee444653 /llvm/lib/MC/MCWin64EH.cpp
parent4159fd819a89cb18e03a91576372ae257ee5fbc7 (diff)
downloadllvm-95657630bda3e73c19d190e25fd9d92b07fc3455.zip
llvm-95657630bda3e73c19d190e25fd9d92b07fc3455.tar.gz
llvm-95657630bda3e73c19d190e25fd9d92b07fc3455.tar.bz2
[win][x64] Various fixes for unwind v2 (#154834)
* `SetFrame` does not count as a stack allocation. * `mov` in the epilog undoes `SetFrame` (but is not required), it does not deallocate a stack allocation. * `mov` in the epilog MUST be before any stack deallocation or register popping. * Remove assert for having a prolog without any epilogs (this is possible for `noreturn` functions, for instance). * Improve the errors in `MC` to include the problematic function name.
Diffstat (limited to 'llvm/lib/MC/MCWin64EH.cpp')
-rw-r--r--llvm/lib/MC/MCWin64EH.cpp24
1 files changed, 15 insertions, 9 deletions
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index a87648a..8111ccb 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -22,6 +22,7 @@ class MCSection;
/// MCExpr that represents the epilog unwind code in an unwind table.
class MCUnwindV2EpilogTargetExpr final : public MCTargetExpr {
+ const MCSymbol *Function;
const MCSymbol *FunctionEnd;
const MCSymbol *UnwindV2Start;
const MCSymbol *EpilogEnd;
@@ -31,7 +32,7 @@ class MCUnwindV2EpilogTargetExpr final : public MCTargetExpr {
MCUnwindV2EpilogTargetExpr(const WinEH::FrameInfo &FrameInfo,
const WinEH::FrameInfo::Epilog &Epilog,
uint8_t EpilogSize_)
- : FunctionEnd(FrameInfo.FuncletOrFuncEnd),
+ : Function(FrameInfo.Function), FunctionEnd(FrameInfo.FuncletOrFuncEnd),
UnwindV2Start(Epilog.UnwindV2Start), EpilogEnd(Epilog.End),
EpilogSize(EpilogSize_), Loc(Epilog.Loc) {}
@@ -253,13 +254,15 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
OS->getAssembler(), LastEpilog.End, LastEpilog.UnwindV2Start);
if (!MaybeSize) {
context.reportError(LastEpilog.Loc,
- "Failed to evaluate epilog size for Unwind v2");
+ "Failed to evaluate epilog size for Unwind v2 in " +
+ info->Function->getName());
return;
}
assert(*MaybeSize >= 0);
if (*MaybeSize >= (int64_t)UINT8_MAX) {
context.reportError(LastEpilog.Loc,
- "Epilog size is too large for Unwind v2");
+ "Epilog size is too large for Unwind v2 in " +
+ info->Function->getName());
return;
}
EpilogSize = *MaybeSize + 1;
@@ -282,7 +285,8 @@ static void EmitUnwindInfo(MCStreamer &streamer, WinEH::FrameInfo *info) {
// Too many epilogs to handle.
if ((size_t)numCodes + numEpilogCodes > UINT8_MAX) {
context.reportError(info->FunctionLoc,
- "Too many unwind codes with Unwind v2 enabled");
+ "Too many unwind codes with Unwind v2 enabled in " +
+ info->Function->getName());
return;
}
@@ -383,14 +387,16 @@ bool MCUnwindV2EpilogTargetExpr::evaluateAsRelocatableImpl(
auto Offset = GetOptionalAbsDifference(*Asm, FunctionEnd, UnwindV2Start);
if (!Offset) {
Asm->getContext().reportError(
- Loc, "Failed to evaluate epilog offset for Unwind v2");
+ Loc, "Failed to evaluate epilog offset for Unwind v2 in " +
+ Function->getName());
return false;
}
assert(*Offset > 0);
constexpr uint16_t MaxEpilogOffset = 0x0fff;
if (*Offset > MaxEpilogOffset) {
- Asm->getContext().reportError(Loc,
- "Epilog offset is too large for Unwind v2");
+ Asm->getContext().reportError(
+ Loc,
+ "Epilog offset is too large for Unwind v2 in " + Function->getName());
return false;
}
@@ -398,8 +404,8 @@ bool MCUnwindV2EpilogTargetExpr::evaluateAsRelocatableImpl(
auto Size = GetOptionalAbsDifference(*Asm, EpilogEnd, UnwindV2Start);
if (Size != (EpilogSize - 1)) {
Asm->getContext().reportError(
- Loc,
- "Size of this epilog does not match size of last epilog in function");
+ Loc, "Size of this epilog does not match size of last epilog in " +
+ Function->getName());
return false;
}