https://github.com/kovdan01 updated 
https://github.com/llvm/llvm-project/pull/173765

>From 9ddab0cf0b8a4e6af8895ac60718b084a3675f45 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <[email protected]>
Date: Sun, 28 Dec 2025 13:35:34 +0300
Subject: [PATCH 1/2] [PAC][libunwind] Pass ptrauth-qualified values as const
 references

For Apple's arm64e or Linux's pauthtest, `Registers_arm64::link_reg_t`
type is `__ptrauth`-qualified. When passing a value of such a type to a
function accepting non-`__ptrauth`-qualified parameter with `pint_t`
type, an authentication is performed. So, the corresponding callee argument
does not contain an embedded signature, making it prone to substitution
if spilled to the stack.

This patch prevents early authentication of signed values of `link_reg_t`
type by passing them as const l-value references instead of passing by
value with type `pint_t`. This way, the callee would operate with a
`__ptrauth`-qualified value containing a signature, allowing to detect a
substitution if the value is spilled to the stack.
---
 libunwind/src/AddressSpace.hpp   | 18 +++++++++++-------
 libunwind/src/DwarfParser.hpp    | 15 ++++++++++-----
 libunwind/src/EHHeaderParser.hpp |  6 ++++--
 libunwind/src/UnwindCursor.hpp   | 11 ++++++-----
 4 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index 63f9cb367ec0c..6d204a1402c07 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -202,10 +202,12 @@ class _LIBUNWIND_HIDDEN LocalAddressSpace {
 
   pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
                      pint_t datarelBase = 0, pint_t *resultAddr = nullptr);
-  bool findFunctionName(pint_t addr, char *buf, size_t bufLen,
+  template <typename T>
+  bool findFunctionName(const T &addr, char *buf, size_t bufLen,
                         unw_word_t *offset);
-  bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info);
-  bool findOtherFDE(pint_t targetAddr, pint_t &fde);
+  template <typename T>
+  bool findUnwindSections(const T &targetAddr, UnwindInfoSections &info);
+  template <typename T> bool findOtherFDE(const T &targetAddr, pint_t &fde);
 
   static LocalAddressSpace sThisAddressSpace;
 };
@@ -497,8 +499,8 @@ static int findUnwindSectionsByPhdr(struct dl_phdr_info 
*pinfo,
 
 #endif  // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
 
-
-inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
+template <typename T>
+inline bool LocalAddressSpace::findUnwindSections(const T &targetAddr,
                                                   UnwindInfoSections &info) {
 #ifdef __APPLE__
   dyld_unwind_sections dyldInfo;
@@ -669,14 +671,16 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t 
targetAddr,
   return false;
 }
 
-inline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) {
+template <typename T>
+inline bool LocalAddressSpace::findOtherFDE(const T &targetAddr, pint_t &fde) {
   // TO DO: if OS has way to dynamically register FDEs, check that.
   (void)targetAddr;
   (void)fde;
   return false;
 }
 
-inline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf,
+template <typename T>
+inline bool LocalAddressSpace::findFunctionName(const T &addr, char *buf,
                                                 size_t bufLen,
                                                 unw_word_t *offset) {
 #if _LIBUNWIND_USE_DLADDR
diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index 2b04ae2831f9a..a062b5bbd31ab 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -160,14 +160,16 @@ class CFI_Parser {
     }
   };
 
-  static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
+  template <typename T>
+  static bool findFDE(A &addressSpace, const T &pc, pint_t ehSectionStart,
                       size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo,
                       CIE_Info *cieInfo);
   static const char *decodeFDE(A &addressSpace, pint_t fdeStart,
                                FDE_Info *fdeInfo, CIE_Info *cieInfo,
                                bool useCIEInfo = false);
+  template <typename T>
   static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo,
-                                   const CIE_Info &cieInfo, pint_t upToPC,
+                                   const CIE_Info &cieInfo, const T &upToPC,
                                    int arch, PrologInfo *results);
 
   static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo);
@@ -239,7 +241,8 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, 
pint_t fdeStart,
 
 /// Scan an eh_frame section to find an FDE for a pc
 template <typename A>
-bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
+template <typename T>
+bool CFI_Parser<A>::findFDE(A &addressSpace, const T &pc, pint_t 
ehSectionStart,
                             size_t sectionLength, pint_t fdeHint,
                             FDE_Info *fdeInfo, CIE_Info *cieInfo) {
   //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
@@ -451,10 +454,12 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, 
pint_t cie,
 
 /// "run" the DWARF instructions and create the abstract PrologInfo for an FDE
 template <typename A>
+template <typename T>
 bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
                                          const FDE_Info &fdeInfo,
-                                         const CIE_Info &cieInfo, pint_t 
upToPC,
-                                         int arch, PrologInfo *results) {
+                                         const CIE_Info &cieInfo,
+                                         const T &upToPC, int arch,
+                                         PrologInfo *results) {
   // Alloca is used for the allocation of the rememberStack entries. It removes
   // the dependency on new/malloc but the below for loop can not be refactored
   // into functions. Entry could be saved during the processing of a CIE and
diff --git a/libunwind/src/EHHeaderParser.hpp b/libunwind/src/EHHeaderParser.hpp
index 0662a1321e2c7..9f60985eb70e5 100644
--- a/libunwind/src/EHHeaderParser.hpp
+++ b/libunwind/src/EHHeaderParser.hpp
@@ -37,7 +37,8 @@ template <typename A> class EHHeaderParser {
 
   static bool decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
                           EHHeaderInfo &ehHdrInfo);
-  static bool findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
+  template <typename T>
+  static bool findFDE(A &addressSpace, const T &pc, pint_t ehHdrStart,
                       uint32_t sectionLength,
                       typename CFI_Parser<A>::FDE_Info *fdeInfo,
                       typename CFI_Parser<A>::CIE_Info *cieInfo);
@@ -112,7 +113,8 @@ bool EHHeaderParser<A>::decodeTableEntry(
 }
 
 template <typename A>
-bool EHHeaderParser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehHdrStart,
+template <typename T>
+bool EHHeaderParser<A>::findFDE(A &addressSpace, const T &pc, pint_t 
ehHdrStart,
                                 uint32_t sectionLength,
                                 typename CFI_Parser<A>::FDE_Info *fdeInfo,
                                 typename CFI_Parser<A>::CIE_Info *cieInfo) {
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index afa0cae790377..c7d3e4ca85e91 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -121,7 +121,7 @@ class _LIBUNWIND_HIDDEN DwarfFDECache {
   typedef typename A::pint_t pint_t;
 public:
   static constexpr pint_t kSearchAll = static_cast<pint_t>(-1);
-  static pint_t findFDE(pint_t mh, pint_t pc);
+  template <typename T> static pint_t findFDE(pint_t mh, const T &pc);
   static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
   static void removeAllIn(pint_t mh);
   static void iterateCacheEntries(void (*func)(unw_word_t ip_start,
@@ -174,8 +174,9 @@ bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
 #endif
 
 template <typename A>
+template <typename T>
 typename DwarfFDECache<A>::pint_t DwarfFDECache<A>::findFDE(pint_t mh,
-                                                            pint_t pc) {
+                                                            const T &pc) {
   pint_t result = 0;
   _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
   for (entry *p = _buffer; p < _bufferUsed; ++p) {
@@ -1060,7 +1061,7 @@ class UnwindCursor : public AbstractUnwindCursor{
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
                          const typename CFI_Parser<A>::CIE_Info &cieInfo,
-                         pint_t pc, uintptr_t dso_base);
+                         const typename R::link_reg_t &pc, uintptr_t dso_base);
   bool getInfoFromDwarfSection(const typename R::link_reg_t &pc,
                                const UnwindInfoSections &sects,
                                uint32_t fdeSectionOffsetHint = 0);
@@ -1730,8 +1731,8 @@ bool UnwindCursor<A, R>::getInfoFromEHABISection(
 template <typename A, typename R>
 bool UnwindCursor<A, R>::getInfoFromFdeCie(
     const typename CFI_Parser<A>::FDE_Info &fdeInfo,
-    const typename CFI_Parser<A>::CIE_Info &cieInfo, pint_t pc,
-    uintptr_t dso_base) {
+    const typename CFI_Parser<A>::CIE_Info &cieInfo,
+    const typename R::link_reg_t &pc, uintptr_t dso_base) {
   typename CFI_Parser<A>::PrologInfo prolog;
   if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
                                           R::getArch(), &prolog)) {

>From bc4956c4f16d2692162b3cf5c8220268c323b4f0 Mon Sep 17 00:00:00 2001
From: Daniil Kovalev <[email protected]>
Date: Tue, 30 Dec 2025 12:34:21 +0300
Subject: [PATCH 2/2] Address review comments

---
 libunwind/src/AddressSpace.hpp      | 36 +++++++++------
 libunwind/src/DwarfInstructions.hpp | 11 +++--
 libunwind/src/DwarfParser.hpp       | 36 ++++++++-------
 libunwind/src/EHHeaderParser.hpp    | 16 ++++---
 libunwind/src/Registers.hpp         | 23 ++++++++++
 libunwind/src/UnwindCursor.hpp      | 68 ++++++++++++++++-------------
 6 files changed, 121 insertions(+), 69 deletions(-)

diff --git a/libunwind/src/AddressSpace.hpp b/libunwind/src/AddressSpace.hpp
index 6d204a1402c07..8f73b9c912df1 100644
--- a/libunwind/src/AddressSpace.hpp
+++ b/libunwind/src/AddressSpace.hpp
@@ -202,12 +202,17 @@ class _LIBUNWIND_HIDDEN LocalAddressSpace {
 
   pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
                      pint_t datarelBase = 0, pint_t *resultAddr = nullptr);
-  template <typename T>
-  bool findFunctionName(const T &addr, char *buf, size_t bufLen,
-                        unw_word_t *offset);
-  template <typename T>
-  bool findUnwindSections(const T &targetAddr, UnwindInfoSections &info);
-  template <typename T> bool findOtherFDE(const T &targetAddr, pint_t &fde);
+  // Note: R::link_reg_arg_t is used intentionally instead of `pint_t` to keep
+  // signature of `__ptrauth`-qualified values of `link_reg_t` type on AArch64
+  // PAuth-enabled ABI intact. See corresponding typedefs in `Registers_arm64`.
+  template <typename R>
+  bool findFunctionName(typename R::link_reg_arg_t addr, char *buf,
+                        size_t bufLen, unw_word_t *offset);
+  template <typename R>
+  bool findUnwindSections(typename R::link_reg_arg_t targetAddr,
+                          UnwindInfoSections &info);
+  template <typename R>
+  bool findOtherFDE(typename R::link_reg_arg_t targetAddr, pint_t &fde);
 
   static LocalAddressSpace sThisAddressSpace;
 };
@@ -499,9 +504,10 @@ static int findUnwindSectionsByPhdr(struct dl_phdr_info 
*pinfo,
 
 #endif  // defined(_LIBUNWIND_USE_DL_ITERATE_PHDR)
 
-template <typename T>
-inline bool LocalAddressSpace::findUnwindSections(const T &targetAddr,
-                                                  UnwindInfoSections &info) {
+template <typename R>
+inline bool
+LocalAddressSpace::findUnwindSections(typename R::link_reg_arg_t targetAddr,
+                                      UnwindInfoSections &info) {
 #ifdef __APPLE__
   dyld_unwind_sections dyldInfo;
   if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) {
@@ -671,17 +677,19 @@ inline bool LocalAddressSpace::findUnwindSections(const T 
&targetAddr,
   return false;
 }
 
-template <typename T>
-inline bool LocalAddressSpace::findOtherFDE(const T &targetAddr, pint_t &fde) {
+template <typename R>
+inline bool
+LocalAddressSpace::findOtherFDE(typename R::link_reg_arg_t targetAddr,
+                                pint_t &fde) {
   // TO DO: if OS has way to dynamically register FDEs, check that.
   (void)targetAddr;
   (void)fde;
   return false;
 }
 
-template <typename T>
-inline bool LocalAddressSpace::findFunctionName(const T &addr, char *buf,
-                                                size_t bufLen,
+template <typename R>
+inline bool LocalAddressSpace::findFunctionName(typename R::link_reg_arg_t 
addr,
+                                                char *buf, size_t bufLen,
                                                 unw_word_t *offset) {
 #if _LIBUNWIND_USE_DLADDR
   Dl_info dyldInfo;
diff --git a/libunwind/src/DwarfInstructions.hpp 
b/libunwind/src/DwarfInstructions.hpp
index d2822e8be29ef..3be55dcbfab2c 100644
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -33,7 +33,10 @@ class DwarfInstructions {
   typedef typename A::pint_t pint_t;
   typedef typename A::sint_t sint_t;
 
-  static int stepWithDwarf(A &addressSpace, const typename R::link_reg_t &pc,
+  // Note: R::link_reg_arg_t is used intentionally instead of `pint_t` to keep
+  // signature of `__ptrauth`-qualified values of `link_reg_t` type on AArch64
+  // PAuth-enabled ABI intact. See corresponding typedefs in `Registers_arm64`.
+  static int stepWithDwarf(A &addressSpace, typename R::link_reg_arg_t pc,
                            pint_t fdeStart, R &registers, bool &isSignalFrame,
                            bool stage2);
 
@@ -209,7 +212,7 @@ bool DwarfInstructions<A, R>::isReturnAddressSignedWithPC(A 
&addressSpace,
 
 template <typename A, typename R>
 int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace,
-                                           const typename R::link_reg_t &pc,
+                                           typename R::link_reg_arg_t pc,
                                            pint_t fdeStart, R &registers,
                                            bool &isSignalFrame, bool stage2) {
   FDE_Info fdeInfo;
@@ -217,8 +220,8 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace,
   if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
                                &cieInfo) == NULL) {
     PrologInfo prolog;
-    if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
-                                            R::getArch(), &prolog)) {
+    if (CFI_Parser<A>::template parseFDEInstructions<R>(
+            addressSpace, fdeInfo, cieInfo, pc, R::getArch(), &prolog)) {
       // get pointer to cfa (architecture specific)
       pint_t cfa = getCFA(addressSpace, prolog, registers);
 
diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
index a062b5bbd31ab..98956520a77cf 100644
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -160,17 +160,22 @@ class CFI_Parser {
     }
   };
 
-  template <typename T>
-  static bool findFDE(A &addressSpace, const T &pc, pint_t ehSectionStart,
-                      size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo,
-                      CIE_Info *cieInfo);
+  // Note: R::link_reg_arg_t is used intentionally instead of `pint_t` to keep
+  // signature of `__ptrauth`-qualified values of `link_reg_t` type on AArch64
+  // PAuth-enabled ABI intact. See corresponding typedefs in `Registers_arm64`.
+  template <typename R>
+  static bool findFDE(A &addressSpace, typename R::link_reg_arg_t pc,
+                      pint_t ehSectionStart, size_t sectionLength,
+                      pint_t fdeHint, FDE_Info *fdeInfo, CIE_Info *cieInfo);
+  template <typename R>
+  static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo,
+                                   const CIE_Info &cieInfo,
+                                   typename R::link_reg_arg_t upToPC, int arch,
+                                   PrologInfo *results);
+
   static const char *decodeFDE(A &addressSpace, pint_t fdeStart,
                                FDE_Info *fdeInfo, CIE_Info *cieInfo,
                                bool useCIEInfo = false);
-  template <typename T>
-  static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo,
-                                   const CIE_Info &cieInfo, const T &upToPC,
-                                   int arch, PrologInfo *results);
 
   static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo);
 };
@@ -241,10 +246,11 @@ const char *CFI_Parser<A>::decodeFDE(A &addressSpace, 
pint_t fdeStart,
 
 /// Scan an eh_frame section to find an FDE for a pc
 template <typename A>
-template <typename T>
-bool CFI_Parser<A>::findFDE(A &addressSpace, const T &pc, pint_t 
ehSectionStart,
-                            size_t sectionLength, pint_t fdeHint,
-                            FDE_Info *fdeInfo, CIE_Info *cieInfo) {
+template <typename R>
+bool CFI_Parser<A>::findFDE(A &addressSpace, typename R::link_reg_arg_t pc,
+                            pint_t ehSectionStart, size_t sectionLength,
+                            pint_t fdeHint, FDE_Info *fdeInfo,
+                            CIE_Info *cieInfo) {
   //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
   pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart;
   const pint_t ehSectionEnd = (sectionLength == SIZE_MAX)
@@ -454,12 +460,12 @@ const char *CFI_Parser<A>::parseCIE(A &addressSpace, 
pint_t cie,
 
 /// "run" the DWARF instructions and create the abstract PrologInfo for an FDE
 template <typename A>
-template <typename T>
+template <typename R>
 bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
                                          const FDE_Info &fdeInfo,
                                          const CIE_Info &cieInfo,
-                                         const T &upToPC, int arch,
-                                         PrologInfo *results) {
+                                         typename R::link_reg_arg_t upToPC,
+                                         int arch, PrologInfo *results) {
   // Alloca is used for the allocation of the rememberStack entries. It removes
   // the dependency on new/malloc but the below for loop can not be refactored
   // into functions. Entry could be saved during the processing of a CIE and
diff --git a/libunwind/src/EHHeaderParser.hpp b/libunwind/src/EHHeaderParser.hpp
index 9f60985eb70e5..c0951da122e02 100644
--- a/libunwind/src/EHHeaderParser.hpp
+++ b/libunwind/src/EHHeaderParser.hpp
@@ -37,9 +37,13 @@ template <typename A> class EHHeaderParser {
 
   static bool decodeEHHdr(A &addressSpace, pint_t ehHdrStart, pint_t ehHdrEnd,
                           EHHeaderInfo &ehHdrInfo);
-  template <typename T>
-  static bool findFDE(A &addressSpace, const T &pc, pint_t ehHdrStart,
-                      uint32_t sectionLength,
+
+  // Note: R::link_reg_arg_t is used intentionally instead of `pint_t` to keep
+  // signature of `__ptrauth`-qualified values of `link_reg_t` type on AArch64
+  // PAuth-enabled ABI intact. See corresponding typedefs in `Registers_arm64`.
+  template <typename R>
+  static bool findFDE(A &addressSpace, typename R::link_reg_arg_t pc,
+                      pint_t ehHdrStart, uint32_t sectionLength,
                       typename CFI_Parser<A>::FDE_Info *fdeInfo,
                       typename CFI_Parser<A>::CIE_Info *cieInfo);
 
@@ -113,9 +117,9 @@ bool EHHeaderParser<A>::decodeTableEntry(
 }
 
 template <typename A>
-template <typename T>
-bool EHHeaderParser<A>::findFDE(A &addressSpace, const T &pc, pint_t 
ehHdrStart,
-                                uint32_t sectionLength,
+template <typename R>
+bool EHHeaderParser<A>::findFDE(A &addressSpace, typename R::link_reg_arg_t pc,
+                                pint_t ehHdrStart, uint32_t sectionLength,
                                 typename CFI_Parser<A>::FDE_Info *fdeInfo,
                                 typename CFI_Parser<A>::CIE_Info *cieInfo) {
   pint_t ehHdrEnd = ehHdrStart + sectionLength;
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index 45a2b0921ea3b..b702e043b081c 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -68,6 +68,7 @@ class _LIBUNWIND_HIDDEN Registers_x86 {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -289,6 +290,7 @@ class _LIBUNWIND_HIDDEN Registers_x86_64 {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint64_t    getRegister(int num) const;
@@ -611,6 +613,7 @@ class _LIBUNWIND_HIDDEN Registers_ppc {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -1186,6 +1189,7 @@ class _LIBUNWIND_HIDDEN Registers_ppc64 {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint64_t    getRegister(int num) const;
@@ -1852,6 +1856,14 @@ class _LIBUNWIND_HIDDEN Registers_arm64 {
   typedef uint64_t reg_t;
   typedef uint64_t __ptrauth_unwind_registers_arm64_link_reg link_reg_t;
 
+  // Use `link_reg_arg_t` to pass values of `link_reg_t` type as function
+  // arguments. We need to use a const l-value reference to keep signature of
+  // `__ptrauth`-qualified values of `link_reg_t` type on AArch64 PAuth-enabled
+  // ABI intact. Passing the raw pointer by value would cause authentication on
+  // the caller side and make the pointer prone to substitution if spilled to
+  // the stack in the callee.
+  typedef const link_reg_t &link_reg_arg_t;
+
   bool        validRegister(int num) const;
   uint64_t    getRegister(int num) const;
   void        setRegister(int num, uint64_t value);
@@ -2257,6 +2269,7 @@ class _LIBUNWIND_HIDDEN Registers_arm {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -2765,6 +2778,7 @@ class _LIBUNWIND_HIDDEN Registers_or1k {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -2967,6 +2981,7 @@ class _LIBUNWIND_HIDDEN Registers_mips_o32 {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -3305,6 +3320,7 @@ class _LIBUNWIND_HIDDEN Registers_mips_newabi {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint64_t    getRegister(int num) const;
@@ -3611,6 +3627,7 @@ class _LIBUNWIND_HIDDEN Registers_sparc {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -3800,6 +3817,7 @@ class _LIBUNWIND_HIDDEN Registers_sparc64 {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool validRegister(int num) const;
   uint64_t getRegister(int num) const;
@@ -3988,6 +4006,7 @@ class _LIBUNWIND_HIDDEN Registers_hexagon {
 
   typedef uint32_t reg_t;
   typedef uint32_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint32_t    getRegister(int num) const;
@@ -4206,6 +4225,7 @@ class _LIBUNWIND_HIDDEN Registers_riscv {
 
   typedef ::libunwind::reg_t reg_t;
   typedef ::libunwind::reg_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   reg_t       getRegister(int num) const;
@@ -4506,6 +4526,7 @@ class _LIBUNWIND_HIDDEN Registers_ve {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint64_t    getRegister(int num) const;
@@ -4952,6 +4973,7 @@ class _LIBUNWIND_HIDDEN Registers_s390x {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool        validRegister(int num) const;
   uint64_t    getRegister(int num) const;
@@ -5243,6 +5265,7 @@ class _LIBUNWIND_HIDDEN Registers_loongarch {
 
   typedef uint64_t reg_t;
   typedef uint64_t link_reg_t;
+  typedef const link_reg_t &link_reg_arg_t;
 
   bool validRegister(int num) const;
   uint64_t getRegister(int num) const;
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index c7d3e4ca85e91..e1d2f6d31c9b6 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -121,7 +121,13 @@ class _LIBUNWIND_HIDDEN DwarfFDECache {
   typedef typename A::pint_t pint_t;
 public:
   static constexpr pint_t kSearchAll = static_cast<pint_t>(-1);
-  template <typename T> static pint_t findFDE(pint_t mh, const T &pc);
+
+  // Note: R::link_reg_arg_t is used intentionally instead of `pint_t` to keep
+  // signature of `__ptrauth`-qualified values of `link_reg_t` type on AArch64
+  // PAuth-enabled ABI intact. See corresponding typedefs in `Registers_arm64`.
+  template <typename R>
+  static pint_t findFDE(pint_t mh, typename R::link_reg_arg_t pc);
+
   static void add(pint_t mh, pint_t ip_start, pint_t ip_end, pint_t fde);
   static void removeAllIn(pint_t mh);
   static void iterateCacheEntries(void (*func)(unw_word_t ip_start,
@@ -174,9 +180,9 @@ bool DwarfFDECache<A>::_registeredForDyldUnloads = false;
 #endif
 
 template <typename A>
-template <typename T>
-typename DwarfFDECache<A>::pint_t DwarfFDECache<A>::findFDE(pint_t mh,
-                                                            const T &pc) {
+template <typename R>
+typename DwarfFDECache<A>::pint_t
+DwarfFDECache<A>::findFDE(pint_t mh, typename R::link_reg_arg_t pc) {
   pint_t result = 0;
   _LIBUNWIND_LOG_IF_FALSE(_lock.lock_shared());
   for (entry *p = _buffer; p < _bufferUsed; ++p) {
@@ -1059,10 +1065,13 @@ class UnwindCursor : public AbstractUnwindCursor{
 #endif
 
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
+  // Note: R::link_reg_arg_t is used intentionally instead of `pint_t` to keep
+  // signature of `__ptrauth`-qualified values of `link_reg_t` type on AArch64
+  // PAuth-enabled ABI intact. See corresponding typedefs in `Registers_arm64`.
   bool getInfoFromFdeCie(const typename CFI_Parser<A>::FDE_Info &fdeInfo,
                          const typename CFI_Parser<A>::CIE_Info &cieInfo,
-                         const typename R::link_reg_t &pc, uintptr_t dso_base);
-  bool getInfoFromDwarfSection(const typename R::link_reg_t &pc,
+                         typename R::link_reg_arg_t pc, uintptr_t dso_base);
+  bool getInfoFromDwarfSection(typename R::link_reg_arg_t pc,
                                const UnwindInfoSections &sects,
                                uint32_t fdeSectionOffsetHint = 0);
   int stepWithDwarfFDE(bool stage2) {
@@ -1080,7 +1089,7 @@ class UnwindCursor : public AbstractUnwindCursor{
 #endif
 
 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
-  bool getInfoFromCompactEncodingSection(const typename R::link_reg_t &pc,
+  bool getInfoFromCompactEncodingSection(typename R::link_reg_arg_t pc,
                                          const UnwindInfoSections &sects);
   int stepWithCompactEncoding(bool stage2 = false) {
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
@@ -1732,10 +1741,10 @@ template <typename A, typename R>
 bool UnwindCursor<A, R>::getInfoFromFdeCie(
     const typename CFI_Parser<A>::FDE_Info &fdeInfo,
     const typename CFI_Parser<A>::CIE_Info &cieInfo,
-    const typename R::link_reg_t &pc, uintptr_t dso_base) {
+    typename R::link_reg_arg_t pc, uintptr_t dso_base) {
   typename CFI_Parser<A>::PrologInfo prolog;
-  if (CFI_Parser<A>::parseFDEInstructions(_addressSpace, fdeInfo, cieInfo, pc,
-                                          R::getArch(), &prolog)) {
+  if (CFI_Parser<A>::template parseFDEInstructions<R>(
+          _addressSpace, fdeInfo, cieInfo, pc, R::getArch(), &prolog)) {
     // Save off parsed FDE info
     _info.start_ip          = fdeInfo.pcStart;
     _info.end_ip            = fdeInfo.pcEnd;
@@ -1756,7 +1765,7 @@ bool UnwindCursor<A, R>::getInfoFromFdeCie(
 
 template <typename A, typename R>
 bool UnwindCursor<A, R>::getInfoFromDwarfSection(
-    const typename R::link_reg_t &pc, const UnwindInfoSections &sects,
+    typename R::link_reg_arg_t pc, const UnwindInfoSections &sects,
     uint32_t fdeSectionOffsetHint) {
   typename CFI_Parser<A>::FDE_Info fdeInfo;
   typename CFI_Parser<A>::CIE_Info cieInfo;
@@ -1764,34 +1773,33 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(
   bool foundInCache = false;
   // If compact encoding table gave offset into dwarf section, go directly 
there
   if (fdeSectionOffsetHint != 0) {
-    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
-                                    sects.dwarf_section_length,
-                                    sects.dwarf_section + fdeSectionOffsetHint,
-                                    &fdeInfo, &cieInfo);
+    foundFDE = CFI_Parser<A>::template findFDE<R>(
+        _addressSpace, pc, sects.dwarf_section, sects.dwarf_section_length,
+        sects.dwarf_section + fdeSectionOffsetHint, &fdeInfo, &cieInfo);
   }
 #if defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
   if (!foundFDE && (sects.dwarf_index_section != 0)) {
-    foundFDE = EHHeaderParser<A>::findFDE(
+    foundFDE = EHHeaderParser<A>::template findFDE<R>(
         _addressSpace, pc, sects.dwarf_index_section,
         (uint32_t)sects.dwarf_index_section_length, &fdeInfo, &cieInfo);
   }
 #endif
   if (!foundFDE) {
     // otherwise, search cache of previously found FDEs.
-    pint_t cachedFDE = DwarfFDECache<A>::findFDE(sects.dso_base, pc);
+    pint_t cachedFDE =
+        DwarfFDECache<A>::template findFDE<R>(sects.dso_base, pc);
     if (cachedFDE != 0) {
-      foundFDE =
-          CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
-                                 sects.dwarf_section_length,
-                                 cachedFDE, &fdeInfo, &cieInfo);
+      foundFDE = CFI_Parser<A>::template findFDE<R>(
+          _addressSpace, pc, sects.dwarf_section, sects.dwarf_section_length,
+          cachedFDE, &fdeInfo, &cieInfo);
       foundInCache = foundFDE;
     }
   }
   if (!foundFDE) {
     // Still not found, do full scan of __eh_frame section.
-    foundFDE = CFI_Parser<A>::findFDE(_addressSpace, pc, sects.dwarf_section,
-                                      sects.dwarf_section_length, 0,
-                                      &fdeInfo, &cieInfo);
+    foundFDE = CFI_Parser<A>::template findFDE<R>(
+        _addressSpace, pc, sects.dwarf_section, sects.dwarf_section_length, 0,
+        &fdeInfo, &cieInfo);
   }
   if (foundFDE) {
     if (getInfoFromFdeCie(fdeInfo, cieInfo, pc, sects.dso_base)) {
@@ -1816,7 +1824,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(
 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
 template <typename A, typename R>
 bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(
-    const typename R::link_reg_t &pc, const UnwindInfoSections &sects) {
+    typename R::link_reg_arg_t pc, const UnwindInfoSections &sects) {
   const bool log = false;
   if (log)
     fprintf(stderr, "getInfoFromCompactEncodingSection(pc=0x%llX, 
mh=0x%llX)\n",
@@ -2774,7 +2782,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool 
isReturnAddress) {
 
   // Ask address space object to find unwind sections for this pc.
   UnwindInfoSections sects;
-  if (_addressSpace.findUnwindSections(pc, sects)) {
+  if (_addressSpace.template findUnwindSections<R>(pc, sects)) {
 #if defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
     // If there is a compact unwind encoding table, look there first.
     if (sects.compact_unwind_section != 0) {
@@ -2830,8 +2838,8 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool 
isReturnAddress) {
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   // There is no static unwind info for this pc. Look to see if an FDE was
   // dynamically registered for it.
-  pint_t cachedFDE = DwarfFDECache<A>::findFDE(DwarfFDECache<A>::kSearchAll,
-                                               pc);
+  pint_t cachedFDE =
+      DwarfFDECache<A>::template findFDE<R>(DwarfFDECache<A>::kSearchAll, pc);
   if (cachedFDE != 0) {
     typename CFI_Parser<A>::FDE_Info fdeInfo;
     typename CFI_Parser<A>::CIE_Info cieInfo;
@@ -2843,7 +2851,7 @@ void UnwindCursor<A, R>::setInfoBasedOnIPRegister(bool 
isReturnAddress) {
   // Lastly, ask AddressSpace object about platform specific ways to locate
   // other FDEs.
   pint_t fde;
-  if (_addressSpace.findOtherFDE(pc, fde)) {
+  if (_addressSpace.template findOtherFDE<R>(pc, fde)) {
     typename CFI_Parser<A>::FDE_Info fdeInfo;
     typename CFI_Parser<A>::CIE_Info cieInfo;
     if (!CFI_Parser<A>::decodeFDE(_addressSpace, fde, &fdeInfo, &cieInfo)) {
@@ -3313,7 +3321,7 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, 
size_t bufLen,
 #else
   typename R::link_reg_t pc = this->getReg(UNW_REG_IP);
 #endif
-  return _addressSpace.findFunctionName(pc, buf, bufLen, offset);
+  return _addressSpace.template findFunctionName<R>(pc, buf, bufLen, offset);
 }
 
 #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to