[llvm] [clang] [clang-tools-extra] [libunwind] [libunwind] Replace process_vm_readv with SYS_rt_sigprocmask (PR #74791)
Alexander Richardson via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 19 11:12:53 PST 2023
================
@@ -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
More information about the llvm-commits
mailing list