From: Mark Wielaard Date: Wed, 24 Sep 2025 21:16:29 +0000 (+0200) Subject: Deal with linux arches that don't have getdents, only getdents64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fusers%2Fmark%2Ftry-getdents;p=thirdparty%2Fvalgrind.git Deal with linux arches that don't have getdents, only getdents64 --- diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index 33b58f5a5..325ce1e3f 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -4091,6 +4091,10 @@ static SizeT filter_dirent64_entries(struct vki_dirent64 *dirp, SizeT orig_size) return new_size; } +/* Make sure we really need the proc filtering using (32bit) getdents, + which not every linux arch implements. */ +#if defined(VGO_linux) && defined(__NR_getdents) + /* Filter out Valgrind's internal file descriptors from getdents results with refill capability. When entries are filtered out, attempts to read more entries to avoid empty results. Returns filtered size on success, or -1 if retry syscall failed. */ @@ -4119,6 +4123,7 @@ static SizeT filter_valgrind_fds_from_getdents_with_refill(Int fd, struct vki_di return new_size; } +#endif /* defined(VGO_linux) && defined(__NR_getdents) */ /* Filter out Valgrind's internal file descriptors from getdents64 results with refill capability. Same logic as getdents version but for 64-bit dirent structures. @@ -4155,6 +4160,10 @@ POST(sys_getdents) if (RES > 0) { SizeT result_size = RES; + /* Make sure we really need the proc filtering using (32bit) getdents, + which not every linux arch implements. */ +#if defined(VGO_linux) && defined(__NR_getdents) + /* Only filter Valgrind FDs when listing /proc/PID/fd or /proc/PID/fdinfo directories */ if (is_proc_fd_directory(ARG1)) { SizeT filtered_size = filter_valgrind_fds_from_getdents_with_refill(ARG1, (struct vki_dirent *)ARG2, RES, ARG3, status); @@ -4166,6 +4175,7 @@ POST(sys_getdents) if (result_size != RES) SET_STATUS_Success(result_size); } +#endif /* defined(VGO_linux) && defined(__NR_getdents) */ POST_MEM_WRITE( ARG2, result_size ); } diff --git a/none/tests/Makefile.am b/none/tests/Makefile.am index ccdd85e53..716ce000d 100644 --- a/none/tests/Makefile.am +++ b/none/tests/Makefile.am @@ -172,7 +172,6 @@ EXTRA_DIST = \ floored.stderr.exp floored.stdout.exp floored.vgtest \ fork.stderr.exp fork.stdout.exp fork.vgtest \ fucomip.stderr.exp fucomip.vgtest \ - getdents_filter.stderr.exp getdents_filter.stdout.exp getdents_filter.vgtest \ gxx304.stderr.exp gxx304.vgtest \ ifunc.stderr.exp ifunc.stdout.exp ifunc.vgtest \ ioctl_moans.stderr.exp ioctl_moans.vgtest \ @@ -292,7 +291,6 @@ check_PROGRAMS = \ fdleak_fcntl fdleak_ipv4 fdleak_open fdleak_pipe \ fdleak_socketpair \ floored fork fucomip \ - getdents_filter \ ioctl_moans \ libvex_test \ libvexmultiarch_test \ diff --git a/none/tests/linux/Makefile.am b/none/tests/linux/Makefile.am index 7bfcedc86..55426e2b2 100644 --- a/none/tests/linux/Makefile.am +++ b/none/tests/linux/Makefile.am @@ -10,6 +10,7 @@ EXTRA_DIST = \ bug498317.stderr.exp bug498317.supp bug498317.vgtest \ bug506910.stderr.exp bug506910.vgtest \ clonev.stdout.exp clonev.stderr.exp clonev.vgtest \ + getdents_filter.stderr.exp getdents_filter.stdout.exp getdents_filter.vgtest \ membarrier.stderr.exp membarrier.vgtest \ mremap.stderr.exp mremap.stderr.exp-glibc27 mremap.stdout.exp \ mremap.vgtest \ @@ -28,6 +29,7 @@ check_PROGRAMS = \ brk-overflow2 \ bug498317 \ clonev \ + getdents_filter \ mremap \ mremap2 \ mremap3 \ diff --git a/none/tests/getdents_filter.c b/none/tests/linux/getdents_filter.c similarity index 96% rename from none/tests/getdents_filter.c rename to none/tests/linux/getdents_filter.c index d508cdde0..887418fad 100644 --- a/none/tests/getdents_filter.c +++ b/none/tests/linux/getdents_filter.c @@ -83,7 +83,9 @@ static void test_retry_logic_with_small_buffer(void) * may return only Valgrind FDs, which will trigger the retry mechanism. */ for (;;) { - nread = syscall(SYS_getdents, fd, buf, SMALL_BUF_SIZE); + /* Note, using getdents64 since some linux arches don't implement + the 32bit getdents. */ + nread = syscall(SYS_getdents64, fd, buf, SMALL_BUF_SIZE); if (nread == -1) { printf("retry_test_error\n"); diff --git a/none/tests/getdents_filter.stderr.exp b/none/tests/linux/getdents_filter.stderr.exp similarity index 100% rename from none/tests/getdents_filter.stderr.exp rename to none/tests/linux/getdents_filter.stderr.exp diff --git a/none/tests/getdents_filter.stdout.exp b/none/tests/linux/getdents_filter.stdout.exp similarity index 100% rename from none/tests/getdents_filter.stdout.exp rename to none/tests/linux/getdents_filter.stdout.exp diff --git a/none/tests/getdents_filter.vgtest b/none/tests/linux/getdents_filter.vgtest similarity index 100% rename from none/tests/getdents_filter.vgtest rename to none/tests/linux/getdents_filter.vgtest