diff options
author | Martin Storsjö <martin@martin.st> | 2022-10-11 14:29:36 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2022-10-12 11:07:12 +0300 |
commit | afa6bb643fd4a691262f407c3ed477c5cb293529 (patch) | |
tree | a266b0fe6c56ef851a738175f960151e02c82aec /llvm/lib/MC/MCWin64EH.cpp | |
parent | c43bff64e903f726d456ca27fd167b91198ae169 (diff) | |
download | llvm-afa6bb643fd4a691262f407c3ed477c5cb293529.zip llvm-afa6bb643fd4a691262f407c3ed477c5cb293529.tar.gz llvm-afa6bb643fd4a691262f407c3ed477c5cb293529.tar.bz2 |
[MC] [Win64EH] Generate ARM64 packed unwind info with signed return addresses
Differential Revision: https://reviews.llvm.org/D135660
Diffstat (limited to 'llvm/lib/MC/MCWin64EH.cpp')
-rw-r--r-- | llvm/lib/MC/MCWin64EH.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp index f39383e..d2afb9c 100644 --- a/llvm/lib/MC/MCWin64EH.cpp +++ b/llvm/lib/MC/MCWin64EH.cpp @@ -734,6 +734,7 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, enum { Start, Start2, + Start3, IntRegs, FloatRegs, InputArgs, @@ -742,6 +743,7 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, End } Location = Start; bool StandaloneLR = false, FPLRPair = false; + bool PAC = false; int StackOffset = 0; int Nops = 0; // Iterate over the prolog and check that all opcodes exactly match @@ -757,15 +759,21 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, return false; Location = Start2; break; - case Win64EH::UOP_SaveR19R20X: + case Win64EH::UOP_PACSignReturnAddress: if (Location != Start2) return false; + PAC = true; + Location = Start3; + break; + case Win64EH::UOP_SaveR19R20X: + if (Location != Start2 && Location != Start3) + return false; Predecrement = Inst.Offset; RegI = 2; Location = IntRegs; break; case Win64EH::UOP_SaveRegX: - if (Location != Start2) + if (Location != Start2 && Location != Start3) return false; Predecrement = Inst.Offset; if (Inst.Register == 19) @@ -828,7 +836,7 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, Location = InputArgs; break; case Win64EH::UOP_SaveFRegPX: - if (Location != Start2 || Inst.Register != 8) + if ((Location != Start2 && Location != Start3) || Inst.Register != 8) return false; Predecrement = Inst.Offset; RegF = 2; @@ -858,8 +866,9 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, break; case Win64EH::UOP_AllocSmall: case Win64EH::UOP_AllocMedium: - if (Location != Start2 && Location != IntRegs && Location != FloatRegs && - Location != InputArgs && Location != StackAdjust) + if (Location != Start2 && Location != Start3 && Location != IntRegs && + Location != FloatRegs && Location != InputArgs && + Location != StackAdjust) return false; // Can have either a single decrement, or a pair of decrements with // 4080 and another decrement. @@ -874,8 +883,8 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, case Win64EH::UOP_SaveFPLRX: // Not allowing FPLRX after StackAdjust; if a StackAdjust is used, it // should be followed by a FPLR instead. - if (Location != Start2 && Location != IntRegs && Location != FloatRegs && - Location != InputArgs) + if (Location != Start2 && Location != Start3 && Location != IntRegs && + Location != FloatRegs && Location != InputArgs) return false; StackOffset = Inst.Offset; Location = FrameRecord; @@ -903,6 +912,8 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, return false; if (Nops != 0 && Nops != 4) return false; + if (PAC && !FPLRPair) + return false; int H = Nops == 4; // There's an inconsistency regarding packed unwind info with homed // parameters; according to the documentation, the epilog shouldn't have @@ -933,7 +944,7 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength, RegF--; // Convert from actual number of registers, to value stored assert(FuncLength <= 0x7FF && "FuncLength should have been checked earlier"); int Flag = 0x01; // Function segments not supported yet - int CR = FPLRPair ? 3 : StandaloneLR ? 1 : 0; + int CR = PAC ? 2 : FPLRPair ? 3 : StandaloneLR ? 1 : 0; info->PackedInfo |= Flag << 0; info->PackedInfo |= (FuncLength & 0x7FF) << 2; info->PackedInfo |= (RegF & 0x7) << 13; |