summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--TODO1
-rw-r--r--libsyscalls.h1406
-rw-r--r--libsyscalls/advanced.h19
-rw-r--r--libsyscalls/internal-begin.h85
-rw-r--r--libsyscalls/internal-end.h3
-rw-r--r--libsyscalls_get_datatype_description.c25
-rw-r--r--libsyscalls_get_integer_alignment.c58
-rw-r--r--linux/integers.c21
-rw-r--r--linux/integers.mk4
-rw-r--r--linux/linux-support.mk2
-rw-r--r--linux/syscalls.h14
-rw-r--r--linux/tests/os-dependent-integers4
-rwxr-xr-xlinux/what-architecture-am-i-using7
-rw-r--r--mk/generate.mk10
-rwxr-xr-xtest23
-rw-r--r--tests/default-integers21
-rw-r--r--tests/load-functions4
-rw-r--r--tests/os-dependent-integers9
-rw-r--r--testutil/get-integer-alignment.c45
20 files changed, 1643 insertions, 123 deletions
diff --git a/Makefile b/Makefile
index 996315d..ebd5e71 100644
--- a/Makefile
+++ b/Makefile
@@ -57,9 +57,13 @@ TEST_ENV =
#extended for each support operating system with the number of syscall parameters they use
NPARAMS =
+#extended for each support operating system with the maximum used number of fields in its structs and unions
+NFIELDS =
+
#extended for each support operating system
OBJ =\
libsyscalls_get_datatype_description.o\
+ libsyscalls_get_integer_alignment.o\
libsyscalls_get_signals.o\
libsyscalls_get_syscall.o\
libsyscalls_get_syscall_display_info.o\
@@ -88,6 +92,7 @@ SUBHDR =\
TESTUTILS =\
testutil/get-datatype-description.tu\
testutil/get-error.tu\
+ testutil/get-integer-alignment.tu\
testutil/get-section-fraction.tu\
testutil/get-signals.tu\
testutil/get-syscall-errors.tu\
diff --git a/TODO b/TODO
index c140623..0dffc6b 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,3 @@
-Add support for describing structs and unions (and arrays thereof)
Add calling convention
Add value decoding
Add value encoding
diff --git a/libsyscalls.h b/libsyscalls.h
index 066de20..caf4a4b 100644
--- a/libsyscalls.h
+++ b/libsyscalls.h
@@ -77,6 +77,19 @@ enum libsyscalls_arch {
LIBSYSCALLS_ARCH_XTENSA
};
+/**
+ * Data types
+ *
+ * Be aware that some values in this enumeration may have
+ * multiple names, especially structs and unions: up to
+ * one name per combination of operating system and
+ * architecture. Each value may have very different
+ * meaning per name. This may be done because the number
+ * of available values is limited. Also note that functions
+ * may return values that do not have a name at all, these
+ * are anonymous structs and unions whose definitions also
+ * depend on the operating system and architecture.
+ */
enum libsyscalls_datatype {
/* Type renaming, these macros will be undefined later */
@@ -100,13 +113,14 @@ enum libsyscalls_datatype {
X(LIBSYSCALLS_TYPE_DYNAMIC ## SUFFIX,, "(undetermined type)") D\
/* the system call should never returned to the calling process (return to tracer is usually expected) */\
X(LIBSYSCALLS_TYPE_NO_RETURN ## SUFFIX,, "no_return") D\
- /* either used as return type or to skip a register in the parameters
+ /* either used as return type, to skip a register in the parameters
* (do not dismiss this, on some architectures a system call
* may need padding with dummy arguments to align latter
* register pairs; an application printing the system call
* must choose between omitting, printing the argument, or
* indicating that there is a dummy parameter (of course
- * the latter two can be combined)) */\
+ * the latter two can be combined)), or to add padding
+ * (or reserved space for future expansion) to a struct */\
X(LIBSYSCALLS_TYPE_VOID ## SUFFIX,, "void")
#define LIBSYSCALLS_LIST_SPLIT_PRIMITIVES(X, SUFFIX, D, FIRST)\
@@ -263,166 +277,1183 @@ enum libsyscalls_datatype {
#undef LIBSYSCALLS_TYPE_CHAR_ARRAY_UNKNOWN_FILL
};
+/**
+ * Broad classification on system calls
+ */
enum libsyscalls_syscall_category {
+ /**
+ * The library knows about the system calls but
+ * has not yet implemented detailed information
+ * about the system call
+ */
LIBSYSCALLS_CAT_SUPPORT_PENDING,
+
+ /**
+ * The system call has a name but is not implemented
+ * in the kernel, and thus does not have an ABI either
+ *
+ * Be aware that this information may be outdated
+ * and that `LIBSYSCALLS_CAT_SUPPORT_PENDING` might
+ * actually be more appropriate
+ *
+ * This value is not used for system calls that have
+ * be removed, those are still described as if still
+ * implemented by the kernel
+ */
LIBSYSCALLS_CAT_NOT_IMPLEMENTED,
- LIBSYSCALLS_CAT_NETWORK_ENABLED_IPC,
- LIBSYSCALLS_CAT_IPC,
- LIBSYSCALLS_CAT_FILESYSTEM,
- LIBSYSCALLS_CAT_FILE_DESCRIPTORS,
- LIBSYSCALLS_CAT_PROCESSES,
- LIBSYSCALLS_CAT_LOGGING,
- LIBSYSCALLS_CAT_TIME,
- LIBSYSCALLS_CAT_SIGNALS,
- LIBSYSCALLS_CAT_MEMORY,
- LIBSYSCALLS_CAT_SYSTEM,
- LIBSYSCALLS_CAT_SCHEDULING
+
+ LIBSYSCALLS_CAT_NETWORK_ENABLED_IPC, /**< See enum libsyscalls_network_enabled_ipc_syscall_subcategory */
+ LIBSYSCALLS_CAT_IPC, /**< See enum libsyscalls_ipc_syscall_subcategory */
+ LIBSYSCALLS_CAT_FILESYSTEM, /**< See enum libsyscalls_filesystem_syscall_subcategory */
+ LIBSYSCALLS_CAT_FILE_DESCRIPTORS, /**< See enum libsyscalls_file_descriptors_syscall_subcategory */
+ LIBSYSCALLS_CAT_PROCESSES, /**< See enum libsyscalls_processes_syscall_subcategory */
+ LIBSYSCALLS_CAT_LOGGING, /**< See enum libsyscalls_logging_syscall_subcategory */
+ LIBSYSCALLS_CAT_TIME, /**< See enum libsyscalls_time_syscall_subcategory */
+ LIBSYSCALLS_CAT_SIGNALS, /**< See enum libsyscalls_singals_syscall_subcategory */
+ LIBSYSCALLS_CAT_MEMORY, /**< See enum libsyscalls_memory_syscall_subcategory */
+ LIBSYSCALLS_CAT_SYSTEM, /**< See enum libsyscalls_system_syscall_subcategory */
+ LIBSYSCALLS_CAT_SCHEDULING /**< See enum libsyscalls_scheduling_syscall_subcategory */
};
-/* IPC that can but does not have to be over a network,
- * "bind" system calls can create inodes in the file system */
+/**
+ * Interprocess communication system calls that may
+ * either communicate other the a network or locally
+ * on the machine
+ *
+ * Generally these do not affect the filesystem, the only exception
+ * is LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_BIND may create index
+ * nodes and LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_CONNECT may
+ * access the index nodes
+ *
+ * May system calls used for this class of communication
+ * objects used LIBSYSCALLS_CAT_FILE_DESCRIPTORS system calls
+ */
enum libsyscalls_network_enabled_ipc_syscall_subcategory {
+ /**
+ * System calls that create a non-persistent
+ * communication object (such as a file descriptor)
+ * for this category of interprocess communication;
+ * meaning a file descriptor or similar object
+ * that causes the shared resource to be deallocated
+ * once all instances of the object has been released
+ *
+ * socket(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_CREATE,
+
+ /**
+ * System calls that accept incoming connections and
+ * create a new communication object, or rejects them
+ *
+ * accept(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_ACCEPT,
+
+ /**
+ * System calls that enable a communication object to
+ * use LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_ACCEPT
+ * system calls
+ *
+ * listen(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_LISTEN,
+
+ /**
+ * System calls that assigns a communication object
+ * to an local address, this can be a filesystem path
+ * or a network address, or a local identifier; this
+ * system calls gives the communication an address,
+ * and may create an index node on the file system
+ *
+ * bind(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_BIND,
+
+ /**
+ * System calls that attaches a communication object
+ * to an local address, this can be a filesystem path
+ * or a network address, or a local identifier; this
+ * system calls tells the kernel which other communication
+ * object the object shall communicate with, it does
+ * not give explicitly the communication object an
+ * address, however the kernel may give it one if one
+ * has not already be assigned
+ *
+ * connect(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_CONNECT,
+
+ /**
+ * System calls that inspect details about a
+ * communication object
+ *
+ * getsockname(2), getpeername(2), and getsockopt(2)
+ * are examples of system calls in this category
+ */
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_STAT
};
+/**
+ * Interprocess communication system calls that always
+ * local to the machine or a networked filesystem
+ */
enum libsyscalls_ipc_syscall_subcategory {
+ /**
+ * System calls that create a non-persistent
+ * communication object (such as a file descriptor)
+ * for this category of interprocess communication;
+ * meaning a file descriptor or similar object
+ * that causes the shared resource to be deallocated
+ * once all instances of the object has been released
+ *
+ * pipe(2) and socketpair(2) are examples of system
+ * calls in this category
+ */
+ LIBSYSCALLS_IPC_SUBCAT_CREATE,
+
+ /**
+ * System calls that lock, unlock or inspects a lock
+ * on a file, for locks that are strictly advisory
+ *
+ * Note this information can be out of date and the
+ * system call may deal with mandatory file locks,
+ * for example since Linux 5.5, flock(2) has mandatory
+ * on some network file systems; the library does not
+ * take into consideration which version of the kernel
+ * is used, but assumes the latest version (of course
+ * the library may be out of date in regard to this
+ * information even if it is build to the latest kernel)
+ */
LIBSYSCALLS_IPC_SUBCAT_ADVISORY_FILE_LOCK,
+
+ /**
+ * System calls that lock, unlock or inspects a lock
+ * on a file, for locks that are strictly mandatory
+ *
+ * Note this information can be out of date and the
+ * system call may deal with advisory file locks; the
+ * library does not take into consideration which
+ * version of the kernel is used, but assumes the latest
+ * version (of course the library may be out of date in
+ * regard to this information even if it is build to the
+ * latest kernel)
+ */
LIBSYSCALLS_IPC_SUBCAT_MANDATORY_FILE_LOCK,
- LIBSYSCALLS_IPC_SUBCAT_FILE_LOCK, /* may or may not be advisory (e.g. flock(2) since Linux 5.5) */
- LIBSYSCALLS_IPC_SUBCAT_CONTROL, /* includes creation, deletion, and stat */
+
+ /**
+ * System calls that lock, unlock or inspects a lock
+ * on a file, for locks that may be either advisory
+ * or mandatory
+ *
+ * flock(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_IPC_SUBCAT_FILE_LOCK,
+
+ /**
+ * System calls that create or deletes communication
+ * objects, or inspects or changes details about such
+ * objects
+ *
+ * Some system calls use LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_CREATE
+ * instead
+ *
+ * shmget(2), shmctl(2), mq_open(2), mq_unlink(2),
+ * mq_notify(2), and mq_getsetattr(2) are examples of
+ * system calls in this category
+ */
+ LIBSYSCALLS_IPC_SUBCAT_CONTROL,
+
+ /**
+ * System calls that attach to an existing IPC object
+ *
+ * shmat(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_IPC_SUBCAT_ATTACH,
+
+ /**
+ * System calls that detach from an IPC object
+ *
+ * shmdt(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_IPC_SUBCAT_DETACH,
+
+ /**
+ * Communication system calls that do not have a timeout
+ */
LIBSYSCALLS_IPC_SUBCAT_COMMUNICATE,
+
+ /**
+ * Communication system calls that may have a relative
+ * or absolute timeout
+ */
+ LIBSYSCALLS_IPC_SUBCAT_COMMUNICATE_WITH_TIMEOUT,
+
+ /**
+ * Communication system calls that may have a relative timeout
+ */
LIBSYSCALLS_IPC_SUBCAT_COMMUNICATE_WITH_RELATIVE_TIMEOUT,
+
+ /**
+ * Communication system calls that may have an absolute timeout
+ */
LIBSYSCALLS_IPC_SUBCAT_COMMUNICATE_WITH_ABSOLUTE_TIMEOUT
};
-/* syscalls that can work on either paths or FDs ([1]) are located here */
+/**
+ * System calls that operate on the filesystem or can either
+ * operate on a filesystem or a file descriptor that does
+ * not involve the filesystem but is usually used with a
+ * filesystem; this category also include system calls that
+ * effect such systems but does not itself touch the filesystem
+ * but rather the process
+ *
+ * System calls in this category may have timeouts that may
+ * use relative or absolute time
+ */
enum libsyscalls_filesystem_syscall_subcategory {
+ /**
+ * System calls that retrieve the metadata of file
+ *
+ * stat(2) and fstatat(2) are examples of system calls
+ * in this category; fstat(2) however is not
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_STAT,
+
+ /**
+ * System calls that motifies the metadata of file
+ *
+ * chmod(2) and fchmodat(2) are examples of system calls
+ * in this category; fchmod(2) however is not
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_MODIFY,
- LIBSYSCALLS_FILESYSTEM_SUBCAT_SYNC, /* [1] some of these only work on file descriptors or memory maps */
+
+ /**
+ * System calls that commit changes to one or more files
+ * to the filesystem or mmap(2)ed anonymous memory
+ *
+ * sync(2), fsync(2), and msync(2) are examples of system
+ * calls in this category
+ */
+ LIBSYSCALLS_FILESYSTEM_SUBCAT_SYNC,
+
+ /**
+ * System calls the create named index nodes (links)
+ * on a filesystem
+ *
+ * Note that LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_BIND
+ * system calls may also create links
+ *
+ * linkat(2), link(2), symlink(2), mknod(2), and mkdir(2)
+ * are examples of system calls in this category
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_LINK,
+
+ /**
+ * System calls the remove the path to an index node
+ * (removes a link) on a filesystem
+ *
+ * unlink(2) and rmdir(2) are examples of system calls
+ * in this category
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_UNLINK,
+
+ /**
+ * System calls that can operate both as
+ * LIBSYSCALLS_FILESYSTEM_SUBCAT_LINK and
+ * LIBSYSCALLS_FILESYSTEM_SUBCAT_UNLINK system calls,
+ * either one at a time or both at the same them
+ *
+ * rename(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_LINK_OR_UNLINK,
- LIBSYSCALLS_FILESYSTEM_SUBCAT_UMASK, /* modifies the process, not the filesystem */
+
+ /**
+ * System calls that inspects or changes (or both
+ * at the same time) the process's or thread's
+ * umask, which affects the permissions that shall
+ * be eliminated when an index node or IPC object
+ * is created
+ *
+ * umask(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_FILESYSTEM_SUBCAT_UMASK,
+
+ /**
+ * System calles that in some way operate on
+ * mountpoints
+ *
+ * Note that some system calls in the category takes
+ * file descriptors as input or outputs
+ *
+ * mount(2), umount(2), and fsopen(2) are examples
+ * of system calls in this category
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_MOUNTPOINT,
+
+ /**
+ * System calls that retrieve the information about
+ * a mounted filesystem
+ *
+ * statfs(2) and the hypothetical fstatfsat(2) are
+ * examples of system calls in this category;
+ * fstatfs(2) however is not
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_STATFS,
+
+ /**
+ * System calls that make changes to a file
+ * content without requiring a file descriptor
+ * to it, however the system call may optionally
+ * accept a file descriptor
+ *
+ * Hypothetically an operating system could provide
+ * system calls that fall under this category and
+ * could be used to change the target path of an
+ * existing symbolic link
+ *
+ * truncate(2) and the hypothetical ftruncateat(2)
+ * are examples of system calls in this category;
+ * ftruncate(2) however is not
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_WRITE,
+
+ /**
+ * System calls that reads the contents of a file
+ * content without requiring a file descriptor
+ * to it, however the system call may optionally
+ * accept a file descriptor
+ *
+ * There currently are not such system calls,
+ * however, an operating system could not only
+ * provide such system call to read the contents
+ * of a file, but the read the file listing in
+ * a directory or the target path of a symbolic
+ * link
+ */
+ LIBSYSCALLS_FILESYSTEM_SUBCAT_READ,
+
+ /**
+ * System calls that retrieves the target path
+ * of a symbolic link without requiring a file
+ * descriptor to it, however the system call
+ * may optionally accept a file descriptor
+ *
+ * readlink(2) and the readlinkat(2) are examples
+ * of system calls in this category; the
+ * hypothetical freadlink(2) however is not
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_READLINK,
+
+ /**
+ * System calls that are used to monitoring
+ * changes and accesses to a file or filesystem
+ *
+ * This system calls may create file descriptors
+ * or use such file descriptors
+ *
+ * All inotify(7) and fanotify(7) system calls are
+ * examples of system calls in this category;
+ * mq_notify(2) however is not
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_MONITOR,
+
+ /**
+ * System calls that are used dealing with
+ * filesystem quotas
+ *
+ * This system calls may create file descriptors
+ * or use such file descriptors
+ *
+ * quotactl(2) is an example of system call in
+ * this category
+ */
LIBSYSCALLS_FILESYSTEM_SUBCAT_QUOTA
};
-/* syscalls that work FDs but not paths are located here */
+/**
+ * System calls that operate on or create a file descriptor
+ * without fitting into a special category
+ *
+ * System calls in this category may have timeouts that may
+ * use relative or absolute time
+ */
enum libsyscalls_file_syscall_descriptors_subcategory {
+ /**
+ * System calls that retrieve metadata about a
+ * file through a file descriptor to it
+ *
+ * fstat(2) is an example of system call in
+ * this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_STAT,
+
+ /**
+ * System calls that modifies metadata about a
+ * file through a file descriptor to it
+ *
+ * fchmod(2) and fchown(2) are examples of
+ * system calls in this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_MODIFY,
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_DUP_OR_CLOSE, /* includes partial close (shutdown) */
+
+ /**
+ * System calls that duplicates or closes,
+ * possibly both at the same time, file descriptors,
+ * or closes the file descriptor in one or two
+ * directions
+ *
+ * dup(2), dup2(2), close(2), and shutdown(2)
+ * are examples of system calls in this category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_DUP_OR_CLOSE,
+
+ /**
+ * System calls that closes or unshares,
+ * possibly both at the same time, file descriptors,
+ * or closes the file descriptor in one or two
+ * directions
+ *
+ * close_range(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_CLOSE_OR_UNSHARE,
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ, /* may have timeout */
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_OR_PEEK,
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_WRITE, /* may have timeout */
+
+ /**
+ * System calls that read from a file descriptor
+ * and changes the file offset while doing so
+ *
+ * For IPC objects that do not have a file offset
+ * (such as pipes and sockets) this means that
+ * read data is removed from the object
+ *
+ * read(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ,
+
+ /**
+ * System calls that read from a file descriptor
+ * without changing the file offset
+ *
+ * For IPC objects that do not have a file offset
+ * (such as pipes and sockets) this means that
+ * read data will remain in the object, and if
+ * the system calls is made again, the same data
+ * will be read
+ *
+ * pread(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_PEEK,
+
+ /**
+ * System calls that changes the file offset for
+ * a file descriptor without changing reading
+ * or writing
+ *
+ * lseek(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_SEEK,
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_PEEK, /* may have timeout */
+
+ /**
+ * System calls that write to a file descriptor
+ * with or without changing the file offset
+ *
+ * write(2), pwrite(2), send(2), and sendto(2)
+ * are examples of system calls in this category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_WRITE,
+
+ /**
+ * System calls that read from a file descriptor
+ * with or without chaning the file offset
+ *
+ * recv(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_OR_PEEK,
+
+ /**
+ * System calls that performs
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ actions
+ * on one file descriptor and
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_WRITE actions
+ * on another file descriptor, or possibly on the
+ * same file descriptor
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_AND_WRITE,
+
+ /**
+ * System calls that performs
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_PEEK actions
+ * on one file descriptor and
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_WRITE actions
+ * on another file descriptor
+ *
+ * tee(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_PEEK_AND_WRITE,
+
+ /**
+ * System calls that performs
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_OR_PEEK
+ * actions on one file descriptor and
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_WRITE actions
+ * on another file descriptor
+ *
+ * splice(2) and sendfile(2) are examples of system
+ * calls in this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_OR_PEEK_AND_WRITE,
+
+ /**
+ * System calls that performs
+ * LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_OR_PEEK
+ * actions on a file descriptor while receiving
+ * metadata (this metadata does not need to fall
+ * under the category of LIBSYSCALLS_STAT_FILE_DESCRIPTORS,
+ * indeed it unlikely will)
+ *
+ * System calls under this category may receive
+ * new file descriptors
+ *
+ * recvfrom(2) and recvmsg(2) is an example of a
+ * system call in this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_READ_OR_PEEK_AND_STAT,
+
+ /**
+ * System calls that informs the kernel in what
+ * manner the process will use a file descriptor
+ *
+ * posix_fadvise(2) and readahead(2) are examples of
+ * system calls in this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_ADVISE,
+
+ /**
+ * System calls that retrieve metadata about a
+ * filesystem through a file descriptor
+ *
+ * fstatfs(2) is an example of system call in
+ * this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_STATFS,
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_CREATE,
+
+ /**
+ * System calls that create a resource that is used
+ * for LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_POLL
+ * actions
+ *
+ * epoll_create(2) is an example of system call in
+ * this category
+ */
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_CREATE_POLL,
- LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_POLL /* can work as pause or relative sleep */
+
+ /**
+ * System calls that configure a resource that is
+ * used for LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_POLL
+ * actions
+ *
+ * epoll_ctl(2) is an example of system call in
+ * this category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_CONFIGURE_POLL,
+
+ /**
+ * System calls that wait until file descriptor
+ * are ready for writing or have data to read,
+ * or until some other event on the file descriptor
+ * has occurred
+ *
+ * epoll_wait(2), poll(2) and pselect6(2) are
+ * examples of system calls in this category
+ */
+ LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_POLL
};
+/**
+ * System calls that affect a process itself
+ *
+ * Much of the information that can be queried
+ * with system calls in this category may be
+ * available through a virtual filesystem
+ */
enum libsyscalls_processes_syscall_subcategory {
+ /**
+ * System calls that causes the thread, process,
+ * process group, or session to exit
+ *
+ * exit(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_EXIT,
+
+ /**
+ * System calls that retrive information about
+ * the thread, process, process group, or session
+ *
+ * gettid(2), getpid(2), getpgid(2), getsid(2),
+ * getuid(2), and getcwd(2) are examples of system
+ * calls in this category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_STAT_SELF,
- LIBSYSCALLS_PROCESSES_SUBCAT_STAT_CHILD, /* may also stat self */
- LIBSYSCALLS_PROCESSES_SUBCAT_STAT_PARENT, /* may also stat self or children */
+
+ /**
+ * System calls that retrive information about the
+ * process's child processes, or other descendants,
+ * or itself
+ */
+ LIBSYSCALLS_PROCESSES_SUBCAT_STAT_CHILD,
+
+ /**
+ * System calls that retrive information about the
+ * process's parent or other ancestors, or itself
+ * or its descendants
+ *
+ * getppid(2) and getxpid(2) are examples of system
+ * calls in this category
+ */
+ LIBSYSCALLS_PROCESSES_SUBCAT_STAT_PARENT,
+
+ /**
+ * System calls that retrive information about any
+ * process
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_STAT_OTHER,
+
+ /**
+ * System calls that change the process's privileges
+ *
+ * The system call may also retrieve information
+ * about the process
+ *
+ * setuid(2) in an example of a system call in this
+ * category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_CHANGE_PERMISSIONS,
+
+ /**
+ * System calls that forks the process, either
+ * the create a new process or a new thread
+ *
+ * fork(2) and clone(2) are examples of system
+ * calls in this category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_CLONE,
+
+ /**
+ * System calls that changes the program the
+ * process is executing
+ *
+ * execve(2) and execveat(2) are examples of
+ * system calls in this category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_EXEC,
+
+ /**
+ * System calls that change the working directory
+ * of the process or thread
+ *
+ * chdir(2) in an example of a system call in
+ * this category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_CHDIR,
+
+ /**
+ * System calls that change the file system root
+ * of the process or thread
+ *
+ * chroot(2) and pivot_root(2) are examples of
+ * system calls in this category
+ */
LIBSYSCALLS_PROCESSES_SUBCAT_CHROOT,
- LIBSYSCALLS_PROCESSES_SUBCAT_SESSION /* vhangup, setsid, setpgid */
+
+ /**
+ * System calls that affect the process's session
+ * or process group
+ *
+ * setsid(2), setpgid(2), and vhangup(2) are
+ * examples of system calls in this category
+ */
+ LIBSYSCALLS_PROCESSES_SUBCAT_SESSION
};
+/**
+ * System calls that enables or disable system logging
+ *
+ * For each system call in this category, the system call
+ * may use the filesystem or a file descriptor
+ */
enum libsyscalls_logging_syscall_subcategory {
+ /**
+ * System calls that turn on or off logging for
+ * processes
+ *
+ * acct(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_LOGGING_SUBCAT_PROCESSES
};
+/**
+ * System calls whose primary function are time related
+ */
enum libsyscalls_time_syscall_subcategory {
+ /**
+ * System calls that can either get or set (or both)
+ * the current time or time zone information, or the
+ * time of a virtual clock such as a process's run
+ * time
+ *
+ * adjtime(2), adjtimex(2), and clock_adjtime(2)
+ * are examples of system calls in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_GET_OR_SET,
+
+ /**
+ * System calls that can get the current time or
+ * time zone information, or the time of a virtual
+ * clock
+ *
+ * time(2), gettimeofday(2), and clock_gettime(2)
+ * are examples of system calls in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_GET,
+
+ /**
+ * System calls that can set the current time or
+ * time zone information, or the time of a virtual
+ * clock
+ *
+ * stime(2), settimeofday(2), and clock_settime(2)
+ * are examples of system calls in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_SET,
+
+ /**
+ * System calls that receive metadata about a
+ * clock
+ *
+ * clock_gettres(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_INTROSPECT,
+
+ /**
+ * System calls that arm or disarm a timer that
+ * uses relative time
+ *
+ * alarm(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE,
+
+ /**
+ * System calls that arm or disarm a timer that
+ * uses absolute time
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE,
+
+ /**
+ * System calls that arm or disarm a timer that
+ * can use either relative or absolute time
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER,
+
+ /**
+ * System calls that read the amount of time
+ * remaining until a timer that uses relative
+ * time is run over (is triggered)
+ *
+ * These system calls may also retrieve a timer's
+ * overrun interval
+ *
+ * getitimer(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE_READ,
+
+ /**
+ * System calls that read the time a timer that
+ * uses absolute time runs over (is triggered)
+ *
+ * These system calls may also retrieve a
+ * timer's overrun interval
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE_READ,
+
+ /**
+ * System calls that act both as
+ * LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE_READ
+ * and LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE_READ
+ * system calls
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_READ,
+
+ /**
+ * System calls that act both as
+ * LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE
+ * and LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE_READ
+ * system calls and may more may not do both at
+ * the same time
+ *
+ * setitimer(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE_WITH_READ,
+
+ /**
+ * System calls that act both as
+ * LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE
+ * and LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE_READ
+ * system calls and may more may not do both at
+ * the same time
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE_WITH_READ,
+
+ /**
+ * System calls that act both as
+ * LIBSYSCALLS_TIME_SUBCAT_TIMER and
+ * LIBSYSCALLS_TIME_SUBCAT_TIMER_READ system calls
+ * and may more may not do both at the same time
+ */
LIBSYSCALLS_TIME_SUBCAT_TIMER_WITH_READ,
+
+ /**
+ * System calls that suspends the process until
+ * a relative point in time (this could be virtual
+ * time such as a process's run time)
+ *
+ * The system call may return early for any reason,
+ * for example because the a signal was sent to
+ * the process
+ *
+ * nanosleep(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_SLEEP_RELATIVE,
+
+ /**
+ * System calls that suspends the process until
+ * an absolute point in time (this could be virtual
+ * time such as a process's run time)
+ *
+ * The system call may return early for any reason,
+ * for example because the a signal was sent to the
+ * process or the time of the clock was modified
+ */
LIBSYSCALLS_TIME_SUBCAT_SLEEP_ABSOLUTE,
+
+ /**
+ * System calls that act both as
+ * LIBSYSCALLS_TIME_SUBCAT_TIMER_RELATIVE_READ
+ * and LIBSYSCALLS_TIME_SUBCAT_TIMER_ABSOLUTE_READ
+ * system calls
+ *
+ * clock_nanosleep(2) is an example of a system
+ * call in this category
+ */
LIBSYSCALLS_TIME_SUBCAT_SLEEP
};
+/**
+ * System calls that deal with signals (signal(7))
+ */
enum libsyscalls_signals_syscall_subcategory {
+ /**
+ * System calls that only causes the process
+ * to suspend until it receives a signal
+ *
+ * Many system calls will be interrepted if
+ * there is a pending signal or one is received
+ * during the system call. There are also some
+ * system calls that can be used to emulating
+ * the behaviour of system calls in this category
+ * but that have another primary purpose.
+ *
+ * pause(2) in example of a system call in this
+ * category
+ */
LIBSYSCALLS_SIGNALS_SUBCAT_PAUSE,
+
+ /**
+ * System calls that send a signal to a process
+ *
+ * kill(2) in example of a system call in this
+ * category
+ */
LIBSYSCALLS_SIGNALS_SUBCAT_KILL
};
-/* These may work on memory mapped files */
+/**
+ * System calls that deal with memory allocations
+ * including memory mapped files
+ */
enum libsyscalls_memory_syscall_subcategory {
+ /**
+ * System calls that allocate memory or change
+ * the allocation size of an allocated memory
+ * segment
+ *
+ * The system calls may also return information
+ * about how much memory has allocated
+ *
+ * These system calls may change the address of
+ * an allocated memory segment
+ *
+ * brk(2), mmap(2), mremap(2) are examples of system
+ * calls in this category
+ */
LIBSYSCALLS_MEMORY_SUBCAT_ALLOCATE,
- LIBSYSCALLS_MEMORY_SUBCAT_READ,
+
+ /**
+ * System calls that deallocate allocated memory
+ * segments
+ *
+ * munmap(2) is an example of a system call in
+ * this category
+ */
+ LIBSYSCALLS_MEMORY_SUBCAT_DEALLOCATE,
+
+ /**
+ * System calls modifies memory
+ */
LIBSYSCALLS_MEMORY_SUBCAT_WRITE,
+
+ /**
+ * System calls advises the kernel on issues
+ * regarding the process's memory
+ */
LIBSYSCALLS_MEMORY_SUBCAT_ADVISE,
+
+ /**
+ * System calls that can operate both as
+ * LIBSYSCALLS_FILESYSTEM_SUBCAT_LINK and
+ * LIBSYSCALLS_FILESYSTEM_SUBCAT_UNLINK system calls,
+ * either one at a time or both at the same them
+ *
+ * madvise(2) is an example of a system call in
+ * this category
+ */
LIBSYSCALLS_MEMORY_SUBCAT_WRITE_OR_ADVISE,
+
+ /**
+ * System calls that prevent memory to be
+ * paged out into the swap area
+ *
+ * mlock(2) is an example of a system call in
+ * this category
+ */
LIBSYSCALLS_MEMORY_SUBCAT_LOCK,
+
+ /**
+ * System calls that enables memory to be
+ * paged out into the swap area
+ *
+ * munlock(2) is an example of a system call in
+ * this category
+ */
LIBSYSCALLS_MEMORY_SUBCAT_UNLOCK,
- LIBSYSCALLS_MEMORY_SUBCAT_STAT /* stats memory allocated to the process, not system resources */
+
+ /**
+ * System calls that retrieves details about
+ * memory allocated to the process
+ *
+ * mincore(2) is an example of a system call in
+ * this category
+ */
+ LIBSYSCALLS_MEMORY_SUBCAT_STAT,
+
+ /**
+ * System calls that changes details about
+ * memory allocated to the process
+ *
+ * mprotect(2) is an example of a system call
+ * in this category
+ */
+ LIBSYSCALLS_MEMORY_SUBCAT_MODIFY
};
+/**
+ * System calls that deal directly with the
+ * operating system or machine
+ */
enum libsyscalls_system_syscall_subcategory {
+ /**
+ * System calls that deal set swap memory
+ *
+ * swapon(2) and swapoff(2) are examples of system
+ * calls in this category
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_SWAP,
+
+ /**
+ * System calls that poweroff, reboots, suspends
+ * the machine or live patches the kernel
+ *
+ * Note that it is common to preform this task by
+ * communicating with the init system
+ *
+ * reboot(2) is an example of a system call in this
+ * category
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_REBOOT,
+
+ /**
+ * System calls that get the name of the machine
+ * or the operating system, as well as version
+ * and CPU details
+ *
+ * Note that this information may also be available
+ * through a virtual file system
+ *
+ * uname(2) and gethostname(2) are examples of
+ * system calls in this category
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_GET_NAME,
+
+ /**
+ * System calls that set the name of the machine
+ *
+ * Note that this information may also be settable
+ * via a virtual file system
+ *
+ * sethostname(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_SET_NAME,
+
+ /**
+ * System calls that get runtime information about
+ * the system, such as CPU and memory usage and
+ * entropy
+ *
+ * Note that this information may also be settable
+ * via a virtual file system
+ *
+ * sysinfo(2) is an example of a system call
+ * in this category
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_STAT,
+
+ /**
+ * System calls that get generate random data, and
+ * may thereby deplete the systems entropy pool
+ *
+ * Note that this may also be possible to do via a
+ * virtual file system
+ *
+ * getrandom(2) is an example of a system call in
+ * this category
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_RANDOM,
+
+ /**
+ * System calls that are generally harmless and
+ * required for a process to perform important
+ * actions
+ *
+ * On Linux the following system calls have this
+ * classification:
+ * - getpagesize(2)
+ */
LIBSYSCALLS_SYSTEM_SUBCAT_FUNDAMENTAL
};
+/**
+ * System calls that affect process sheduling
+ */
enum libsyscalls_scheduling_syscall_subcategory {
- LIBSYSCALLS_SCHEDULING_SUBCAT_YEILD,
+ /**
+ * System calls that causes the thread, process,
+ * process group, session, or user the give up it's
+ * allotted time
+ *
+ * sched_yield(2) is an example of system call in
+ * this category
+ */
+ LIBSYSCALLS_SCHEDULING_SUBCAT_YIELD,
+
+ /**
+ * System calls that changes a thread's, process's
+ * process group's, session's, or user's, or the
+ * machines scheduling parameters
+ *
+ * sched_setscheduler(2), sched_setaffinity(2),
+ * and setpriority(2) are examples of system calls
+ * in this category
+ */
LIBSYSCALLS_SCHEDULING_SUBCAT_SET,
+
+ /**
+ * System calls that retrieves a thread's, process's
+ * process group's, session's, or user's, or the
+ * machines scheduling parameters
+ *
+ * sched_getscheduler(2), sched_getaffinity(2),
+ * and getpriority(2) are examples of system calls
+ * in this category
+ */
LIBSYSCALLS_SCHEDULING_SUBCAT_GET,
+
+ /**
+ * System calls that can operate both as
+ * LIBSYSCALLS_SCHEDULING_SUBCAT_GET and
+ * LIBSYSCALLS_SCHEDULING_SUBCAT_SET system calls,
+ * either one at a time or both at the same them
+ *
+ * nice(2) is an example of a system call in this
+ * category
+ */
+ LIBSYSCALLS_SCHEDULING_SUBCAT_GET_OR_SET,
+
+ /**
+ * System calls the retrieve metadata for the
+ * scheduling options that are available on the
+ * system
+ *
+ * sched_get_priority_max(2) is an example of
+ * a system call in this category
+ */
LIBSYSCALLS_SCHEDULING_SUBCAT_INTROSPECT
};
+/**
+ * Less broad classification on system calls
+ *
+ * Each value in `enum libsyscalls_syscall_category` have
+ * its own field (enumeration of values) name after the
+ * `enum` value; except that LIBSYSCALLS_CAT_SUPPORT_PENDING
+ * and LIBSYSCALLS_CAT_NOT_IMPLEMENTED does not have any,
+ * which also means that whereever this union is used, its
+ * value is undefined, if the broad classification is either
+ * LIBSYSCALLS_CAT_SUPPORT_PENDING or LIBSYSCALLS_CAT_NOT_IMPLEMENTED
+ */
union libsyscalls_syscall_subcategory {
- enum_libsyscalls_network_enabled_ipc_syscall_subcategory network_enabled_ipc;
- enum_libsyscalls_ipc_syscall_subcategory ipc;
- enum_libsyscalls_filesystem_syscall_subcategory filesystem;
- enum_libsyscalls_file_descriptors_syscall_subcategory file_descriptors;
- enum_libsyscalls_processes_syscall_subcategory processes;
- enum_libsyscalls_logging_syscall_subcategory logging;
- enum_libsyscalls_time_syscall_subcategory time;
- enum_libsyscalls_signals_syscall_subcategory signals;
- enum_libsyscalls_memory_syscall_subcategory memory;
- enum_libsyscalls_system_syscall_subcategory system;
- enum_libsyscalls_scheduling_syscall_subcategory scheduling;
+ enum_libsyscalls_network_enabled_ipc_syscall_subcategory network_enabled_ipc; /**< Use for LIBSYSCALLS_CAT_NETWORK_ENABLED_IPC */
+ enum_libsyscalls_ipc_syscall_subcategory ipc; /**< Use for LIBSYSCALLS_CAT_IPC */
+ enum_libsyscalls_filesystem_syscall_subcategory filesystem; /**< Use for LIBSYSCALLS_CAT_FILESYSTEM */
+ enum_libsyscalls_file_descriptors_syscall_subcategory file_descriptors; /**< Use for LIBSYSCALLS_CAT_FILE_DESCRIPTORS */
+ enum_libsyscalls_processes_syscall_subcategory processes; /**< Use for LIBSYSCALLS_CAT_PROCESSES */
+ enum_libsyscalls_logging_syscall_subcategory logging; /**< Use for LIBSYSCALLS_CAT_LOGGING */
+ enum_libsyscalls_time_syscall_subcategory time; /**< Use for LIBSYSCALLS_CAT_TIME */
+ enum_libsyscalls_signals_syscall_subcategory signals; /**< Use for LIBSYSCALLS_CAT_SIGNALS */
+ enum_libsyscalls_memory_syscall_subcategory memory; /**< Use for LIBSYSCALLS_CAT_MEMORY */
+ enum_libsyscalls_system_syscall_subcategory system; /**< Use for LIBSYSCALLS_CAT_SYSTEM */
+ enum_libsyscalls_scheduling_syscall_subcategory scheduling; /**< Use for LIBSYSCALLS_CAT_SCHEDULING */
};
/**
@@ -445,7 +1476,7 @@ struct libsyscalls_syscall_abi {
/**
* For set any bit indexed I (starting from 0), the
* system call parameter I is a pointer that the
- * the system call reads from
+ * system call reads from
*
* Note that there are types that fundamentally are
* pointers (such as strings), for these, this bit
@@ -456,7 +1487,7 @@ struct libsyscalls_syscall_abi {
/**
* For set any bit indexed I (starting from 0), the
* system call parameter I is a pointer that the
- * the system call write to
+ * system call write to
*
* Note that there are types that fundamentally are
* pointers (such as strings), for these, this bit
@@ -509,7 +1540,7 @@ struct libsyscalls_syscall_abi {
short int : LIBSYSCALLS_PAD_(sizeof(short int)/sizeof(char)*CHAR_BIT, 4*16 + 2*6 + 3*1);
/**
- * This is internally by `libsyscalls_get_syscall_display_info`
+ * This is used internally by `libsyscalls_get_syscall_display_info`
* to find out how values ought to be printed to be both human
* and machines friendly (symbolic names are indeed easier for
* the application to deal with as their values can depend on
@@ -521,8 +1552,8 @@ struct libsyscalls_syscall_abi {
* If this is value is 0, `libsyscalls_get_syscall_display_info`
* will not be able to provide any useful information, which
* would either be because everything is provided here (in
- * struct libsyscalls_syscall_abi) or because the library hasn't
- * yet added full support for the system call
+ * `struct libsyscalls_syscall_abi`) or because the library
+ * hasn't yet added full support for the system call
*/
LIBSYSCALLS_SYMBOL_PRINTER symbol_printer : 16;
@@ -678,7 +1709,7 @@ struct libsyscalls_syscall_type_info {
*/
enum_libsyscalls_datatype type;
- char padding__[LIBSYSCALLS_PAD_(sizeof(long) / sizeof(char), sizeof(enum_libsyscalls_datatype) / sizeof(char) + 1)];
+ char padding__[LIBSYSCALLS_PAD_(sizeof(void *)/sizeof(char), sizeof(enum_libsyscalls_datatype)/sizeof(char) + 1)];
unsigned char : CHAR_BIT - 1;
/**
@@ -814,7 +1845,7 @@ enum libsyscalls_datatype_annotation {
};
/**
- * Register-split information for a data type
+ * Register-split/struct field-split information for a data type
*/
enum libsyscalls_datatype_section {
/**
@@ -1001,10 +2032,10 @@ enum libsyscalls_datatype_section {
LIBSYSCALLS_SECTION_LOWER_QUARTER
/*
- * Get the number of registers the data type was split into
+ * Get the number of registers/fields the data type was split into
*
* @param S:enum libsyscalls_datatype_section The data type section information
- * @return :unsigned int The number registers the data type was split into;
+ * @return :unsigned int The number registers/fields the data type was split into;
* invalid if `S` is LIBSYSCALLS_SECTION_UNDETERMINED
*/
#define LIBSYSCALLS_GET_SECTION_FRACTION(S)\
@@ -1041,23 +2072,29 @@ struct libsyscalls_datatype_description {
* number of bits in the entire data type, otherwise the data
* type may have been split (LIBSYSCALLS_SECTION_UNDETERMINED,
* guaranteed to be split otherwise) and this value is just
- * the number of bits stored in the register
+ * the number of bits stored in the register or struct field
+ *
+ * It is possible for the datatype to contain unused dummy
+ * bits in order to make it a power of 2 or a multiple of
+ * a smaller data type. For example, on x86, `long double`
+ * uses 128 bits, even though the value only uses 80 bits.
+ * The dummy bits are included in the value on this field.
*/
unsigned width_in_bits;
/**
* The size (in number of elements) of the array the data type
* is used in, or 1 if the data type was not an array or
- * 0 if the array size is determined by another parameter
+ * 0 if the array size is determined by another parameter/field
*/
unsigned array_size;
/**
* Only used if .array_size is 0
*
- * The position of the arrays size in the parameter list
- * relative to the array, e.g. 1 for the next parameter
- * or -1 for the previous parameter
+ * The position of the array's size in the parameter/field list
+ * relative to the array, e.g. 1 for the next parameter/field
+ * or -1 for the previous parameter/field
*
* If 0, use .absolute_position_of_array_size instead
*/
@@ -1066,7 +2103,7 @@ struct libsyscalls_datatype_description {
/**
* Only used if .array_size is 0
*
- * The position of the arrays size in the parameter list,
+ * The position of the array's size in the parameter/field list,
* indexed starting from 0
*
* If -1, use .relative_position_of_array_size instead
@@ -1077,10 +2114,10 @@ struct libsyscalls_datatype_description {
* Only used if .array_size is 0
*
* Assuming the kernel writes into the array, if 1, the number
- * of elements written to the array (starting from its
- * beginning) is writting into the array size parameter if it
- * is marked as an output parameter and return otherwise; if
- * 0, the number of bits written must be infered from its
+ * of elements written to the array (starting from its beginning)
+ * is writting into the array size parameter/field if it is
+ * marked as an output parameter/field and return otherwise;
+ * if 0, the number of bits written must be infered from its
* contents, e.g. via null byte termination (how this is done
* depends on the system call)
*/
@@ -1116,17 +2153,17 @@ struct libsyscalls_datatype_description {
*
* How signed numbers are represented
*/
- enum libsyscalls_datatype_sign_representation sign_representation;
+ enum libsyscalls_datatype_sign_representation sign_representation : 8;
/**
* Additional information about what the value represents
*/
- enum libsyscalls_datatype_annotation annotation;
+ enum libsyscalls_datatype_annotation annotation : 8;
/**
* What part of the value is stored in the instance
*/
- enum libsyscalls_datatype_section section;
+ enum libsyscalls_datatype_section section : 16;
/**
* This is a ~0 terminated array — but, it can also
@@ -1143,9 +2180,9 @@ struct libsyscalls_datatype_description {
* bits; the bitwise OR of the results is the
* unsigned value used in the instance of the data type
*
- * Data types for register-splits ARE NOT shifted,
- * there is always a value in .byteorder that is 0,
- * unless .byteorder[0] is ~0
+ * Data types for register-splits/struct field-splits
+ * ARE NOT shifted, there is always a value in
+ * .byteorder that is 0, unless .byteorder[0] is ~0
*
* To avoid problems checking for ~0, use the
* LIBSYSCALLS_IS_BYTEORDER_END macro; please also be
@@ -1179,6 +2216,187 @@ struct libsyscalls_datatype_description {
#endif
};
+/**
+ * Details about of field in a `struct` or `union`
+ */
+struct libsyscalls_structure_field {
+ /**
+ * The name of the field, or `NULL` if anonymous
+ */
+ const char *name;
+
+ /**
+ * The fields data type
+ */
+ enum_libsyscalls_datatype type : 16;
+
+ /**
+ * The number bytes from the data type that is used
+ * for the field, 0 if the field is not a bit field
+ */
+ unsigned short int bitlength : 16;
+
+ /**
+ * If 1, the field is expected to be populated
+ * before the system call is entered
+ */
+ unsigned short int input_field : 1;
+
+ /**
+ * If 1, the field is expected to be populated
+ * by the system call unless it returns an error
+ */
+ unsigned short int output_field : 1;
+
+ /**
+ * If 1, the field is expected to be populated
+ * by the system call provided that it returns
+ * an error
+ */
+ unsigned short int error_field : 1;
+
+ /**
+ * If 1, if the field's value can be resolved
+ * into a symbolic string by the library
+ */
+ unsigned short int symbolic_field : 1;
+
+ /**
+ * If 1, the field is a pointer that the reads from
+ *
+ * Note that there are types that fundamentally are
+ * pointers (such as strings), for these, this bit
+ * is not set unless it is a pointer to a string
+ *
+ * This field may always 0 when .input_field is 0
+ */
+ unsigned short int input_pointer : 1;
+
+ /**
+ * If 1, the field is a pointer that the writes to
+ *
+ * Note that there are types that fundamentally are
+ * pointers (such as strings), for these, this bit
+ * is not set unless it is a pointer to a string
+ */
+ unsigned short int output_pointer : 1;
+
+ unsigned short int padding1__ : 16 - (6*1);
+
+#if LIBSYSCALLS_IS_PADDING_REQUIRED_(3, 16, LIBSYSCALLS_POINTER_BIT_)
+# if !LIBSYSCALLS_CAN_ALIGN_(3, 16, CHAR_BIT)
+# error Sorry, we require that the a byte is no longer than (3*16) bits while evenly dividing (3*16) bits
+# endif
+ char padding2__[LIBSYSCALLS_PAD_(sizeof(void *)/sizeof(char), (3*16)/CHAR_BIT)];
+#endif
+};
+
+/**
+ * Details about a `struct` or `union`
+ */
+struct libsyscalls_structure_description {
+ /**
+ * The alignment, in bits, that shall
+ * be used for the data type; never 0
+ */
+ unsigned short int alignment : 16;
+
+ /**
+ * The size of the data type, in bits
+ *
+ * If 0, the data type's size is flexible and its
+ * size is determined by its content but not enough of
+ * it was provided to determine its size.
+ * .relative_position_of_size or .absolute_position_of_size
+ * may or may not be useful to determine the size of the
+ * data type, if .size is 0 (and .array_size is 1, which
+ * it in such case must be).
+ */
+ unsigned short int size : 16;
+
+ /**
+ * The number of fields in the `struct`/`union`
+ */
+ unsigned short int num_fields : 14;
+
+ /**
+ * Only used if .array_size is 0
+ *
+ * Assuming the kernel writes into the array, if 1, the number
+ * of elements written to the array (starting from its beginning)
+ * is writting into the array size parameter/field if it is
+ * marked as an output parameter/field and return otherwise;
+ * if 0, the number of bits written must be infered from its
+ * contents, e.g. via null byte termination (how this is done
+ * depends on the system call)
+ */
+ unsigned short int fill_is_known : 1;
+
+ /**
+ * If 1, the data type is a `union`,
+ * if 0, the data type is a `struct`
+ */
+ unsigned short int is_union : 1;
+
+ /**
+ * The size (in number of elements) of the array the data type
+ * is used in, or 1 if the data type was not an array or
+ * 0 if the array size is determined by another parameter/field
+ *
+ * If 1, .relative_position_of_size will be set to 0,
+ * and .absolute_position_of_size -1, hoever if that is not
+ * the case and this field is set to 1, then .size (which may
+ * or may not be 0 at this point) is determined by the indicated
+ * parameter
+ */
+ unsigned short int array_size : 16;
+
+ /**
+ * The position of the array's or structure's size in the
+ * parameter/field list relative to the array/structure,
+ * e.g. 1 for the next parameter/field or -1 for the previous
+ * parameter/field
+ *
+ * If 0, use .absolute_position_of_size instead
+ */
+ signed short int relative_position_of_size : 16;
+
+ /**
+ * The position of the array's or structure's size in the
+ * parameter/field list, indexed starting from 0
+ *
+ * If -1, use .relative_position_of_size instead
+ */
+ signed short int absolute_position_of_size : 16;
+
+ /**
+ * This is used internally by `libsyscalls_get_struct_display_info`
+ * to find out how values ought to be printed to be both human
+ * and machines friendly (symbolic names are indeed easier for
+ * the application to deal with as their values can depend on
+ * the architecture)
+ *
+ * If this is value is 0, `libsyscalls_get_struct_display_info`
+ * will not be able to provide any useful information, which
+ * would either be because everything is provided here (in
+ * `struct libsyscalls_structure_description`) or because the
+ * library hasn't yet added full support for the structure
+ */
+ LIBSYSCALLS_SYMBOL_PRINTER symbol_printer : 16;
+
+#if LIBSYSCALLS_IS_PADDING_REQUIRED_(7, 16, LIBSYSCALLS_POINTER_BIT_)
+# if !LIBSYSCALLS_CAN_ALIGN_(7, 16, CHAR_BIT)
+# error Sorry, we require that the a byte is no longer than (7*16) bits while evenly dividing (7*16) bits
+# endif
+ char padding__[LIBSYSCALLS_PAD_(sizeof(void *)/sizeof(char), (7*16)/CHAR_BIT)];
+#endif
+
+ /**
+ * Information about each field in the `struct`/`union`
+ */
+ struct libsyscalls_structure_field fields[LIBSYSCALLS_FLEXABLE_OR_NFIELDS_];
+};
+
/**
* Return a description of a libsyscalls error
@@ -1368,6 +2586,52 @@ enum libsyscalls_error
libsyscalls_get_datatype_description(enum libsyscalls_os, enum libsyscalls_arch, enum libsyscalls_datatype,
struct libsyscalls_datatype_description *);
+/**
+ * Get the alignment used for or a scalar integer data type
+ *
+ * This function does not discriminate between optimal and mandatory
+ * alignment; some CPUs operate on misalign data for some types,
+ * whereas other CPUs cannot, but even if it can operate on misalign
+ * data it will be less efficient. This function returns (into
+ * `*alignment_out` the optional (default) alignment even there is
+ * a mandatory alignment that is smaller. As a caveat, the operating
+ * system may proscribe an multiple of the optimal alignment
+ * (usually this would be the size of the data type instead of the
+ * optimal alignment), in such cases, that proscribed alignment will
+ * be returned instead.
+ *
+ * @param os The operating system the data type is used on
+ * @param arch The architecture the data type is used on
+ * @param width_in_bits The width of the integer, in bits
+ * @param alignment_out Output parameter for the alignment, in bits
+ * (may be NULL, will never be filled with 0)
+ * @return LIBSYSCALLS_E_OK - On success
+ * LIBSYSCALLS_E_OSNOSUP - The library is not compiled with support for
+ * the selected operating system (`os`)
+ * LIBSYSCALLS_E_ARCHNOSUP - The library is not compiled with support for
+ * the selected architecture (`arch`) on the
+ * selected operating system (`os`)
+ * LIBSYSCALLS_E_INVAL - `width_in_bits` is 0
+ * LIBSYSCALLS_E_NOSUCHTYPE - The selected architecture (`arch`) does not
+ * support any integer width the specified
+ * width (`width_in_bits`), or the operating
+ * system (`os`) does not support the data type
+ * (that would only be the case if the data type
+ * uses a new register that must be specifically
+ * supported in the operating system's context
+ * switching)
+ *
+ * The function may complete successfully even if out ought to
+ * return LIBSYSCALLS_E_ARCHNOSUP, in such cases, the result
+ * is indeed reliable
+ */
+LIBSYSCALLS_GCC_ATTRIBUTES_(__warn_unused_result__)
+enum libsyscalls_error
+libsyscalls_get_integer_alignment(enum libsyscalls_os, enum libsyscalls_arch, unsigned, unsigned *);
+
+/* TODO add libsyscalls_get_struct_description */
+/* TODO add libsyscalls_get_struct_display_info */
+
#include "libsyscalls/internal-end.h"
#endif
diff --git a/libsyscalls/advanced.h b/libsyscalls/advanced.h
index 22ed3d0..7876178 100644
--- a/libsyscalls/advanced.h
+++ b/libsyscalls/advanced.h
@@ -4,10 +4,15 @@
#endif
-#define LIBSYSCALLS_TYPEOFFSET_SPECIAL_TYPES 0 /* does not use LIBSYSCALLS_TYPEBITSMASK */
-#define LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES 8
-#define LIBSYSCALLS_TYPEOFFSET_COMPOSITE_PRIMITIVES 48
-#define LIBSYSCALLS_TYPEOFFSET_UNANNOTATED_NUMERICALS 64
-#define LIBSYSCALLS_TYPEOFFSET_ANNOTATED_NUMERICALS 256
-#define LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS 512
-#define LIBSYSCALLS_TYPEOFFSET_STRUCTS_AND_UNIONS 1024
+#define LIBSYSCALLS_TYPEOFFSET_SPECIAL_TYPES 0 /* does not use LIBSYSCALLS_TYPEBITSMASK */
+#define LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES 8
+#define LIBSYSCALLS_TYPEOFFSET_COMPOSITE_PRIMITIVES 48
+#define LIBSYSCALLS_TYPEOFFSET_UNANNOTATED_NUMERICALS 64
+#define LIBSYSCALLS_TYPEOFFSET_ANNOTATED_NUMERICALS 256
+#define LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS 512
+#define LIBSYSCALLS_TYPEOFFSET_STRUCTS_AND_UNIONS 1024
+#define LIBSYSCALLS_TYPEOFFSET_ANON_STRUCTS_AND_UNIONS 3072 /* these are OS and maybe even architecture specific structures
+ * structures and unions that do not have a name (or has a name
+ * but is only used as a substructure); they are not listed in
+ * `enum libsyscalls_datatype`, but can appear when querying
+ * the layout of a struct or union */
diff --git a/libsyscalls/internal-begin.h b/libsyscalls/internal-begin.h
index 5c42b7e..0d89bb7 100644
--- a/libsyscalls/internal-begin.h
+++ b/libsyscalls/internal-begin.h
@@ -7,6 +7,18 @@
#include <limits.h>
#include <stddef.h>
+
+/**
+ * Opaque type for symbol printer function identification
+ */
+typedef unsigned short int LIBSYSCALLS_SYMBOL_PRINTER;
+
+/**
+ * Opaque type for symbol printer function parameters
+ */
+typedef struct libsyscalls_symbol_printer_data LIBSYSCALLS_SYMBOL_PRINTER_DATA;
+
+
/* a comma possible into a macro */
#define LIBSYSCALLS_COMMA_ ,
@@ -14,6 +26,9 @@
#ifndef LIBSYSCALLS_FLEXABLE_OR_NPARAMS_
# define LIBSYSCALLS_FLEXABLE_OR_NPARAMS_
#endif
+#ifndef LIBSYSCALLS_FLEXABLE_OR_NFIELDS_
+# define LIBSYSCALLS_FLEXABLE_OR_NFIELDS_
+#endif
#if defined(__GNUC__)
# define LIBSYSCALLS_GCC_ATTRIBUTES_(...) __attribute__((__VA_ARGS__))
@@ -23,16 +38,65 @@
#define LIBSYSCALLS_PAD_(WANT, HAVE) (((WANT) - (HAVE) % (WANT)) % (WANT))
-
-/**
- * Opaque type for symbol printer function identification
- */
-typedef unsigned short int LIBSYSCALLS_SYMBOL_PRINTER;
-
-/**
- * Opaque type for symbol printer function parameters
- */
-typedef struct libsyscalls_symbol_printer_data LIBSYSCALLS_SYMBOL_PRINTER_DATA;
+#define LIBSYSCALLS_IS_PADDING_REQUIRED_(FIELDS, FIELD_BITSIZE, ALIGN_TO_BITS)\
+ ((((FIELDS) & ~((FIELDS) - 1)) * (FIELD_BITSIZE)) % ALIGN_TO_BITS)
+
+#define LIBSYSCALLS_CAN_ALIGN_(FIELDS, FIELD_BITSIZE, ALIGN_BITS)\
+ (!((FIELDS) * (FIELD_BITSIZE) % (ALIGN_BITS) || (ALIGN_BITS) > (FIELDS) * (FIELD_BITSIZE)))
+
+#if defined(__INTPTR_WIDTH__)
+# define LIBSYSCALLS_POINTER_BIT_ __INTPTR_WIDTH__
+#elif defined(__SIZEOF_POINTER__)
+# define LIBSYSCALLS_POINTER_BIT_ (__SIZEOF_POINTER__ * CHAR_BIT)
+#elif defined(__LLP128__) || defined(_LLP128)
+# define LIBSYSCALLS_POINTER_BIT_ 128
+#elif defined(__LLP64__) || defined(_LLP64)
+# define LIBSYSCALLS_POINTER_BIT_ 64
+#elif defined(__LP64__) || defined(_LP64)
+# define LIBSYSCALLS_POINTER_BIT_ 64
+#elif defined(__ILP64__) || defined(_ILP64)
+# define LIBSYSCALLS_POINTER_BIT_ 64
+#elif defined(__SILP64__) || defined(_SILP64)
+# define LIBSYSCALLS_POINTER_BIT_ 64
+#elif defined(__LLP32__) || defined(_LLP32)
+# define LIBSYSCALLS_POINTER_BIT_ 32
+#elif defined(__LP32__) || defined(_LP32)
+# define LIBSYSCALLS_POINTER_BIT_ 32
+#elif defined(__ILP32__) || defined(_ILP32)
+# define LIBSYSCALLS_POINTER_BIT_ 32
+#elif defined(__SILP32__) || defined(_SILP32)
+# define LIBSYSCALLS_POINTER_BIT_ 32
+#elif defined(__IP32__) || defined(_IP32)
+# define LIBSYSCALLS_POINTER_BIT_ 32
+#elif defined(__SIP32__) || defined(_SIP32)
+# define LIBSYSCALLS_POINTER_BIT_ 32
+#elif defined(__IP16__) || defined(_IP16)
+# define LIBSYSCALLS_POINTER_BIT_ 16
+#elif defined(__SIP16__) || defined(_SIP16)
+# define LIBSYSCALLS_POINTER_BIT_ 16
+#elif defined(__SP16__) || defined(_SP16)
+# define LIBSYSCALLS_POINTER_BIT_ 16
+#elif defined(__INTPTR_MAX__) && defined(__LONG_MAX__)
+# if __INTPTR_MAX__ == __LONG_MAX__
+# define LIBSYSCALLS_POINTER_BIT_ LONG_BIT
+# elif __INTPTR_MAX__ / __LONG_MAX__ / __LONG_MAX__ == 2
+# define LIBSYSCALLS_POINTER_BIT_ (LONG_BIT + LONG_BIT)
+# elif __INTPTR_MAX__ / __LONG_MAX__ / __LONG_MAX__ / __LONG_MAX__ / __LONG_MAX__ == 8
+# define LIBSYSCALLS_POINTER_BIT_ (LONG_BIT + LONG_BIT + LONG_BIT + LONG_BIT)
+# endif
+#endif
+#if !defined(LIBSYSCALLS_POINTER_BIT_) && defined(__INTPTR_MAX__)
+# if __INTPTR_MAX__ == 32767ULL
+# define LIBSYSCALLS_POINTER_BIT_ 16
+# elif __INTPTR_MAX__ == 2147483647ULL
+# define LIBSYSCALLS_POINTER_BIT_ 32
+# elif __INTPTR_MAX__ == 9223372036854775807ULL
+# define LIBSYSCALLS_POINTER_BIT_ 64
+# endif
+#endif
+#if !defined(LIBSYSCALLS_POINTER_BIT_)
+# error Cannot figure out bit width of (void *)
+#endif
#define LIBSYSCALLS_LIST_ERRORS_X_(ENUM, STR) ENUM
@@ -75,6 +139,7 @@ typedef struct libsyscalls_symbol_printer_data LIBSYSCALLS_SYMBOL_PRINTER_DATA;
= LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS\
| LIBSYSCALLS_TYPEBITS##SUFFIX)
+
#define LIBSYSCALLS_BITSIZEOF_(T) (sizeof(T) / sizeof(char) * CHAR_BIT)
#define LIBSYSCALLS_FIELD_BITSIZEOF_(S, F) LIBSYSCALLS_BITSIZEOF_(((S *)0)->F)
diff --git a/libsyscalls/internal-end.h b/libsyscalls/internal-end.h
index ed7af58..2aeb2f0 100644
--- a/libsyscalls/internal-end.h
+++ b/libsyscalls/internal-end.h
@@ -8,6 +8,9 @@
#undef LIBSYSCALLS_FLEXABLE_OR_NPARAMS_
#undef LIBSYSCALLS_GCC_ATTRIBUTES_
#undef LIBSYSCALLS_PAD_
+#undef LIBSYSCALLS_IS_PADDING_REQUIRED_
+#undef LIBSYSCALLS_CAN_ALIGN_
+#undef LIBSYSCALLS_POINTER_BIT_
#undef LIBSYSCALLS_LIST_ERRORS_X_
#undef LIBSYSCALLS_DATATYPE_X_
diff --git a/libsyscalls_get_datatype_description.c b/libsyscalls_get_datatype_description.c
index 8d46812..71a2170 100644
--- a/libsyscalls_get_datatype_description.c
+++ b/libsyscalls_get_datatype_description.c
@@ -17,29 +17,29 @@ enum endian {
X(LIBSYSCALLS_ARCH_ALPHA, 8, 64, 64, TODO(bi), TWOS_COMPLEMENT) D\
*/\
X(LIBSYSCALLS_ARCH_AMD64, 8, 64, 64, Little, TWOS_COMPLEMENT) D\
- X(LIBSYSCALLS_ARCH_AMD64_X32, 8, 32, 32, Little, TWOS_COMPLEMENT) D /* amd64, 32-bit convesion*/\
+ X(LIBSYSCALLS_ARCH_AMD64_X32, 8, 32, 32, Little, TWOS_COMPLEMENT) D /* amd64, 32-bit convesion */\
/*
- X(LIBSYSCALLS_ARCH_ARM_OABI, 8, TODO, TODO, TODO(bi), TWOS_COMPLEMENT) D\
- X(LIBSYSCALLS_ARCH_ARM_EABI, 8, TODO, TODO, TODO(bi), TWOS_COMPLEMENT) D\
+ X(LIBSYSCALLS_ARCH_ARM_OABI, 8, TODO, TODO, TODO(bi), TWOS_COMPLEMENT) D / * TODO (alignment) * / \
+ X(LIBSYSCALLS_ARCH_ARM_EABI, 8, TODO, TODO, TODO(bi), TWOS_COMPLEMENT) D / * TODO (alignment) * /\
X(LIBSYSCALLS_ARCH_IA64, 8, 64, 64, TODO, TWOS_COMPLEMENT) D\
*/\
X(LIBSYSCALLS_ARCH_M68K, 8, 32, 32, Big, TWOS_COMPLEMENT) D\
/*
- X(LIBSYSCALLS_ARCH_MICROBLAZE, 8, TODO, TODO, TODO, TODO) D\
+ X(LIBSYSCALLS_ARCH_MICROBLAZE, 8, TODO, TODO, TODO, TODO) D / * TODO (alignment) * /\
X(LIBSYSCALLS_ARCH_MIPS_O32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D / * mips32 * /\
- X(LIBSYSCALLS_ARCH_MIPS_N32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D / * mips64, 32-bit convention * /\
- X(LIBSYSCALLS_ARCH_MIPS_N64, 8, 64, 64, TODO(bi), TWOS_COMPLEMENT) D / * mips64 * /\
+ X(LIBSYSCALLS_ARCH_MIPS_N32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D / * TODO (alignment) * / / * mips64, 32-bit convention * /\
+ X(LIBSYSCALLS_ARCH_MIPS_N64, 8, 64, 64, TODO(bi), TWOS_COMPLEMENT) D / * TODO (alignment) * / / * mips64 * /\
*/\
X(LIBSYSCALLS_ARCH_PARISC_32, 8, 32, 32, Big, TWOS_COMPLEMENT) D\
X(LIBSYSCALLS_ARCH_PARISC_64, 8, 64, 64, Big, TWOS_COMPLEMENT) D\
/*
X(LIBSYSCALLS_ARCH_POWERPC_32, 8, 32, 32, TODO(bi), TODO) D\
- X(LIBSYSCALLS_ARCH_POWERPC_64, 8, 64, 64, TODO(bi), TODO) D\
- X(LIBSYSCALLS_ARCH_POWERPC_NOSPU, 8, 64, 64, TODO(bi), TODO) D\
- X(LIBSYSCALLS_ARCH_POWERPC_SPU, 8, 64, 64, TODO(bi), TODO) D\
- X(LIBSYSCALLS_ARCH_S390_32, 8, 32, 32, Big, TODO) D\
- X(LIBSYSCALLS_ARCH_S390_64, 8, 64, 64, Big, TODO) D\
- X(LIBSYSCALLS_ARCH_SH, 8, 32, 32, TODO(bi), TODO) D / * not sh-5 * /\
+ X(LIBSYSCALLS_ARCH_POWERPC_64, 8, 64, 64, TODO(bi), TODO) D / * TODO (alignment) * /\
+ X(LIBSYSCALLS_ARCH_POWERPC_NOSPU, 8, 64, 64, TODO(bi), TODO) D / * TODO (alignment) * /\
+ X(LIBSYSCALLS_ARCH_POWERPC_SPU, 8, 64, 64, TODO(bi), TODO) D / * TODO (alignment) * /\
+ X(LIBSYSCALLS_ARCH_S390_32, 8, 32, 32, Big, TODO) D / * TODO (alignment) * /\
+ X(LIBSYSCALLS_ARCH_S390_64, 8, 64, 64, Big, TODO) D / * TODO (alignment) * /\
+ X(LIBSYSCALLS_ARCH_SH, 8, 32, 32, TODO(bi), TODO) D / * TODO (alignment) * / / * not sh-5 * /\
*/\
X(LIBSYSCALLS_ARCH_SPARC_32, 8, 32, 32, Big, TWOS_COMPLEMENT) D\
/*
@@ -50,6 +50,7 @@ enum endian {
X(LIBSYSCALLS_ARCH_XTENSA, 8, 32, 32, TODO, TODO)
*/
/* Don't forget to update SUPPORTED_ARCHES in Makefile */
+ /* TODO (alignment) means that it is missing in libsyscalls_get_integer_alignment.c and must also be added thither */
#include "generated/types.c"
diff --git a/libsyscalls_get_integer_alignment.c b/libsyscalls_get_integer_alignment.c
new file mode 100644
index 0000000..7802a06
--- /dev/null
+++ b/libsyscalls_get_integer_alignment.c
@@ -0,0 +1,58 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+#include "generated/integers.c"
+
+enum libsyscalls_error
+libsyscalls_get_integer_alignment(enum libsyscalls_os os, enum libsyscalls_arch arch, unsigned width_in_bits, unsigned *alignment_out)
+{
+ unsigned maxalign;
+
+ if (!width_in_bits)
+ return LIBSYSCALLS_E_INVAL;
+
+ switch ((int)arch) {
+ case LIBSYSCALLS_ARCH_M68K: /* https://m680x0.github.io/doc/abi.html#scalar-types
+ * https://lists.nongnu.org/archive/html/qemu-devel/2015-02/msg04797.html */
+ maxalign = 16;
+ break;
+
+ case LIBSYSCALLS_ARCH_I386:
+ maxalign = 32;
+ break;
+
+ case LIBSYSCALLS_ARCH_AMD64:
+ case LIBSYSCALLS_ARCH_AMD64_X32:
+ case LIBSYSCALLS_ARCH_ALPHA: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
+ case LIBSYSCALLS_ARCH_IA64: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
+ case LIBSYSCALLS_ARCH_MIPS_O32: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
+ case LIBSYSCALLS_ARCH_PARISC_32: /* https://www.ece.lsu.edu/ee4720/doc/pa1.1.pdf (page 26) */
+ case LIBSYSCALLS_ARCH_PARISC_64:
+ case LIBSYSCALLS_ARCH_POWERPC_32: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
+ case LIBSYSCALLS_ARCH_SPARC_32: /* https://www.gaisler.com/doc/sparcv8.pdf (page 46) */
+ case LIBSYSCALLS_ARCH_SPARC_64: /* https://static.lwn.net/images/pdf/LDD3/ch11.pdf */
+ case LIBSYSCALLS_ARCH_XTENSA: /* https://loboris.eu/ESP32/Xtensa_lx%20Overview%20handbook.pdf (page 97) */
+ maxalign = 64;
+ break;
+
+ default:
+ return LIBSYSCALLS_E_ARCHNOSUP;
+ }
+
+ if (width_in_bits & (width_in_bits - 1) || width_in_bits & 7 || width_in_bits > 64)
+ return LIBSYSCALLS_E_NOSUCHTYPE;
+ *alignment_out = width_in_bits < maxalign ? width_in_bits : maxalign;
+
+#define CASE(UPPERCASE, LOWERCASE)\
+ case LIBSYSCALLS_OS_##UPPERCASE:\
+ return get_##LOWERCASE##_integer_alignment(arch, width_in_bits, alignment_out)
+
+ switch ((int)os) {
+ LIST_OSES(CASE, ;);
+ default:
+ return LIBSYSCALLS_E_OSNOSUP;
+ }
+
+#undef CASE
+}
diff --git a/linux/integers.c b/linux/integers.c
new file mode 100644
index 0000000..469ede0
--- /dev/null
+++ b/linux/integers.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+
+/* This file is included from ../libsyscalls_get_integer_alignment.c */
+
+
+#if 0
+static enum libsyscalls_error
+get_linux_integer_alignment(enum libsyscalls_arch arch, unsigned width_in_bits, unsigned *alignmentp)
+{
+ /* ../libsyscalls_get_integer_alignment.c has already set `*alignmentp`
+ * according the the architectures specifications. Linux does not proscribe
+ * excess alignment and there is thus nothing for this function to do. */
+
+ (void) arch;
+ (void) width_in_bits;
+ (void) alignmentp;
+ return LIBSYSCALLS_E_OK;
+}
+#else
+# define get_linux_integer_alignment(arch, width_in_bits, alignmentp) (LIBSYSCALLS_E_OK)
+#endif
diff --git a/linux/integers.mk b/linux/integers.mk
new file mode 100644
index 0000000..93dacfd
--- /dev/null
+++ b/linux/integers.mk
@@ -0,0 +1,4 @@
+# See LICENSE file for copyright and license details.
+
+libsyscalls_get_integer_alignment.o: linux/integers.c
+libsyscalls_get_integer_alignment.lo: linux/integers.c
diff --git a/linux/linux-support.mk b/linux/linux-support.mk
index d596922..c4a3f94 100644
--- a/linux/linux-support.mk
+++ b/linux/linux-support.mk
@@ -33,6 +33,7 @@ SUPPORTED_LINUX_ARCHES =\
OPERATING_SYSTEMS += linux
NPARAMS += 8
+NFIELDS += 60
SUPPORTED_LINUX_ARCHES != printf '%s\n' $(SUPPORTED_LINUX_ARCHES) $(SUPPORTED_ARCHES) | sort | uniq -d
@@ -42,6 +43,7 @@ TEST_ENV += SUPPORTED_LINUX_ARCHES="$(SUPPORTED_LINUX_ARCHES)"
include linux/download.mk
include linux/errors.mk
+include linux/integers.mk
include linux/signals.mk
include linux/syscalls.mk
include linux/syscall-table.mk
diff --git a/linux/syscalls.h b/linux/syscalls.h
index ed278cd..e11120f 100644
--- a/linux/syscalls.h
+++ b/linux/syscalls.h
@@ -258,8 +258,8 @@ SYS(sys_stat, FILESYSTEM, STAT, 2, ZERO(INT), PARAMS(_,STRING, OUT,STRUCT_OLD_ST
SYS(sys_newfstat, FILE_DESCRIPTORS, STAT, 2, ZERO(INT), PARAMS(_,INT_FD, OUT,STRUCT_STAT));
SYS(sys_fstat64, FILE_DESCRIPTORS, STAT, 2, ZERO(INT), PARAMS(_,LONG_FD, OUT,STRUCT_STAT64));
SYS(sys_fstat, FILE_DESCRIPTORS, STAT, 2, ZERO(INT), PARAMS(_,INT, OUT,STRUCT_OLD_STAT));
-SYS(sys_pipe, FILE_DESCRIPTORS, CREATE, 1, ZERO(INT), PARAMS(OUT,2_INTS_FD));
-SYS(sys_alpha_pipe, FILE_DESCRIPTORS, CREATE, 0, 2_INTS_FD, PARAMS());
+SYS(sys_pipe, IPC, CREATE, 1, ZERO(INT), PARAMS(OUT,2_INTS_FD));
+SYS(sys_alpha_pipe, IPC, CREATE, 0, 2_INTS_FD, PARAMS());
SYS(sys_readlink, FILESYSTEM, READLINK, 3, INT, PARAMS(_,STRING, OUT,BUFFER, _,INT));
SYS(sys_munlockall, MEMORY, UNLOCK, 0, ZERO(INT), PARAMS());
SYS(sys_munlock, MEMORY, UNLOCK, 2, ZERO(INT), PARAMS(_,MEMORY_ADDRESS, _,SIZE));
@@ -284,7 +284,7 @@ SYS(sys_mq_timedreceive_time32, IPC, COMMUNICATE_WITH_ABSOLUTE_TIMEOUT, 5, SSIZE
SYS(sys_vhangup, PROCESSES, SESSION, 0, ZERO(INT), PARAMS());
SYS(sys_setsid, PROCESSES, SESSION, 0, INT, PARAMS());
SYS(sys_setpgid, PROCESSES, SESSION, 2, INT, PARAMS(_,INT, _,INT));
-SYS(sys_sched_yield, SCHEDULING, YEILD, 0, ZERO(INT), PARAMS());
+SYS(sys_sched_yield, SCHEDULING, YIELD, 0, ZERO(INT), PARAMS());
SYS(sys_sched_setparam, SCHEDULING, SET, 2, ZERO(INT), PARAMS(_,INT, IN,STRUCT_SCHED_PARAM));
SYS(sys_sched_getparam, SCHEDULING, GET, 2, ZERO(INT), PARAMS(_,INT, OUT,STRUCT_SCHED_PARAM));
SYS(sys_sched_rr_get_interval, SCHEDULING, GET, 2, ZERO(INT), PARAMS(_,INT, OUT,STRUCT_TIMESPEC));
@@ -339,7 +339,7 @@ SYS(sys_umount, FILESYSTEM, MOUNTPOINT, 2, ZERO(INT), PARAMS(_,STRING, SYM,UINT)
SYS(sys_msync, FILESYSTEM, SYNC, 3, ZERO(INT), PARAMS(_,MEMORY_ADDRESS, _,SIZE, SYM,UINT), SYMBOLS(MSYNC));
SYS(sys_madvise, MEMORY, WRITE_OR_ADVISE, 3, ZERO(INT), PARAMS(_,MEMORY_ADDRESS, _,SIZE, SYM,INT), SYMBOLS(MADVISE));
SYS(sys_epoll_create1, FILE_DESCRIPTORS, CREATE_POLL, 1, INT_FD, PARAMS(SYM,UINT), SYMBOLS(EPOLL));
-SYS(sys_epoll_ctl, FILE_DESCRIPTORS, CREATE_POLL, 4, ZERO(INT), PARAMS(_,INT_FD, SYM,INT, _,INT, IN,STRUCT_EPOLL_EVENT), SYMBOLS(EPOLL_CTL));
+SYS(sys_epoll_ctl, FILE_DESCRIPTORS, CONFIGURE_POLL, 4, ZERO(INT), PARAMS(_,INT_FD, SYM,INT, _,INT, IN,STRUCT_EPOLL_EVENT), SYMBOLS(EPOLL_CTL));
SYS(sys_accept4, NETWORK_ENABLED_IPC, ACCEPT, 4, INT_FD, PARAMS(_,INT_FD, OUT,STRUCT_SOCKADDR, OUT,INT, _,UINT), SYMBOLS(SOCK_FD));
SYS(sys_clock_nanosleep, TIME, SLEEP, 4, ZERO(INT), PARAMS(SYM,INT, SYM,UINT, IN,STRUCT_TIMESPEC, OUT,STRUCT_TIMESPEC), SYMBOLS(CLOCKID, TIMER));
SYS(sys_clock_nanosleep_time32, TIME, SLEEP, 4, ZERO(INT), PARAMS(SYM,INT, SYM,UINT, IN,STRUCT_OLD_TIMESPEC32, OUT,STRUCT_OLD_TIMESPEC32), SYMBOLS(CLOCKID, TIMER));
@@ -376,7 +376,7 @@ SYS(sys_shmat, IPC, ATTACH, 3, MEMORY_ADDRESS, PARAMS(_,INT, _,MEMORY_ADDRESS, S
SYS(sys_faccessat2, FILESYSTEM, STAT, 4, ZERO(INT), PARAMS(SYM,INT_ATFD, _,STRING,SYM,UINT, SYM,UINT), SYMBOLS(FACCESSAT, FACCESSAT2));
SYS(sys_fsopen, FILESYSTEM, MOUNTPOINT, 2, INT_FD, PARAMS(_,STRING, SYM,UINT), SYMBOLS(FSOPEN));
SYS(sys_statx, FILESYSTEM, STAT, 5, ZERO(INT), PARAMS(SYM,INT_ATFD, _,STRING, SYM,UINT, SYM,UINT, OUT,STRUCT_STATX), SYMBOLS(3STATX));
-SYS(sys_pipe2, FILE_DESCRIPTORS, CREATE, 2, ZERO(INT), PARAMS(OUT,2_INTS_FD, SYM,UINT), SYMBOLS(PIPE));
+SYS(sys_pipe2, IPC, CREATE, 2, ZERO(INT), PARAMS(OUT,2_INTS_FD, SYM,UINT), SYMBOLS(PIPE));
SYS(sys_getrandom, SYSTEM, RANDOM, 3, SSIZE, PARAMS(OUT,BUFFER, _,SIZE, SYM,UINT), SYMBOLS(GRND));
SYS(sys_inotify_init1, FILESYSTEM, MONITOR, 1, INT_FD, PARAMS(SYM,UINT), SYMBOLS(INOTIFY_FD));
SYS(sys_inotify_add_watch, FILESYSTEM, MONITOR, 3, INT32, PARAMS(_,INT_FD, _,STRING, SYM,UINT32), SYMBOLS(INOTIFY_MASK));
@@ -388,8 +388,8 @@ SYS(sys_msgsnd, IPC, COMMUNICATE, 4, ZERO(SSIZE), PARAMS(_,INT, OUT,STRUCT_MSGBU
SYS(sys_fanotify_mark, FILESYSTEM, MONITOR, 5, ZERO(INT), PARAMS(_,INT_FD, SYM,UINT, SYM,UINT64, SYM,INT_ATFD, _,STRING), SYMBOLS(FANOTIFY_MARK, ATFD));
SYS(sys_mq_open, IPC, CONTROL, 4, INT_FD, PARAMS(_,STRING, SYM,UINT, SYM,USHORT, IN,STRUCT_MQ_ATTR), SYMBOLS(MQ_OPEN, MODE));
SYS(sys_fanotify_init, FILESYSTEM, MONITOR, 2, INT_FD, PARAMS(SYM,UINT, SYM,UINT), SYMBOLS(FAN_CLASS, FAN_EVENT_F));
-SYS(sys_socket, FILE_DESCRIPTORS, CREATE, 3, INT_FD, PARAMS(SYM,INT, SYM,UINT, SYM,UINT), SYMBOLS(SOCKET));
-SYS(sys_socketpair, FILE_DESCRIPTORS, CREATE, 4, ZERO(INT), PARAMS(SYM,INT, SYM,UINT, SYM,UINT, OUT,2_INTS_FD), SYMBOLS(SOCKET));
+SYS(sys_socket, NETWORK_ENABLED_IPC, CREATE, 3, INT_FD, PARAMS(SYM,INT, SYM,UINT, SYM,UINT), SYMBOLS(SOCKET));
+SYS(sys_socketpair, IPC, CREATE, 4, ZERO(INT), PARAMS(SYM,INT, SYM,UINT, SYM,UINT, OUT,2_INTS_FD), SYMBOLS(SOCKET));
SYS(sys_epoll_wait, FILE_DESCRIPTORS, POLL, 4, INT, PARAMS(_,INT_FD, OUT,STRUCT_EPOLL_EVENT_ARRAY, _,INT, _,INT));
SYS(sys_epoll_pwait, FILE_DESCRIPTORS, POLL, 6, INT, PARAMS(_,INT_FD, OUT,STRUCT_EPOLL_EVENT_ARRAY, _,INT, _,INT, IN,ULONG_ARRAY, _,SIZE));
SYS(sys_epoll_pwait2, FILE_DESCRIPTORS, POLL, 6, INT, PARAMS(_,INT_FD, OUT,STRUCT_EPOLL_EVENT_ARRAY, _,INT, IN,STRUCT_TIMESPEC, IN,ULONG_ARRAY, _,SIZE));
diff --git a/linux/tests/os-dependent-integers b/linux/tests/os-dependent-integers
new file mode 100644
index 0000000..73de229
--- /dev/null
+++ b/linux/tests/os-dependent-integers
@@ -0,0 +1,4 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+. tests/default-integers
diff --git a/linux/what-architecture-am-i-using b/linux/what-architecture-am-i-using
index 1c7a9ba..646c9e7 100755
--- a/linux/what-architecture-am-i-using
+++ b/linux/what-architecture-am-i-using
@@ -9,6 +9,13 @@ if uname -s | grep -i linux > /dev/null; then
if test "$arch" = x86_64; then
printf '%s\n' AMD64
if test $# = 0 || "$@"; then
+ if test ! -f /proc/config.gz; then
+ printf '%s\n' '/proc/config.gz is missing' >&2
+ exit 1
+ elif test ! -r /proc/config.gz; then
+ printf '%s\n' '/proc/config.gz is not readable' >&2
+ exit 1
+ fi
if test $# = 0 || gunzip < /proc/config.gz | grep '^CONFIG_X86_X32_ABI=y$' > /dev/null; then
printf '%s\n' AMD64_X32
fi
diff --git a/mk/generate.mk b/mk/generate.mk
index 17671f4..9575c34 100644
--- a/mk/generate.mk
+++ b/mk/generate.mk
@@ -1,7 +1,8 @@
# See LICENSE file for copyright and license details.
NPARAMS != printf '%d\n' 1 $(NPARAMS) | sort -n | sed -n '$$p'
+NFIELDS != printf '%d\n' 1 $(NFIELDS) | sort -n | sed -n '$$p'
-IMPORTANT_CPPFLAGS += -DNPARAMS="$(NPARAMS)"
+IMPORTANT_CPPFLAGS += -DNPARAMS="$(NPARAMS)" -DNFIELDS="$(NFIELDS)"
GET_SYSCALL_RANGE_GEN != printf 'generated/get_syscall_range.%s.c\n' $(OPERATING_SYSTEMS)
@@ -21,6 +22,9 @@ libsyscalls_get_syscall_errors.lo: generated/errors.c
libsyscalls_get_datatype_description.o: generated/types.c
libsyscalls_get_datatype_description.lo: generated/types.c
+libsyscalls_get_integer_alignment.o: generated/integers.c
+libsyscalls_get_integer_alignment.lo: generated/integers.c
+
$(GET_SYSCALL_RANGE_GEN): get_syscall_range.template.c mk/generate.mk
mkdir -p -- generated
@@ -48,6 +52,10 @@ generated/types.c: Makefile mk/generate.mk
mkdir -p -- generated
printf '\43include "../%s/types.c"\n' $(OPERATING_SYSTEMS) > $@
+generated/integers.c: Makefile mk/generate.mk
+ mkdir -p -- generated
+ printf '\43include "../%s/integers.c"\n' $(OPERATING_SYSTEMS) > $@
+
generated/arches.h: Makefile mk/generate.mk
mkdir -p -- generated
printf '\43include "%s-arches.h"\n' $(OPERATING_SYSTEMS) > $@
diff --git a/test b/test
index c825493..185d915 100755
--- a/test
+++ b/test
@@ -29,11 +29,15 @@ alias t=.
# have already been written and passed, set to . otherwise
-set -v
-
-test -n "${SUPPORTED_OSES}" # This check that the test's environment has set up, if this fails, run through `make check`
+if ! env | grep '^SUPPORTED_OSES=' >/dev/null; then
+ printf '%s\n' \
+ "The test's environment has not been set up;" \
+ 'you should run the test via `make check`'
+ exit 1
+fi
-(. tests/test-self-check;) >/dev/null 2>/dev/null
+set -v
+(. tests/test-self-check) >/dev/null 2>/dev/null
@@ -41,31 +45,22 @@ t tests/enums
. tests/load-types
t tests/errors
-
t tests/syscall-ranges
-
t tests/syscall-errors
-
t tests/signals
-
t tests/split-register-classes
. tests/load-archinfo
t tests/archinfo
t tests/fundamental-primitives
-
t tests/is-struct
-
t tests/array-types
-
t tests/fixed-array-types
-
t tests/split-register-types
-
t tests/os-dependent-primitives
-
t tests/os-dependent-arrays
+t tests/os-dependent-integers
diff --git a/tests/default-integers b/tests/default-integers
new file mode 100644
index 0000000..12faa5a
--- /dev/null
+++ b/tests/default-integers
@@ -0,0 +1,21 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ if ! issupported $os $arch; then
+ continue
+ fi
+
+ if test $arch = M68K; then
+ maxalign=16
+ elif test $arch = I386; then
+ maxalign=32
+ else
+ maxalign=64
+ fi
+
+ for width in 8 16 32 64; do
+ test "$(get-integer-alignment.tu $osn $archn $width $os $arch)" = $(min $maxalign $width)
+ done
+done
diff --git a/tests/load-functions b/tests/load-functions
index f0c5311..a31f236 100644
--- a/tests/load-functions
+++ b/tests/load-functions
@@ -58,3 +58,7 @@ issupported () {
cpp_enum_clean () {
$CPP < libsyscalls.h 2>/dev/null | grep -v '#' | tr '\n,{}' ' \n\n\n'
}
+
+min () {
+ printf '%s\n' "$@" | tr -d + | sort -n | sed -n 1p
+}
diff --git a/tests/os-dependent-integers b/tests/os-dependent-integers
new file mode 100644
index 0000000..09a11e3
--- /dev/null
+++ b/tests/os-dependent-integers
@@ -0,0 +1,9 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ if issupported $os; then
+ . $(printf '%s\n' $os | tr '[A-Z]' '[a-z]')/tests/os-dependent-integers
+ fi
+done
diff --git a/testutil/get-integer-alignment.c b/testutil/get-integer-alignment.c
new file mode 100644
index 0000000..6c91824
--- /dev/null
+++ b/testutil/get-integer-alignment.c
@@ -0,0 +1,45 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
+
+int
+main(int argc, char **argv)
+{
+ int os, arch, width;
+ unsigned alignment = -1;
+ enum libsyscalls_error err;
+
+ if (argc != 6) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
+ os = atoi(argv[1]);
+ arch = atoi(argv[2]);
+ width = atoi(argv[3]);
+
+ err = libsyscalls_get_integer_alignment((enum libsyscalls_os)os, (enum libsyscalls_arch)arch,
+ (unsigned)width, &alignment);
+ if (err) {
+ fprintf(stderr, "libsyscalls_get_integer_alignment %s %s %s: ", argv[4], argv[5], argv[3]);
+ libsyscalls_perror(NULL, err);
+ return 1;
+ }
+
+ printf("%u\n", alignment);
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}