/* See LICENSE file for copyright and license details. */
/* This file is included from ../libsyscalls_get_struct_description.c */
/* Don't forget to add new ones to ../libsyscalls.h */
#define LIST_LINUX_STRUCTS(X, D)\
X(STRUCT, AIO_SIGSET, 0 /* TODO bitmask */,\
FIELD("sigmask", ULONG_ARRAY, IN, INPTR),\
FIELD("sigsetsize", SIZE, IN)) D\
X(STRUCT, COMPAT_AIO_SIGSET, 0 /* TODO bitmask */,\
FIELD("sigmask", UINT32, IN, OUT),\
FIELD("sigsetsize", UINT32, IN, OUT)) D\
X(STRUCT, CACHESTAT, 0,\
FIELD("nr_cache", UINT64, IN, OUT),\
FIELD("nr_dirty", UINT64, IN, OUT),\
FIELD("nr_writeback", UINT64, IN, OUT),\
FIELD("nr_evicted", UINT64, IN, OUT),\
FIELD("nr_recently_evicted", UINT64, IN, OUT)) D\
X(STRUCT, CACHESTAT_RANGE, 0,\
FIELD("off", UINT64, IN, OUT),\
FIELD("len", UINT64, IN, OUT)) D\
X(STRUCT, CLONE_ARGS, 0, /* TODO which fields are IN and OUT? */\
FIELD("flags", UINT64, IN) /* TODO bitmask */,\
FIELD("pidfd", UINT64, IN) /* TODO actually (int *) */,\
FIELD("child_tid", UINT64, IN) /* TODO actually (pid_t *) */,\
FIELD("parent_tid", UINT64, IN) /* TODO actually (pid_t *) */,\
FIELD("exit_signal", UINT64, IN) /* TODO actually INT_SIGNAL */,\
FIELD("stack", UINT64, IN),\
FIELD("stack_size", UINT64, IN),\
FIELD("tls", UINT64, IN), /* TODO actually MEMORY_ADDRESS */\
/* Since Linux 5.5: */\
FIELD("set_tid", UINT64, IN), /* TODO acually (pid_t *) with count in next field */\
FIELD("set_tid_size", UINT64, IN),\
FIELD("cgroup", UINT64, IN)) /* TODO actually INT_FD */ D\
X(STRUCT, EPOLL_EVENT, 0, /* TODO different in libc */\
FIELD("events", UINT, IN, OUT) /* TODO bitmask */,\
FIELD("data", UINT64, PARTIAL, IN, OUT)) D\
X(STRUCT, OABI_EPOLL_EVENT, 0, /* TODO different in libc */\
FIELD("events", UINT, IN, OUT) /* TODO bitmask */,\
FIELD("data", UINT64_FRONT_32, PARTIAL, IN, OUT),\
FIELD("data", UINT64_BACK_32, PARTIAL, IN, OUT)) D\
X(STRUCT, FILE_HANDLE, 0) D /* TODO */\
X(STRUCT, FUTEX_WAITV, 0,\
FIELD("val", UINT64, IN, OUT),\
FIELD("uaddr", UINT64, IN, OUT), /* TODO actually (void *) */\
FIELD("flags", UINT32, IN, OUT), /* TODO bitmask */\
FIELD(NULL, UINT32, IN, OUT)) D\
X(STRUCT, IOB, 0) D /* TODO */\
X(STRUCT, IOVEC, 0) D /* TODO */\
X(STRUCT, IO_EVENT, 0,\
FIELD("data", UINT64, IN, OUT),\
FIELD("obj", UINT64, IN, OUT),\
FIELD("res", INT64, IN, OUT),\
FIELD("res2", INT64, IN, OUT)) D\
X(STRUCT, IO_URING_PARAMS, 0) D /* TODO */\
X(STRUCT, ITIMERSPEC, 0,\
FIELD("it_interval", STRUCT_TIMESPEC, IN, OUT),\
FIELD("it_value", STRUCT_TIMESPEC, IN, OUT)) D\
X(STRUCT, ITIMERSPEC64, 0,\
FIELD("it_interval", STRUCT_TIMESPEC64, IN, OUT),\
FIELD("it_value", STRUCT_TIMESPEC64, IN, OUT)) D\
X(STRUCT, KEXEC_SEGMENT, 0) D /* TODO */\
X(STRUCT, COMPAT_KEXEC_SEGMENT, 0) D /* TODO */\
X(STRUCT, LANDLOCK_RULESET_ATTR, 0) D /* TODO */\
X(STRUCT, LINUX_DIRENT, 0) D /* TODO */\
X(STRUCT, LINUX_DIRENT64, 0) D /* TODO */\
X(STRUCT, MMAP_ARG_STRUCT, 0) D /* TODO */\
X(STRUCT, MMSGHDR, 0) D /* TODO */\
X(STRUCT, MOUNT_ATTR, 0) D /* TODO */\
X(STRUCT, MQ_ATTR, 0) D /* TODO */\
X(STRUCT, MSGBUF, 0) D /* TODO */\
X(STRUCT, MSGHDR, 0) D /* TODO */\
X(STRUCT, MSQID_DS, 0) D /* TODO */\
X(STRUCT, NEW_UTSNAME, 0,\
FIELD("sysname", BUFFER_65, OUT),\
FIELD("nodename", BUFFER_65, OUT),\
FIELD("release", BUFFER_65, OUT),\
FIELD("version", BUFFER_65, OUT),\
FIELD("machine", BUFFER_65, OUT),\
FIELD("domainname", BUFFER_65, OUT)) D\
X(STRUCT, OLDOLD_UTSNAME, 0,\
FIELD("sysname", BUFFER_9, OUT),\
FIELD("nodename", BUFFER_9, OUT),\
FIELD("release", BUFFER_9, OUT),\
FIELD("version", BUFFER_9, OUT),\
FIELD("machine", BUFFER_9, OUT)) D\
X(STRUCT, OLD_ITIMERSPEC32, 0,\
FIELD("it_interval", STRUCT_OLD_TIMESPEC32, IN, OUT),\
FIELD("it_value", STRUCT_OLD_TIMESPEC32, IN, OUT)) D\
X(STRUCT, ITIMERVAL, 0,\
FIELD("it_interval", STRUCT_TIMEVAL, IN, OUT),\
FIELD("it_value", STRUCT_TIMEVAL, IN, OUT)) D\
X(STRUCT, OLD_ITIMERVAL, 0,\
FIELD("it_interval", STRUCT_OLD_TIMEVAL, IN, OUT),\
FIELD("it_value", STRUCT_OLD_TIMEVAL, IN, OUT)) D\
X(STRUCT, OLD_LINUX_DIRENT, 0) D /* TODO */\
X(STRUCT, OLD_SIGACTION, 0) D /* TODO */\
X(STRUCT, OLD_STAT, 0) D /* TODO */\
X(STRUCT, OLD_TIMESPEC32, 0) D /* TODO */\
X(STRUCT, OLD_TIMEVAL, 0) D /* TODO */\
X(STRUCT, OLD_TIMEVAL32, 0) D /* TODO */\
X(STRUCT, OLD_TIMEX32, 0) D /* TODO */\
X(STRUCT, OLD_UTIMBUF32, 0) D /* TODO */\
X(STRUCT, OLD_UTSNAME, 0,\
FIELD("sysname", BUFFER_65, OUT),\
FIELD("nodename", BUFFER_65, OUT),\
FIELD("release", BUFFER_65, OUT),\
FIELD("version", BUFFER_65, OUT),\
FIELD("machine", BUFFER_65, OUT)) D\
X(STRUCT, OPEN_HOW, 0) D /* TODO */\
X(STRUCT, PERF_EVENT_ATTR, 0) D /* TODO */\
X(STRUCT, POLLFD, 0,\
FIELD("pollfd", INT_FD, IN),\
FIELD("events", SHORT, IN), /* TODO bitmask */\
FIELD("revents", SHORT, OUT)) D /* TODO bitmask */\
X(STRUCT, RLIMIT, 0,\
FIELD("rlim_cur", ULONG, IN, OUT),\
FIELD("rlim_max", ULONG, IN, OUT)) D\
X(STRUCT, RLIMIT64, 0,\
FIELD("rlim_cur", UINT64, IN, OUT),\
FIELD("rlim_max", UINT64, IN, OUT)) D\
X(STRUCT, COMPAT_RLIMIT, 0,\
FIELD("rlim_cur", UINT32, IN, OUT),\
FIELD("rlim_max", UINT32, IN, OUT)) D\
X(STRUCT, ROBUST_LIST_HEAD, 0) D /* TODO */\
X(STRUCT, RSEQ, 0) D /* TODO */\
X(STRUCT, RUSAGE, 0) D /* TODO */\
X(STRUCT, SCHED_ATTR, 0,\
FIELD("size", UINT32, IN, OUT),\
FIELD("sched_policy", UINT32, IN, OUT),\
FIELD("sched_flags", UINT64, IN, OUT),\
FIELD("sched_nice", INT32, IN, OUT),\
FIELD("sched_priority", UINT32, IN, OUT),\
FIELD("sched_runtime", UINT64, IN, OUT),\
FIELD("sched_deadline", UINT32, IN, OUT),\
FIELD("sched_period", UINT32, IN, OUT)) D\
X(STRUCT, SCHED_PARAM, 0,\
FIELD("sched_priority", INT, IN, OUT)) D\
X(STRUCT, SEL_ARG_STRUCT, 0) D /* TODO */\
X(STRUCT, SEMBUF, 0,\
FIELD("sem_num", USHORT, IN, OUT),\
FIELD("sem_op", SHORT, IN, OUT), /* TODO enum */\
FIELD("sem_flg", SHORT, IN, OUT)) D /* TODO bitmask */\
X(STRUCT, SEMID_DS, 0) D /* TODO */\
X(STRUCT, SHMID_DS, 0) D /* TODO */\
X(STRUCT, SIGACTION, 0) D /* TODO */\
X(STRUCT, SIGALTSTACK, 0) D /* TODO */\
X(STRUCT, SIGEVENT, 0) D /* TODO */\
X(STRUCT, SIGINFO, 0) D /* TODO */\
X(STRUCT, SOCKADDR, 0) D /* TODO */\
X(STRUCT, STAT, 0) D /* TODO */\
X(STRUCT, STAT64, 0) D /* TODO */\
X(STRUCT, STATFS, 0) D /* TODO */\
X(STRUCT, STATFS64, 0) D /* TODO */\
X(STRUCT, STATX, 0) D /* TODO */\
X(STRUCT, SYSINFO, 0) D /* TODO */\
X(STRUCT, TIMESPEC, 0) D /* TODO */\
X(STRUCT, TIMESPEC64, 0) D /* TODO */\
X(STRUCT, TIMEVAL, 0) D /* TODO */\
X(STRUCT, TIMEX, 0) D /* TODO */\
X(STRUCT, TIMEZONE, 0) D /* TODO */\
X(STRUCT, TMS, 0) D /* TODO */\
X(STRUCT, USTAT, 0) D /* TODO */\
X(STRUCT, UTIMBUF, 0) D /* TODO */\
X(UNION, BPF_ATTR, 0) /* TODO */
#define X(TYPE, NAME, ...)\
static struct libsyscalls_structure_description linux_##TYPE##_##NAME##_prototype = TYPE(__VA_ARGS__)
LIST_LINUX_STRUCTS(X, ;);
#undef X
static enum libsyscalls_error
fix_linux_struct_description(enum libsyscalls_arch arch, enum libsyscalls_datatype datatype, unsigned class,
const void *data, size_t data_size, struct libsyscalls_structure_description *description)
{
switch ((int)datatype) {
case LIBSYSCALLS_TYPE_STRUCT_SOCKADDR:
if (class != LIBSYSCALLS_TYPEBITS_SCALAR)
return LIBSYSCALLS_E_NOSUCHTYPE;
description->size = 0;
description->relative_position_of_size = +1;
description->absolute_position_of_size = -1;
/* TODO that is the alignment of `struct sockaddr`? */
break;
case LIBSYSCALLS_TYPE_STRUCT_CLONE_ARGS:
description->alignment = 64;
break;
case LIBSYSCALLS_TYPE_STRUCT_RSEQ:
description->alignment = 4 * 64;
break;
default:
break;
}
(void) arch;
(void) data;
(void) data_size;
return LIBSYSCALLS_E_OK;
}
static enum libsyscalls_error
get_linux_struct_description(enum libsyscalls_arch arch, enum libsyscalls_datatype datatype, unsigned class,
const void *data, size_t data_size, struct libsyscalls_structure_description **description_out,
int *dont_align_fields_out)
{
struct libsyscalls_structure_description *description;
switch ((int)datatype) {
case LIBSYSCALLS_TYPE_STRUCT_EPOLL_EVENT:
if (arch == LIBSYSCALLS_ARCH_AMD64 || arch == LIBSYSCALLS_ARCH_AMD64_X32)
datatype = LIBSYSCALLS_TYPE_STRUCT_OABI_EPOLL_EVENT;
break;
default:
break;
}
#define CASE(TYPE, NAME, ...)\
case LIBSYSCALLS_TYPE_##TYPE##_##NAME:\
description = copy_struct(&linux_##TYPE##_##NAME##_prototype);\
break
switch ((int)datatype) {
LIST_LINUX_STRUCTS(CASE, ;);
default:
return LIBSYSCALLS_E_NOSUCHTYPE;
}
#undef CASE
if (!description)
return LIBSYSCALLS_E_NOMEM;
(void) class;
(void) data;
(void) data_size;
*description_out = description;
*dont_align_fields_out = 0;
return LIBSYSCALLS_E_OK;
}