[llvm] 6ad4fda - [llvm-readobj] Decode the new ARM64 SEH info for return address signing

Martin Storsjö via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 11 04:36:50 PDT 2022


Author: Martin Storsjö
Date: 2022-10-11T14:32:01+03:00
New Revision: 6ad4fdacaeea4777e98a3ab41512c49d3d1b6151

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

LOG: [llvm-readobj] Decode the new ARM64 SEH info for return address signing

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

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

Added: 
    llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind-pac.s
    llvm/test/tools/llvm-readobj/COFF/arm64-unwind-pac.s

Modified: 
    llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
    llvm/tools/llvm-readobj/ARMWinEHPrinter.h

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind-pac.s b/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind-pac.s
new file mode 100644
index 0000000000000..3511dd6534cf0
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/arm64-packed-unwind-pac.s
@@ -0,0 +1,31 @@
+// REQUIRES: aarch64-registered-target
+// RUN: llvm-mc -filetype=obj -triple aarch64-windows %s -o %t.o
+// RUN: llvm-readobj --unwind %t.o | FileCheck %s
+
+// CHECK:      UnwindInformation [
+// CHECK-NEXT:   RuntimeFunction {
+// CHECK-NEXT:     Function: func
+// CHECK-NEXT:     Fragment: No
+// CHECK-NEXT:     FunctionLength: 44
+// CHECK-NEXT:     RegF: 0
+// CHECK-NEXT:     RegI: 0
+// CHECK-NEXT:     HomedParameters: No
+// CHECK-NEXT:     CR: 2
+// CHECK-NEXT:     FrameSize: 32
+// CHECK-NEXT:     Prologue [
+// CHECK-NEXT:       mov x29, sp
+// CHECK-NEXT:       stp x29, lr, [sp, #-32]!
+// CHECK-NEXT:       pacibsp
+// CHECK-NEXT:       end
+// CHECK-NEXT:     ]
+// CHECK-NEXT:   }
+// CHECK-NEXT: ]
+
+        .text
+        .globl func
+func:
+        ret
+
+        .section .pdata,"dr"
+        .long func at IMGREL
+        .long 0x0140002d // FunctionLength=11 RegF=0 RegI=0 H=0 CR=2 FrameSize=2

diff  --git a/llvm/test/tools/llvm-readobj/COFF/arm64-unwind-pac.s b/llvm/test/tools/llvm-readobj/COFF/arm64-unwind-pac.s
new file mode 100644
index 0000000000000..b6e051908c88b
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/COFF/arm64-unwind-pac.s
@@ -0,0 +1,39 @@
+// REQUIRES: aarch64-registered-target
+// RUN: llvm-mc -filetype=obj -triple aarch64-windows %s -o %t.o
+// RUN: llvm-readobj --unwind %t.o | FileCheck --strict-whitespace %s
+
+// CHECK:            Prologue [
+// CHECK-NEXT:         0xd600              ; stp x19, lr, [sp, #0]
+// CHECK-NEXT:         0x01                ; sub sp, #16
+// CHECK-NEXT:         0xfc                ; pacibsp
+// CHECK-NEXT:         0xe4                ; end
+// CHECK-NEXT:       ]
+// CHECK-NEXT:       Epilogue [
+// CHECK-NEXT:         0x01                ; add sp, #16
+// CHECK-NEXT:         0xfc                ; autibsp
+// CHECK-NEXT:         0xe4                ; end
+// CHECK-NEXT:       ]
+
+.section .pdata,"dr"
+        .long func at IMGREL
+        .long "$unwind$func"@IMGREL
+
+        .text
+        .globl  func
+func:
+        pacibsp
+        sub sp, sp, #16
+        stp x19, x30, [sp]
+        mov w19, w1
+        blr x0
+        mov w0, w19
+        ldp x19, x30, [sp]
+        add sp, sp, #16
+        autibsp
+        ret
+
+.section .xdata,"dr"
+"$unwind$func":
+.byte 0x0a, 0x00, 0xa0, 0x10
+.byte 0xd6, 0x00, 0x01, 0xfc
+.byte 0xe4, 0xe3, 0xe3, 0xe3

diff  --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
index 188199c6c129d..d64534551ad40 100644
--- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
+++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.cpp
@@ -172,6 +172,7 @@ const Decoder::RingEntry Decoder::Ring64[] = {
     {0xff, 0xe9, 1, &Decoder::opcode_machine_frame},
     {0xff, 0xea, 1, &Decoder::opcode_context},
     {0xff, 0xec, 1, &Decoder::opcode_clear_unwound_to_call},
+    {0xff, 0xfc, 1, &Decoder::opcode_pac_sign_return_address},
 };
 
 static void printRange(raw_ostream &OS, ListSeparator &LS, unsigned First,
@@ -976,6 +977,17 @@ bool Decoder::opcode_clear_unwound_to_call(const uint8_t *OC, unsigned &Offset,
   return false;
 }
 
+bool Decoder::opcode_pac_sign_return_address(const uint8_t *OC,
+                                             unsigned &Offset, unsigned Length,
+                                             bool Prologue) {
+  if (Prologue)
+    SW.startLine() << format("0x%02x                ; pacibsp\n", OC[Offset]);
+  else
+    SW.startLine() << format("0x%02x                ; autibsp\n", OC[Offset]);
+  ++Offset;
+  return false;
+}
+
 void Decoder::decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
                             bool Prologue) {
   assert((!Prologue || Offset == 0) && "prologue should always use offset 0");
@@ -1333,7 +1345,7 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
   int SavSZ = (IntSZ + FpSZ + 8 * 8 * RF.H() + 0xf) & ~0xf;
   int LocSZ = (RF.FrameSize() << 4) - SavSZ;
 
-  if (RF.CR() == 3) {
+  if (RF.CR() == 2 || RF.CR() == 3) {
     SW.startLine() << "mov x29, sp\n";
     if (LocSZ <= 512) {
       SW.startLine() << format("stp x29, lr, [sp, #-%d]!\n", LocSZ);
@@ -1344,7 +1356,7 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
   if (LocSZ > 4080) {
     SW.startLine() << format("sub sp, sp, #%d\n", LocSZ - 4080);
     SW.startLine() << "sub sp, sp, #4080\n";
-  } else if ((RF.CR() != 3 && LocSZ > 0) || LocSZ > 512) {
+  } else if ((RF.CR() != 3 && RF.CR() != 2 && LocSZ > 0) || LocSZ > 512) {
     SW.startLine() << format("sub sp, sp, #%d\n", LocSZ);
   }
   if (RF.H()) {
@@ -1406,6 +1418,11 @@ bool Decoder::dumpPackedARM64Entry(const object::COFFObjectFile &COFF,
                                19 + 2 * I + 1, 16 * I);
     }
   }
+  // CR=2 is yet undocumented, see
+  // https://github.com/MicrosoftDocs/cpp-docs/pull/4202 for upstream
+  // progress on getting it documented.
+  if (RF.CR() == 2)
+    SW.startLine() << "pacibsp\n";
   SW.startLine() << "end\n";
 
   return true;

diff  --git a/llvm/tools/llvm-readobj/ARMWinEHPrinter.h b/llvm/tools/llvm-readobj/ARMWinEHPrinter.h
index eb2393de8f67d..745a9cbb51cf6 100644
--- a/llvm/tools/llvm-readobj/ARMWinEHPrinter.h
+++ b/llvm/tools/llvm-readobj/ARMWinEHPrinter.h
@@ -131,6 +131,8 @@ class Decoder {
                       bool Prologue);
   bool opcode_clear_unwound_to_call(const uint8_t *Opcodes, unsigned &Offset,
                                     unsigned Length, bool Prologue);
+  bool opcode_pac_sign_return_address(const uint8_t *Opcodes, unsigned &Offset,
+                                      unsigned Length, bool Prologue);
 
   void decodeOpcodes(ArrayRef<uint8_t> Opcodes, unsigned Offset,
                      bool Prologue);


        


More information about the llvm-commits mailing list