Skip to content

Commit 825e4ae

Browse files
authored
[AArch64][Windows] Add MC support for ec_context (#69520)
ARM64EC uses the same CONTEXT structure as x86_64 as opposed to the regular ARM64 context, a new unwind MSFT_OP_EC_CONTEXT is added to handle this.
1 parent 5edf586 commit 825e4ae

File tree

7 files changed

+33
-3
lines changed

7 files changed

+33
-3
lines changed

llvm/include/llvm/Support/Win64EH.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum UnwindOpcodes {
6060
UOP_SaveNext,
6161
UOP_TrapFrame,
6262
UOP_Context,
63+
UOP_ECContext,
6364
UOP_ClearUnwoundToCall,
6465
UOP_PACSignLR,
6566
UOP_SaveAnyRegI,

llvm/lib/MC/MCWin64EH.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ static void checkARM64Instructions(MCStreamer &Streamer,
318318
case Win64EH::UOP_TrapFrame:
319319
case Win64EH::UOP_PushMachFrame:
320320
case Win64EH::UOP_Context:
321+
case Win64EH::UOP_ECContext:
321322
case Win64EH::UOP_ClearUnwoundToCall:
322323
// Can't reason about these opcodes and how they map to actual
323324
// instructions.
@@ -411,6 +412,9 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
411412
case Win64EH::UOP_Context:
412413
Count += 1;
413414
break;
415+
case Win64EH::UOP_ECContext:
416+
Count += 1;
417+
break;
414418
case Win64EH::UOP_ClearUnwoundToCall:
415419
Count += 1;
416420
break;
@@ -593,6 +597,10 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer,
593597
b = 0xEA;
594598
streamer.emitInt8(b);
595599
break;
600+
case Win64EH::UOP_ECContext:
601+
b = 0xEB;
602+
streamer.emitInt8(b);
603+
break;
596604
case Win64EH::UOP_ClearUnwoundToCall:
597605
b = 0xEC;
598606
streamer.emitInt8(b);
@@ -1010,6 +1018,7 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength,
10101018
return false;
10111019
case Win64EH::UOP_TrapFrame:
10121020
case Win64EH::UOP_Context:
1021+
case Win64EH::UOP_ECContext:
10131022
case Win64EH::UOP_ClearUnwoundToCall:
10141023
case Win64EH::UOP_PushMachFrame:
10151024
// These are special opcodes that aren't normally generated.

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
223223
bool parseDirectiveSEHTrapFrame(SMLoc L);
224224
bool parseDirectiveSEHMachineFrame(SMLoc L);
225225
bool parseDirectiveSEHContext(SMLoc L);
226+
bool parseDirectiveSEHECContext(SMLoc L);
226227
bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
227228
bool parseDirectiveSEHPACSignLR(SMLoc L);
228229
bool parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired, bool Writeback);
@@ -6737,6 +6738,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
67376738
parseDirectiveSEHMachineFrame(Loc);
67386739
else if (IDVal == ".seh_context")
67396740
parseDirectiveSEHContext(Loc);
6741+
else if (IDVal == ".seh_ec_context")
6742+
parseDirectiveSEHECContext(Loc);
67406743
else if (IDVal == ".seh_clear_unwound_to_call")
67416744
parseDirectiveSEHClearUnwoundToCall(Loc);
67426745
else if (IDVal == ".seh_pac_sign_lr")
@@ -7401,6 +7404,13 @@ bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
74017404
return false;
74027405
}
74037406

7407+
/// parseDirectiveSEHECContext
7408+
/// ::= .seh_ec_context
7409+
bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
7410+
getTargetStreamer().emitARM64WinCFIECContext();
7411+
return false;
7412+
}
7413+
74047414
/// parseDirectiveSEHClearUnwoundToCall
74057415
/// ::= .seh_clear_unwound_to_call
74067416
bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {

llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
104104
void emitARM64WinCFITrapFrame() override { OS << "\t.seh_trap_frame\n"; }
105105
void emitARM64WinCFIMachineFrame() override { OS << "\t.seh_pushframe\n"; }
106106
void emitARM64WinCFIContext() override { OS << "\t.seh_context\n"; }
107+
void emitARM64WinCFIECContext() override { OS << "\t.seh_ec_context\n"; }
107108
void emitARM64WinCFIClearUnwoundToCall() override {
108109
OS << "\t.seh_clear_unwound_to_call\n";
109110
}

llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class AArch64TargetStreamer : public MCTargetStreamer {
6666
virtual void emitARM64WinCFITrapFrame() {}
6767
virtual void emitARM64WinCFIMachineFrame() {}
6868
virtual void emitARM64WinCFIContext() {}
69+
virtual void emitARM64WinCFIECContext() {}
6970
virtual void emitARM64WinCFIClearUnwoundToCall() {}
7071
virtual void emitARM64WinCFIPACSignLR() {}
7172
virtual void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) {}
@@ -132,6 +133,7 @@ class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer {
132133
void emitARM64WinCFITrapFrame() override;
133134
void emitARM64WinCFIMachineFrame() override;
134135
void emitARM64WinCFIContext() override;
136+
void emitARM64WinCFIECContext() override;
135137
void emitARM64WinCFIClearUnwoundToCall() override;
136138
void emitARM64WinCFIPACSignLR() override;
137139
void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override;

llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,10 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinCFIContext() {
219219
emitARM64WinUnwindCode(Win64EH::UOP_Context, -1, 0);
220220
}
221221

222+
void AArch64TargetWinCOFFStreamer::emitARM64WinCFIECContext() {
223+
emitARM64WinUnwindCode(Win64EH::UOP_ECContext, -1, 0);
224+
}
225+
222226
void AArch64TargetWinCOFFStreamer::emitARM64WinCFIClearUnwoundToCall() {
223227
emitARM64WinUnwindCode(Win64EH::UOP_ClearUnwoundToCall, -1, 0);
224228
}

llvm/test/MC/AArch64/seh.s

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
// CHECK-NEXT: Function: func
5555
// CHECK-NEXT: ExceptionRecord: .xdata
5656
// CHECK-NEXT: ExceptionData {
57-
// CHECK-NEXT: FunctionLength: 152
57+
// CHECK-NEXT: FunctionLength: 156
5858
// CHECK: Prologue [
5959
// CHECK-NEXT: 0xe76983 ; stp q9, q10, [sp, #-64]!
6060
// CHECK-NEXT: 0xe73d83 ; str q29, [sp, #-64]!
@@ -70,6 +70,7 @@
7070
// CHECK-NEXT: 0xe70008 ; str x0, [sp, #64]
7171
// CHECK-NEXT: 0xfc ; pacibsp
7272
// CHECK-NEXT: 0xec ; clear unwound to call
73+
// CHECK-NEXT: 0xeb ; EC context
7374
// CHECK-NEXT: 0xea ; context
7475
// CHECK-NEXT: 0xe9 ; machine frame
7576
// CHECK-NEXT: 0xe8 ; trap frame
@@ -95,8 +96,8 @@
9596
// CHECK-NEXT: ]
9697
// CHECK-NEXT: EpilogueScopes [
9798
// CHECK-NEXT: EpilogueScope {
98-
// CHECK-NEXT: StartOffset: 36
99-
// CHECK-NEXT: EpilogueStartIndex: 68
99+
// CHECK-NEXT: StartOffset: 37
100+
// CHECK-NEXT: EpilogueStartIndex: 69
100101
// CHECK-NEXT: Opcodes [
101102
// CHECK-NEXT: 0x01 ; add sp, #16
102103
// CHECK-NEXT: 0xe4 ; end
@@ -163,6 +164,8 @@ func:
163164
nop
164165
.seh_context
165166
nop
167+
.seh_ec_context
168+
nop
166169
.seh_clear_unwound_to_call
167170
pacibsp
168171
.seh_pac_sign_lr

0 commit comments

Comments
 (0)