[libunwind] 78eabca - [libunwind] Add support for PC reg column in arm64

Marco Vanotti via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 17 17:42:30 PST 2021


Author: Marco Vanotti
Date: 2021-02-17T17:42:19-08:00
New Revision: 78eabcaa48df72e01b352b4b5077cece0693950c

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

LOG: [libunwind] Add support for PC reg column in arm64

This change adds support for the dwarf PC register column in arm64, allowing
CFI directives to make use of it.

As of the last revision of the DWARF for ARM 64-bit architecture[0], the pc
register has been added as a valir register, with number 32.

This allows libunwinder to restore both pc and lr, which is useful
for stack switches and signal contexts.

[0]:
https://github.com/ARM-software/abi-aa/blob/f52e1ad3f81254497a83578dc102f6aac89e52d0/aadwarf64/aadwarf64.rst

Reviewed By: phosek, #libunwind

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

Added: 
    

Modified: 
    libunwind/include/libunwind.h
    libunwind/src/Registers.hpp

Removed: 
    


################################################################################
diff  --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index 5bae8d02f799..0feecd7bd6fc 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -493,16 +493,16 @@ enum {
 
 // 64-bit ARM64 registers
 enum {
-  UNW_ARM64_X0  = 0,
-  UNW_ARM64_X1  = 1,
-  UNW_ARM64_X2  = 2,
-  UNW_ARM64_X3  = 3,
-  UNW_ARM64_X4  = 4,
-  UNW_ARM64_X5  = 5,
-  UNW_ARM64_X6  = 6,
-  UNW_ARM64_X7  = 7,
-  UNW_ARM64_X8  = 8,
-  UNW_ARM64_X9  = 9,
+  UNW_ARM64_X0 = 0,
+  UNW_ARM64_X1 = 1,
+  UNW_ARM64_X2 = 2,
+  UNW_ARM64_X3 = 3,
+  UNW_ARM64_X4 = 4,
+  UNW_ARM64_X5 = 5,
+  UNW_ARM64_X6 = 6,
+  UNW_ARM64_X7 = 7,
+  UNW_ARM64_X8 = 8,
+  UNW_ARM64_X9 = 9,
   UNW_ARM64_X10 = 10,
   UNW_ARM64_X11 = 11,
   UNW_ARM64_X12 = 12,
@@ -523,24 +523,25 @@ enum {
   UNW_ARM64_X27 = 27,
   UNW_ARM64_X28 = 28,
   UNW_ARM64_X29 = 29,
-  UNW_ARM64_FP  = 29,
+  UNW_ARM64_FP = 29,
   UNW_ARM64_X30 = 30,
-  UNW_ARM64_LR  = 30,
+  UNW_ARM64_LR = 30,
   UNW_ARM64_X31 = 31,
-  UNW_ARM64_SP  = 31,
+  UNW_ARM64_SP = 31,
+  UNW_ARM64_PC = 32,
   // reserved block
   UNW_ARM64_RA_SIGN_STATE = 34,
   // reserved block
-  UNW_ARM64_D0  = 64,
-  UNW_ARM64_D1  = 65,
-  UNW_ARM64_D2  = 66,
-  UNW_ARM64_D3  = 67,
-  UNW_ARM64_D4  = 68,
-  UNW_ARM64_D5  = 69,
-  UNW_ARM64_D6  = 70,
-  UNW_ARM64_D7  = 71,
-  UNW_ARM64_D8  = 72,
-  UNW_ARM64_D9  = 73,
+  UNW_ARM64_D0 = 64,
+  UNW_ARM64_D1 = 65,
+  UNW_ARM64_D2 = 66,
+  UNW_ARM64_D3 = 67,
+  UNW_ARM64_D4 = 68,
+  UNW_ARM64_D5 = 69,
+  UNW_ARM64_D6 = 70,
+  UNW_ARM64_D7 = 71,
+  UNW_ARM64_D8 = 72,
+  UNW_ARM64_D9 = 73,
   UNW_ARM64_D10 = 74,
   UNW_ARM64_D11 = 75,
   UNW_ARM64_D12 = 76,

diff  --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index efeaf435591e..de8e067b9d0c 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -1849,31 +1849,39 @@ inline bool Registers_arm64::validRegister(int regNum) const {
     return false;
   if (regNum == UNW_ARM64_RA_SIGN_STATE)
     return true;
-  if ((regNum > 31) && (regNum < 64))
+  if ((regNum > 32) && (regNum < 64))
     return false;
   return true;
 }
 
 inline uint64_t Registers_arm64::getRegister(int regNum) const {
-  if (regNum == UNW_REG_IP)
+  if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
     return _registers.__pc;
-  if (regNum == UNW_REG_SP)
+  if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
     return _registers.__sp;
   if (regNum == UNW_ARM64_RA_SIGN_STATE)
     return _registers.__ra_sign_state;
-  if ((regNum >= 0) && (regNum < 32))
+  if (regNum == UNW_ARM64_FP)
+    return _registers.__fp;
+  if (regNum == UNW_ARM64_LR)
+    return _registers.__lr;
+  if ((regNum >= 0) && (regNum < 29))
     return _registers.__x[regNum];
   _LIBUNWIND_ABORT("unsupported arm64 register");
 }
 
 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
-  if (regNum == UNW_REG_IP)
+  if (regNum == UNW_REG_IP || regNum == UNW_ARM64_PC)
     _registers.__pc = value;
-  else if (regNum == UNW_REG_SP)
+  else if (regNum == UNW_REG_SP || regNum == UNW_ARM64_SP)
     _registers.__sp = value;
   else if (regNum == UNW_ARM64_RA_SIGN_STATE)
     _registers.__ra_sign_state = value;
-  else if ((regNum >= 0) && (regNum < 32))
+  else if (regNum == UNW_ARM64_FP)
+    _registers.__fp = value;
+  else if (regNum == UNW_ARM64_LR)
+    _registers.__lr = value;
+  else if ((regNum >= 0) && (regNum < 29))
     _registers.__x[regNum] = value;
   else
     _LIBUNWIND_ABORT("unsupported arm64 register");
@@ -1943,12 +1951,14 @@ inline const char *Registers_arm64::getRegisterName(int regNum) {
     return "x27";
   case UNW_ARM64_X28:
     return "x28";
-  case UNW_ARM64_X29:
+  case UNW_ARM64_FP:
     return "fp";
-  case UNW_ARM64_X30:
+  case UNW_ARM64_LR:
     return "lr";
-  case UNW_ARM64_X31:
+  case UNW_ARM64_SP:
     return "sp";
+  case UNW_ARM64_PC:
+    return "pc";
   case UNW_ARM64_D0:
     return "d0";
   case UNW_ARM64_D1:


        


More information about the cfe-commits mailing list