[llvm] c43bff6 - [AArch64] Add support for the SEH opcode for return address signing

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 12 01:07:51 PDT 2022


Author: Martin Storsjö
Date: 2022-10-12T11:07:11+03:00
New Revision: c43bff64e903f726d456ca27fd167b91198ae169

URL: https://github.com/llvm/llvm-project/commit/c43bff64e903f726d456ca27fd167b91198ae169
DIFF: https://github.com/llvm/llvm-project/commit/c43bff64e903f726d456ca27fd167b91198ae169.diff

LOG: [AArch64] Add support for the SEH opcode for return address signing

This was documented upstream in
https://github.com/MicrosoftDocs/cpp-docs/pull/4202.

Differential Revision: https://reviews.llvm.org/D135276

Added: 
    

Modified: 
    llvm/include/llvm/Support/Win64EH.h
    llvm/lib/MC/MCWin64EH.cpp
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
    llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
    llvm/test/MC/AArch64/seh.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/Win64EH.h b/llvm/include/llvm/Support/Win64EH.h
index 31345beaa66a5..4bc3d81070645 100644
--- a/llvm/include/llvm/Support/Win64EH.h
+++ b/llvm/include/llvm/Support/Win64EH.h
@@ -61,6 +61,7 @@ enum UnwindOpcodes {
   UOP_TrapFrame,
   UOP_Context,
   UOP_ClearUnwoundToCall,
+  UOP_PACSignReturnAddress,
   // The following set of unwind opcodes is for ARM.  They are documented at
   // https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
 

diff  --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index 3e2bc34b4d060..f39383ed3eb78 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -377,6 +377,9 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
     case Win64EH::UOP_ClearUnwoundToCall:
       Count += 1;
       break;
+    case Win64EH::UOP_PACSignReturnAddress:
+      Count += 1;
+      break;
     }
   }
   return Count;
@@ -543,6 +546,10 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer,
     b = 0xEC;
     streamer.emitInt8(b);
     break;
+  case Win64EH::UOP_PACSignReturnAddress:
+    b = 0xFC;
+    streamer.emitInt8(b);
+    break;
   }
 }
 

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index a206d10caf660..ebc4e53b7a6c5 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -218,6 +218,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
   bool parseDirectiveSEHMachineFrame(SMLoc L);
   bool parseDirectiveSEHContext(SMLoc L);
   bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
+  bool parseDirectiveSEHPACSignReturnAddress(SMLoc L);
 
   bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
                            SmallVectorImpl<SMLoc> &Loc);
@@ -6099,6 +6100,8 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
       parseDirectiveSEHContext(Loc);
     else if (IDVal == ".seh_clear_unwound_to_call")
       parseDirectiveSEHClearUnwoundToCall(Loc);
+    else if (IDVal == ".seh_pac_sign_return_address")
+      parseDirectiveSEHPACSignReturnAddress(Loc);
     else
       return true;
   } else
@@ -6775,6 +6778,13 @@ bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(SMLoc L) {
   return false;
 }
 
+/// parseDirectiveSEHPACSignReturnAddress
+/// ::= .seh_pac_sign_return_address
+bool AArch64AsmParser::parseDirectiveSEHPACSignReturnAddress(SMLoc L) {
+  getTargetStreamer().emitARM64WinCFIPACSignReturnAddress();
+  return false;
+}
+
 bool
 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
                                     AArch64MCExpr::VariantKind &ELFRefKind,

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 46edb12959d28..983a38420e9d1 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -107,6 +107,9 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
   void emitARM64WinCFIClearUnwoundToCall() override {
     OS << "\t.seh_clear_unwound_to_call\n";
   }
+  void emitARM64WinCFIPACSignReturnAddress() override {
+    OS << "\t.seh_pac_sign_return_address\n";
+  }
 
 public:
   AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index 86c7baf8f4298..bdccb99d257b7 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -67,6 +67,7 @@ class AArch64TargetStreamer : public MCTargetStreamer {
   virtual void emitARM64WinCFIMachineFrame() {}
   virtual void emitARM64WinCFIContext() {}
   virtual void emitARM64WinCFIClearUnwoundToCall() {}
+  virtual void emitARM64WinCFIPACSignReturnAddress() {}
 
 private:
   std::unique_ptr<AssemblerConstantPools> ConstantPools;
@@ -120,6 +121,7 @@ class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer {
   void emitARM64WinCFIMachineFrame() override;
   void emitARM64WinCFIContext() override;
   void emitARM64WinCFIClearUnwoundToCall() override;
+  void emitARM64WinCFIPACSignReturnAddress() override;
 
 private:
   void emitARM64WinUnwindCode(unsigned UnwindCode, int Reg, int Offset);

diff  --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
index 820d940c1ed2d..0188bb1ade181 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
@@ -221,6 +221,10 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinCFIClearUnwoundToCall() {
   emitARM64WinUnwindCode(Win64EH::UOP_ClearUnwoundToCall, -1, 0);
 }
 
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFIPACSignReturnAddress() {
+  emitARM64WinUnwindCode(Win64EH::UOP_PACSignReturnAddress, -1, 0);
+}
+
 MCWinCOFFStreamer *llvm::createAArch64WinCOFFStreamer(
     MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
     std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,

diff  --git a/llvm/test/MC/AArch64/seh.s b/llvm/test/MC/AArch64/seh.s
index 0b7c2e6306638..23da04ea0ce47 100644
--- a/llvm/test/MC/AArch64/seh.s
+++ b/llvm/test/MC/AArch64/seh.s
@@ -20,7 +20,7 @@
 // CHECK-NEXT:   }
 // CHECK:        Section {
 // CHECK:          Name: .xdata
-// CHECK:          RawDataSize: 52
+// CHECK:          RawDataSize: 56
 // CHECK:          RelocationCount: 1
 // CHECK:          Characteristics [
 // CHECK-NEXT:       ALIGN_4BYTES
@@ -41,7 +41,7 @@
 
 // CHECK-NEXT: Relocations [
 // CHECK-NEXT:   Section (4) .xdata {
-// CHECK-NEXT:     0x28 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
+// CHECK-NEXT:     0x2C IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Section (5) .pdata {
 // CHECK-NEXT:     0x0 IMAGE_REL_ARM64_ADDR32NB .text
@@ -54,8 +54,9 @@
 // CHECK-NEXT:     Function: func
 // CHECK-NEXT:     ExceptionRecord: .xdata
 // CHECK-NEXT:     ExceptionData {
-// CHECK-NEXT:       FunctionLength: 100
+// CHECK-NEXT:       FunctionLength: 104
 // CHECK:            Prologue [
+// CHECK-NEXT:         0xfc                ; pacibsp
 // CHECK-NEXT:         0xec                ; clear unwound to call
 // CHECK-NEXT:         0xea                ; context
 // CHECK-NEXT:         0xe9                ; machine frame
@@ -80,9 +81,15 @@
 // CHECK-NEXT:         0x01                ; sub sp, #16
 // CHECK-NEXT:         0xe4                ; end
 // CHECK-NEXT:       ]
-// CHECK-NEXT:       Epilogue [
-// CHECK-NEXT:         0x01                ; add sp, #16
-// CHECK-NEXT:         0xe4                ; end
+// CHECK-NEXT:       EpilogueScopes [
+// CHECK-NEXT:         EpilogueScope {
+// CHECK-NEXT:           StartOffset: 24
+// CHECK-NEXT:           EpilogueStartIndex: 32
+// CHECK-NEXT:           Opcodes [
+// CHECK-NEXT:             0x01                ; add sp, #16
+// CHECK-NEXT:             0xe4                ; end
+// CHECK-NEXT:           ]
+// CHECK-NEXT:         }
 // CHECK-NEXT:       ]
 // CHECK-NEXT:       ExceptionHandler [
 // CHECK-NEXT:         Routine: __C_specific_handler (0x0)
@@ -145,6 +152,8 @@ func:
     .seh_context
     nop
     .seh_clear_unwound_to_call
+    pacibsp
+    .seh_pac_sign_return_address
     .seh_endprologue
     nop
     .seh_startepilogue


        


More information about the llvm-commits mailing list