summaryrefslogblamecommitdiffstats
path: root/libsyscalls.h
blob: caf4a4b995684c45521894ddb976e0b721628130 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14













                                                         



                                                                                




























































                                                                                                              












                                                           






















                                                                                                                        
                                                                           




                                                                    

                                                                   



























































































































































                                                                                                                                    


                                       
                                   




                                                       
                                        












                                                              
                                        











                                                                                                                  

  












                                                                   
                                                          



















                                                             
                                                      








                                                             
                                                      










                                                             
                                                    













                                                                  
                                                       







                                                            


                                                   



                                                      
                                          

























                                                                
                                                  












                                                                
                                                   






























                                                                           
                                      






                                                          
                                      



                                                                
                                           









                                                                      
                                                                 



                                                                       


                                                                










                                                               
                                                 





                                                              
                                           






                                                                
                                             



















                                                                 
                                           







                                                              
                                             









                                                             
                                                     






















                                                            
                                                 








                                                           
                                             















                                                           
                                            

























                                                         
                                               











                                                          
                                              










                                                        


                                           






                                                           
                                                       






                                                      
                                                 







                                                      
                                                   




















                                                            
                                                             




































                                                          
                                                 


























                                                            
                                                           










                                                            
                                                           










                                                            
                                                                   














                                                                   
                                                                  







                                                            
                                                   







                                                      
                                                   








                                                           
                                                        




















                                                            

  






                                              
                                                






                                                         
                                          








                                                          
                                               





















                                                           
                                                









                                                            
                                                        







                                                      
                                           







                                                    
                                          







                                                         
                                           







                                                        
                                            








                                                         

  





                                                         
                                              






                                                         


                                            


                                                       
                                           








                                                            
                                           








                                                          
                                    








                                                          
                                    







                                                          
                                           







                                                          
                                               




                                                       
                                               




                                                       
                                      











                                                         
                                                    







                                                       
                                                    






                                                          
                                           










                                                          
                                                         







                                                          
                                                         






                                                          
                                                












                                                           
                                               









                                                           
                                               









                                                          


                                     


                                                  
                                              













                                                         
                                         






                                                       


                                       



                                                 
                                             













                                                            
                                           












                                                        
                                        




                                                    
                                         









                                                             
                                                  







                                                     
                                       







                                                       
                                         

















                                                       

  



                                           
                                             





                                                          
                                       










                                                           
                                         











                                                           
                                           









                                                          
                                           











                                                          
                                       










                                                          
                                         









                                                        


                                             


                                             
                                                 


















                                                           
                                          









                                                            
                                          



















                                                          


                                                










                                                                     
                                       










                                                                                                                                         





















                                                             
                                 









                                                           
                               



















































                                                                                                
                                                                            










                                                                        

                                                                   


























































































































































                                                                                                                             
                                                                                                                          






































































































































                                                                         
                                                                

























































































































































































                                                                                                                  
                                                                          

                                                                                          
                                                                                                                  



































                                                                                                           






                                                                    





                                                                      
                                                                       





                                        


                                                                       







                                                             
                                                                        









                                                                      



                                                                         


































                                                                                       
                                                                              



                                                                 
                                                            



                                                           
                                                       

           


                                                               










                                                               


                                                             
          










                                                             

                                    









                                                                                                




                                                                                                                     
                                                                                                             
      

  




















































































































































































                                                                                                          



































                                                                                           



                                                          

























                                                                                                            



                                                          

























                                                                                                                        



                                                                
























                                                                                                                               



                                                                



























































                                                                                                                          













































                                                                                                    


                                     
/* See LICENSE file for copyright and license details. */
#ifndef LIBSYSCALLS_H
#define LIBSYSCALLS_H

#include "libsyscalls/internal-begin.h"
#include "libsyscalls/short-enums.h"
#include "libsyscalls/advanced.h"


/**
 * Macro for enumerating libsyscall error numbers
 * 
 * The numbers are stored in `libsyscalls_error`
 * 
 * @param  X:macro(NAME, STR)  Macro that expands, will be given two arguments:
 *                             the enum value name of the error (identifier),
 *                             and the description of the error (string literal)
 * @param  D:code              Macro that expands between each expansion of X
 *
 * The primary purpose of the existance of this macro
 * is to ease implementation of the library; it will
 * probably not disappear (no promises)
 */
#define LIBSYSCALLS_LIST_ERRORS(X, D)\
	X(LIBSYSCALLS_E_OK, "Success") D\
	X(LIBSYSCALLS_E_OSNOSUP, "Operating system not supported") D\
	X(LIBSYSCALLS_E_ARCHNOSUP, "Architecture not supported for selected operating system") D\
	X(LIBSYSCALLS_E_NOSUCHSYSCALL, "No such system call") D\
	X(LIBSYSCALLS_E_NOERRORS, "There is no error listing for selected operating system") D\
	X(LIBSYSCALLS_E_NOSIGNALS, "There is no signal listing for selected operating system") D\
	X(LIBSYSCALLS_E_NOMEM, "Failed to allocate required memory") D\
	X(LIBSYSCALLS_E_INVAL, "Invalid arguments passed to function") D\
	X(LIBSYSCALLS_E_NOSUCHTYPE, "Type does not exist on the selected operating system or architecture") D\
	X(LIBSYSCALLS_E_ISSTRUCT, "Type is a structure or union")

/**
 * libsyscall error numbers
 */
enum libsyscalls_error {
	LIBSYSCALLS_LIST_ERRORS(LIBSYSCALLS_LIST_ERRORS_X_, LIBSYSCALLS_COMMA_)
};

/**
 * Operating systems
 */
enum libsyscalls_os {
	LIBSYSCALLS_OS_LINUX
};

/**
 * Architectures
 */
enum libsyscalls_arch {
	LIBSYSCALLS_ARCH_ALPHA,
	LIBSYSCALLS_ARCH_AMD64,
	LIBSYSCALLS_ARCH_AMD64_X32, /* 32-bit ABI, not traditional 32-bit x86 ISA */
	LIBSYSCALLS_ARCH_ARM_OABI,
	LIBSYSCALLS_ARCH_ARM_EABI,
	LIBSYSCALLS_ARCH_IA64,
	LIBSYSCALLS_ARCH_M68K,
	LIBSYSCALLS_ARCH_MICROBLAZE,
	LIBSYSCALLS_ARCH_MIPS_O32,
	LIBSYSCALLS_ARCH_MIPS_N32,
	LIBSYSCALLS_ARCH_MIPS_N64,
	LIBSYSCALLS_ARCH_PARISC_32,
	LIBSYSCALLS_ARCH_PARISC_64,
	LIBSYSCALLS_ARCH_POWERPC_32,
	LIBSYSCALLS_ARCH_POWERPC_64,
	LIBSYSCALLS_ARCH_POWERPC_NOSPU,
	LIBSYSCALLS_ARCH_POWERPC_SPU,
	LIBSYSCALLS_ARCH_S390_32,
	LIBSYSCALLS_ARCH_S390_64,
	LIBSYSCALLS_ARCH_SH,
	LIBSYSCALLS_ARCH_SPARC_32,
	LIBSYSCALLS_ARCH_SPARC_64,
	LIBSYSCALLS_ARCH_I386,
	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 */
#define LIBSYSCALLS_TYPE_CHAR_ARRAY              LIBSYSCALLS_TYPE_BUFFER
#define LIBSYSCALLS_TYPE_CHAR_ARRAY_UNKNOWN_FILL LIBSYSCALLS_TYPE_BUFFER_UNKNOWN_FILL

	/* You can use these macros classify and convert data types */
#define LIBSYSCALLS_TYPEBITSMASK                0xF000
#define LIBSYSCALLS_TYPEBITS_SCALAR             0x0000 /* predefined total width, even if aggregate */
#define LIBSYSCALLS_TYPEBITS_ARRAY              0x1000 /* count is stored in next parameter, and is updated with fill
                                                        * or returned if no outputable to the next parameter */
#define LIBSYSCALLS_TYPEBITS_ARRAY_UNKNOWN_FILL 0x2000 /* count is stored in next parameter, fill is in no way returned,
                                                        * this chould either be because the array is always (unless an
                                                        * error is returned) entirely filled or because the end is
                                                        * infered from the contents (e.g. null byte termination) */

#define LIBSYSCALLS_LIST_SPECIAL_TYPES(X, SUFFIX, D, FIRST)\
	/* the type used in the system call has not yet be added recorded in the library */\
	X(LIBSYSCALLS_TYPE_UNKNOWN ## SUFFIX, FIRST, "(unknown type)") D\
	/* the type depends on the system call input or output */\
	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, 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)), 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)\
	X(LIBSYSCALLS_TYPE_UINT64_HIGH_32 ## SUFFIX, FIRST, "uint64_t {. << 32}") D\
	X(LIBSYSCALLS_TYPE_UINT64_LOW_32 ## SUFFIX,, "uint64_t {. & 0xFFFFFFFF}") D\
	X(LIBSYSCALLS_TYPE_UINT64_FRONT_32 ## SUFFIX,, "uint64_t {((uint32_t *)&.)[0]}") D\
	X(LIBSYSCALLS_TYPE_UINT64_BACK_32 ## SUFFIX,, "uint64_t {((uint32_t *)&.)[1]}") D\
	X(LIBSYSCALLS_TYPE_INT64_HIGH_32 ## SUFFIX,, "int64_t {. << 32}") D\
	X(LIBSYSCALLS_TYPE_INT64_LOW_32 ## SUFFIX,, "int64_t {. & 0xFFFFFFFF}") D\
	X(LIBSYSCALLS_TYPE_INT64_FRONT_32 ## SUFFIX,, "int64_t {((uint32_t *)&.)[0]}") D\
	X(LIBSYSCALLS_TYPE_INT64_BACK_32 ## SUFFIX,, "int64_t {((uint32_t *)&.)[1]}")

#define LIBSYSCALLS_LIST_COMPOSITE_PRIMITIVES(X, SUFFIX, D, FIRST)\
	X(LIBSYSCALLS_TYPE_STRING ## SUFFIX, FIRST, "const char *") D\
	X(LIBSYSCALLS_TYPE_STRINGS_THEN_NULL ## SUFFIX,, "const char **")

#define LIBSYSCALLS_LIST_UNANNOTATED_NUMERICALS(X, SUFFIX, D, FIRST)\
	X(LIBSYSCALLS_TYPE_MEMORY_ADDRESS ## SUFFIX, FIRST, "void *") D\
	X(LIBSYSCALLS_TYPE_CHAR ## SUFFIX,, "char") D\
	X(LIBSYSCALLS_TYPE_SCHAR ## SUFFIX,, "signed char") D\
	X(LIBSYSCALLS_TYPE_UCHAR ## SUFFIX,, "unsigned char") D\
	X(LIBSYSCALLS_TYPE_SHORT ## SUFFIX,, "short int") D\
	X(LIBSYSCALLS_TYPE_USHORT ## SUFFIX,, "unsigned short int") D\
	X(LIBSYSCALLS_TYPE_INT ## SUFFIX,, "int") D\
	X(LIBSYSCALLS_TYPE_UINT ## SUFFIX,, "unsigned int") D\
	X(LIBSYSCALLS_TYPE_LONG ## SUFFIX,, "long int") D\
	X(LIBSYSCALLS_TYPE_ULONG ## SUFFIX,, "unsigned long int") D\
	X(LIBSYSCALLS_TYPE_LLONG ## SUFFIX,, "long long int") D\
	X(LIBSYSCALLS_TYPE_ULLONG ## SUFFIX,, "unsigned long long int") D\
	X(LIBSYSCALLS_TYPE_SSIZE ## SUFFIX,, "ssize_t") D\
	X(LIBSYSCALLS_TYPE_SIZE ## SUFFIX,, "size_t") D\
	X(LIBSYSCALLS_TYPE_PTRDIFF ## SUFFIX,, "ptrdiff_t") D\
	X(LIBSYSCALLS_TYPE_UPTRDIFF ## SUFFIX,, "uptrdiff_t") D\
	X(LIBSYSCALLS_TYPE_INTPTR ## SUFFIX,, "intptr_t") D\
	X(LIBSYSCALLS_TYPE_UINTPTR ## SUFFIX,, "uintptr_t") D\
	X(LIBSYSCALLS_TYPE_INT8 ## SUFFIX,, "int8_t") D\
	X(LIBSYSCALLS_TYPE_UINT8 ## SUFFIX,, "uint8_t") D\
	X(LIBSYSCALLS_TYPE_INT16 ## SUFFIX,, "int16_t") D\
	X(LIBSYSCALLS_TYPE_UINT16 ## SUFFIX,, "uint16_t") D\
	X(LIBSYSCALLS_TYPE_INT32 ## SUFFIX,, "int32_t") D\
	X(LIBSYSCALLS_TYPE_UINT32 ## SUFFIX,, "uint32_t") D\
	X(LIBSYSCALLS_TYPE_INT64 ## SUFFIX,, "int64_t") D\
	X(LIBSYSCALLS_TYPE_UINT64 ## SUFFIX,, "uint64_t")

#define LIBSYSCALLS_LIST_ANNOTATED_NUMERICALS(X, SUFFIX, D, FIRST)\
	X(LIBSYSCALLS_TYPE_INT_SIGNAL ## SUFFIX, FIRST, "int") D /* OS signal */\
     	X(LIBSYSCALLS_TYPE_INT_FD ## SUFFIX,, "int") D /* file descriptor */ \
	X(LIBSYSCALLS_TYPE_INT_ATFD ## SUFFIX,, "int") D /* file descriptor or current working directory */ \
	X(LIBSYSCALLS_TYPE_LONG_FD ## SUFFIX,, "long int") D\
	X(LIBSYSCALLS_TYPE_LONG_ATFD ## SUFFIX,, "long int")

#define LIBSYSCALLS_LIST_STRUCTS_AND_UNIONS(X, SUFFIX, D, FIRST)\
	X(LIBSYSCALLS_TYPE_STRUCT_AIO_SIGSET ## SUFFIX, FIRST, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_CACHESTAT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_CACHESTAT_RANGE ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_CLONE_ARGS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_EPOLL_EVENT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_FILE_HANDLE ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_FUTEX_WAITV ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_IOB ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_IOVEC ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_IO_EVENT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_IO_URING_PARAMS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_ITIMERSPEC ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_KEXEC_SEGMENT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_LANDLOCK_RULESET_ATTR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_LINUX_DIRENT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_LINUX_DIRENT64 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MMAP_ARG_STRUCT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MMSGHDR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MOUNT_ATTR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MQ_ATTR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MSGBUF ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MSGHDR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_MSQID_DS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_NEW_UTSNAME ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLDOLD_UTSNAME ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_ITIMERSPEC32 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_ITIMERVAL ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_LINUX_DIRENT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_SIGACTION ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_STAT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_TIMESPEC32 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_TIMEVAL ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_TIMEVAL32 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_TIMEX32 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_UTIMBUF32 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OLD_UTSNAME ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_OPEN_HOW ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_PERF_EVENT_ATTR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_POLLFD ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_RLIMIT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_RLIMIT64 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_ROBUST_LIST_HEAD ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_RSEQ ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_RUSAGE ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SCHED_ATTR ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SCHED_PARAM ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SEL_ARG_STRUCT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SEMBUF ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SEMID_DS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SHMID_DS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SIGACTION ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SIGALTSTACK ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SIGEVENT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SIGINFO ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SOCKADDR ## SUFFIX,, "struct") D /* size is always in the next argument */\
	X(LIBSYSCALLS_TYPE_STRUCT_STAT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_STAT64 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_STATFS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_STATFS64 ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_STATX ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_SYSINFO ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_TIMESPEC ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_TIMEX ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_TIMEZONE ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_TMS ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_USTAT ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_STRUCT_UTIMBUF ## SUFFIX,, "struct") D\
	X(LIBSYSCALLS_TYPE_UNION_BPF_ATTR ## SUFFIX,, "union")

#define LIBSYSCALLS_LIST_FIXED_ARRAYS(X, SUFFIX, D, FIRST)\
	X(LIBSYSCALLS_TYPE_2_INTS ## SUFFIX, FIRST, "int[2]") D\
	X(LIBSYSCALLS_TYPE_2_INTS_FD ## SUFFIX,, "int[2]") D\
	X(LIBSYSCALLS_TYPE_2_UINT32S ## SUFFIX,, "uint32[2]") D\
	X(LIBSYSCALLS_TYPE_FD_SET ## SUFFIX,, "unsigned long[]") /* size depends on OS, (1024 / CHAR_BIT / sizeof(long)) in Linux */

	/* these don't have any suffix */
	LIBSYSCALLS_MAKE_SPECIAL_TYPES_(),
	LIBSYSCALLS_MAKE_SPLIT_PRIMITIVES_(),
	LIBSYSCALLS_MAKE_COMPOSITE_PRIMITIVES_(),
	LIBSYSCALLS_MAKE_UNANNOTATED_NUMERICALS_(),
	LIBSYSCALLS_MAKE_ANNOTATED_NUMERICALS_(),
	LIBSYSCALLS_MAKE_STRUCTS_AND_UNIONS_(),

	/* the following are always pointers unless returned */

	/* size in next parameter (or the previous parameter if there is no next parameter),
	 * updated with fill if possible, otherwise returned (these use the suffix _ARRAY) */
	LIBSYSCALLS_MAKE_UNANNOTATED_NUMERICALS_(_ARRAY),
	LIBSYSCALLS_MAKE_ANNOTATED_NUMERICALS_(_ARRAY),
	LIBSYSCALLS_MAKE_STRUCTS_AND_UNIONS_(_ARRAY),

	/* size in next parameter (or the previous parameter if there is no next parameter),
	 * fill is in no way returned (these use the suffix _ARRAY_UNKNOWN_FILL) */
	LIBSYSCALLS_MAKE_UNANNOTATED_NUMERICALS_(_ARRAY_UNKNOWN_FILL),
	LIBSYSCALLS_MAKE_ANNOTATED_NUMERICALS_(_ARRAY_UNKNOWN_FILL),
	LIBSYSCALLS_MAKE_STRUCTS_AND_UNIONS_(_ARRAY_UNKNOWN_FILL),

	/* these don't have any suffix */
	LIBSYSCALLS_MAKE_FIXED_ARRAYS_()

#undef LIBSYSCALLS_TYPE_CHAR_ARRAY
#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,  /**< 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 */
};

/**
 * 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,

	/**
	 * 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
};

/**
 * 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,

	/**
	 * 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,

	/**
	 * 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
};

/**
 * 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,

	/**
	 * 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,

	/**
	 * 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,

	/**
	 * 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,

	/**
	 * 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,

	/**
	 * 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,

	/**
	 * 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,

	/**
	 * 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
};

/**
 * 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,

	/**
	 * 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,

	/**
	 * 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 {
	/**
	 * 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; /**< 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 */
};

/**
 * System call interface
 */
struct libsyscalls_syscall_abi {
	/**
	 * Classification of what the system call does
	 * 
	 * Check `.category` to se which group of
	 * classifications to used
	 */
	union libsyscalls_syscall_subcategory subcategory;

	/**
	 * Broad classification of what the system calls does
	 */
	enum_libsyscalls_syscall_category category : 16;

	/**
	 * For set any bit indexed I (starting from 0), the
	 * system call parameter I is a pointer that the
	 * system call 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
	 */
	unsigned short int in_pointer_mask : 16;

	/**
	 * For set any bit indexed I (starting from 0), the
	 * system call parameter I is a pointer that the
	 * system call write 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 out_pointer_mask : 16;

	/**
	 * For set any bit indexed I (starting from 0), the
	 * system call parameter I can be resolved into a
	 * symbolic string by the library
	 */
	unsigned short int symbolic_mask : 16;

	/**
	 * The minimum number of arguments that must be
	 * passed into the system call, -1 if unknown
	 */
	short int min_argument_count : 6;

	/**
	 * The maximum number of arguments that can be
	 * passed into the system call, -1 if unknown
	 */
	short int max_argument_count : 6;

	/**
	 * If set, the library can resolve the value the
	 * system call returns into a symbolic string
	 */
	unsigned short int symbolic_return : 1;

	/**
	 * If 1, the system call shall always either return
	 * an error, return the value 0, or not return at all
	 */
	unsigned short int expect_zero : 1;

	/**
	 * If 1, the system call invocation must be parsed
	 * especially as it is not does follow what is
	 * proscribed for the used data types
	 *
	 * The library may use this temporarily until it
	 * in a later version provides a convension that
	 * can be followed
	 */
	unsigned short int queer : 1;

	short int : LIBSYSCALLS_PAD_(sizeof(short int)/sizeof(char)*CHAR_BIT, 4*16 + 2*6 + 3*1);

	/**
	 * 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
	 * the architecture), and occasionally to determine what types
	 * are used for on arguments whose type is argument dependent,
	 * and to figure which optional arguments are included in the
	 * system call
	 * 
	 * 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
	 */
	LIBSYSCALLS_SYMBOL_PRINTER symbol_printer : 16;

	/**
	 * The system call's return type
	 */
	enum_libsyscalls_datatype return_type : 16;

	/**
	 * The type of each of the systems call's parameter
	 * 
	 * The application must not read `.parameters_types[.max_argument_count]`
	 * or beyond, doing so will probably mean reading beyond the memory
	 * allocated for the instance of the structure
	 */
	enum_libsyscalls_datatype parameters_types[LIBSYSCALLS_FLEXABLE_OR_NPARAMS_];
};

/**
 * System call description
 */
struct libsyscalls_syscall {
	/**
	 * What system call is named
	 */
	const char *name;

	/**
	 * The ABI for the system call for architecture it was
	 * queried for
	 * 
	 * May or may not be `NULL` if the system call is defined
	 * but not implemented
	 */
	struct libsyscalls_syscall_abi *actual_syscall;

	/**
	 * Like .actual_syscall except this is used for example when
	 * a 32-bit process is running on a 64-bit operating system
	 *
	 * If `NULL` use .actual_syscall
	 */
	struct libsyscalls_syscall_abi *actual_compat_syscall;
};

/**
 * Named number (errors and signals)
 */
struct libsyscalls_named_number {
	/**
	 * The value if the number, it is up to the
	 * application select signess
	 *
	 * It is usually safe to use unsigned (.u)
	 * as the numbers are usually positive but
	 * not so large that the sign bit would be
	 * set, unless the numbers are supposted to
	 * be unsigned
	 */
	union {
		signed long long int s;
		unsigned long long int u;
	} number;

	/**
	 * The name of the number, including namespacing
	 * (e.g. "E" prefix for errno numbers and "SIG"
	 * or "_SIG" prefix for singals)
	 */
	const char *name;
};

/**
 * Function that returns a name for a value
 * 
 * This function is called multiple times to extract
 * names of multiple subvalues, for example, for
 * the system call access() second parameter, it
 * will return the string "X_OK", "W_OK", "R_OK",
 * and "F_OK", or a subset thereof; one per invocation
 * 
 * The proper way to use this function, is:
 * 
 *     static void
 *     print_unsigned(libsyscalls_symbol_printer_function *function,
 *                    LIBSYSCALLS_SYMBOL_PRINTER_DATA *data,
 *                    unsigned long long int value, FILE *output)
 *     {
 *             const char *sym, *prefix = "";
 *             char format[] = "%s%llu";
 *             char *fallback = strchr(format, '\0') - 1;
 *             do {
 *                     sym = (*function)(data, &value, &fallback);
 *                     if (!sym)
 *                             break;
 *                     fprintf(output, "%s%s", prefix, sym);
 *                     prefix = "|";
 *             } while (value);
 *             if (value || !*prefix)
 *                     fprintf(output, format, prefix, value);
 *     }
 * 
 * @param  data          Data passed to the function (which that function
 *                       has been paired with for the paramter/return),
 *                       which it may require to known exactly what to do
 * @param  valuep        The caller set a variable to the value pass in to
 *                       the system call parameter (or the system call's
 *                       return value), the value if any extract symbol
 *                       will removed from from the variable. If the function
 *                       return NULL, this value can be 0, in which case all
 *                       values have been extract, otherwise (which it is not
 *                       0) there is some value (either invalid or not known
 *                       to the library) that shall must be printed manually
 *                       by the application (see `fallback_out` parameter).
 *                       Note that, if the value 0 has a name, this function
 *                       never return NULL if the variable reaches 0, instead
 *                       it will repeated return the name of that value.
 * @param  fallback_out  The caller set a variable to 0 and pointer to it,
 *                       when this function return NULL, the variable MAY
 *                       (even before that) have been set to 'x', 'o', or
 *                       'd', indicating a suggestion how any value left
 *                       over in `*valuep` shall be displayed: 'x' for in
 *                       hexadecimal, 'o' for octal, and 'd' for decimal
 *                       (signness depends on the system call parameter's
 *                       type's (or as the case may be, the system call's
 *                       return type) signness).
 * @return               The name of some value in `*valuep`, or `NULL` if
 *                       none was found. The returned string may be stored
 *                       in `data` and those override at the next call.
 */
typedef const char *libsyscalls_symbol_printer_function(LIBSYSCALLS_SYMBOL_PRINTER_DATA *, unsigned long long int *, char *);

/**
 * Information about a system call parameter or return value
 */
struct libsyscalls_syscall_type_info {
	/**
	 * Function for extracting names values from a variable
	 */
	libsyscalls_symbol_printer_function *function;

	/**
	 * First argument to pass to `.function`
	 */
	LIBSYSCALLS_SYMBOL_PRINTER_DATA *data;

	/**
	 * The data type used for the parameter or return value
	 * in the specific invocation of the system call
	 *
	 * If set to LIBSYSCALLS_TYPE_VOID for an optional
	 * parameter, that parameter was not used
	 */
	enum_libsyscalls_datatype type;

	char padding__[LIBSYSCALLS_PAD_(sizeof(void *)/sizeof(char), sizeof(enum_libsyscalls_datatype)/sizeof(char) + 1)];
	unsigned char : CHAR_BIT - 1;

	/**
	 * Only used for the return value
	 * 
	 * Same as `.expect_zero` in `struct libsyscalls_syscall_abi`,
	 * however if 0 in `struct libsyscalls_syscall_abi`, it can
	 * still be 1 here if if it is determined that for the specificly
	 * used system call arguments, the system call shall always
	 * return 0 (or not return) or an error
	 */
	unsigned char expect_zero : 1;
};

/**
 * System call information tweak for the arguments passed
 * to the system call, as well as information about how
 * to print named values in the arguments and return
 */
struct libsyscalls_syscall_display_info {
	/**
	 * The size of this structure, this can be used
	 * by the application to test what is available
	 * in the case it may have compiled against a
	 * newer version than used in the version of the
	 * library the application is linked with
	 * 
	 * Data is stored beyond this, do not try to make
	 * a copy; that will not go well
	 */
	size_t size;

	/**
	 * Information about each system call parameter
	 *
	 * All positive integer within [0, .max_argument_count]
	 * for the `struct libsyscalls_syscall_abi` are valid,
	 * but no index beyond `.max_argument_count` is valid
	 */
	struct libsyscalls_syscall_type_info *params;

	/**
	 * Information about the system call's return value
	 */
	struct libsyscalls_syscall_type_info *retvalue;
};

/**
 * Signed number representation
 */
enum libsyscalls_datatype_sign_representation {
	/**
	 * The data type was LIBSYSCALLS_TYPE_UNKNOWN or
	 * LIBSYSCALLS_TYPE_DYNAMIC
	 */
	LIBSYSCALLS_SIGN_UNDETERMINED,

	/**
	 * Two's complement
	 * 
	 * -x is ~x + 1, -0 is +0
	 */
	LIBSYSCALLS_SIGN_TWOS_COMPLEMENT,

	/**
	 * One's cmplement
	 * 
	 * -x is ~x, -0 is not +0
	 */
	LIBSYSCALLS_SIGN_ONES_COMPLEMENT,

	/**
	 * Sign–magnitude
	 * 
	 * -x is (x | most significant bit), -0 is not +0
	 */
	LIBSYSCALLS_SIGN_SIGN_MAGNITUDE,

	/**
	 * Excess-K, with K being (unsigned maximum + 1)/2
	 * 
	 * 0 is represented with just the most significant bit set,
	 * any offset from 0 is added to this value, i.e., x is
	 * represented by ((unsigned maximum + 1)/2 + x); -0 is +0
	 */
	LIBSYSCALLS_SIGN_EXCESS_HALF
};

/**
 * Data type usage annotation
 */
enum libsyscalls_datatype_annotation {
	/**
	 * The data type was LIBSYSCALLS_TYPE_UNKNOWN or
	 * LIBSYSCALLS_TYPE_DYNAMIC
	 */
	LIBSYSCALLS_ANNOTATION_UNDETERMINED,

	/**
	 * The value does not have usage annotation
	 */
	LIBSYSCALLS_ANNOTATION_NONE,

	/**
	 * The value represents an operating system signal (e.g. SIGKILL)
	 * 
	 * This affords the application the opportunity to print
	 * more detail information about a signal (such as when
	 * it is used, whether it is a realtime signal, default
	 * action, whether it can be caught, and what its normal
	 * usage is)
	 */
	LIBSYSCALLS_ANNOTATION_SIGNAL,

	/**
	 * The value represents a file descriptor
	 * 
	 * This affords the application the opportunity to print
	 * file information (such as file name, address, file type,
	 * and offset)
	 */
	LIBSYSCALLS_ANNOTATION_FD,

	/**
	 * The value represents a file descriptor or a special value
	 * for a known file such as AT_FDCWD
	 * 
	 * This affords the application the opportunity to print
	 * file information (such as file name, address, file type,
	 * and offset)
	 */
	LIBSYSCALLS_ANNOTATION_ATFD
};

/**
 * Register-split/struct field-split information for a data type
 */
enum libsyscalls_datatype_section {
	/**
	 * The data type was LIBSYSCALLS_TYPE_UNKNOWN or
	 * LIBSYSCALLS_TYPE_DYNAMIC
	 */
	LIBSYSCALLS_SECTION_UNDETERMINED,

	/**
	 * The whole value is represented
	 * 
	 * The value is contained within a single parameter
	 */
	LIBSYSCALLS_SECTION_WHOLE,

	/*
	 * This whether a data type represents a half section
	 * of larger data type
	 * 
	 * @param   S:enum libsyscalls_datatype_section  The data type section information
	 * @return  :int                                 Whether the larger that type was split into two halves
	 */
#define LIBSYSCALLS_IS_SECTION_HALF(S)\
	(((S) >= LIBSYSCALLS_SECTION_UPPER_HALF) &&\
	 ((S) <= LIBSYSCALLS_SECTION_ODD_BYTES_AS_HALF))

	/**
	 * The most significant half of the value is represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0xFFFFFFFF00000000 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_LOWER_HALF)
	 */
	LIBSYSCALLS_SECTION_UPPER_HALF,

	/**
	 * The least significant half of the value is represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0x00000000FFFFFFFF if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_UPPER_HALF)
	 */
	LIBSYSCALLS_SECTION_LOWER_HALF,

	/**
	 * The second most and second least significant quarters
	 * of the value represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0x0000FFFFFFFF0000 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_OUTER_HALF)
	 */
	LIBSYSCALLS_SECTION_INNER_HALF,

	/**
	 * The most and least significant quarters of the value
	 * represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0xFFFF00000000FFFF if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_INNER_HALF)
	 */
	LIBSYSCALLS_SECTION_OUTER_HALF,

	/**
	 * The second most and least significant quarters of the
	 * value represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0x0000FFFF0000FFFF if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_ODD_QUARTERS_AS_HALF)
	 */
	LIBSYSCALLS_SECTION_EVEN_QUARTERS_AS_HALF,

	/**
	 * The most and second least significant quarters of the
	 * value represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0xFFFF0000FFFF0000 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_EVEN_QUARTERS_AS_HALF)
	 */
	LIBSYSCALLS_SECTION_ODD_QUARTERS_AS_HALF,

	/**
	 * The bytes that would be indexed (starting from 0) with
	 * an even number in big endian (how humans write numbers)
	 * are represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0x00FF00FF00FF00FF if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_EVEN_BYTES_AS_HALF)
	 */
	LIBSYSCALLS_SECTION_EVEN_BYTES_AS_HALF,

	/**
	 * The bytes that would be indexed (starting from 0) with
	 * an odd number in big endian (how humans write numbers)
	 * are represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 32-bits —
	 * 0xFF00FF00FF00FF00 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with another neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_ODD_BYTES_AS_HALF)
	 */
	LIBSYSCALLS_SECTION_ODD_BYTES_AS_HALF,

	/*
	 * This whether a data type represents a quarter section
	 * of larger data type
	 * 
	 * @param   S:enum libsyscalls_datatype_section  The data type section information
	 * @return  :int                                 Whether the larger that type was split into four quarters
	 */
#define LIBSYSCALLS_IS_SECTION_QUARTER(S)\
	(((S) >= LIBSYSCALLS_SECTION_UPPER_QUARTER) &&\
	 ((S) <= LIBSYSCALLS_SECTION_LOWER_QUARTER))

	/**
	 * The most significant quarter of the value is represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 16-bits —
	 * 0xFFFF000000000000 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with three neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_UPPER_MID_QUARTER,
	 * a LIBSYSCALLS_SECTION_LOWER_MID_QUARTER, and
	 * a LIBSYSCALLS_SECTION_LOWER_QUARTER)
	 */
	LIBSYSCALLS_SECTION_UPPER_QUARTER,

	/**
	 * The second most significant quarter of the value is represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 16-bits —
	 * 0x0000FFFF00000000 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with three neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_UPPER_QUARTER,
	 * a LIBSYSCALLS_SECTION_LOWER_MID_QUARTER, and
	 * a LIBSYSCALLS_SECTION_LOWER_QUARTER)
	 */
	LIBSYSCALLS_SECTION_UPPER_MID_QUARTER,

	/**
	 * The least most significant quarter of the value is represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 16-bits —
	 * 0x00000000FFFF0000 if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with three neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_UPPER_QUARTER,
	 * a LIBSYSCALLS_SECTION_UPPER_MID_QUARTER, and
	 * a LIBSYSCALLS_SECTION_LOWER_QUARTER)
	 */
	LIBSYSCALLS_SECTION_LOWER_MID_QUARTER,

	/**
	 * The least significant quarter of the value is represented
	 * 
	 * Example: if the data type is 64-bits, the value stored
	 * in parameter whose type was queried is just 16-bits —
	 * 0x000000000000FFFF if the whole value is 0xFFFFFFFFFFFFFFFF,
	 * — and most combined with three neighbouring parameter
	 * (a LIBSYSCALLS_SECTION_UPPER_QUARTER,
	 * a LIBSYSCALLS_SECTION_UPPER_MID_QUARTER, and
	 * a LIBSYSCALLS_SECTION_LOWER_MID_QUARTER)
	 */
	LIBSYSCALLS_SECTION_LOWER_QUARTER

	/*
	 * 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/fields the data type was split into;
	 *                                               invalid if `S` is LIBSYSCALLS_SECTION_UNDETERMINED
	 */
#define LIBSYSCALLS_GET_SECTION_FRACTION(S)\
	(LIBSYSCALLS_IS_SECTION_HALF(S) ? 2U :\
	 LIBSYSCALLS_IS_SECTION_QUARTER(S) ? 4U : 1U)
};

/**
 * Information on how an instance of data type is to be parsed
 * 
 * Data types are usually either signed or unsigned, but there
 * are a few exceptions: LIBSYSCALLS_TYPE_UNKNOWN and
 * LIBSYSCALLS_TYPE_DYNAMIC are described as both signed and
 * unsigned as their signness is unknown and could be either,
 * or neither, which brings us to the next exception: some
 * data types are neither signed nor unsigned; these are types
 * that are not numerical, i.e. non-values (LIBSYSCALLS_TYPE_NO_RETURN
 * and LIBSYSCALLS_TYPE_VOID), memory addresses
 * (LIBSYSCALLS_TYPE_MEMORY_ADDRESS) and textual types
 * (LIBSYSCALLS_TYPE_CHAR, LIBSYSCALLS_TYPE_STRING, and
 * LIBSYSCALLS_TYPE_STRINGS_THEN_NULL), as well as arrays of
 * such types (including LIBSYSCALLS_TYPE_BUFFER and
 * LIBSYSCALLS_TYPE_BUFFER_UNKNOWN_FILL), and finally bitset
 * arrays (currently only LIBSYSCALLS_TYPE_FD_SET)
 */
struct libsyscalls_datatype_description {
	/**
	 * The number of bits used for the represented section
	 * of the data type
	 * 
	 * 0 for LIBSYSCALLS_TYPE_NO_RETURN and LIBSYSCALLS_TYPE_VOID
	 * 
	 * if .section is LIBSYSCALLS_SECTION_WHOLE, this is the
	 * 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 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/field
	 */
	unsigned array_size;

	/**
	 * Only used if .array_size is 0
	 * 
	 * 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
	 */
	signed relative_position_of_array_size : 5;

	/**
	 * Only used if .array_size is 0
	 * 
	 * 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
	 */
	signed absolute_position_of_array_size : 5;

	/**
	 * 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 fill_is_known : 1;

	/**
	 * Whether the data type is signed
	 */
	unsigned is_signed : 1;

	/**
	 * Whether the data type is unsigned
	 */
	unsigned is_unsigned : 1;

	/**
	 * Only used if .is_signed is 1 and .sign_representation
	 * is not LIBSYSCALLS_SIGN_UNDETERMINED
	 * 
	 * This value can be inferred from .sign_representation;
	 * its 1 if the data type's minimum value is the negative
	 * of its maximum value (which also means that -0 and +0
	 * are distinct), and 0 otherwise, which means that the
	 * minimum value is the negative of (the minimum value + 1)
	 * (it also means that -0 and +0 are the identical)
	 */
	unsigned min_is_minus_max : 1;

	int padding__ : LIBSYSCALLS_PAD_(sizeof(int)/sizeof(char)*CHAR_BIT, 2*5 + 4*1);

	/**
	 * Only used if .is_signed is 1
	 *
	 * How signed numbers are represented
	 */
	enum libsyscalls_datatype_sign_representation sign_representation : 8;

	/**
	 * Additional information about what the value represents
	 */
	enum libsyscalls_datatype_annotation annotation : 8;

	/**
	 * What part of the value is stored in the instance
	 */
	enum libsyscalls_datatype_section section : 16;

	/**
	 * This is a ~0 terminated array — but, it can also
	 * be terminated by the end of the array — describing
	 * the order of the bytes the the data type
	 *
	 * The lowest non-zero values contains the width of
	 * a byte (in bytes), however no such value exists
	 * in this array if the data type is just one byte
	 * (or none)
	 * 
	 * For each unsigned byte in the data type, indexed
	 * I from 0, it shall be shifted left .byteorder[i]
	 * bits; the bitwise OR of the results is the
	 * unsigned value used in the instance of the data type
	 *
	 * 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
	 * aware that both the type and length can change in
	 * the future: do not assume it's `unsigned char`,
	 * and do not assume it has 32 elements, do not only
	 * `LIBSYSCALLS_IS_BYTEORDER_END` to detect ~0, but
	 * also check that no more than
	 * `sizeof(x.byteorder) / sizeof(*x.byteorder)`
	 * elements are read (where x is the instance of the
	 * structure) (you should definitely have your own
	 * macro for that one)
	 */
	unsigned char byteorder[32];

	/**
	 * Test whether a value in `struct libsyscalls_datatype_description.byteorder`
	 * marks the end of the byteorder's shift value (testing
	 * that the value is ~0). Using this macro helps avoiding
	 * bugs caused by integer type promotion.
	 * 
	 * @param   SHIFT  The value to test `struct libsyscalls_datatype_description.byteorder`
	 * @return  :int   Whether the value is ~0
	 */
#ifdef UINTMAX_C
# define LIBSYSCALLS_IS_BYTEORDER_END(SHIFT)\
	(!~((SHIFT) | ~LIBSYSCALLS_FIELD_MASK_(UINTMAX_C(1), struct libsyscalls_datatype_description, byteorder[0])))
#else
# define LIBSYSCALLS_IS_BYTEORDER_END(SHIFT)\
	(!~((SHIFT) | ~LIBSYSCALLS_FIELD_MASK_(1ULL, struct libsyscalls_datatype_description, byteorder[0])))
#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
 * 
 * @param   error  The libsyscalls error
 * @return         Description of the error, the first character will be in uppercase
 */
LIBSYSCALLS_GCC_ATTRIBUTES_(__const__, __returns_nonnull__, __warn_unused_result__)
const char *
libsyscalls_strerror(enum libsyscalls_error);

/**
 * Print a line with a description of a
 * libsyscalls error to standard error
 * 
 * @param   prefix  Unless NULL or the empty string, the description
 *                  will be prefixed with this string followed by ": "
 * @param   error   The libsyscalls error
 */
void
libsyscalls_perror(const char *, enum libsyscalls_error);

/**
 * Get the valid range system call numbers
 * 
 * @param   os       The operating system the range shall valid for
 * @param   arch     The architecture the range shall valid for
 * @param   min_out  Output parameter for the lowest used system call number (may be NULL)
 * @param   max_out  Output parameter for the highest used system call number (may be NULL)
 * @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`)
 * 
 * This function always fails if the selected combination
 * of operating system (`os`) and architecture (`arch`) is
 * unsupported
 * 
 * Beware that range is used system call numbers are [*min_out, *max_out]
 * (not [*min_out, *max_out - 1]) but there may still be numbers within
 * this range that does not correspond to a system call
 */
LIBSYSCALLS_GCC_ATTRIBUTES_(__warn_unused_result__)
enum libsyscalls_error
libsyscalls_get_syscall_range(enum libsyscalls_os, enum libsyscalls_arch, long long int *, long long int *);

/**
 * Get the description of a system call
 * 
 * @param   os           The operating system the range shall valid for
 * @param   arch         The architecture the range shall valid for
 * @param   syscallnr    The system call's number
 * @param   syscall_out  Output parameter for the system call description
 *                       (the argument may be NULL, *syscall_out will
 *                       never be set to NULL)
 * @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_NOSUCHSYSCALL - `syscallnr` does not correspond to a known
 *                                                     system call for the selected architecture (`arch`)
 *                                                     on the selected operating system (`os`)
 * 
 * This function always fails if the selected combination
 * of operating system (`os`) and architecture (`arch`) is
 * unsupported
 */
LIBSYSCALLS_GCC_ATTRIBUTES_(__warn_unused_result__)
enum libsyscalls_error
libsyscalls_get_syscall(enum libsyscalls_os, enum libsyscalls_arch, long long int, const struct libsyscalls_syscall **);

/**
 * Get the system call errors defined by an operating system
 * 
 * If an error has multiple names, it is only listed once
 * and the listed name is arbitrary
 * 
 * The returned listing will be sorted by the error numbers
 * in ascending order
 * 
 * @param   os              The operating system whose errors shall be returned
 * @param   arch            The architecture the error numbers shall be valid for
 * @param   errors_out      Output parameter for the error list (may be NULL, never filled with NULL)
 * @param   num_errors_out  Output parameter for the number of errors returned in `*errors_out` (may be NULL)
 *                          (if `errors_out` is NULL, the number that would be returned is stored)
 * @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_NOERRORS  - The operating system does not use named error numbers
 *
 * This function will always fail if the operating system (`os`)
 * is not supported, however it may be successful even if the
 * architecture (`arch`) not supported
 */
enum libsyscalls_error
libsyscalls_get_syscall_errors(enum libsyscalls_os, enum libsyscalls_arch, const struct libsyscalls_named_number **, size_t *);

/**
 * Get the system signals defined by an operating system
 * 
 * If a signal has multiple names, it is only listed once
 * and the listed name is arbitrary
 * 
 * The returned listing will be sorted by the signal
 * numbers in ascending order
 * 
 * @param   os               The operating system whose errors shall be returned
 * @param   arch             The architecture the error numbers shall be valid for
 * @param   signals_out      Output parameter for the signal list (may be NULL, never filled with NULL)
 * @param   num_signals_out  Output parameter for the number of signals returned in `*signals_out` (may be NULL)
 *                           (if `signals_out` is NULL, the number that would be returned is stored)
 * @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_NOSIGNALS  - The operating system does not use named signal numbers
 *
 * This function will always fail if the operating system (`os`)
 * is not supported, however it may be successful even if the
 * architecture (`arch`) not supported
 */
enum libsyscalls_error
libsyscalls_get_signals(enum libsyscalls_os, enum libsyscalls_arch, const struct libsyscalls_named_number **, size_t *);

/**
 * Get system call information tweak for the arguments passed
 * to the system call, as well as information about how to
 * print named values in the arguments and return
 * 
 * @param   os                 The operating system the system call was invoked on
 * @param   arch               The architecture the system call was invoked on
 * @param   syscall            The ABI of the system call (see libsyscalls_get_syscall)
 * @param   syscall_number     The system call's number
 * @param   syscall_arguments  The values store in register (as upon system call entry)
 *                             the used for the system call, in the order the registers
 *                             are used as system call arguments
 * @param   info_out           Output parameter for the additional system call information
 * @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_NOMEM      - Failed to allocate memory for `*info_out`
 *                             LIBSYSCALLS_E_INVAL      - One of the arguments was NULL
 */
LIBSYSCALLS_GCC_ATTRIBUTES_(__warn_unused_result__, __nonnull__)
enum libsyscalls_error
libsyscalls_get_syscall_display_info(enum libsyscalls_os, enum libsyscalls_arch, const struct libsyscalls_syscall_abi *,
                                     long long int, unsigned long long int *, struct libsyscalls_syscall_display_info **);

/**
 * Get information on how an instance of data type is to be parsed
 * 
 * @param   os               The operating system the data type is used on
 * @param   arch             The architecture the data type is used on
 * @param   datatype         The datatype, `LIBSYSCALLS_TYPE_DYNAMIC` can
 *                           be used to get the size of the registers used
 *                           as system call parameters
 * @param   description_out  Output parameter for the type description
 * @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      - `datatype` is not a valid data type
 *                           LIBSYSCALLS_E_NOSUCHTYPE - `datatype` does not exist on the selected
 *                                                      operating system (`os`) or architecture (`arch`)
 *                           LIBSYSCALLS_E_ISSTRUCT   - `datatype` represents a structure
 * 
 * The function may complete successfully for some data
 * types even if it for other data types would return
 * LIBSYSCALLS_E_OSNOSUP or LIBSYSCALLS_E_ARCHNOSUP
 */
LIBSYSCALLS_GCC_ATTRIBUTES_(__warn_unused_result__)
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