================ @@ -2700,19 +2701,18 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) { // [1] https://github.com/torvalds/linux/blob/master/arch/arm64/kernel/vdso/sigreturn.S const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP)); // The PC might contain an invalid address if the unwind info is bad, so - // directly accessing it could cause a segfault. Use process_vm_readv to read - // the memory safely instead. process_vm_readv was added in Linux 3.2, and - // AArch64 supported was added in Linux 3.7, so the syscall is guaranteed to - // be present. Unfortunately, there are Linux AArch64 environments where the - // libc wrapper for the syscall might not be present (e.g. Android 5), so call - // the syscall directly instead. + // directly accessing it could cause a segfault. Use pipe/write/read to read + // the memory safely instead. + int pipefd[2]; + if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) == -1) + return false; uint32_t instructions[2]; - struct iovec local_iov = {&instructions, sizeof instructions}; - struct iovec remote_iov = {reinterpret_cast<void *>(pc), sizeof instructions}; - long bytesRead = - syscall(SYS_process_vm_readv, getpid(), &local_iov, 1, &remote_iov, 1, 0); + const auto bufferSize = sizeof instructions; + if (write(pipefd[1], reinterpret_cast<void *>(pc), bufferSize) != bufferSize) + return false; + const auto bytesRead = read(pipefd[0], instructions, bufferSize); ---------------- ajordanr-google wrote:
Gotcha, that all makes sense. Thanks! --- Playing around with `SYS_rt_procmask` on Linux x86_64, There's apparently a point in which we can still read a given address but `SYS_rt_procmask` sets `errno = 14` (Bad Address) Looping over the raw syscall with: ``` syscall(SYS_rt_sigprocmask, /* how= */ -1, Addr, Addr, 8); ```` until it breaks gives ``` Addr: 0x56322ab46ff8; Offset: 59704; errno: 22; Value: 0x0 Addr: 0x56322ab46ff9; Offset: 59705; errno: 14; Value: 0x0 Addr: 0x56322ab46ffa; Offset: 59706; errno: 14; Value: 0x0 Addr: 0x56322ab46ffb; Offset: 59707; errno: 14; Value: 0x0 Addr: 0x56322ab46ffc; Offset: 59708; errno: 14; Value: 0x0 Addr: 0x56322ab46ffd; Offset: 59709; errno: 14; Value: 0x0 Addr: 0x56322ab46ffe; Offset: 59710; errno: 14; Value: 0x0 Addr: 0x56322ab46fff; Offset: 59711; errno: 14; Value: 0x0 fish: Job 1, './main' terminated by signal SIGSEGV (Address boundary error) ``` Seems there's about a 7 to 8 byte boundary where it fails but we can still read, at least on x86_64. So the 8 byte alignment on AARCH64 as mentioned in address_is_readable.cc seems to make sense, though we'd probably want to still check both the beginning and end of the `instructions` range. I think that should be sufficient. 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