From: Paul Floyd Date: Sat, 14 May 2022 14:46:03 +0000 (+0200) Subject: More changes for FreeBSD 13.1 X-Git-Tag: VALGRIND_3_20_0~79 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6cb8e52c34767de504aeb16150a8cba11397a8d6;p=thirdparty%2Fvalgrind.git More changes for FreeBSD 13.1 These concern auxv, swapoff and fcntl F_KINFO I wanted to use the new fcntl K_INFO to replace the existing horrible implementation of resolve_filename, but it seems to have change the behaviour for redirected files. Several fdleak regtests fail because stdout resolves to an empty string. --- diff --git a/coregrind/m_aspacemgr/aspacemgr-common.c b/coregrind/m_aspacemgr/aspacemgr-common.c index 6814410c09..282cc50d70 100644 --- a/coregrind/m_aspacemgr/aspacemgr-common.c +++ b/coregrind/m_aspacemgr/aspacemgr-common.c @@ -422,6 +422,9 @@ Bool ML_(am_resolve_filename) ( Int fd, /*OUT*/HChar* buf, Int nbuf ) return False; #elif defined(VGO_freebsd) + + +#if (1) Int mib[4]; SysRes sres; vki_size_t len; @@ -444,15 +447,29 @@ Bool ML_(am_resolve_filename) ( Int fd, /*OUT*/HChar* buf, Int nbuf ) eb = filedesc_buf + len; while (bp < eb) { kf = (struct vki_kinfo_file *)bp; - if (kf->kf_fd == fd) + if (kf->vki_kf_fd == fd) break; - bp += kf->kf_structsize; + bp += kf->vki_kf_structsize; } - if (bp >= eb || *kf->kf_path == '\0') + if (bp >= eb || *kf->vki_kf_path == '\0') VG_(strncpy)( buf, "[unknown]", nbuf ); else - VG_(strncpy)( buf, kf->kf_path, nbuf ); + VG_(strncpy)( buf, kf->vki_kf_path, nbuf ); return True; +#else + // PJF it will be a relief to get rid of the above bit of ugliness + struct vki_kinfo_file kinfo_file; + kinfo_file.vki_kf_structsize = VKI_KINFO_FILE_SIZE; + if (0 == ML_(am_fcntl) ( fd, VKI_F_KINFO, (Addr)&kinfo_file )) { + if (nbuf > 0) { + VG_(strncpy)( buf, kinfo_file.vki_kf_path, nbuf < VKI_PATH_MAX ? nbuf : VKI_PATH_MAX ); + buf[nbuf-1] = 0; + } + if (buf[0] == '/') return True; + } + return False; +#endif + #elif defined(VGO_darwin) HChar tmp[VKI_MAXPATHLEN+1]; if (0 == ML_(am_fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) { diff --git a/coregrind/m_initimg/initimg-freebsd.c b/coregrind/m_initimg/initimg-freebsd.c index bfa1907769..6029ffb69b 100644 --- a/coregrind/m_initimg/initimg-freebsd.c +++ b/coregrind/m_initimg/initimg-freebsd.c @@ -694,7 +694,7 @@ Addr setup_client_stack( void* init_sp, // case AT_PS_STRINGS: #endif -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) // I think that this is a pointer to a "fenestrasX" structture // lots of stuff that I don't understand // arc4random, passing through VDSO page ... diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c index 94c2f030ac..4fdfcbd28b 100644 --- a/coregrind/m_libcfile.c +++ b/coregrind/m_libcfile.c @@ -119,6 +119,8 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result ) return False; #elif defined(VGO_freebsd) + +#if (1) Int mib[4]; SysRes sres; vki_size_t len; @@ -148,16 +150,36 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result ) eb = filedesc_buf + len; while (bp < eb) { kf = (struct vki_kinfo_file *)bp; - if (kf->kf_fd == fd) + if (kf->vki_kf_fd == fd) break; - bp += kf->kf_structsize; + bp += kf->vki_kf_structsize; } - if (bp >= eb || *kf->kf_path == '\0') + if (bp >= eb || *kf->vki_kf_path == '\0') VG_(strncpy)( buf, "[unknown]", bufsiz ); else - VG_(strncpy)( buf, kf->kf_path, bufsiz ); + VG_(strncpy)( buf, kf->vki_kf_path, bufsiz ); *result = buf; return True; +#else + // PJF it will be a relief to get rid of the above bit of ugliness + // however it does not seem to have the same functionality + // regarding pipes where it profuces just an empty string + struct vki_kinfo_file kinfo_file; + kinfo_file.vki_kf_structsize = VKI_KINFO_FILE_SIZE; + if (0 == VG_(fcntl) ( fd, VKI_F_KINFO, (Addr)&kinfo_file )) { + static HChar *buf = NULL; + + if (buf == NULL) + buf = VG_(malloc)("resolve_filename", VKI_PATH_MAX); + + *result = buf; + VG_(strcpy)( buf, kinfo_file.vki_kf_path ); + if (buf[0] == '/') return True; + } + *result = NULL; + return False; +#endif + # elif defined(VGO_darwin) HChar tmp[VKI_MAXPATHLEN+1]; if (0 == VG_(fcntl)(fd, VKI_F_GETPATH, (UWord)tmp)) { @@ -181,6 +203,8 @@ Bool VG_(resolve_filename) ( Int fd, const HChar** result ) #if defined(VGO_freebsd) + +#if (1) /* This should only be called after a successful call to * Bool VG_(resolve_filename) ( Int fd, const HChar** result ) * so that filedesc_buf is still valid for fd */ @@ -194,16 +218,29 @@ Bool VG_(resolve_filemode) ( Int fd, Int * result ) eb = filedesc_buf + sizeof(filedesc_buf); while (bp < eb) { kf = (struct vki_kinfo_file *)bp; - if (kf->kf_fd == fd) + if (kf->vki_kf_fd == fd) break; - bp += kf->kf_structsize; + bp += kf->vki_kf_structsize; } if (bp >= eb) *result = -1; else - *result = kf->kf_flags; + *result = kf->vki_kf_flags; return True; } +#else +/* less ugly version, no dependency on resolve_filename */ +Bool VG_(resolve_filemode) ( Int fd, Int * result ) +{ + struct vki_kinfo_file kinfo_file; + kinfo_file.vki_kf_structsize = VKI_KINFO_FILE_SIZE; + if (0 == VG_(fcntl) ( fd, VKI_F_KINFO, (Addr)&kinfo_file )) { + *result = kinfo_file.vki_kf_flags; + return True; + } + return False; +} +#endif #endif diff --git a/coregrind/m_syswrap/priv_syswrap-freebsd.h b/coregrind/m_syswrap/priv_syswrap-freebsd.h index 5d6bec529c..70fc431cc0 100644 --- a/coregrind/m_syswrap/priv_syswrap-freebsd.h +++ b/coregrind/m_syswrap/priv_syswrap-freebsd.h @@ -372,7 +372,7 @@ DECL_TEMPLATE(freebsd, sys_getcontext) // 421 DECL_TEMPLATE(freebsd, sys_setcontext) // 422 DECL_TEMPLATE(freebsd, sys_swapcontext) // 423 -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) DECL_TEMPLATE(freebsd, sys_freebsd13_swapoff) // 424 #else DECL_TEMPLATE(freebsd, sys_swapoff) // 424 @@ -552,7 +552,7 @@ DECL_TEMPLATE(freebsd, sys___specialfd) // 577 #endif -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) // unimpl __NR_fspacectl 580 // unimpl __NR_sched_getcpu 581 diff --git a/coregrind/m_syswrap/syswrap-freebsd.c b/coregrind/m_syswrap/syswrap-freebsd.c index 0f2c2681d3..b1d60dac4b 100644 --- a/coregrind/m_syswrap/syswrap-freebsd.c +++ b/coregrind/m_syswrap/syswrap-freebsd.c @@ -1326,6 +1326,15 @@ PRE(sys_fcntl) int, fd, int, cmd, struct flock *, lock); break; + case VKI_F_KINFO: + PRINT("sys_fcntl[ARG3=='kinfo_file'] ( %" FMT_REGWORD "u, %" FMT_REGWORD "u, %#" FMT_REGWORD "x )", ARG1,ARG2,ARG3); + PRE_REG_READ3(int, "fcntl", + int, fd, int, cmd, + struct vki_kinfo_file *, kinfo); + if (ARG3) { + struct vki_kinfo_file* p_kinfo_file = (struct vki_kinfo_file*)ARG3; + PRE_MEM_WRITE("fcntl(ARG3=='kinfo_file)", ARG3, p_kinfo_file->vki_kf_structsize); + } default: PRINT("sys_fcntl[UNKNOWN] ( %lu, %lu, %lu )", ARG1,ARG2,ARG3); @@ -3856,7 +3865,7 @@ POST(sys_swapcontext) POST_MEM_WRITE( ARG1, sizeof(struct vki_ucontext) ); } -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) // SYS_freebsd13_swapoff 424 // int swapoff(const char *special); PRE(sys_freebsd13_swapoff) @@ -6296,7 +6305,7 @@ PRE(sys___specialfd) #endif // (FREEBSD_VERS >= FREEBSD_13_0) -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) // SYS_swapoff 582 // int swapoff(const char *special, u_int flags); @@ -6813,7 +6822,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { BSDX_(__NR_setcontext, sys_setcontext), // 422 BSDXY(__NR_swapcontext, sys_swapcontext), // 423 -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) BSDX_(__NR_freebsd13_swapoff, sys_freebsd13_swapoff), // 424 #else BSDX_(__NR_swapoff, sys_swapoff), // 424 @@ -7022,7 +7031,7 @@ const SyscallTableEntry ML_(syscall_table)[] = { // unimpl __NR_aio_readv 579 #endif -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) // unimpl __NR_fspacectl 580 // unimpl __NR_sched_getcpu 581 BSDX_(__NR_swapoff, sys_swapoff), // 582 diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 38c5014188..a94fe9477f 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -1569,7 +1569,7 @@ struct vki_dirent { #define VKI_F_GETOWN 6 /* for sockets. */ #define VKI_F_OGETLK 7 /* get record locking information */ #define VKI_F_OSETLK 8 /* set record locking information */ -#define VKI_F_OSETLKW 9 /* F_SETLK; wait if blocked */ +#define VKI_F_OSETLKW 9 /* F_SETLK; wait if blocked */ #define VKI_F_DUP2FD 10 /* duplicate file descriptor to arg */ #define VKI_F_GETLK 11 /* get record locking information */ #define VKI_F_SETLK 12 /* set record locking information */ @@ -1577,11 +1577,13 @@ struct vki_dirent { #define VKI_F_SETLK_REMOTE 14 /* debugging support for remote locks */ #define VKI_F_READAHEAD 15 /* read ahead */ #define VKI_F_RDAHEAD 16 /* Darwin compatible read ahead */ -#define VKI_F_DUPFD_CLOEXEC 17 /* dup close_on_exec */ -#define VKI_F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */ +#define VKI_F_DUPFD_CLOEXEC 17 /* dup close_on_exec */ +#define VKI_F_DUP2FD_CLOEXEC 18 /* Like F_DUP2FD, but FD_CLOEXEC is set */ #define VKI_F_ADD_SEALS 19 /* apply seals to underlying file */ #define VKI_F_GET_SEALS 20 /* get seals to underlying file */ #define VKI_F_ISUNIONSTACK 21 /* kludge for libc (part of a union stack?) */ +/* FreeBSD 13.1 and later */ +#define VKI_F_KINFO 22 /* Return kinfo_file for this fd */ /* for F_[GET|SET]FL */ #define VKI_FD_CLOEXEC 1 /* actually anything with low bit set goes */ @@ -2101,6 +2103,39 @@ struct vki_uuid { vki_uint8_t node[6]; }; +//---------------------------------------------------------------------- +// sys/_sockaddr_storage.h +//---------------------------------------------------------------------- + +#define VKI__SS_MAXSIZE 128U +#define VKI__SS_ALIGNSIZE (sizeof(__int64_t)) +#define VKI__SS_PAD1SIZE (VKI__SS_ALIGNSIZE - sizeof(unsigned char) - \ + sizeof(vki_sa_family_t)) +#define VKI__SS_PAD2SIZE (VKI__SS_MAXSIZE - sizeof(unsigned char) - \ + sizeof(sa_family_t) - VKI__SS_PAD1SIZE - VKI__SS_ALIGNSIZE) + +struct vki_sockaddr_storage { + unsigned char vki_ss_len; /* address length */ + vki_sa_family_t vki_ss_family; /* address family */ + char vki___ss_pad1[VKI__SS_PAD1SIZE]; + __int64_t vki___ss_align; /* force desired struct alignment */ + char vki___ss_pad2VKI_[_SS_PAD2SIZE]; +}; + +//---------------------------------------------------------------------- +// From sys/captrights.h +//---------------------------------------------------------------------- + +#define VKI_CAP_RIGHTS_VERSION_00 0 +#define VKI_CAP_RIGHTS_VERSION VKI_CAP_RIGHTS_VERSION_00 + +struct vki_cap_rights { + vki_uint64_t cki_cr_rights[VKI_CAP_RIGHTS_VERSION + 2]; +}; + +typedef struct vki_cap_rights vki_cap_rights_t; + + //---------------------------------------------------------------------- // From sys/user.h //---------------------------------------------------------------------- @@ -2146,23 +2181,119 @@ struct vki_kinfo_vmentry { char kve_path[VKI_PATH_MAX]; }; +#define VKI_KINFO_FILE_SIZE 1392 + struct vki_kinfo_file { - int kf_structsize; /* Variable size of record. */ - int kf_type; /* Descriptor type. */ - int kf_fd; /* Array index. */ - int kf_ref_count; /* Reference count. */ - int kf_flags; /* Flags. */ - int _kf_pad0; /* Round to 64 bit alignment */ - Off64T kf_offset; /* Seek location. */ - int kf_vnode_type; /* Vnode type. */ - int kf_sock_domain; /* Socket domain. */ - int kf_sock_type; /* Socket type. */ - int kf_sock_protocol; /* Socket protocol. */ - char kf_sa_local[128]; /* Socket address. */ - char kf_sa_peer[128]; /* Peer address. */ - int _kf_ispare[16]; /* Space for more stuff. */ + int vki_kf_structsize; /* Variable size of record. */ + int vki_kf_type; /* Descriptor type. */ + int vki_kf_fd; /* Array index. */ + int vki_kf_ref_count; /* Reference count. */ + int vki_kf_flags; /* Flags. */ + int vki_kf_pad0; /* Round to 64 bit alignment. */ + Off64T vki_kf_offset; /* Seek location. */ + union { + struct { + /* API compatiblity with FreeBSD < 12. */ + int vki_kf_vnode_type; + int vki_kf_sock_domain; + int vki_kf_sock_type; + int kf_sock_protocol; + struct vki_sockaddr_storage vki_kf_sa_local; + struct vki_sockaddr_storage vki_kf_sa_peer; + }; + union { + struct { + /* Sendq size */ + vki_uint32_t vki_kf_sock_sendq; + /* Socket domain. */ + int vki_kf_sock_domain0; + /* Socket type. */ + int vki_kf_sock_type0; + /* Socket protocol. */ + int vki_kf_sock_protocol0; + /* Socket address. */ + struct vki_sockaddr_storage vki_kf_sa_local; + /* Peer address. */ + struct vki_sockaddr_storage vki_kf_sa_peer; + /* Address of so_pcb. */ + vki_uint64_t vki_kf_sock_pcb; + /* Address of inp_ppcb. */ + vki_uint64_t vki_kf_sock_inpcb; + /* Address of unp_conn. */ + vki_uint64_t vki_kf_sock_unpconn; + /* Send buffer state. */ + vki_uint16_t vki_kf_sock_snd_sb_state; + /* Receive buffer state. */ + vki_uint16_t vki_kf_sock_rcv_sb_state; + /* Recvq size. */ + vki_uint32_t vki_kf_sock_recvq; + } vki_kf_sock; + struct { + /* Vnode type. */ + int vki_kf_file_type; + /* Space for future use */ + int vki_kf_spareint[3]; + vki_uint64_t vki_kf_spareint64[30]; + /* Vnode filesystem id. */ + vki_uint64_t vki_kf_file_fsid; + /* File device. */ + vki_uint64_t vki_kf_file_rdev; + /* Global file id. */ + vki_uint64_t vki_kf_file_fileid; + /* File size. */ + vki_uint64_t vki_kf_file_size; + /* Vnode filesystem id, FreeBSD 11 compat. */ + vki_uint32_t vki_kf_file_fsid_freebsd11; + /* File device, FreeBSD 11 compat. */ + vki_uint32_t kf_file_rdev_freebsd11; + /* File mode. */ + vki_uint16_t vki_kf_file_mode; + /* Round to 64 bit alignment. */ + vki_uint16_t vki_kf_file_pad0; + vki_uint32_t kf_file_pad1; + } kf_file; + struct { + vki_uint32_t vki_kf_spareint[4]; + vki_uint64_t vki_kf_spareint64[32]; + vki_uint32_t vki_kf_sem_value; + vki_uint16_t vki_kf_sem_mode; + } kf_sem; + struct { + vki_uint32_t vki_kf_spareint[4]; + vki_uint64_t vki_kf_spareint64[32]; + vki_uint64_t vki_kf_pipe_addr; + vki_uint64_t vki_kf_pipe_peer; + vki_uint32_t vki_kf_pipe_buffer_cnt; + /* Round to 64 bit alignment. */ + vki_uint32_t vki_kf_pipe_pad0[3]; + } kf_pipe; + struct { + vki_uint32_t vki_kf_spareint[4]; + vki_uint64_t vki_kf_spareint64[32]; + vki_uint32_t vki_kf_pts_dev_freebsd11; + vki_uint32_t vki_kf_pts_pad0; + vki_uint64_t vki_kf_pts_dev; + /* Round to 64 bit alignment. */ + vki_uint32_t vki_kf_pts_pad1[4]; + } kf_pts; + struct { + vki_uint32_t vki_kf_spareint[4]; + vki_uint64_t vki_kf_spareint64[32]; + vki_pid_t vki_kf_pid; + } vki_kf_proc; + struct { + vki_uint64_t vki_kf_eventfd_value; + vki_uint32_t vki_kf_eventfd_flags; + } vki_kf_eventfd; + } vki_kf_un; + }; + vki_uint16_t vki_kf_status; /* Status flags. */ + vki_uint16_t vki_kf_pad1; /* Round to 32 bit alignment. */ + int vki__kf_ispare0; /* Space for more stuff. */ + vki_cap_rights_t vki_kf_cap_rights; /* Capability rights. */ + vki_uint64_t vki__kf_cap_spare; /* Space for future cap_rights_t. */ /* Truncated before copyout in sysctl */ - char kf_path[VKI_PATH_MAX]; /* Path to file, if any. */ + char vki_kf_path[VKI_PATH_MAX]; /* Path to file, if any. */ }; //---------------------------------------------------------------------- @@ -2240,19 +2371,6 @@ struct vki_arch_elf_state { #endif -//---------------------------------------------------------------------- -// From sys/caprights.h -//---------------------------------------------------------------------- - -#define VKI_CAP_RIGHTS_VERSION_00 0 -#define VKI_CAP_RIGHTS_VERSION VKI_CAP_RIGHTS_VERSION_00 - -struct vki_cap_rights { - vki_uint64_t cr_rights[VKI_CAP_RIGHTS_VERSION + 2]; -}; - -typedef struct vki_cap_rights vki_cap_rights_t; - //---------------------------------------------------------------------- // From ufs/ufs/quota.h //---------------------------------------------------------------------- diff --git a/include/vki/vki-scnums-freebsd.h b/include/vki/vki-scnums-freebsd.h index d1df3d4dd8..bb1228a553 100644 --- a/include/vki/vki-scnums-freebsd.h +++ b/include/vki/vki-scnums-freebsd.h @@ -458,7 +458,7 @@ #define __NR_getcontext 421 #define __NR_setcontext 422 #define __NR_swapcontext 423 -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) #define __NR_freebsd13_swapoff 424 #else #define __NR_swapoff 424 @@ -653,7 +653,7 @@ #endif -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) #define __NR_fspacectl 580 #define __NR_sched_getcpu 581 diff --git a/memcheck/tests/freebsd/scalar.c b/memcheck/tests/freebsd/scalar.c index 5a0b4e85d1..0a6eabeeb0 100644 --- a/memcheck/tests/freebsd/scalar.c +++ b/memcheck/tests/freebsd/scalar.c @@ -1396,7 +1396,7 @@ int main(void) GO(SYS_swapcontext, "2s 2m"); SY(SYS_swapcontext, x0+1, x0+2); FAIL; -#if (FREEBSD_VERS >= FREEBSD_14) +#if (FREEBSD_VERS >= FREEBSD_13_1) /* SYS_freebsd13_swapoff 424 */ GO(SYS_freebsd13_swapoff, "1s 1m"); SY(SYS_freebsd13_swapoff, x0+1); FAIL;