================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits