================ @@ -2974,6 +2966,39 @@ 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), and provided under + // the Apache License 2.0. + + // Align to 8-bytes. + const auto alignedAddr = addr & ~pint_t{7}; + const auto sigsetAddr = reinterpret_cast<sigset_t *>(alignedAddr); + // We have to check that addr is nullptr because sigprocmask allows that + // as an argument without failure. + if (!sigsetAddr) + return false; + + // We MUST use the raw sigprocmask syscall here, as wrappers may try to + // access sigsetAddr which may cause a SIGSEGV. The raw syscall however is + // safe. Additionally, we need to pass the kernel_sigset_size, which is + // different from libc sizeof(sigset_t). Some archs have sigset_t + // defined as unsigned long, so let's use that. + const auto approxKernelSigsetSize = sizeof(unsigned long); ---------------- arichardson wrote:
It is important that we get this right since otherwise the syscall returns EINVAL without trying to access the user memory: https://elixir.bootlin.com/linux/v6.6.7/source/kernel/signal.c#L3184 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