@@ -559,26 +559,6 @@ class UnwindCursor : public AbstractUnwindCursor {
559
559
_info.handler = 0 ;
560
560
return UNW_STEP_SUCCESS;
561
561
}
562
- bool isReadableAddr (const void *addr) const {
563
- // This code is heavily based on Abseil's 'address_is_readable.cc',
564
- // which is Copyright Abseil Authors (2017), and provided under
565
- // the Apache License 2.0.
566
-
567
- // We have to check that addr is a nullptr because sigprocmask allows that
568
- // as an argument without failure.
569
- if (!addr)
570
- return false ;
571
- // Align to 8-bytes.
572
- const auto uintptr_addr = reinterpret_cast <uintptr_t >(addr) & ~uintptr_t {7 };
573
- const auto sigsetaddr = reinterpret_cast <sigset_t *>(uintptr_addr);
574
- [[maybe_unused]] int Result = sigprocmask (/* how=*/ -1 , sigsetaddr, nullptr );
575
- // Because our "how" is invalid, this syscall should always fail, and our
576
- // errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed
577
- // by the POSIX standard, so this is (for now) Linux specific.
578
- assert (Result == -1 );
579
- assert (errno == EFAULT || errno == EINVAL);
580
- return errno != EFAULT;
581
- }
582
562
583
563
A &_addressSpace;
584
564
unw_proc_info_t _info;
@@ -1012,6 +992,7 @@ class UnwindCursor : public AbstractUnwindCursor{
1012
992
R dummy;
1013
993
return stepThroughSigReturn (dummy);
1014
994
}
995
+ bool isReadableAddr (const pint_t addr) const ;
1015
996
#if defined(_LIBUNWIND_TARGET_AARCH64)
1016
997
bool setInfoForSigReturn (Registers_arm64 &);
1017
998
int stepThroughSigReturn (Registers_arm64 &);
@@ -2723,8 +2704,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
2723
2704
const pint_t pc = static_cast <pint_t >(this ->getReg (UNW_REG_IP));
2724
2705
// The PC might contain an invalid address if the unwind info is bad, so
2725
2706
// directly accessing it could cause a SIGSEGV.
2726
- if (!isReadableAddr (static_cast <const void *>(pc)) ||
2727
- !isReadableAddr (static_cast <const void *>(pc + 4 )))
2707
+ if (!isReadableAddr (pc) || !isReadableAddr (pc + 4 ))
2728
2708
return false ;
2729
2709
auto *instructions = reinterpret_cast <const uint32_t *>(pc);
2730
2710
// Look for instructions: mov x8, #0x8b; svc #0x0
@@ -2779,8 +2759,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
2779
2759
const pint_t pc = static_cast <pint_t >(getReg (UNW_REG_IP));
2780
2760
// The PC might contain an invalid address if the unwind info is bad, so
2781
2761
// directly accessing it could cause a SIGSEGV.
2782
- if (!isReadableAddr (static_cast <const void *>(pc)) ||
2783
- !isReadableAddr (static_cast <const void *>(pc + 4 )))
2762
+ if (!isReadableAddr (pc) || !isReadableAddr (pc + 4 ))
2784
2763
return false ;
2785
2764
const auto *instructions = reinterpret_cast <const uint32_t *>(pc);
2786
2765
// Look for the two instructions used in the sigreturn trampoline
@@ -2838,8 +2817,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) {
2838
2817
const pint_t pc = static_cast <pint_t >(this ->getReg (UNW_REG_IP));
2839
2818
// The PC might contain an invalid address if the unwind info is bad, so
2840
2819
// directly accessing it could cause a SIGSEGV.
2841
- if (!isReadableAddr (static_cast <const void *>(pc)) ||
2842
- !isReadableAddr (static_cast <const void *>(pc + 2 )))
2820
+ if (!isReadableAddr (pc) || !isReadableAddr (pc + 2 ))
2843
2821
return false ;
2844
2822
const auto inst = *reinterpret_cast <const uint16_t *>(pc);
2845
2823
if (inst == 0x0a77 || inst == 0x0aad ) {
@@ -2988,6 +2966,30 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
2988
2966
buf, bufLen, offset);
2989
2967
}
2990
2968
2969
+ #if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2970
+ template <typename A, typename R>
2971
+ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
2972
+ // This code is heavily based on Abseil's 'address_is_readable.cc',
2973
+ // which is Copyright Abseil Authors (2017), and provided under
2974
+ // the Apache License 2.0.
2975
+
2976
+ // We have to check that addr is nullptr (0) because sigprocmask allows that
2977
+ // as an argument without failure.
2978
+ if (addr == 0 )
2979
+ return false ;
2980
+ // Align to 8-bytes.
2981
+ const auto alignedAddr = addr & ~pint_t {7 };
2982
+ const auto sigsetAddr = reinterpret_cast <sigset_t *>(alignedAddr);
2983
+ [[maybe_unused]] int Result = sigprocmask (/* how=*/ -1 , sigsetAddr, nullptr );
2984
+ // Because our "how" is invalid, this syscall should always fail, and our
2985
+ // errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed
2986
+ // by the POSIX standard, so this is (for now) Linux specific.
2987
+ assert (Result == -1 );
2988
+ assert (errno == EFAULT || errno == EINVAL);
2989
+ return errno != EFAULT;
2990
+ }
2991
+ #endif
2992
+
2991
2993
#if defined(_LIBUNWIND_USE_CET)
2992
2994
extern " C" void *__libunwind_cet_get_registers (unw_cursor_t *cursor) {
2993
2995
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
0 commit comments