Skip to content

[AArch64][Windows] Add MC support for ec_context #69520

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

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/Win64EH.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum UnwindOpcodes {
UOP_SaveNext,
UOP_TrapFrame,
UOP_Context,
UOP_ECContext,
UOP_ClearUnwoundToCall,
UOP_PACSignLR,
UOP_SaveAnyRegI,
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/MC/MCWin64EH.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ static void checkARM64Instructions(MCStreamer &Streamer,
case Win64EH::UOP_TrapFrame:
case Win64EH::UOP_PushMachFrame:
case Win64EH::UOP_Context:
case Win64EH::UOP_ECContext:
case Win64EH::UOP_ClearUnwoundToCall:
// Can't reason about these opcodes and how they map to actual
// instructions.
Expand Down Expand Up @@ -411,6 +412,9 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
case Win64EH::UOP_Context:
Count += 1;
break;
case Win64EH::UOP_ECContext:
Count += 1;
break;
case Win64EH::UOP_ClearUnwoundToCall:
Count += 1;
break;
Expand Down Expand Up @@ -593,6 +597,10 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer,
b = 0xEA;
streamer.emitInt8(b);
break;
case Win64EH::UOP_ECContext:
b = 0xEB;
streamer.emitInt8(b);
break;
case Win64EH::UOP_ClearUnwoundToCall:
b = 0xEC;
streamer.emitInt8(b);
Expand Down Expand Up @@ -1010,6 +1018,7 @@ static bool tryARM64PackedUnwind(WinEH::FrameInfo *info, uint32_t FuncLength,
return false;
case Win64EH::UOP_TrapFrame:
case Win64EH::UOP_Context:
case Win64EH::UOP_ECContext:
case Win64EH::UOP_ClearUnwoundToCall:
case Win64EH::UOP_PushMachFrame:
// These are special opcodes that aren't normally generated.
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
bool parseDirectiveSEHTrapFrame(SMLoc L);
bool parseDirectiveSEHMachineFrame(SMLoc L);
bool parseDirectiveSEHContext(SMLoc L);
bool parseDirectiveSEHECContext(SMLoc L);
bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
bool parseDirectiveSEHPACSignLR(SMLoc L);
bool parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired, bool Writeback);
Expand Down Expand Up @@ -6712,6 +6713,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
parseDirectiveSEHMachineFrame(Loc);
else if (IDVal == ".seh_context")
parseDirectiveSEHContext(Loc);
else if (IDVal == ".seh_ec_context")
parseDirectiveSEHECContext(Loc);
else if (IDVal == ".seh_clear_unwound_to_call")
parseDirectiveSEHClearUnwoundToCall(Loc);
else if (IDVal == ".seh_pac_sign_lr")
Expand Down Expand Up @@ -7376,6 +7379,13 @@ bool AArch64AsmParser::parseDirectiveSEHContext(SMLoc L) {
return false;
}

/// parseDirectiveSEHECContext
/// ::= .seh_ec_context
bool AArch64AsmParser::parseDirectiveSEHECContext(SMLoc L) {
getTargetStreamer().emitARM64WinCFIECContext();
return false;
}

/// parseDirectiveSEHClearUnwoundToCall
/// ::= .seh_clear_unwound_to_call
bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
void emitARM64WinCFITrapFrame() override { OS << "\t.seh_trap_frame\n"; }
void emitARM64WinCFIMachineFrame() override { OS << "\t.seh_pushframe\n"; }
void emitARM64WinCFIContext() override { OS << "\t.seh_context\n"; }
void emitARM64WinCFIECContext() override { OS << "\t.seh_ec_context\n"; }
void emitARM64WinCFIClearUnwoundToCall() override {
OS << "\t.seh_clear_unwound_to_call\n";
}
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class AArch64TargetStreamer : public MCTargetStreamer {
virtual void emitARM64WinCFITrapFrame() {}
virtual void emitARM64WinCFIMachineFrame() {}
virtual void emitARM64WinCFIContext() {}
virtual void emitARM64WinCFIECContext() {}
virtual void emitARM64WinCFIClearUnwoundToCall() {}
virtual void emitARM64WinCFIPACSignLR() {}
virtual void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) {}
Expand Down Expand Up @@ -132,6 +133,7 @@ class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer {
void emitARM64WinCFITrapFrame() override;
void emitARM64WinCFIMachineFrame() override;
void emitARM64WinCFIContext() override;
void emitARM64WinCFIECContext() override;
void emitARM64WinCFIClearUnwoundToCall() override;
void emitARM64WinCFIPACSignLR() override;
void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,10 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinCFIContext() {
emitARM64WinUnwindCode(Win64EH::UOP_Context, -1, 0);
}

void AArch64TargetWinCOFFStreamer::emitARM64WinCFIECContext() {
emitARM64WinUnwindCode(Win64EH::UOP_ECContext, -1, 0);
}

void AArch64TargetWinCOFFStreamer::emitARM64WinCFIClearUnwoundToCall() {
emitARM64WinUnwindCode(Win64EH::UOP_ClearUnwoundToCall, -1, 0);
}
Expand Down
9 changes: 6 additions & 3 deletions llvm/test/MC/AArch64/seh.s
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
// CHECK-NEXT: Function: func
// CHECK-NEXT: ExceptionRecord: .xdata
// CHECK-NEXT: ExceptionData {
// CHECK-NEXT: FunctionLength: 152
// CHECK-NEXT: FunctionLength: 156
// CHECK: Prologue [
// CHECK-NEXT: 0xe76983 ; stp q9, q10, [sp, #-64]!
// CHECK-NEXT: 0xe73d83 ; str q29, [sp, #-64]!
Expand All @@ -70,6 +70,7 @@
// CHECK-NEXT: 0xe70008 ; str x0, [sp, #64]
// CHECK-NEXT: 0xfc ; pacibsp
// CHECK-NEXT: 0xec ; clear unwound to call
// CHECK-NEXT: 0xeb ; EC context
// CHECK-NEXT: 0xea ; context
// CHECK-NEXT: 0xe9 ; machine frame
// CHECK-NEXT: 0xe8 ; trap frame
Expand All @@ -95,8 +96,8 @@
// CHECK-NEXT: ]
// CHECK-NEXT: EpilogueScopes [
// CHECK-NEXT: EpilogueScope {
// CHECK-NEXT: StartOffset: 36
// CHECK-NEXT: EpilogueStartIndex: 68
// CHECK-NEXT: StartOffset: 37
// CHECK-NEXT: EpilogueStartIndex: 69
// CHECK-NEXT: Opcodes [
// CHECK-NEXT: 0x01 ; add sp, #16
// CHECK-NEXT: 0xe4 ; end
Expand Down Expand Up @@ -163,6 +164,8 @@ func:
nop
.seh_context
nop
.seh_ec_context
nop
.seh_clear_unwound_to_call
pacibsp
.seh_pac_sign_lr
Expand Down
8 changes: 8 additions & 0 deletions llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ const Decoder::RingEntry Decoder::Ring64[] = {
{0xff, 0xe8, 1, &Decoder::opcode_trap_frame},
{0xff, 0xe9, 1, &Decoder::opcode_machine_frame},
{0xff, 0xea, 1, &Decoder::opcode_context},
{0xff, 0xeb, 1, &Decoder::opcode_ec_context},
{0xff, 0xec, 1, &Decoder::opcode_clear_unwound_to_call},
{0xff, 0xfc, 1, &Decoder::opcode_pac_sign_lr},
};
Expand Down Expand Up @@ -969,6 +970,13 @@ bool Decoder::opcode_context(const uint8_t *OC, unsigned &Offset,
return false;
}

bool Decoder::opcode_ec_context(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; EC context\n", OC[Offset]);
++Offset;
return false;
}

bool Decoder::opcode_clear_unwound_to_call(const uint8_t *OC, unsigned &Offset,
unsigned Length, bool Prologue) {
SW.startLine() << format("0x%02x ; clear unwound to call\n",
Expand Down
2 changes: 2 additions & 0 deletions llvm/tools/llvm-readobj/ARMWinEHPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ class Decoder {
unsigned Length, bool Prologue);
bool opcode_context(const uint8_t *Opcodes, unsigned &Offset, unsigned Length,
bool Prologue);
bool opcode_ec_context(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
bool opcode_clear_unwound_to_call(const uint8_t *Opcodes, unsigned &Offset,
unsigned Length, bool Prologue);
bool opcode_pac_sign_lr(const uint8_t *Opcodes, unsigned &Offset,
Expand Down