diff --git a/.github/workflows/abi-check.yml b/.github/workflows/abi-check.yml index 1c5c1f8b53..11db22ec4e 100644 --- a/.github/workflows/abi-check.yml +++ b/.github/workflows/abi-check.yml @@ -136,6 +136,6 @@ jobs: $extra_args \ ./glibc/usr/*-linux-gnu/include/ \ ./packages/mlibc-headers-only/usr/include/ \ - -Mmfs >> $GITHUB_STEP_SUMMARY 2>&1 + -Mmfst >> $GITHUB_STEP_SUMMARY 2>&1 echo '```' >> $GITHUB_STEP_SUMMARY working-directory: build/ diff --git a/ABI_BREAKS.md b/ABI_BREAKS.md index 0dd2a6388e..e3f6b369c1 100644 --- a/ABI_BREAKS.md +++ b/ABI_BREAKS.md @@ -2,7 +2,17 @@ This document lists the ABI breaks that were made in each mlibc major version. -## Version 5, 6 +## Version 6 + +Numerous ABI breaks. These were not properly logged, and are therefore missing here. Pending update, if one ever comes. + +- [#1458](https://github.com/managarm/mlibc/pull/1458): mlibc only defined `fenv_t` for x86(_64) before, new we define it correctly for all supported architectures. +- [#1458](https://github.com/managarm/mlibc/pull/1458): due to incorrect macro usage, `LONG_BIT` was previously always defined to 64, even on 32-bit architectures. Now, it is set to 32 on 32-bit architectures. +- [#1458](https://github.com/managarm/mlibc/pull/1458): `PRI*FAST*` macros had values that caused `-Wformat` warnings on 32-bit architectures, which got fixed. +- [#1458](https://github.com/managarm/mlibc/pull/1458): `ND_NA_FLAG_*` macros were incorrectly not byte-swapped on big-endian architectures. +- [#1458](https://github.com/managarm/mlibc/pull/1458): some members of `struct link_map` were always using `Elf64_Addr` instead of the correct `ElfW(Addr)` type. + +## Version 5 Numerous ABI breaks. These were not properly logged, and are therefore missing here. Pending update, if one ever comes. diff --git a/options/ansi/include/bits/ansi/fenv.h b/options/ansi/include/bits/ansi/fenv.h index 326f8c0f1e..1eb6c9bb43 100644 --- a/options/ansi/include/bits/ansi/fenv.h +++ b/options/ansi/include/bits/ansi/fenv.h @@ -1,6 +1,10 @@ #ifndef MLIBC_FENV_H #define MLIBC_FENV_H +#if !defined(__ASSEMBLER__) +#include +#endif /* !defined(__ASSEMBLER__) */ + #if defined(__x86_64__) || defined(__i386__) #define FE_DENORMAL 2 @@ -17,6 +21,17 @@ #define FE_UPWARD 0x800 #define FE_TOWARDZERO 0xC00 +typedef __mlibc_uint16 fexcept_t; + +typedef struct { + __mlibc_uint32 __control_word; + __mlibc_uint32 __status_word; + __mlibc_uint32 __unused[5]; +#if defined(__x86_64__) + __mlibc_uint32 __mxcsr; +#endif +} fenv_t; + #elif defined(__aarch64__) #define FE_INVALID 1 @@ -32,6 +47,13 @@ #define FE_DOWNWARD 0x800000 #define FE_TOWARDZERO 0xC00000 +typedef unsigned int fexcept_t; + +typedef struct { + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; + #elif defined(__riscv) && __riscv_xlen == 64 #define FE_INEXACT 1 @@ -47,6 +69,9 @@ #define FE_DOWNWARD 2 #define FE_UPWARD 3 +typedef unsigned int fexcept_t; +typedef unsigned int fenv_t; + #elif defined (__m68k__) #if __HAVE_68881__ || __mcffpu__ || __HAVE_FPU_ @@ -71,6 +96,14 @@ #endif +#if !defined(__ASSEMBLER__) +typedef unsigned int fexcept_t; + +typedef struct { + fexcept_t __excepts; +} fenv_t; +#endif /* !defined(__ASSEMBLER__) */ + #elif defined(__loongarch64) #define FE_INEXACT 0x010000 @@ -86,6 +119,12 @@ #define FE_UPWARD 0x200 #define FE_DOWNWARD 0x300 +typedef unsigned int fexcept_t; + +typedef struct { + unsigned int __fp_control_register; +} fenv_t; + #else #error Unknown architecture #endif diff --git a/options/ansi/include/fenv.h b/options/ansi/include/fenv.h index 7366706fa9..7c7da09cb6 100644 --- a/options/ansi/include/fenv.h +++ b/options/ansi/include/fenv.h @@ -2,22 +2,12 @@ #ifndef _FENV_H #define _FENV_H -#include #include #ifdef __cplusplus extern "C" { #endif -typedef struct { - __mlibc_uint32 __control_word; - __mlibc_uint32 __status_word; - __mlibc_uint32 __unused[5]; - __mlibc_uint32 __mxcsr; -} fenv_t; - -typedef __mlibc_uint16 fexcept_t; - #ifndef __MLIBC_ABI_ONLY int feclearexcept(int __excepts); diff --git a/options/ansi/include/inttypes.h b/options/ansi/include/inttypes.h index 5eeeca1799..a87af2814e 100644 --- a/options/ansi/include/inttypes.h +++ b/options/ansi/include/inttypes.h @@ -9,9 +9,11 @@ #ifndef __MLIBC_ABI_ONLY #if UINTPTR_MAX == UINT64_MAX +# define __PRIFAST "l" # define __PRI64 "l" # define __PRIPTR "l" #else +# define __PRIFAST "" # define __PRI64 "ll" # define __PRIPTR "" #endif @@ -27,14 +29,14 @@ #define PRIi16 "i" #define PRIdLEAST16 "d" #define PRIiLEAST16 "i" -#define PRIdFAST16 "ld" -#define PRIiFAST16 "li" +#define PRIdFAST16 __PRIFAST "d" +#define PRIiFAST16 __PRIFAST "i" #define PRId32 "d" #define PRIi32 "i" #define PRIdLEAST32 "d" #define PRIiLEAST32 "i" -#define PRIdFAST32 "ld" -#define PRIiFAST32 "li" +#define PRIdFAST32 __PRIFAST "d" +#define PRIiFAST32 __PRIFAST "i" #define PRId64 __PRI64 "d" #define PRIi64 __PRI64 "i" #define PRIdLEAST64 __PRI64 "d" @@ -65,10 +67,10 @@ #define PRIuLEAST16 "u" #define PRIxLEAST16 "x" #define PRIXLEAST16 "X" -#define PRIoFAST16 "lo" -#define PRIuFAST16 "lu" -#define PRIxFAST16 "lx" -#define PRIXFAST16 "lX" +#define PRIoFAST16 __PRIFAST "o" +#define PRIuFAST16 __PRIFAST "u" +#define PRIxFAST16 __PRIFAST "x" +#define PRIXFAST16 __PRIFAST "X" #define PRIo32 "o" #define PRIu32 "u" #define PRIx32 "x" @@ -77,10 +79,10 @@ #define PRIuLEAST32 "u" #define PRIxLEAST32 "x" #define PRIXLEAST32 "X" -#define PRIoFAST32 "lo" -#define PRIuFAST32 "lu" -#define PRIxFAST32 "lx" -#define PRIXFAST32 "lX" +#define PRIoFAST32 __PRIFAST "o" +#define PRIuFAST32 __PRIFAST "u" +#define PRIxFAST32 __PRIFAST "x" +#define PRIXFAST32 __PRIFAST "X" #define PRIo64 __PRI64 "o" #define PRIu64 __PRI64 "u" #define PRIx64 __PRI64 "x" diff --git a/options/ansi/include/limits.h b/options/ansi/include/limits.h index 8daa542bb3..752325c11d 100644 --- a/options/ansi/include/limits.h +++ b/options/ansi/include/limits.h @@ -7,24 +7,6 @@ # define MB_LEN_MAX 4 #endif -#ifdef LONG_MAX -# ifdef LONG_MAX == INT32_MAX -# define LONG_BIT 32 -# else -/* Safe assumption */ -# define LONG_BIT 64 -# endif -#elif defined __LONG_MAX__ -# if __LONG_MAX__ == INT32_MAX -# define LONG_BIT 32 -# else -/* Safe assumption */ -# define LONG_BIT 64 -# endif -#else -# error "Unsupported configuration, please define either LONG_MAX or __LONG_MAX__" -#endif - #undef SCHAR_MIN #undef SCHAR_MAX #undef CHAR_MIN @@ -99,12 +81,19 @@ /* POSIX states 9 is the minimum for NL_ARGMAX */ #define NL_ARGMAX 9 -#if INTPTR_MAX == INT64_MAX +#if __INTPTR_MAX__ == __INT64_MAX__ # define SSIZE_MAX LONG_MAX -#elif INTPTR_MAX == INT32_MAX +#elif __INTPTR_MAX__ == __INT32_MAX__ # define SSIZE_MAX INT_MAX #endif +#if __LONG_MAX__ == __INT32_MAX__ +# define LONG_BIT 32 +#else +/* Safe assumption */ +# define LONG_BIT 64 +#endif + #define _POSIX_ARG_MAX 4096 #define _POSIX_OPEN_MAX 16 #define _POSIX_HOST_NAME_MAX 255 diff --git a/options/elf/include/link.h b/options/elf/include/link.h index 91a5fb6b8f..e557a69077 100644 --- a/options/elf/include/link.h +++ b/options/elf/include/link.h @@ -29,7 +29,7 @@ struct dl_phdr_info { }; struct link_map { - Elf64_Addr l_addr; + ElfW(Addr) l_addr; char *l_name; ElfW(Dyn) *l_ld; struct link_map *l_next, *l_prev; @@ -38,9 +38,9 @@ struct link_map { struct r_debug { int r_version; struct link_map *r_map; - Elf64_Addr r_brk; + ElfW(Addr) r_brk; enum { RT_CONSISTENT, RT_ADD, RT_DELETE } r_state; - Elf64_Addr r_ldbase; + ElfW(Addr) r_ldbase; }; #ifndef __MLIBC_ABI_ONLY diff --git a/options/posix/include/netinet/icmp6.h b/options/posix/include/netinet/icmp6.h index 5251bbdd14..a429e55f72 100644 --- a/options/posix/include/netinet/icmp6.h +++ b/options/posix/include/netinet/icmp6.h @@ -189,9 +189,15 @@ struct nd_redirect { #define nd_rd_code nd_rd_hdr.icmp6_code #define nd_rd_cksum nd_rd_hdr.icmp6_cksum +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define ND_NA_FLAG_OVERRIDE 0x00000020 #define ND_NA_FLAG_SOLICITED 0x00000040 #define ND_NA_FLAG_ROUTER 0x00000080 +#else +#define ND_NA_FLAG_OVERRIDE 0x20000000 +#define ND_NA_FLAG_SOLICITED 0x40000000 +#define ND_NA_FLAG_ROUTER 0x80000000 +#endif struct nd_opt_home_agent_info { uint8_t nd_opt_home_agent_info_type; diff --git a/tests/meson.build b/tests/meson.build index a270709b3c..6690249ff5 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -106,6 +106,7 @@ all_test_cases = [ 'posix/usershell', 'posix/shm', 'posix/swab', + 'posix/select', 'glibc/getopt', 'glibc/ffsl-ffsll', 'glibc/error_message_count', diff --git a/tests/posix/select.c b/tests/posix/select.c new file mode 100644 index 0000000000..53184df4d3 --- /dev/null +++ b/tests/posix/select.c @@ -0,0 +1,32 @@ +#include +#include +#include + +int main() { + fd_set fds; + FD_ZERO(&fds); + + assert(!FD_ISSET(0, &fds)); + assert(!FD_ISSET(1, &fds)); + assert(!FD_ISSET(FD_SETSIZE - 1, &fds)); + + FD_SET(0, &fds); + assert(fds.fds_bits[0] == 1); + FD_SET(1, &fds); + assert(fds.fds_bits[0] == 3); + FD_SET(FD_SETSIZE - 1, &fds); + assert(fds.fds_bits[(FD_SETSIZE / (CHAR_BIT * sizeof(fds.fds_bits[0]))) - 1] == (typeof(fds.fds_bits[0])) (1UL << ((sizeof(fds.fds_bits[0]) * 8) - 1))); + + assert(FD_ISSET(0, &fds)); + assert(FD_ISSET(1, &fds)); + assert(FD_ISSET(FD_SETSIZE - 1, &fds)); + + FD_CLR(1, &fds); + assert(fds.fds_bits[0] == 1); + + assert(FD_ISSET(0, &fds)); + assert(!FD_ISSET(1, &fds)); + assert(FD_ISSET(FD_SETSIZE - 1, &fds)); + + return 0; +}