[llvm] [clang] [clang-tools-extra] [libunwind] [libunwind] Replace process_vm_readv with SYS_rt_sigprocmask (PR #74791)
Jordan R AW via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 19 14:02:08 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);
----------------
ajordanr-google wrote:
Looking at linux-6.6.7 source code, we have some minor variety on `sigset_t` size...
TL;DR: They are almost all `_NSIG` bits long, which is 64 bits or, in the case of MIPS, maybe 128? There are two exceptions to this, where they are not a struct of size `_NSIG/_NSIG_BPW * sizeof(unsigned long)` but rather just `unsigned long`. I assume `_NSIG_BPW == sizeof(long) == sizeof(unsigned long)`, which seems reasonable given the comments (and not `_NSIG_BPW == sizeof(int)`).
---
`sigset_t` is almost always defined as:
```
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
```
Where:
```
arch/parisc/include/asm/signal.h-7-#define _NSIG 64
arch/parisc/include/asm/signal.h-8-/* bits-per-word, where word apparently means 'long' not 'int' */
arch/parisc/include/asm/signal.h-9-#define _NSIG_BPW BITS_PER_LONG
arch/parisc/include/asm/signal.h:10:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/xtensa/include/uapi/asm/signal.h-18-#define _NSIG 64
arch/xtensa/include/uapi/asm/signal.h-19-#define _NSIG_BPW 32
arch/xtensa/include/uapi/asm/signal.h:20:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/ia64/include/asm/signal.h-15-#define _NSIG 64
arch/ia64/include/asm/signal.h-16-#define _NSIG_BPW 64
arch/ia64/include/asm/signal.h:17:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/alpha/include/asm/signal.h-10-#define _NSIG 64
arch/alpha/include/asm/signal.h-11-#define _NSIG_BPW 64
arch/alpha/include/asm/signal.h:12:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/arm/include/asm/signal.h-10-#define _NSIG 64
arch/arm/include/asm/signal.h-11-#define _NSIG_BPW 32
arch/arm/include/asm/signal.h:12:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/s390/include/asm/signal.h-12-/* Most things should be clean enough to redefine this at will, if care
arch/s390/include/asm/signal.h-13- is taken to make libc match. */
arch/s390/include/asm/signal.h-14-#include <asm/sigcontext.h>
arch/s390/include/asm/signal.h-15-#define _NSIG _SIGCONTEXT_NSIG
arch/s390/include/asm/signal.h-16-#define _NSIG_BPW _SIGCONTEXT_NSIG_BPW
arch/s390/include/asm/signal.h:17:#define _NSIG_WORDS _SIGCONTEXT_NSIG_WORDS
arch/s390/include/uapi/asm/sigcontext.h:30:/* Has to be at least _NSIG_WORDS from asm/signal.h */
arch/s390/include/uapi/asm/sigcontext.h-31-#define _SIGCONTEXT_NSIG 64
arch/s390/include/uapi/asm/sigcontext.h-32-#define _SIGCONTEXT_NSIG_BPW 64
// or
arch/x86/include/asm/signal.h-11-#define _NSIG 64
arch/x86/include/asm/signal.h-12-
arch/x86/include/asm/signal.h-13-#ifdef __i386__
arch/x86/include/asm/signal.h-14-# define _NSIG_BPW 32
arch/x86/include/asm/signal.h-15-#else
arch/x86/include/asm/signal.h-16-# define _NSIG_BPW 64
arch/x86/include/asm/signal.h-17-#endif
arch/x86/include/asm/signal.h-18-
arch/x86/include/asm/signal.h:19:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/m68k/include/asm/signal.h-10-#define _NSIG 64
arch/m68k/include/asm/signal.h-11-#define _NSIG_BPW 32
arch/m68k/include/asm/signal.h:12:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or (quite weirdly)
arch/mips/include/uapi/asm/signal.h-15-#define _NSIG 128
arch/mips/include/uapi/asm/signal.h-16-#define _NSIG_BPW (sizeof(unsigned long) * 8)
arch/mips/include/uapi/asm/signal.h:17:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or
arch/sparc/include/uapi/asm/signal.h-81-#define __NEW_NSIG 64
arch/sparc/include/uapi/asm/signal.h-82-#ifdef __arch64__
arch/sparc/include/uapi/asm/signal.h-83-#define _NSIG_BPW 64
arch/sparc/include/uapi/asm/signal.h-84-#else
arch/sparc/include/uapi/asm/signal.h-85-#define _NSIG_BPW 32
arch/sparc/include/uapi/asm/signal.h-86-#endif
arch/sparc/include/uapi/asm/signal.h:87:#define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW)
// or
arch/powerpc/include/uapi/asm/signal.h-7-#define _NSIG 64
arch/powerpc/include/uapi/asm/signal.h-8-#ifdef __powerpc64__
arch/powerpc/include/uapi/asm/signal.h-9-#define _NSIG_BPW 64
arch/powerpc/include/uapi/asm/signal.h-10-#else
arch/powerpc/include/uapi/asm/signal.h-11-#define _NSIG_BPW 32
arch/powerpc/include/uapi/asm/signal.h-12-#endif
arch/powerpc/include/uapi/asm/signal.h:13:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
// or (finally)
include/uapi/asm-generic/signal.h-7-#define _NSIG 64
include/uapi/asm-generic/signal.h-8-#define _NSIG_BPW __BITS_PER_LONG
include/uapi/asm-generic/signal.h:9:#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
```
Here are the two exceptions to that (and their line numbers):
```
arch/x86/include/uapi/asm/signal.h:17:typedef unsigned long sigset_t;
arch/alpha/include/uapi/asm/signal.h:14:typedef unsigned long sigset_t;
```
There were also various `old_sigset_t` and `__kernel_sigset_t`, which were defined like:
```
arch/ia64/include/asm/signal.h:24:typedef unsigned long old_sigset_t;
arch/alpha/include/asm/signal.h:14:typedef unsigned long old_sigset_t; /* at least 32 bits */
arch/m68k/include/asm/signal.h:14:typedef unsigned long old_sigset_t; /* at least 32 bits */
arch/s390/include/asm/signal.h:19:typedef unsigned long old_sigset_t; /* at least 32 bits */
arch/x86/include/asm/signal.h:21:typedef unsigned long old_sigset_t; /* at least 32 bits */
arch/parisc/include/asm/signal.h:17:typedef unsigned long old_sigset_t; /* at least 32 bits */
arch/mips/include/uapi/asm/signal.h:23:typedef unsigned long old_sigset_t; /* at least 32 bits */
arch/powerpc/include/uapi/asm/signal.h:15:typedef unsigned long old_sigset_t; /* at least 32 bits */
```
and
```
arch/ia64/include/uapi/asm/posix_types.h:5:typedef unsigned long __kernel_sigset_t; /* at least 32 bits */
arch/s390/include/uapi/asm/posix_types.h:46:typedef unsigned long __kernel_sigset_t; /* at least 32 bits */
arch/alpha/include/uapi/asm/posix_types.h:14:typedef unsigned long __kernel_sigset_t; /* at least 32 bits */
```
https://github.com/llvm/llvm-project/pull/74791
More information about the llvm-commits
mailing list