diff --git a/lib/libsys/Symbol.sys.map b/lib/libsys/Symbol.sys.map index 63446888c8d4..46767f5b6a4d 100644 --- a/lib/libsys/Symbol.sys.map +++ b/lib/libsys/Symbol.sys.map @@ -1,402 +1,404 @@ /* * It'd be nice to automatically generate the syscall symbols, but we * don't know to what version they will eventually belong to, so for now * it has to be manual. */ FBSD_1.0 { __acl_aclcheck_fd; __acl_aclcheck_file; __acl_aclcheck_link; __acl_delete_fd; __acl_delete_file; __acl_delete_link; __acl_get_fd; __acl_get_file; __acl_get_link; __acl_set_fd; __acl_set_file; __acl_set_link; __getcwd; __mac_execve; __mac_get_fd; __mac_get_file; __mac_get_link; __mac_get_pid; __mac_get_proc; __mac_set_fd; __mac_set_file; __mac_set_link; __mac_set_proc; __setugid; __syscall; __sysctl; _exit; _umtx_op; abort2; access; acct; adjtime; aio_cancel; aio_error; aio_fsync; aio_read; aio_return; aio_waitcomplete; aio_write; audit; auditctl; auditon; bind; chdir; chflags; chmod; chown; chroot; clock_getres; clock_gettime; clock_settime; dup; dup2; eaccess; execve; extattr_delete_fd; extattr_delete_file; extattr_delete_link; extattr_get_fd; extattr_get_file; extattr_get_link; extattr_list_fd; extattr_list_file; extattr_list_link; extattr_set_fd; extattr_set_file; extattr_set_link; extattrctl; fchdir; fchflags; fchmod; fchown; fhopen; flock; fpathconf; futimes; getaudit; getaudit_addr; getauid; getcontext; getdtablesize; getegid; geteuid; getfh; getgid; getitimer; getpagesize; getpeername; getpgid; getpgrp; getpid; getppid; getpriority; getresgid; getresuid; getrlimit; getrusage; getsid; getsockname; getsockopt; gettimeofday; getuid; ioctl; issetugid; jail; jail_attach; kenv; kill; kldfind; kldfirstmod; kldload; kldnext; kldstat; kldsym; kldunload; kldunloadf; kqueue; kmq_notify; /* Do we want these to be public interfaces? */ kmq_open; /* librt uses them to provide mq_xxx. */ kmq_setattr; kmq_timedreceive; kmq_timedsend; kmq_unlink; ksem_close; ksem_destroy; ksem_getvalue; ksem_init; ksem_open; ksem_post; ksem_timedwait; ksem_trywait; ksem_unlink; ksem_wait; ktrace; lchflags; lchmod; lchown; lgetfh; link; lio_listio; listen; lutimes; mac_syscall; madvise; mincore; minherit; mkdir; mkfifo; mlock; mlockall; modfind; modfnext; modnext; modstat; mount; mprotect; msgget; msgrcv; msgsnd; msgsys; munlock; munlockall; munmap; nfssvc; nmount; ntp_adjtime; ntp_gettime; pathconf; posix_openpt; preadv; profil; pwritev; quotactl; readlink; reboot; rename; revoke; rfork; + rfork_thread; rmdir; rtprio; rtprio_thread; sched_get_priority_max; sched_get_priority_min; sched_getparam; sched_getscheduler; sched_rr_get_interval; sched_setparam; sched_setscheduler; sched_yield; semget; semop; semsys; sendfile; setaudit; setaudit_addr; setauid; setegid; seteuid; setgid; setitimer; setlogin; setpgid; setpriority; setregid; setresgid; setresuid; setreuid; setrlimit; setsid; setsockopt; settimeofday; setuid; shm_unlink; shmat; shmdt; shmget; shmsys; shutdown; sigaltstack; sigpending; sigqueue; sigreturn; socket; socketpair; swapon; symlink; sync; sysarch; syscall; thr_create; thr_exit; thr_kill; thr_kill2; thr_new; thr_self; thr_set_name; thr_suspend; thr_wake; ktimer_create; /* Do we want these to be public interfaces? */ ktimer_delete; /* librt uses them to provide timer_xxx. */ ktimer_getoverrun; ktimer_gettime; ktimer_settime; umask; undelete; unlink; unmount; utimes; utrace; uuidgen; vfork; __error; ftruncate; lseek; mmap; pread; pwrite; truncate; }; FBSD_1.1 { __semctl; cpuset; cpuset_getid; cpuset_setid; cpuset_getaffinity; cpuset_setaffinity; faccessat; fchmodat; fchownat; fexecve; futimesat; jail_get; jail_set; jail_remove; linkat; lpathconf; mkdirat; mkfifoat; msgctl; readlinkat; renameat; setfib; shmctl; symlinkat; unlinkat; }; FBSD_1.2 { cap_enter; cap_getmode; getloginclass; getpagesizes; pdgetpid; pdkill; posix_fallocate; rctl_get_racct; rctl_get_rules; rctl_get_limits; rctl_add_rule; rctl_remove_rule; setloginclass; }; FBSD_1.3 { aio_mlock; bindat; cap_fcntls_get; cap_fcntls_limit; cap_ioctls_get; cap_ioctls_limit; __cap_rights_get; cap_rights_limit; chflagsat; clock_getcpuclockid2; connectat; ffclock_getcounter; ffclock_getestimate; ffclock_setestimate; pipe2; posix_fadvise; procctl; }; FBSD_1.4 { futimens; utimensat; }; FBSD_1.5 { elf_aux_info; fhstat; fhstatfs; fstat; fstatat; fstatfs; getdirentries; getfsstat; getrandom; mknodat; statfs; cpuset_getdomain; cpuset_setdomain; }; FBSD_1.6 { __sysctlbyname; aio_readv; aio_writev; close_range; copy_file_range; fhlink; fhlinkat; fhreadlink; getfhat; funlinkat; shm_rename; }; FBSD_1.7 { fspacectl; kqueuex; membarrier; sched_getcpu; swapoff; timerfd_create; timerfd_gettime; timerfd_settime; }; FBSD_1.8 { exterrctl; fchroot; getgroups; getrlimitusage; inotify_add_watch_at; inotify_rm_watch; jail_attach_jd; jail_remove_jd; kcmp; setcred; setgroups; }; FBSD_1.9 { pdrfork; + pdrfork_thread; }; FBSDprivate_1.0 { /* Add entries in sort(1) order */ __set_error_selector; __sigwait; nlm_syscall; rpctls_syscall; }; diff --git a/lib/libsys/aarch64/Makefile.sys b/lib/libsys/aarch64/Makefile.sys index 04b95602c580..c7aaf52d535a 100644 --- a/lib/libsys/aarch64/Makefile.sys +++ b/lib/libsys/aarch64/Makefile.sys @@ -1,7 +1,9 @@ MIASM:= ${MIASM:Nfreebsd[467]_*} SRCS+= __vdso_gettc.c \ + pdrfork_thread_gen.c \ + rfork_thread_gen.c \ sched_getcpu_gen.c MDASM= cerror.S \ vfork.S diff --git a/lib/libsys/amd64/Symbol.sys.map b/lib/libsys/amd64/Symbol.sys.map index b037e12d45f5..67a8df7d2a8c 100644 --- a/lib/libsys/amd64/Symbol.sys.map +++ b/lib/libsys/amd64/Symbol.sys.map @@ -1,26 +1,21 @@ FBSD_1.0 { - rfork_thread; amd64_get_fsbase; amd64_get_gsbase; amd64_set_fsbase; amd64_set_gsbase; }; FBSD_1.6 { x86_pkru_get_perm; x86_pkru_set_perm; x86_pkru_protect_range; x86_pkru_unprotect_range; }; FBSD_1.8 { amd64_set_tlsbase; }; -FBSD_1.9 { - pdrfork_thread; -}; - FBSDprivate_1.0 { _vfork; }; diff --git a/lib/libsys/arm/Makefile.sys b/lib/libsys/arm/Makefile.sys index 27d78978a2f4..424d2f9cc9d8 100644 --- a/lib/libsys/arm/Makefile.sys +++ b/lib/libsys/arm/Makefile.sys @@ -1,6 +1,8 @@ SRCS+= __vdso_gettc.c \ + pdrfork_thread_gen.c \ + rfork_thread_gen.c \ sched_getcpu_gen.c MDASM= \ cerror.S \ vfork.S diff --git a/lib/libsys/i386/Symbol.sys.map b/lib/libsys/i386/Symbol.sys.map index a35349e4953b..03a28f9e486c 100644 --- a/lib/libsys/i386/Symbol.sys.map +++ b/lib/libsys/i386/Symbol.sys.map @@ -1,29 +1,24 @@ FBSD_1.0 { i386_clr_watch; i386_get_fsbase; i386_get_gsbase; i386_get_ioperm; i386_get_ldt; i386_set_fsbase; i386_set_gsbase; i386_set_ioperm; i386_set_ldt; i386_set_watch; i386_vm86; - rfork_thread; }; FBSD_1.6 { x86_pkru_get_perm; x86_pkru_protect_range; x86_pkru_set_perm; x86_pkru_unprotect_range; }; -FBSD_1.9 { - pdrfork_thread; -}; - FBSDprivate_1.0 { _vfork; }; diff --git a/lib/libsys/pdrfork_thread_gen.c b/lib/libsys/pdrfork_thread_gen.c new file mode 100644 index 000000000000..d36b2cc11993 --- /dev/null +++ b/lib/libsys/pdrfork_thread_gen.c @@ -0,0 +1,34 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2026 The FreeBSD Foundation + * + * This software were developed by + * Konstantin Belousov under sponsorship from + * the FreeBSD Foundation. + */ + +#include +#include +#include +#include + +pid_t +pdrfork_thread(int *fdp, int pdflags, int rfflags, void *stack_addr, + int (*start_fn)(void *), void *arg) +{ + pid_t res; + int ret; + + /* See comment in rfork_thread_gen.c. */ + if (stack_addr != NULL) { + errno = EOPNOTSUPP; + return (-1); + } + res = pdrfork(fdp, pdflags, rfflags); + if (res == 0) { + ret = start_fn(arg); + _exit(ret); + } + return (res); +} diff --git a/lib/libsys/powerpc/Makefile.sys b/lib/libsys/powerpc/Makefile.sys index 9979d5179f51..f066aae1a4fa 100644 --- a/lib/libsys/powerpc/Makefile.sys +++ b/lib/libsys/powerpc/Makefile.sys @@ -1,4 +1,6 @@ SRCS+= __vdso_gettc.c \ + pdrfork_thread_gen.c \ + rfork_thread_gen.c \ sched_getcpu_gen.c MDASM+= cerror.S diff --git a/lib/libsys/powerpc64/Makefile.sys b/lib/libsys/powerpc64/Makefile.sys index 9979d5179f51..f066aae1a4fa 100644 --- a/lib/libsys/powerpc64/Makefile.sys +++ b/lib/libsys/powerpc64/Makefile.sys @@ -1,4 +1,6 @@ SRCS+= __vdso_gettc.c \ + pdrfork_thread_gen.c \ + rfork_thread_gen.c \ sched_getcpu_gen.c MDASM+= cerror.S diff --git a/lib/libsys/rfork_thread_gen.c b/lib/libsys/rfork_thread_gen.c new file mode 100644 index 000000000000..5a8f6e3f650f --- /dev/null +++ b/lib/libsys/rfork_thread_gen.c @@ -0,0 +1,40 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2026 The FreeBSD Foundation + * + * This software were developed by + * Konstantin Belousov under sponsorship from + * the FreeBSD Foundation. + */ + +#include +#include + +pid_t +rfork_thread(int flags, void *stack_addr, int (*start_fn)(void *), void *arg) +{ + pid_t res; + int ret; + + /* + * Generic implementation cannot switch stacks. Only + * architecture-specific code knows how to do it. Require + * that caller knows that, and refuse to do operate if the + * stack was supplied. + * + * Note that implementations that do switch stack, would fault + * immediately if the passed stack is NULL. They do not need to + * specifically check for the NULL stack value. + */ + if (stack_addr != NULL) { + errno = EOPNOTSUPP; + return (-1); + } + res = rfork(flags); + if (res == 0) { + ret = start_fn(arg); + _exit(ret); + } + return (res); +} diff --git a/lib/libsys/riscv/Makefile.sys b/lib/libsys/riscv/Makefile.sys index 2ff84735f484..87181565f0be 100644 --- a/lib/libsys/riscv/Makefile.sys +++ b/lib/libsys/riscv/Makefile.sys @@ -1,5 +1,7 @@ SRCS+= __vdso_gettc.c \ + pdrfork_thread_gen.c \ + rfork_thread_gen.c \ sched_getcpu_gen.c MDASM= cerror.S \ vfork.S