Migrate ClearPacBits() to a more generic implementation and location

PiperOrigin-RevId: 736664098
Change-Id: Ic99ff4ebae02097b9f7691ebdcb2e10f7d255834
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index e318d72..df071af 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -126,6 +126,7 @@
   "debugging/symbolize.h"
   "debugging/internal/address_is_readable.cc"
   "debugging/internal/address_is_readable.h"
+  "debugging/internal/addresses.h"
   "debugging/internal/bounded_utf8_length_sequence.h"
   "debugging/internal/decode_rust_punycode.cc"
   "debugging/internal/decode_rust_punycode.h"
diff --git a/absl/debugging/BUILD.bazel b/absl/debugging/BUILD.bazel
index 6e61bb3..01d3230 100644
--- a/absl/debugging/BUILD.bazel
+++ b/absl/debugging/BUILD.bazel
@@ -202,6 +202,7 @@
     ],
     hdrs = [
         "internal/address_is_readable.h",
+        "internal/addresses.h",
         "internal/elf_mem_image.h",
         "internal/vdso_support.h",
     ],
diff --git a/absl/debugging/CMakeLists.txt b/absl/debugging/CMakeLists.txt
index a96b4f3..30eeb5b 100644
--- a/absl/debugging/CMakeLists.txt
+++ b/absl/debugging/CMakeLists.txt
@@ -174,6 +174,7 @@
     debugging_internal
   HDRS
     "internal/address_is_readable.h"
+    "internal/addresses.h"
     "internal/elf_mem_image.h"
     "internal/vdso_support.h"
   SRCS
diff --git a/absl/debugging/internal/addresses.h b/absl/debugging/internal/addresses.h
new file mode 100644
index 0000000..e40c54e
--- /dev/null
+++ b/absl/debugging/internal/addresses.h
@@ -0,0 +1,53 @@
+// Copyright 2025 The Abseil Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef ABSL_DEBUGGING_INTERNAL_ADDRESSES_H_
+#define ABSL_DEBUGGING_INTERNAL_ADDRESSES_H_
+
+#include <stdint.h>
+
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace debugging_internal {
+
+// Removes any metadata (tag bits) from the given pointer, converting it into a
+// user-readable address.
+inline uintptr_t StripPointerMetadata(void* ptr) {
+#if defined(__aarch64__)
+  // When PAC-RET (-mbranch-protection=pac-ret) is enabled, return addresses
+  // stored on the stack will be signed, which means that pointer bits outside
+  // of the virtual address range are potentially set. Since the stacktrace code
+  // is expected to return normal code pointers, this function clears those
+  // bits.
+  register uintptr_t x30 __asm__("x30") = reinterpret_cast<uintptr_t>(ptr);
+  // The normal instruction for clearing PAC bits is XPACI, but for
+  // compatibility with ARM platforms that do not support pointer
+  // authentication, we use the hint space instruction XPACLRI instead. Hint
+  // space instructions behave as NOPs on unsupported platforms.
+#define ABSL_XPACLRI_HINT "hint #0x7;"
+  asm(ABSL_XPACLRI_HINT : "+r"(x30));  // asm("xpaclri" : "+r"(x30));
+#undef ABSL_XPACLRI_HINT
+  return x30;
+#else
+  return reinterpret_cast<uintptr_t>(ptr);
+#endif
+}
+
+}  // namespace debugging_internal
+ABSL_NAMESPACE_END
+}  // namespace absl
+
+#endif  // ABSL_DEBUGGING_INTERNAL_ADDRESSES_H_
diff --git a/absl/debugging/internal/stacktrace_aarch64-inl.inc b/absl/debugging/internal/stacktrace_aarch64-inl.inc
index dccadae..baea9a8 100644
--- a/absl/debugging/internal/stacktrace_aarch64-inl.inc
+++ b/absl/debugging/internal/stacktrace_aarch64-inl.inc
@@ -18,6 +18,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/debugging/internal/address_is_readable.h"
+#include "absl/debugging/internal/addresses.h"
 #include "absl/debugging/internal/vdso_support.h"  // a no-op on non-elf or non-glibc systems
 #include "absl/debugging/stacktrace.h"
 
@@ -178,22 +179,6 @@
   return new_frame_pointer;
 }
 
-// When PAC-RET (-mbranch-protection=pac-ret) is enabled, return addresses
-// stored on the stack will be signed, which means that pointer bits outside of
-// the VA range are potentially set. Since the stacktrace code is expected to
-// return normal code pointers, this function clears those bits.
-inline void* ClearPacBits(void* ptr) {
-  register void* x30 __asm__("x30") = ptr;
-  // The normal instruction for clearing PAC bits is XPACI, but for
-  // compatibility with ARM platforms that do not support pointer
-  // authentication, we use the hint space instruction XPACLRI instead. Hint
-  // space instructions behave as NOPs on unsupported platforms.
-#define ABSL_XPACLRI_HINT "hint #0x7;"
-  asm(ABSL_XPACLRI_HINT : "+r"(x30));  // asm("xpaclri" : "+r"(x30));
-#undef ABSL_XPACLRI_HINT
-  return x30;
-}
-
 template <bool IS_STACK_FRAMES, bool IS_WITH_CONTEXT>
 // We count on the bottom frame being this one. See the comment
 // at prev_return_address
@@ -235,7 +220,8 @@
     if (skip_count > 0) {
       skip_count--;
     } else {
-      result[n] = ClearPacBits(prev_return_address);
+      result[n] = reinterpret_cast<void *>(
+          absl::debugging_internal::StripPointerMetadata(prev_return_address));
       if (IS_STACK_FRAMES) {
         sizes[n] = static_cast<int>(
             ComputeStackFrameSize(prev_frame_pointer, frame_pointer));