I recently discussed with Rich about the work needed to get 64-bit time_t support into musl. One of the first steps he identified was to find out which interfaces we would want to abstract or wrap for a new ABI given that we have to make a binary incompatible interface anyway.
I have found all the data structures that are provided by both the kernel headers and the musl headers now, and annotated what I think we the path forward could be. I already provided the same list on IRC, but here is a (slightly updated) copy for everyone else.
The takeaway is that we probably need to add new definitions for flock64, statfs, stat, termios, {msg,sem,shm}{buf,info,id_ds}, ipc_perm, rlimit, rusage, sched_param, time_t, timeval, timespec, itimerval, itimerspec, and timex, and then wrap all kernel interfaces that use those.
The same list can also be helpful when we try to clean up the kernel header files -- my idea was that we may want to prefix each struct tag with __kernel_ as we do for typedefs, and then have a kernel header that redefines them like
#ifdef __WANT_KERNEL_STRUCTS #define __kernel_flock flock #endif struct __kernel_flock { ... };
Arnd
/* sparc and mips are incompatible, keep wrapping flock64 */ include/uapi/asm-generic/fcntl.h:struct flock { arch/mips/include/uapi/asm/fcntl.h:struct flock {
/* pt_regs and sigcontext are arch specific, cannot abstract */ arch/*/include/uapi/asm/ptrace.h:struct pt_regs { arch/*/include/uapi/asm/ptrace.h:struct user_regs_struct { arch/arm64/include/uapi/asm/sigcontext.h:struct _aarch64_ctx { arch/arm64/include/uapi/asm/sigcontext.h:struct esr_context { arch/arm64/include/uapi/asm/sigcontext.h:struct extra_context { arch/arm64/include/uapi/asm/sigcontext.h:struct sve_context { arch/*/include/uapi/asm/sigcontext.h:struct sigcontext {
/* arch specific, has wrapper */ arch/*/include/uapi/asm/signal.h:struct sigaction { include/uapi/asm-generic/signal.h:struct sigaction {
/* arch specific, maybe add wrapper? */ arch/*/include/uapi/asm/signal.h:typedef struct sigaltstack { include/uapi/asm-generic/signal.h:typedef struct sigaltstack {
/* arch specific, need to look closer for incompatibilities */ include/uapi/asm-generic/siginfo.h:typedef struct sigevent {
/* arch specific, should add wrapper */ arch/*/include/uapi/asm/statfs.h:struct statfs { include/uapi/asm-generic/statfs.h:struct statfs {
/* arch specific, wrap statx instead */ arch/*/include/uapi/asm/stat.h:struct stat { include/uapi/asm-generic/stat.h:struct stat { include/uapi/linux/stat.h:struct statx { include/uapi/linux/stat.h:struct statx_timestamp {
/* arch specific, should wrap termios2 where possible, * need to check what musl does now */ arch/*/include/uapi/asm/termbits.h:struct termios { include/uapi/asm-generic/termbits.h:struct termios {
/* IPC: wrap them all */ include/uapi/linux/mqueue.h:struct mq_attr { include/uapi/linux/msg.h:struct msgbuf { include/uapi/linux/msg.h:struct msginfo { include/uapi/linux/msg.h:struct msqid_ds { include/uapi/linux/sem.h:struct sembuf { include/uapi/linux/sem.h:struct semid_ds { include/uapi/linux/sem.h:struct seminfo { include/uapi/linux/shm.h:struct shmid_ds { include/uapi/linux/shm.h:struct shm_info { include/uapi/linux/shm.h:struct shminfo {
/* rlimit/rlimit64: keep using only rlimit64 */ include/uapi/linux/resource.h:struct rlimit { include/uapi/linux/resource.h:struct rlimit64 {
/* rusuage: need to wrap: getrusage, wait4 */ include/uapi/linux/resource.h:struct rusage {
/* wrapped already, replace with a more extensible one */ include/uapi/linux/sched/types.h:struct sched_param {
/* prctl(PR_SET_MM); broken in kernel compat mode? * could be wrapped if necessary */ include/uapi/linux/prctl.h:struct prctl_mm_map {
/* inconsistent amount of padding, maybe wrap */ include/uapi/linux/sysinfo.h:struct sysinfo {
/* time64: need to use 64-bit versions of time_t */ include/uapi/linux/time.h:timespec { include/uapi/linux/time.h:struct itimerspec {
/* need to wrap */ include/uapi/linux/utime.h:struct utimbuf { include/uapi/linux/time.h:timeval { include/uapi/linux/time.h:struct itimerval {
/* no need to change */ include/uapi/linux/time.h:struct timezone {
/* probably need to wrap (depending on kernel decision) */ include/uapi/linux/timex.h:struct timex {
/* incompatible on x32 */ include/uapi/linux/times.h:struct tms { include/uapi/linux/uio.h:struct iovec {
/* tape driver ioctls, musl copy is incompatible * on mips64, sparc64 */ include/uapi/linux/mtio.h:struct mtget { include/uapi/linux/mtio.h:struct mtop { include/uapi/linux/mtio.h:struct mtpos {
/* compatible, no need to wrap */ include/uapi/asm-generic/fcntl.h:struct f_owner_ex { include/uapi/asm-generic/poll.h:struct pollfd { include/uapi/asm-generic/termios.h:struct winsize { include/uapi/linux/acct.h:struct acct_v3 include/uapi/linux/eventpoll.h:struct epoll_event { include/uapi/linux/fanotify.h:struct fanotify_event_metadata { include/uapi/linux/fanotify.h:struct fanotify_response { include/uapi/linux/signalfd.h:struct signalfd_siginfo {
/* fixed wire format */ include/uapi/linux/udp.h:struct udphdr { include/uapi/linux/icmp.h:struct icmphdr { include/uapi/linux/if_arp.h:struct arphdr { include/uapi/linux/tcp.h:struct tcphdr { include/uapi/linux/if_ether.h:struct ethhdr { include/uapi/linux/ip.h:struct iphdr {
/* other network stuff, fixed format */ include/uapi/linux/icmpv6.h:struct icmp6_filter { include/uapi/linux/if_arp.h:struct arpreq { include/uapi/linux/if_arp.h:struct arpreq_old { include/uapi/linux/if.h:struct ifconf { include/uapi/linux/if.h:struct ifmap { include/uapi/linux/if.h:struct ifreq { include/uapi/linux/if_packet.h:struct packet_mreq { include/uapi/linux/if_packet.h:struct sockaddr_ll { include/uapi/linux/in6.h:struct in6_addr { include/uapi/linux/in6.h:struct ipv6_mreq { include/uapi/linux/in6.h:struct sockaddr_in6 { include/uapi/linux/in.h:struct group_filter { include/uapi/linux/in.h:struct group_req { include/uapi/linux/in.h:struct group_source_req { include/uapi/linux/in.h:struct in_addr { include/uapi/linux/in.h:struct in_pktinfo { include/uapi/linux/in.h:struct ip_mreq { include/uapi/linux/in.h:struct ip_mreqn { include/uapi/linux/in.h:struct ip_mreq_source { include/uapi/linux/in.h:struct ip_msfilter { include/uapi/linux/in.h:struct sockaddr_in { include/uapi/linux/inotify.h:struct inotify_event { include/uapi/linux/ipc.h:struct ipc_perm include/uapi/linux/ipv6.h:struct in6_pktinfo { include/uapi/linux/ipv6.h:struct ip6_mtuinfo { include/uapi/linux/ipv6_route.h:struct in6_rtmsg { include/uapi/linux/route.h:struct rtentry { include/uapi/linux/tcp.h:struct tcp_diag_md5sig { include/uapi/linux/tcp.h:struct tcp_info { include/uapi/linux/tcp.h:struct tcp_md5sig { include/uapi/linux/tcp.h:struct tcp_repair_window { include/uapi/linux/un.h:struct sockaddr_un {
/* shared typedefs: all in ELF format; can't change */ arch/*/include/uapi/asm/elf.h:typedef ... elf_fpregset_t; arch/*/include/uapi/asm/elf.h:typedef ... elf_greg_t; arch/*/include/uapi/asm/elf.h:typedef elf_greg_t elf_gregset_t[ELF_NGREG]; arch/sparc/include/uapi/asm/uctx.h:} mcontext_t; arch/sparc/include/uapi/asm/uctx.h:typedef struct ucontext ucontext_t; include/uapi/linux/elf.h:typedef struct elf32_hdr Elf32_Ehdr; include/uapi/linux/elf.h:typedef struct elf64_hdr Elf64_Ehdr; include/uapi/linux/elf.h:typedef struct {...} Elf32_Shdr; include/uapi/linux/elf.h:typedef struct {...} Elf64_Shdr; include/uapi/linux/elf.h:typedef struct {...} Elf32_Chdr; include/uapi/linux/elf.h:typedef struct {...} Elf64_Chdr; include/uapi/linux/elf.h:typedef struct {...} Elf32_Nhdr; include/uapi/linux/elf.h:typedef struct {...} Elf64_Nhdr; include/uapi/linux/elf.h:typedef ... include/uapi/linux/elfcore.h:typedef elf_gregset_t gregset_t; include/uapi/linux/elfcore.h: elf_gregset_t pr_reg; /* GP registers */ include/uapi/linux/elfcore.h:typedef elf_greg_t greg_t; include/uapi/linux/elfcore.h:typedef elf_gregset_t gregset_t; include/uapi/linux/elfcore.h:typedef elf_fpregset_t fpregset_t; include/uapi/linux/elfcore.h:struct elf_prpsinfo include/uapi/linux/elfcore.h:struct elf_prstatus include/uapi/linux/elfcore.h:struct elf_siginfo
/* sg.h missing from exported kernel headers, can't change */ include/scsi/sg.h:typedef struct sg_iovec sg_iovec_t; include/scsi/sg.h:typedef struct sg_io_hdr sg_io_hdr_t; include/scsi/sg.h-struct sg_scsi_id { include/scsi/sg.h:typedef struct sg_req_info sg_req_info_t; include/scsi/sg.h:typedef struct sg_io_hdr Sg_io_hdr; include/scsi/sg.h:typedef struct sg_io_vec Sg_io_vec; include/scsi/sg.h:typedef struct sg_scsi_id Sg_scsi_id; include/scsi/sg.h:typedef struct sg_req_info Sg_req_info; include/scsi/sg.h-struct sg_header {
/* 32-bit on alpha, used in ustat (not provided by musl) */ include/uapi/asm-generic/posix_types.h:typedef __kernel_ulong_t __kernel_ino_t; /* 64-bit on mips64, used in mtio (should fix?) and ustat */ include/uapi/asm-generic/posix_types.h:typedef int __kernel_daddr_t;
/* 16 bit on older architectures but only used in IPC interfaces, which will get wrapped anyway */ include/uapi/asm-generic/posix_types.h:typedef unsigned int __kernel_mode_t; include/uapi/asm-generic/posix_types.h:typedef int __kernel_ipc_pid_t; include/uapi/asm-generic/posix_types.h:typedef unsigned int __kernel_uid_t; include/uapi/asm-generic/posix_types.h:typedef unsigned int __kernel_gid_t;