Skip to content

Commit fce7cba

Browse files
fixup! [libunwind] Replace process_vm_readv with pipe
1 parent 440d9dc commit fce7cba

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

libunwind/src/UnwindCursor.hpp

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -559,26 +559,6 @@ class UnwindCursor : public AbstractUnwindCursor {
559559
_info.handler = 0;
560560
return UNW_STEP_SUCCESS;
561561
}
562-
bool isReadableAddr(const void *addr) const {
563-
// This code is heavily based on Abseil's 'address_is_readable.cc',
564-
// which is Copyright Abseil Authors (2017), and provided under
565-
// the Apache License 2.0.
566-
567-
// We have to check that addr is a nullptr because sigprocmask allows that
568-
// as an argument without failure.
569-
if (!addr)
570-
return false;
571-
// Align to 8-bytes.
572-
const auto uintptr_addr = reinterpret_cast<uintptr_t>(addr) & ~uintptr_t{7};
573-
const auto sigsetaddr = reinterpret_cast<sigset_t *>(uintptr_addr);
574-
[[maybe_unused]] int Result = sigprocmask(/*how=*/-1, sigsetaddr, nullptr);
575-
// Because our "how" is invalid, this syscall should always fail, and our
576-
// errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed
577-
// by the POSIX standard, so this is (for now) Linux specific.
578-
assert(Result == -1);
579-
assert(errno == EFAULT || errno == EINVAL);
580-
return errno != EFAULT;
581-
}
582562

583563
A &_addressSpace;
584564
unw_proc_info_t _info;
@@ -1012,6 +992,7 @@ class UnwindCursor : public AbstractUnwindCursor{
1012992
R dummy;
1013993
return stepThroughSigReturn(dummy);
1014994
}
995+
bool isReadableAddr(const pint_t addr) const;
1015996
#if defined(_LIBUNWIND_TARGET_AARCH64)
1016997
bool setInfoForSigReturn(Registers_arm64 &);
1017998
int stepThroughSigReturn(Registers_arm64 &);
@@ -2723,8 +2704,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_arm64 &) {
27232704
const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
27242705
// The PC might contain an invalid address if the unwind info is bad, so
27252706
// directly accessing it could cause a SIGSEGV.
2726-
if (!isReadableAddr(static_cast<const void *>(pc)) ||
2727-
!isReadableAddr(static_cast<const void *>(pc + 4)))
2707+
if (!isReadableAddr(pc) || !isReadableAddr(pc + 4))
27282708
return false;
27292709
auto *instructions = reinterpret_cast<const uint32_t *>(pc);
27302710
// Look for instructions: mov x8, #0x8b; svc #0x0
@@ -2779,8 +2759,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_riscv &) {
27792759
const pint_t pc = static_cast<pint_t>(getReg(UNW_REG_IP));
27802760
// The PC might contain an invalid address if the unwind info is bad, so
27812761
// directly accessing it could cause a SIGSEGV.
2782-
if (!isReadableAddr(static_cast<const void *>(pc)) ||
2783-
!isReadableAddr(static_cast<const void *>(pc + 4)))
2762+
if (!isReadableAddr(pc) || !isReadableAddr(pc + 4))
27842763
return false;
27852764
const auto *instructions = reinterpret_cast<const uint32_t *>(pc);
27862765
// Look for the two instructions used in the sigreturn trampoline
@@ -2838,8 +2817,7 @@ bool UnwindCursor<A, R>::setInfoForSigReturn(Registers_s390x &) {
28382817
const pint_t pc = static_cast<pint_t>(this->getReg(UNW_REG_IP));
28392818
// The PC might contain an invalid address if the unwind info is bad, so
28402819
// directly accessing it could cause a SIGSEGV.
2841-
if (!isReadableAddr(static_cast<const void *>(pc)) ||
2842-
!isReadableAddr(static_cast<const void *>(pc + 2)))
2820+
if (!isReadableAddr(pc) || !isReadableAddr(pc + 2))
28432821
return false;
28442822
const auto inst = *reinterpret_cast<const uint16_t *>(pc);
28452823
if (inst == 0x0a77 || inst == 0x0aad) {
@@ -2988,6 +2966,30 @@ bool UnwindCursor<A, R>::getFunctionName(char *buf, size_t bufLen,
29882966
buf, bufLen, offset);
29892967
}
29902968

2969+
#if defined(_LIBUNWIND_CHECK_LINUX_SIGRETURN)
2970+
template <typename A, typename R>
2971+
bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
2972+
// This code is heavily based on Abseil's 'address_is_readable.cc',
2973+
// which is Copyright Abseil Authors (2017), and provided under
2974+
// the Apache License 2.0.
2975+
2976+
// We have to check that addr is nullptr (0) because sigprocmask allows that
2977+
// as an argument without failure.
2978+
if (addr == 0)
2979+
return false;
2980+
// Align to 8-bytes.
2981+
const auto alignedAddr = addr & ~pint_t{7};
2982+
const auto sigsetAddr = reinterpret_cast<sigset_t *>(alignedAddr);
2983+
[[maybe_unused]] int Result = sigprocmask(/*how=*/-1, sigsetAddr, nullptr);
2984+
// Because our "how" is invalid, this syscall should always fail, and our
2985+
// errno should always be EINVAL or an EFAULT. EFAULT is not guaranteed
2986+
// by the POSIX standard, so this is (for now) Linux specific.
2987+
assert(Result == -1);
2988+
assert(errno == EFAULT || errno == EINVAL);
2989+
return errno != EFAULT;
2990+
}
2991+
#endif
2992+
29912993
#if defined(_LIBUNWIND_USE_CET)
29922994
extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {
29932995
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;

0 commit comments

Comments
 (0)