================ @@ -2974,6 +2966,37 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen, buf, bufLen, offset); } +#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN) +template <typename A, typename R> +bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const { + // This code is heavily based on Abseil's 'address_is_readable.cc', + // which is Copyright Abseil Authors (2017). + + const auto sigsetAddr = reinterpret_cast<sigset_t *>(addr); + // We have to check that addr is nullptr because sigprocmask allows that + // as an argument without failure. + if (!sigsetAddr) + return false; + // We MUST use a raw syscall here, as wrappers may try to access + // sigsetAddr which may cause a SIGSEGV. A raw syscall however is + // safe. Additionally, we need to pass the kernel_sigset_size, which is + // different from libc sizeof(sigset_t). For the majority of architectures, + // it's 64 bits (_NSIG), and libc NSIG is _NSIG + 1. + const auto kernelSigsetSize = NSIG / 8; + const int Result = syscall(SYS_rt_sigprocmask, /*how=*/~0, sigsetAddr, + nullptr, kernelSigsetSize); + (void)Result; + // Because our "how" is invalid, this syscall should always fail, and our + // errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed + // by the POSIX standard. Additionally, this relies on the Linux kernel + // to check copy_from_user before checking if the "how" argument is + // invalid. + assert(Result == -1); + assert(errno == EFAULT || errno == EINVAL); + return errno != EFAULT; ---------------- ajordanr-google wrote:
We should probably save and restore, as we do this above in `getInfoFromTBTable`. Good point. Done. https://github.com/llvm/llvm-project/pull/74791 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits