diff options
Diffstat (limited to 'libc')
62 files changed, 1813 insertions, 564 deletions
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index d7a659a8c..44685e6b8 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1892,7 +1892,7 @@ int getnameinfo(const struct sockaddr *sa, socklen_t hostlen, char *serv, socklen_t servlen, - unsigned flags) + int flags) { int serrno = errno; bool ok = 0; @@ -2699,7 +2699,7 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, hostp = __open_etc_hosts(); if (hostp == NULL) { *result = NULL; - ret = TRY_AGAIN; + *h_errnop = ret = TRY_AGAIN; goto DONE; } } diff --git a/libc/misc/auxvt/getauxval.c b/libc/misc/auxvt/getauxval.c index 2bdffaf2c..7610b7e5c 100755 --- a/libc/misc/auxvt/getauxval.c +++ b/libc/misc/auxvt/getauxval.c @@ -17,32 +17,28 @@ * <http://www.gnu.org/licenses/>. */ -#include "errno.h" -#include "ldso.h" -#include "sys/auxv.h" +#include <errno.h> +#include <ldso.h> +#include <sys/auxv.h> - -/* - * - * aarch64 gcc 11 uses __getauxval() in init_have_lse_atomics() - * - */ unsigned long int __getauxval (unsigned long int __type) { - if ( __type >= AUX_MAX_AT_ID ){ + // Requested value part of cached subset of auxiliary vector? + if (__type < AUX_MAX_AT_ID) { + if (_dl_auxvt[__type].a_type == __type) + return _dl_auxvt[__type].a_un.a_val; + __set_errno (ENOENT); return 0; } - if ( _dl_auxvt[__type].a_type == __type){ - return _dl_auxvt[__type].a_un.a_val; - } + // Otherwise we have to iterate the auxiliary vector. + for (ElfW(auxv_t) *entry = _dl_auxv_start; entry->a_type != AT_NULL; entry++) + if (entry->a_type == __type) + return entry->a_un.a_val; __set_errno (ENOENT); return 0; } -unsigned long int getauxval (unsigned long int __type){ - return __getauxval( __type ); -} - +weak_alias(__getauxval, getauxval) diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c index 87cd1bb72..09cbefc18 100644 --- a/libc/misc/elf/dl-support.c +++ b/libc/misc/elf/dl-support.c @@ -12,6 +12,7 @@ */ #include <link.h> +#include <ldso.h> #include <elf.h> #if defined(USE_TLS) && USE_TLS #include <assert.h> @@ -31,17 +32,29 @@ ElfW(Phdr) *_dl_phdr; size_t _dl_phnum; size_t _dl_pagesize; +ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID]; +ElfW(auxv_t) *_dl_auxv_start; + void internal_function _dl_aux_init (ElfW(auxv_t) *av); void internal_function _dl_aux_init (ElfW(auxv_t) *av) { + _dl_auxv_start = av; + + memset(_dl_auxvt, 0x00, sizeof(_dl_auxvt)); + for (; av->a_type != AT_NULL; av++) + { + if (av->a_type < AUX_MAX_AT_ID) + _dl_auxvt[av->a_type] = *av; + } + /* Get the program headers base address from the aux vect */ - _dl_phdr = (ElfW(Phdr) *) av[AT_PHDR].a_un.a_val; + _dl_phdr = (ElfW(Phdr) *) _dl_auxvt[AT_PHDR].a_un.a_val; /* Get the number of program headers from the aux vect */ - _dl_phnum = (size_t) av[AT_PHNUM].a_un.a_val; + _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val; /* Get the pagesize from the aux vect */ - _dl_pagesize = (av[AT_PAGESZ].a_un.a_val) ? (size_t) av[AT_PAGESZ].a_un.a_val : PAGE_SIZE; + _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE; } #if defined(USE_TLS) && USE_TLS diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 64a9c8214..60695b6ed 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -43,7 +43,7 @@ /* Are we in a secure process environment or are we dealing * with setuid stuff? If we are dynamically linked, then we * already have _dl_secure, otherwise we need to re-examine - * auxvt[] below. + * _dl_auxvt[] below. */ int _pe_secure = 0; libc_hidden_data_def(_pe_secure) @@ -84,6 +84,8 @@ static void fdpic_init_array_jump(void *addr) #ifndef SHARED void *__libc_stack_end = NULL; +#include "dl-auxvt.h" + # ifdef __UCLIBC_HAS_SSP__ # include <dl-osinfo.h> static uintptr_t stack_chk_guard; @@ -373,7 +375,6 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, { #ifndef SHARED unsigned long *aux_dat; - ElfW(auxv_t) auxvt[AT_EGID + 1]; #endif #ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -399,23 +400,14 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, #ifndef SHARED /* Pull stuff from the ELF header when possible */ - memset(auxvt, 0x00, sizeof(auxvt)); aux_dat = (unsigned long*)__environ; while (*aux_dat) { aux_dat++; } aux_dat++; - while (*aux_dat) { - ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat; - if (auxv_entry->a_type <= AT_EGID) { - memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t))); - } - aux_dat += 2; - } /* Get the program headers (_dl_phdr) from the aux vector It will be used into __libc_setup_tls. */ - - _dl_aux_init (auxvt); + _dl_aux_init ((ElfW(auxv_t) *)aux_dat); #endif /* We need to initialize uClibc. If we are dynamically linked this @@ -431,10 +423,10 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc, #ifndef SHARED /* Prevent starting SUID binaries where the stdin. stdout, and * stderr file descriptors are not already opened. */ - if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) || - (auxvt[AT_UID].a_un.a_val != (size_t)-1 && - (auxvt[AT_UID].a_un.a_val != auxvt[AT_EUID].a_un.a_val || - auxvt[AT_GID].a_un.a_val != auxvt[AT_EGID].a_un.a_val))) + if ((_dl_auxvt[AT_UID].a_un.a_val == (size_t)-1 && __check_suid()) || + (_dl_auxvt[AT_UID].a_un.a_val != (size_t)-1 && + (_dl_auxvt[AT_UID].a_un.a_val != _dl_auxvt[AT_EUID].a_un.a_val || + _dl_auxvt[AT_GID].a_un.a_val != _dl_auxvt[AT_EGID].a_un.a_val))) #else if (_dl_secure) #endif diff --git a/libc/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c index cb2c4df87..3bbdef18e 100644 --- a/libc/misc/internals/reloc_static_pie.c +++ b/libc/misc/internals/reloc_static_pie.c @@ -107,6 +107,8 @@ reloc_static_pie(ElfW(Addr) load_addr) PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym); } } +#else + (void)rel_size; #endif } _dl_load_base = load_addr; diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h index b342dc1cf..58a690ee3 100644 --- a/libc/misc/sysvipc/ipc.h +++ b/libc/misc/sysvipc/ipc.h @@ -1,12 +1,19 @@ #ifndef IPC_H #define IPC_H #include <syscall.h> +#include <bits/kernel-features.h> #include <bits/wordsize.h> #ifndef __ARCH_HAS_DEPRECATED_SYSCALLS__ # define __IPC_64 0x0 +#elif defined __mips__ || defined __m68k__ +# if __LINUX_KERNEL_VERSION < 0x050100 +# define __IPC_64 0x100 +# else +# define __IPC_64 0x0 +# endif #else -# if __WORDSIZE == 32 || defined __alpha__ || defined __mips__ +# if __WORDSIZE == 32 || defined __alpha__ # define __IPC_64 0x100 # else # define __IPC_64 0x0 diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c index 185cd268b..2d8bcae99 100644 --- a/libc/misc/sysvipc/msgq.c +++ b/libc/misc/sysvipc/msgq.c @@ -1,5 +1,6 @@ #include <errno.h> #include <sys/msg.h> +#include <stddef.h> #include "ipc.h" #ifdef __UCLIBC_HAS_THREADS_NATIVE__ #include "sysdep-cancel.h" @@ -7,6 +8,12 @@ #define SINGLE_THREAD_P 1 #endif +#if defined(__UCLIBC_USE_TIME64__) +union msqun { + struct msqid_ds* buff; + void *__pad; +}; +#endif #ifdef L_msgctl @@ -18,9 +25,19 @@ static __inline__ _syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msq int msgctl(int msqid, int cmd, struct msqid_ds *buf) { #ifdef __NR_msgctl - return __libc_msgctl(msqid, cmd | __IPC_64, buf); + int __ret = __libc_msgctl(msqid, cmd | __IPC_64, buf); +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) && (defined(__mips) || defined(__riscv)) + union msqun arg = {.buff = buf}; + // When cmd is IPC_RMID, buf should be NULL. + if (arg.__pad != NULL) { + arg.buff->msg_stime = (__time_t)arg.buff->msg_stime_internal_1 | (__time_t)(arg.buff->msg_stime_internal_2) << 32; + arg.buff->msg_rtime = (__time_t)arg.buff->msg_rtime_internal_1 | (__time_t)(arg.buff->msg_rtime_internal_2) << 32; + arg.buff->msg_ctime = (__time_t)arg.buff->msg_ctime_internal_1 | (__time_t)(arg.buff->msg_ctime_internal_2) << 32; + } +#endif + return __ret; #else - return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0); + return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf, 0); #endif } #endif diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c index 07076eff7..66f86f53c 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -57,9 +57,14 @@ int semctl(int semid, int semnum, int cmd, ...) va_end (ap); #ifdef __NR_semctl int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad); -#if defined(__UCLIBC_USE_TIME64__) - arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32; - arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32; +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + // Only when cmd is IPC_STAT and IPC_SET, semun points to struct semid_ds. + // At this point, arg.__pad should not be NULL, but a check is added just + // to be safe. + if ((cmd & (IPC_STAT | IPC_SET)) && (arg.__pad != NULL)) { + arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32; + arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32; + } #endif return __ret; #else diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c index cd46ff0dd..b3366b301 100644 --- a/libc/misc/sysvipc/shm.c +++ b/libc/misc/sysvipc/shm.c @@ -25,6 +25,13 @@ #include <syscall.h> #include "ipc.h" +#if defined(__UCLIBC_USE_TIME64__) +union shmun { + struct shmid_ds* buff; + void *__pad; +}; +#endif + #ifdef L_shmat /* Attach the shared memory segment associated with SHMID to the data segment of the calling process. SHMADDR and SHMFLG determine how @@ -59,7 +66,17 @@ static __always_inline _syscall3(int, __syscall_shmctl, int, shmid, int, cmd, st int shmctl(int shmid, int cmd, struct shmid_ds *buf) { #ifdef __NR_shmctl - return __syscall_shmctl(shmid, cmd | __IPC_64, buf); + int __ret = __syscall_shmctl(shmid, cmd | __IPC_64, buf); +#if (__WORDSIZE == 32) && defined(__mips) && defined(__UCLIBC_USE_TIME64__) + union shmun arg = {.buff = buf}; + // When cmd is IPC_RMID, buf should be NULL. + if (arg.__pad != NULL) { + arg.buff->shm_atime = (__time_t)arg.buff->shm_atime_internal_1 | (__time_t)(arg.buff->shm_atime_internal_2) << 32; + arg.buff->shm_dtime = (__time_t)arg.buff->shm_dtime_internal_1 | (__time_t)(arg.buff->shm_dtime_internal_2) << 32; + arg.buff->shm_ctime = (__time_t)arg.buff->shm_ctime_internal_1 | (__time_t)(arg.buff->shm_ctime_internal_2) << 32; + } +#endif + return __ret; #else return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf, 0); #endif diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c index 3f3000d6f..cb72d14ac 100644 --- a/libc/stdio/_scanf.c +++ b/libc/stdio/_scanf.c @@ -1715,7 +1715,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc) #define MAX_DIGITS 65 /* Allow one leading 0. */ unsigned char buf[MAX_DIGITS+2+ 100]; unsigned char usflag, base; - unsigned char nonzero = 0; + unsigned char nonzero __attribute__((unused)) = 0; unsigned char seendigit = 0; #ifndef __UCLIBC_HAS_FLOATS__ diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index cecea87ec..e51bc6610 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -29,7 +29,7 @@ __UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); struct malloc_state __malloc_state; /* never directly referenced */ /* forward declaration */ -static int __malloc_largebin_index(unsigned int sz); +static int __malloc_largebin_index(unsigned long sz); #ifdef __UCLIBC_MALLOC_DEBUGGING__ @@ -755,10 +755,10 @@ static void* __malloc_alloc(size_t nb, mstate av) Compute index for size. We expect this to be inlined when compiled with optimization, else not, which works out well. */ -static int __malloc_largebin_index(unsigned int sz) +static int __malloc_largebin_index(unsigned long sz) { - unsigned int x = sz >> SMALLBIN_WIDTH; - unsigned int m; /* bit position of highest set bit of m */ + unsigned long x = sz >> SMALLBIN_WIDTH; + unsigned long m; /* bit position of highest set bit of m */ if (x >= 0x10000) return NBINS-1; @@ -776,7 +776,7 @@ static int __malloc_largebin_index(unsigned int sz) S. Warren Jr's book "Hacker's Delight". */ - unsigned int n = ((x - 0x100) >> 16) & 8; + unsigned long n = ((x - 0x100) >> 16) & 8; x <<= n; m = ((x - 0x1000) >> 16) & 4; n += m; diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c index f5936630c..c45dd53a5 100644 --- a/libc/stdlib/stdlib.c +++ b/libc/stdlib/stdlib.c @@ -822,6 +822,7 @@ libc_hidden_def(_stdlib_mb_cur_max) #endif +#if defined(L_mblen) || defined(L_mbtowc) || defined(L_wctomb) #ifdef __UCLIBC_HAS_LOCALE__ /* * The following function return 1 if the encoding is stateful, 0 if stateless. @@ -844,6 +845,7 @@ static __always_inline int is_stateful(unsigned char encoding) #else #define is_stateful(encoding) 0 #endif +#endif /**********************************************************************/ #ifdef L_mblen diff --git a/libc/string/generic/strnlen.c b/libc/string/generic/strnlen.c index 4d4cde84f..82d4122ec 100644 --- a/libc/string/generic/strnlen.c +++ b/libc/string/generic/strnlen.c @@ -29,15 +29,17 @@ '\0' terminator is found in that many characters, return MAXLEN. */ size_t strnlen (const char *str, size_t maxlen) { - const char *char_ptr, *end_ptr = str + maxlen; + const char *char_ptr, *end_ptr; const unsigned long int *longword_ptr; unsigned long int longword, himagic, lomagic; if (maxlen == 0) return 0; - if (__builtin_expect (end_ptr < str, 0)) + if (__builtin_expect ((uintptr_t)str + maxlen < (uintptr_t)str, 0)) end_ptr = (const char *) ~0UL; + else + end_ptr = str + maxlen; /* Handle the first few characters by reading one character at a time. Do this until CHAR_PTR is aligned on a longword boundary. */ diff --git a/libc/string/x86_64/strcat.S b/libc/string/x86_64/strcat.S index 55e09e5f1..209e19062 100644 --- a/libc/string/x86_64/strcat.S +++ b/libc/string/x86_64/strcat.S @@ -106,7 +106,7 @@ ENTRY (BP_SYM (strcat)) /* Align, it is a jump target. */ /* Next 3 insns are 8 bytes total, make sure we decode them in one go */ - .p2align 3,,8 + .p2align 3,,7 3: subq $8,%rax /* correct pointer increment. */ diff --git a/libc/string/x86_64/strcspn.S b/libc/string/x86_64/strcspn.S index 7a06c8867..5ef565db7 100644 --- a/libc/string/x86_64/strcspn.S +++ b/libc/string/x86_64/strcspn.S @@ -94,7 +94,7 @@ L(1): leaq -4(%rdx), %rax /* prepare loop */ /* but it will also align entire function to 16 bytes, */ /* potentially creating largish padding at link time. */ /* We are aligning to 8 bytes instead: */ - .p2align 3,,8 + .p2align 3,,7 L(3): addq $4, %rax /* adjust pointer for full loop round */ diff --git a/libc/string/x86_64/strlen.S b/libc/string/x86_64/strlen.S index 9e84326c2..2fe2f58b2 100644 --- a/libc/string/x86_64/strlen.S +++ b/libc/string/x86_64/strlen.S @@ -102,7 +102,7 @@ ENTRY (strlen) /* Align, it is a jump target. */ /* Next 3 insns are 8 bytes total, make sure we decode them in one go */ - .p2align 3,,8 + .p2align 3,,7 3: subq $8,%rax /* correct pointer increment. */ diff --git a/libc/string/x86_64/strspn.S b/libc/string/x86_64/strspn.S index 366377649..8dc42656b 100644 --- a/libc/string/x86_64/strspn.S +++ b/libc/string/x86_64/strspn.S @@ -89,7 +89,7 @@ L(1): leaq -4(%rdx), %rax /* prepare loop */ /* but it will also align entire function to 16 bytes, */ /* potentially creating largish padding at link time. */ /* We are aligning to 8 bytes instead: */ - .p2align 3,,8 + .p2align 3,,7 L(3): addq $4, %rax /* adjust pointer for full loop round */ diff --git a/libc/sysdeps/linux/aarch64/bits/fenv.h b/libc/sysdeps/linux/aarch64/bits/fenv.h new file mode 100644 index 000000000..4febd2177 --- /dev/null +++ b/libc/sysdeps/linux/aarch64/bits/fenv.h @@ -0,0 +1,78 @@ +/* Copyright (C) 2004-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +/* Define bits representing exceptions in the FPSR status word. */ +enum + { + FE_INVALID = +#define FE_INVALID 1 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 2 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 4 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 8 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 16 + FE_INEXACT, + }; + +/* Amount to shift by to convert an exception bit in FPSR to a an + exception bit mask in FPCR. */ +#define FE_EXCEPT_SHIFT 8 + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* Define bits representing rounding modes in the FPCR Rmode field. */ +#define FE_TONEAREST 0x000000 +#define FE_UPWARD 0x400000 +#define FE_DOWNWARD 0x800000 +#define FE_TOWARDZERO 0xc00000 + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment. */ +typedef struct + { + unsigned int __fpcr; + unsigned int __fpsr; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1l) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -2) +#endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/aarch64/bits/shm.h b/libc/sysdeps/linux/aarch64/bits/shm.h new file mode 100644 index 000000000..bfb603499 --- /dev/null +++ b/libc/sysdeps/linux/aarch64/bits/shm.h @@ -0,0 +1,87 @@ +/* + * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB + * in this tarball. + */ + +#ifndef _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ + __time_t shm_atime; /* time of last shmat() */ + __time_t shm_dtime; /* time of last shmdt() */ + __time_t shm_ctime; /* time of last change by shmctl() */ + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/linux/aarch64/crt1.S b/libc/sysdeps/linux/aarch64/crt1.S index e9f946894..965d3265d 100644 --- a/libc/sysdeps/linux/aarch64/crt1.S +++ b/libc/sysdeps/linux/aarch64/crt1.S @@ -52,8 +52,8 @@ _start: /* Save off the atexit pointer */ mov x19, x0 - /* Calculate load address... idk how this works, but it does */ - adrp x0, _start + /* "Calculate" load address. The link address of __ehdr_start is 0. */ + adrp x0, __ehdr_start /* Do relocations */ bl reloc_static_pie diff --git a/libc/sysdeps/linux/aarch64/fpu_control.h b/libc/sysdeps/linux/aarch64/fpu_control.h new file mode 100644 index 000000000..c3e7f6629 --- /dev/null +++ b/libc/sysdeps/linux/aarch64/fpu_control.h @@ -0,0 +1,102 @@ +/* Copyright (C) 1996-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _AARCH64_FPU_CONTROL_H +#define _AARCH64_FPU_CONTROL_H + +#include <features.h> + +/* Macros for accessing the FPCR and FPSR. */ + +#if __GNUC_PREREQ (6,0) +# define _FPU_GETCW(fpcr) (fpcr = __builtin_aarch64_get_fpcr ()) +# define _FPU_SETCW(fpcr) __builtin_aarch64_set_fpcr (fpcr) +# define _FPU_GETFPSR(fpsr) (fpsr = __builtin_aarch64_get_fpsr ()) +# define _FPU_SETFPSR(fpsr) __builtin_aarch64_set_fpsr (fpsr) +#else +# define _FPU_GETCW(fpcr) \ + ({ \ + __uint64_t __fpcr; \ + __asm__ __volatile__ ("mrs %0, fpcr" : "=r" (__fpcr)); \ + fpcr = __fpcr; \ + }) + +# define _FPU_SETCW(fpcr) \ + ({ \ + __uint64_t __fpcr = fpcr; \ + __asm__ __volatile__ ("msr fpcr, %0" : : "r" (__fpcr)); \ + }) + +# define _FPU_GETFPSR(fpsr) \ + ({ \ + __uint64_t __fpsr; \ + __asm__ __volatile__ ("mrs %0, fpsr" : "=r" (__fpsr)); \ + fpsr = __fpsr; \ + }) + +# define _FPU_SETFPSR(fpsr) \ + ({ \ + __uint64_t __fpsr = fpsr; \ + __asm__ __volatile__ ("msr fpsr, %0" : : "r" (__fpsr)); \ + }) +#endif + +/* Reserved bits should be preserved when modifying register + contents. These two masks indicate which bits in each of FPCR and + FPSR should not be changed. */ + +#define _FPU_RESERVED 0xfe0fe0f8 +#define _FPU_FPSR_RESERVED 0x0fffffe0 + +#define _FPU_DEFAULT 0x00000000 +#define _FPU_FPSR_DEFAULT 0x00000000 + +/* Layout of FPCR and FPSR: + + | | | | | | | | + 0 0 0 0 1 1 1 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 + s s s s s s s s s s s + c c c c c c c c c c c c + N Z C V Q A D F R R S S S L L L I U U I U O D I I U U I U O D I + C H N Z M M T T B E E E D N N X F F Z O D N N X F F Z O + P O O R R Z N N N E K K E E E E E C K K C C C C C + D D I I P + E E D D + E E + */ + +#define _FPU_FPCR_RM_MASK 0xc00000 + +#define _FPU_FPCR_MASK_IXE 0x1000 +#define _FPU_FPCR_MASK_UFE 0x0800 +#define _FPU_FPCR_MASK_OFE 0x0400 +#define _FPU_FPCR_MASK_DZE 0x0200 +#define _FPU_FPCR_MASK_IOE 0x0100 + +#define _FPU_FPCR_IEEE \ + (_FPU_DEFAULT | _FPU_FPCR_MASK_IXE \ + | _FPU_FPCR_MASK_UFE | _FPU_FPCR_MASK_OFE \ + | _FPU_FPCR_MASK_DZE | _FPU_FPCR_MASK_IOE) + +#define _FPU_FPSR_IEEE 0 + +typedef unsigned int fpu_control_t; +typedef unsigned int fpu_fpsr_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif diff --git a/libc/sysdeps/linux/arc/bits/fenv.h b/libc/sysdeps/linux/arc/bits/fenv.h new file mode 100644 index 000000000..c5c76cb93 --- /dev/null +++ b/libc/sysdeps/linux/arc/bits/fenv.h @@ -0,0 +1,75 @@ +/* Floating point environment. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +enum + { + FE_INVALID = +# define FE_INVALID (0x01) + FE_INVALID, + FE_DIVBYZERO = +# define FE_DIVBYZERO (0x02) + FE_DIVBYZERO, + FE_OVERFLOW = +# define FE_OVERFLOW (0x04) + FE_OVERFLOW, + FE_UNDERFLOW = +# define FE_UNDERFLOW (0x08) + FE_UNDERFLOW, + FE_INEXACT = +# define FE_INEXACT (0x10) + FE_INEXACT + }; + +# define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +enum + { + FE_TOWARDZERO = +# define FE_TOWARDZERO (0x0) + FE_TOWARDZERO, + FE_TONEAREST = +# define FE_TONEAREST (0x1) /* default */ + FE_TONEAREST, + FE_UPWARD = +# define FE_UPWARD (0x2) + FE_UPWARD, + FE_DOWNWARD = +# define FE_DOWNWARD (0x3) + FE_DOWNWARD + }; + +typedef unsigned int fexcept_t; + +typedef struct +{ + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1) + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/arc/fpu_control.h b/libc/sysdeps/linux/arc/fpu_control.h new file mode 100644 index 000000000..e833de3aa --- /dev/null +++ b/libc/sysdeps/linux/arc/fpu_control.h @@ -0,0 +1,104 @@ +/* FPU control word bits. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* ARC FPU control register bits. + + [ 0] -> IVE: Enable invalid operation exception. + if 0, soft exception: status register IV flag set. + if 1, hardware exception trap (not supported in Linux yet). + [ 1] -> DZE: Enable division by zero exception. + if 0, soft exception: status register IV flag set. + if 1, hardware exception: (not supported in Linux yet). + [9:8] -> RM: Rounding Mode: + 00 - Rounding toward zero. + 01 - Rounding to nearest (default). + 10 - Rounding (up) toward plus infinity. + 11 - Rounding (down)toward minus infinity. + + ARC FPU status register bits. + + [ 0] -> IV: flag invalid operation. + [ 1] -> DZ: flag division by zero. + [ 2] -> OV: flag Overflow operation. + [ 3] -> UV: flag Underflow operation. + [ 4] -> IX: flag Inexact operation. + [31] -> FWE: Flag Write Enable. + If 1, above flags writable explicitly (clearing), + else IoW and only writable indirectly via bits [12:7]. */ + +#include <features.h> + +#if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__) + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) +# define _FPU_GETS(cw) (cw) = 0 +# define _FPU_SETS(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else + +#define _FPU_RESERVED 0 + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. + So only RM set to b'01. */ +# define _FPU_DEFAULT 0x00000100 + +/* Actually default needs to have FWE bit as 1 but that is already + ingrained into _FPU_SETS macro below. */ +#define _FPU_FPSR_DEFAULT 0x00000000 + +#define __FPU_RND_SHIFT 8 +#define __FPU_RND_MASK 0x3 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw)) + +/* Macros for accessing the hardware status word. + Writing to FPU_STATUS requires a "control" bit FWE to be able to set the + exception flags directly (as opposed to side-effects of FP instructions). + That is done in the macro here to keeps callers agnostic of this detail. + And given FWE is write-only and RAZ, no need to "clear" it in _FPU_GETS + macro. */ +# define _FPU_GETS(cw) \ + __asm__ volatile ("lr %0, [0x301] \r\n" \ + : "=r" (cw)) + +# define _FPU_SETS(cw) \ + do { \ + unsigned int __fwe = 0x80000000 | (cw); \ + __asm__ volatile ("sr %0, [0x301] \r\n" \ + : : "r" (__fwe)); \ + } while (0) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/arm/bits/fenv.h b/libc/sysdeps/linux/arm/bits/fenv.h index 106bf36c2..ab60b9e70 100644 --- a/libc/sysdeps/linux/arm/bits/fenv.h +++ b/libc/sysdeps/linux/arm/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 2004-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,87 +11,77 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif -#ifdef __MAVERICK__ - /* Define bits representing exceptions in the FPU status word. */ enum { - FE_INVALID = 1, -#define FE_INVALID FE_INVALID - FE_OVERFLOW = 4, -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = 8, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_INEXACT = 16, -#define FE_INEXACT FE_INEXACT + FE_INVALID = +#define FE_INVALID 1 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 2 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 4 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 8 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 16 + FE_INEXACT, }; /* Amount to shift by to convert an exception to a mask bit. */ -#define FE_EXCEPT_SHIFT 5 +#define FE_EXCEPT_SHIFT 8 /* All supported exceptions. */ -#define FE_ALL_EXCEPT \ - (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) - -/* IEEE rounding modes. */ -enum - { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x400, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 0x800, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 0xc00, -#define FE_UPWARD FE_UPWARD - }; - -#define FE_ROUND_MASK (FE_UPWARD) - -#else /* !__MAVERICK__ */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) -/* Define bits representing exceptions in the FPU status word. */ +/* VFP supports all of the four defined rounding modes. */ enum { - FE_INVALID = 1, -#define FE_INVALID FE_INVALID - FE_DIVBYZERO = 2, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_OVERFLOW = 4, -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = 8, -#define FE_UNDERFLOW FE_UNDERFLOW - }; - -/* Amount to shift by to convert an exception to a mask bit. */ -#define FE_EXCEPT_SHIFT 16 - -/* All supported exceptions. */ -#define FE_ALL_EXCEPT \ - (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) - -/* The ARM FPU basically only supports round-to-nearest. Other rounding - modes exist, but you have to encode them in the actual instruction. */ + FE_TONEAREST = #define FE_TONEAREST 0 - -#endif /* __MAVERICK__ */ + FE_TONEAREST, + FE_UPWARD = +#define FE_UPWARD 0x400000 + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD 0x800000 + FE_DOWNWARD, + FE_TOWARDZERO = +#define FE_TOWARDZERO 0xc00000 + FE_TOWARDZERO + }; /* Type representing exception flags. */ -typedef unsigned long int fexcept_t; +typedef unsigned int fexcept_t; /* Type representing floating-point environment. */ typedef struct { - unsigned long int __cw; + unsigned int __cw; } fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((fenv_t *) -1l) +#define FE_DFL_ENV ((const fenv_t *) -1l) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((const fenv_t *) -2) +#endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/arm/bits/shm.h b/libc/sysdeps/linux/arm/bits/shm.h index 86245faff..aa1a72e54 100644 --- a/libc/sysdeps/linux/arm/bits/shm.h +++ b/libc/sysdeps/linux/arm/bits/shm.h @@ -49,12 +49,18 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else __time_t shm_atime; /* time of last shmat() */ unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ unsigned long int __uclibc_unused3; +#endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ diff --git a/libc/sysdeps/linux/arm/crt1.S b/libc/sysdeps/linux/arm/crt1.S index 799f11080..040ddfd27 100644 --- a/libc/sysdeps/linux/arm/crt1.S +++ b/libc/sysdeps/linux/arm/crt1.S @@ -248,13 +248,9 @@ _start: #if defined(__ARCH_USE_MMU__) || defined(__UCLIBC_FORMAT_ELF__) #ifdef L_rcrt1 /* We don't need to save a1 since no dynamic linker should have run */ - ldr a1, .L_GOT /* Get value at .L_GOT + 0 (offset to GOT)*/ - adr a2, .L_GOT /* Get address of .L_GOT */ - ldr a3, .L_GOT+16 /* Get value of _start(GOT) stored in .L_GOT */ - adr a4, _start /* Get address of _start after relocation (changes to pc - ~30 or so) */ - add a1, a1, a2 /* Calculate where the GOT is */ - ldr a2, [a1, a3] /* GOT + _start(GOT) = offset of _start from begin of file */ - sub a1, a4, a2 /* Current addr of _start - offset from beginning of file = load addr */ + adr a1, .L__ehdr_start_off /* Get address of .L__ehdr_start_off */ + ldr a2, .L__ehdr_start_off /* Offset from .L__ehdr_start_off to __ehdr_start */ + add a1, a1, a2 /* Address of __ehdr_start = load addr */ bl reloc_static_pie mov a1, #0 /* Clean up a1 so that a random address won't get called at the end of program */ @@ -325,9 +321,10 @@ _start: .word _fini(GOT) .word _init(GOT) .word main(GOT) -#ifdef L_rcrt1 - .word _start(GOT) #endif +#ifdef L_rcrt1 +.L__ehdr_start_off: + .word __ehdr_start - .L__ehdr_start_off #endif #endif diff --git a/libc/sysdeps/linux/arm/fpu_control.h b/libc/sysdeps/linux/arm/fpu_control.h index 1b9b09df6..05ac6a03c 100644 --- a/libc/sysdeps/linux/arm/fpu_control.h +++ b/libc/sysdeps/linux/arm/fpu_control.h @@ -1,6 +1,5 @@ -/* FPU control word definitions. ARM version. - Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* FPU control word definitions. ARM VFP version. + Copyright (C) 2004-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,13 +12,22 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H -#ifdef __VFP_FP__ +#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__) + +#define _FPU_RESERVED 0xffffffff +#define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +#define _FPU_GETCW(cw) (cw) = 0 +#define _FPU_SETCW(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* masking of interrupts */ #define _FPU_MASK_IM 0x00000100 /* invalid operation */ @@ -28,175 +36,39 @@ #define _FPU_MASK_UM 0x00000800 /* underflow */ #define _FPU_MASK_PM 0x00001000 /* inexact */ +#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */ +#define _FPU_MASK_RM 0x00c00000 /* rounding mode */ +#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */ + /* Some bits in the FPSCR are not yet defined. They must be preserved when modifying the contents. */ -#define _FPU_RESERVED 0x0e08e0e0 +#define _FPU_RESERVED 0x00086060 #define _FPU_DEFAULT 0x00000000 -/* Default + exceptions enabled. */ + +/* Default + exceptions enabled. */ #define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00) /* Type of the control word. */ typedef unsigned int fpu_control_t; /* Macros for accessing the hardware control word. */ +#ifdef __SOFTFP__ /* This is fmrx %0, fpscr. */ -#define _FPU_GETCW(cw) \ +# define _FPU_GETCW(cw) \ __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw)) /* This is fmxr fpscr, %0. */ -#define _FPU_SETCW(cw) \ +# define _FPU_SETCW(cw) \ __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw)) +#else +# define _FPU_GETCW(cw) \ + __asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw)) +# define _FPU_SETCW(cw) \ + __asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw)) +#endif -#elif defined __MAVERICK__ - -/* DSPSC register: (from EP9312 User's Guide) - * - * bits 31..29 - DAID - * bits 28..26 - HVID - * bits 25..24 - RSVD - * bit 23 - ISAT - * bit 22 - UI - * bit 21 - INT - * bit 20 - AEXC - * bits 19..18 - SAT - * bits 17..16 - FCC - * bit 15 - V - * bit 14 - FWDEN - * bit 13 - Invalid - * bit 12 - Denorm - * bits 11..10 - RM - * bits 9..5 - IXE, UFE, OFE, RSVD, IOE - * bits 4..0 - IX, UF, OF, RSVD, IO - */ - -/* masking of interrupts */ -#define _FPU_MASK_IM (1 << 5) /* invalid operation */ -#define _FPU_MASK_ZM 0 /* divide by zero */ -#define _FPU_MASK_OM (1 << 7) /* overflow */ -#define _FPU_MASK_UM (1 << 8) /* underflow */ -#define _FPU_MASK_PM (1 << 9) /* inexact */ -#define _FPU_MASK_DM 0 /* denormalized operation */ - -#define _FPU_RESERVED 0xfffff000 /* These bits are reserved. */ - -#define _FPU_DEFAULT 0x00b00000 /* Default value. */ -#define _FPU_IEEE 0x00b003a0 /* Default + exceptions enabled. */ - -/* Type of the control word. */ -typedef unsigned int fpu_control_t; - -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) ({ \ - register int __t1, __t2; \ - \ - __asm__ __volatile__ ( \ - "cfmvr64l %1, mvdx0\n\t" \ - "cfmvr64h %2, mvdx0\n\t" \ - "cfmv32sc mvdx0, dspsc\n\t" \ - "cfmvr64l %0, mvdx0\n\t" \ - "cfmv64lr mvdx0, %1\n\t" \ - "cfmv64hr mvdx0, %2" \ - : "=r" (cw), "=r" (__t1), "=r" (__t2) \ - ); \ -}) - -#define _FPU_SETCW(cw) ({ \ - register int __t0, __t1, __t2; \ - \ - __asm__ __volatile__ ( \ - "cfmvr64l %1, mvdx0\n\t" \ - "cfmvr64h %2, mvdx0\n\t" \ - "cfmv64lr mvdx0, %0\n\t" \ - "cfmvsc32 dspsc, mvdx0\n\t" \ - "cfmv64lr mvdx0, %1\n\t" \ - "cfmv64hr mvdx0, %2" \ - : "=r" (__t0), "=r" (__t1), "=r" (__t2) \ - : "0" (cw) \ - ); \ -}) - -#else /* !__MAVERICK__ */ - -/* We have a slight terminology confusion here. On the ARM, the register - * we're interested in is actually the FPU status word - the FPU control - * word is something different (which is implementation-defined and only - * accessible from supervisor mode.) - * - * The FPSR looks like this: - * - * 31-24 23-16 15-8 7-0 - * | system ID | trap enable | system control | exception flags | - * - * We ignore the system ID bits; for interest's sake they are: - * - * 0000 "old" FPE - * 1000 FPPC hardware - * 0001 FPE 400 - * 1001 FPA hardware - * - * The trap enable and exception flags are both structured like this: - * - * 7 - 5 4 3 2 1 0 - * | reserved | INX | UFL | OFL | DVZ | IVO | - * - * where a `1' bit in the enable byte means that the trap can occur, and - * a `1' bit in the flags byte means the exception has occurred. - * - * The exceptions are: - * - * IVO - invalid operation - * DVZ - divide by zero - * OFL - overflow - * UFL - underflow - * INX - inexact (do not use; implementations differ) - * - * The system control byte looks like this: - * - * 7-5 4 3 2 1 0 - * | reserved | AC | EP | SO | NE | ND | - * - * where the bits mean - * - * ND - no denormalised numbers (force them all to zero) - * NE - enable NaN exceptions - * SO - synchronous operation - * EP - use expanded packed-decimal format - * AC - use alternate definition for C flag on compare operations - */ - -/* masking of interrupts */ -#define _FPU_MASK_IM 0x00010000 /* invalid operation */ -#define _FPU_MASK_ZM 0x00020000 /* divide by zero */ -#define _FPU_MASK_OM 0x00040000 /* overflow */ -#define _FPU_MASK_UM 0x00080000 /* underflow */ -#define _FPU_MASK_PM 0x00100000 /* inexact */ -#define _FPU_MASK_DM 0x00000000 /* denormalized operation */ - -/* The system id bytes cannot be changed. - Only the bottom 5 bits in the trap enable byte can be changed. - Only the bottom 5 bits in the system control byte can be changed. - Only the bottom 5 bits in the exception flags are used. - The exception flags are set by the fpu, but can be zeroed by the user. */ -#define _FPU_RESERVED 0xffe0e0e0 /* These bits are reserved. */ - -/* The fdlibm code requires strict IEEE double precision arithmetic, - no interrupts for exceptions, rounding to nearest. Changing the - rounding mode will break long double I/O. Turn on the AC bit, - the compiler generates code that assumes it is on. */ -#define _FPU_DEFAULT 0x00001000 /* Default value. */ -#define _FPU_IEEE 0x001f1000 /* Default + exceptions enabled. */ - -/* Type of the control word. */ -typedef unsigned int fpu_control_t; - -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("rfs %0" : "=r" (cw)) -#define _FPU_SETCW(cw) __asm__ ("wfs %0" : : "r" (cw)) - -#endif /* __MAVERICK__ */ - -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +#endif /* __SOFTFP__ */ #endif /* _FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/common/Makefile.in b/libc/sysdeps/linux/common/Makefile.in index e0b280c33..4a4317432 100644 --- a/libc/sysdeps/linux/common/Makefile.in +++ b/libc/sysdeps/linux/common/Makefile.in @@ -27,6 +27,7 @@ CSRC-$(UCLIBC_LINUX_SPECIFIC) += \ eventfd_write.c \ fanotify.c \ getrandom.c \ + getentropy.c \ inotify.c \ ioperm.c \ iopl.c \ diff --git a/libc/sysdeps/linux/common/bits/msq.h b/libc/sysdeps/linux/common/bits/msq.h index b594cfff2..0cb734263 100644 --- a/libc/sysdeps/linux/common/bits/msq.h +++ b/libc/sysdeps/linux/common/bits/msq.h @@ -37,17 +37,31 @@ typedef unsigned long int msglen_t; struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ +#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__)) + unsigned long int msg_stime_internal_1; + unsigned long int msg_stime_internal_2; + unsigned long int msg_rtime_internal_1; + unsigned long int msg_rtime_internal_2; + unsigned long int msg_ctime_internal_1; + unsigned long int msg_ctime_internal_2; +#else __time_t msg_stime; /* time of last msgsnd command */ unsigned long int __uclibc_unused1; __time_t msg_rtime; /* time of last msgrcv command */ unsigned long int __uclibc_unused2; __time_t msg_ctime; /* time of last change */ unsigned long int __uclibc_unused3; +#endif unsigned long int __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes; /* max number of bytes allowed on queue */ __pid_t msg_lspid; /* pid of last msgsnd() */ __pid_t msg_lrpid; /* pid of last msgrcv() */ +#if (__WORDSIZE == 32 && defined(__riscv) && defined(__UCLIBC_USE_TIME64__)) + __time_t msg_stime; /* time of last msgsnd command */ + __time_t msg_rtime; /* time of last msgrcv command */ + __time_t msg_ctime; /* time of last change */ +#endif unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; }; diff --git a/libc/sysdeps/linux/common/bits/nan.h b/libc/sysdeps/linux/common/bits/nan.h index 00cb405f1..46cfb613f 100644 --- a/libc/sysdeps/linux/common/bits/nan.h +++ b/libc/sysdeps/linux/common/bits/nan.h @@ -25,7 +25,9 @@ #if __GNUC_PREREQ(3,3) -# define NAN (__builtin_nanf ("")) +# ifndef NAN +# define NAN (__builtin_nanf ("")) +# endif #elif defined __GNUC__ diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h index 24a130981..d855494ee 100644 --- a/libc/sysdeps/linux/common/bits/sem.h +++ b/libc/sysdeps/linux/common/bits/sem.h @@ -45,8 +45,8 @@ struct semid_ds #else __time_t sem_otime; /* last semop() time */ #endif -#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \ - ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__)) +#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \ + ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__)) unsigned long int __uclibc_unused1; #endif #if defined(__UCLIBC_USE_TIME64__) @@ -55,8 +55,8 @@ struct semid_ds #else __time_t sem_ctime; /* last time changed by semctl() */ #endif -#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__)) || \ - ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__)) && !defined(__UCLIBC_USE_TIME64__)) +#if (__WORDSIZE == 32 && !defined(__ARC64_ARCH32__) && !defined(__arc__) && !defined(__arm__) && !defined(__or1k__) && !defined(__xtensa__) && !defined(__riscv)) || \ + ((defined(__ARC64_ARCH32__) || defined(__arc__) || defined(__arm__) || defined(__or1k__) || defined(__xtensa__) || defined(__riscv)) && !defined(__UCLIBC_USE_TIME64__)) unsigned long int __uclibc_unused2; #endif unsigned long int sem_nsems; /* number of semaphores in set */ diff --git a/libc/sysdeps/linux/common/clock_adjtime.c b/libc/sysdeps/linux/common/clock_adjtime.c index 53f64e9d5..ada256ccd 100644 --- a/libc/sysdeps/linux/common/clock_adjtime.c +++ b/libc/sysdeps/linux/common/clock_adjtime.c @@ -15,5 +15,5 @@ _syscall2_64(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx) #elif defined(__NR_clock_adjtime) _syscall2(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx) #else -#error "clock_adjtime syscall is not defined!" +#warning "clock_adjtime syscall is not defined!" #endif diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c new file mode 100644 index 000000000..d255310b6 --- /dev/null +++ b/libc/sysdeps/linux/common/getentropy.c @@ -0,0 +1,46 @@ +/* + * getentropy() by wrapping getrandom(), for µClibc-ng + * + * © 2025 mirabilos Ⓕ CC0 or MirBSD or GNU LGPLv2 + * + * Note: may be a thread cancellation point, unlike the + * implementations in glibc and musl libc. Should this + * ever become a concern, it will need patching. + */ + +#define _DEFAULT_SOURCE +#include <errno.h> +#include <unistd.h> +#include <sys/random.h> +#include <sys/syscall.h> + +#ifdef __NR_getrandom +int +getentropy(void *__buf, size_t __len) +{ + ssize_t n; + + if (__len > 256U) { + errno = EIO; + return (-1); + } + + again: + if ((n = getrandom(__buf, __len, 0)) == -1) + switch (errno) { + case EAGAIN: /* should not happen but better safe than sorry */ + case EINTR: + goto again; + default: + errno = EIO; + /* FALLTHROUGH */ + case EFAULT: + case ENOSYS: + return (-1); + } + if ((size_t)n != __len) + /* also shouldn’t happen (safety net) */ + goto again; + return (0); +} +#endif diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c index bb9841463..1db1663b9 100644 --- a/libc/sysdeps/linux/common/getrandom.c +++ b/libc/sysdeps/linux/common/getrandom.c @@ -8,6 +8,7 @@ #include <sys/syscall.h> #include <sys/random.h> + #ifdef __NR_getrandom -_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags) +_syscall3(ssize_t, getrandom, void *, buf, size_t, buflen, unsigned int, flags) #endif diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h index 3d24e439b..c3d9cf575 100644 --- a/libc/sysdeps/linux/common/sys/random.h +++ b/libc/sysdeps/linux/common/sys/random.h @@ -4,11 +4,19 @@ #ifndef _SYS_RANDOM_H #define _SYS_RANDOM_H 1 + #include <features.h> #include <stddef.h> __BEGIN_DECLS +#include <bits/types.h> + +#ifndef __ssize_t_defined +typedef __ssize_t ssize_t; +# define __ssize_t_defined +#endif + #if defined __UCLIBC_LINUX_SPECIFIC__ # if 0 /*def __ASSUME_GETRANDOM_SYSCALL */ # include <linux/random.h> @@ -26,9 +34,15 @@ __BEGIN_DECLS # define GRND_RANDOM 0x0002 # define GRND_INSECURE 0x0004 # endif -/* FIXME: aren't there a couple of __restrict and const missing ? */ -extern int getrandom(void *__buf, size_t count, unsigned int flags) +extern ssize_t getrandom(void *__buf, size_t count, unsigned int flags) __nonnull ((1)) __wur; + +/* OpenBSD-compatible access to random bytes. + May be a cancellation point here, unlike in glibc/musl. */ +# ifndef __getentropy_defined +extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur; +# define __getentropy_defined +# endif #endif __END_DECLS diff --git a/libc/sysdeps/linux/common/utimes.c b/libc/sysdeps/linux/common/utimes.c index a28594dfd..c471a9b89 100644 --- a/libc/sysdeps/linux/common/utimes.c +++ b/libc/sysdeps/linux/common/utimes.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <sys/time.h> -#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utimes +#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && (!defined __NR_utimes || defined(__UCLIBC_USE_TIME64__)) # include <fcntl.h> # include <stddef.h> int utimes(const char *file, const struct timeval tvp[2]) @@ -50,6 +50,6 @@ int utimes(const char *file, const struct timeval tvp[2]) } #endif -#if defined __NR_utimensat || defined __NR_utimensat_time64 || defined __NR_utimes || defined __NR_utime +#if (((defined __NR_utimensat || defined __NR_utimensat_time64) && (!defined __NR_utimes || defined __UCLIBC_USE_TIME64__))) || defined __NR_utimes || defined __NR_utime libc_hidden_def(utimes) #endif diff --git a/libc/sysdeps/linux/csky/bits/fenv.h b/libc/sysdeps/linux/csky/bits/fenv.h index 3359e1f8e..1428f385a 100644 --- a/libc/sysdeps/linux/csky/bits/fenv.h +++ b/libc/sysdeps/linux/csky/bits/fenv.h @@ -1,65 +1,108 @@ -/* - * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd. - * - * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB - * in this tarball. - */ +/* Floating point environment. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif -/* Define bits representing the exception. We use the bit positions of - the appropriate bits in the FPSR Accrued Exception Byte. */ +#ifdef __csky_hard_float__ +/* Define bits representing the exception. We use the bit positions + of the appropriate bits in the FPU control word. */ enum { - FE_INEXACT = 1 << 3, -#define FE_INEXACT FE_INEXACT - FE_DIVBYZERO = 1 << 4, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_UNDERFLOW = 1 << 5, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 1 << 6, -#define FE_OVERFLOW FE_OVERFLOW - FE_INVALID = 1 << 7 -#define FE_INVALID FE_INVALID + FE_INVALID = +#define FE_INVALID 0x01 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 0x02 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 0x04 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 0x10 + FE_INEXACT, + __FE_DENORMAL = 0x20 }; #define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) -/* The csky FPU supports all of the four defined rounding modes. We use - the bit positions in the FPCR Mode Control Byte as the values for the - appropriate macros. */ +/* The C-SKY FPU supports all of the four defined rounding modes. We + use again the bit positions in the FPU control word as the values + for the appropriate macros. */ +enum + { + FE_TONEAREST = +#define FE_TONEAREST (0x0 << 24) + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO (0x1 << 24) + FE_TOWARDZERO, + FE_UPWARD = +#define FE_UPWARD (0x2 << 24) + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD (0x3 << 24) + FE_DOWNWARD, + __FE_ROUND_MASK = (0x3 << 24) + }; + +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + enum { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 1 << 4, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 2 << 4, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 3 << 4 -#define FE_UPWARD FE_UPWARD + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST }; +# define FE_ALL_EXCEPT 0 + +#endif + /* Type representing exception flags. */ typedef unsigned int fexcept_t; -/* Type representing floating-point environment. This structure - corresponds to the layout of the block written by `fmovem'. */ +/* Type representing floating-point environment. */ typedef struct - { - unsigned int __control_register; - unsigned int __status_register; - unsigned int __instruction_address; - } -fenv_t; +{ + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((__const fenv_t *) -1) +#define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && defined __csky_hard_float__ /* Floating-point environment where none of the exceptions are masked. */ -# define FE_NOMASK_ENV ((__const fenv_t *) -2) +# define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/csky/fpu_control.h b/libc/sysdeps/linux/csky/fpu_control.h new file mode 100644 index 000000000..a2d615554 --- /dev/null +++ b/libc/sysdeps/linux/csky/fpu_control.h @@ -0,0 +1,147 @@ +/* FPU control word bits. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* C-SKY FPU floating point control register bits. + + 31-28 -> Reserved (read as 0, write with 0). + 27 -> 0: Flush denormalized results to zero. + 1: Flush denormalized results to signed minimal normal number. + 26 -> Reserved (read as 0, write with 0). + 25-24 -> Rounding control. + 23-6 -> Reserved (read as 0, write with 0). + 5 -> Enable exception for input denormalized exception. + 4 -> Enable exception for inexact exception. + 3 -> Enable exception for underflow exception. + 2 -> Enable exception for overflow exception. + 1 -> Enable exception for division by zero exception. + 0 -> Enable exception for invalid operation exception. + + Rounding Control: + 00 - Rounding to nearest (RN). + 01 - Rounding toward zero (RZ). + 10 - Rounding (up) toward plus infinity (RP). + 11 - Rounding (down)toward minus infinity (RM). + + C-SKY FPU floating point exception status register bits. + + 15 -> Accumulate bit for any exception. + 14 -> Reserved (read as 0, write with 0). + 13 -> Cause bit for input denormalized exception. + 12 -> Cause bit for inexact exception. + 11 -> Cause bit for underflow exception. + 10 -> Cause bit for overflow exception. + 9 -> Cause bit for division by zero exception. + 8 -> Cause bit for invalid operation exception. + 7 -> Flag bit for any exception. + 6 -> Reserved (read as 0, write with 0). + 5 -> Flag exception for input denormalized exception. + 4 -> Flag exception for inexact exception. + 3 -> Flag exception for underflow exception. + 2 -> Flag exception for overflow exception. + 1 -> Flag exception for division by zero exception. + 0 -> Flag exception for invalid operation exception. */ + +#include <features.h> + +#ifdef __csky_soft_float__ + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) +# define _FPU_GETFPSR(cw) (cw) = 0 +# define _FPU_SETFPSR(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* __csky_soft_float__ */ + +/* Masking of interrupts. */ +# define _FPU_MASK_IDE (1 << 5) /* Input denormalized exception. */ +# define _FPU_MASK_IXE (1 << 4) /* Inexact exception. */ +# define _FPU_MASK_UFE (1 << 3) /* Underflow exception. */ +# define _FPU_MASK_OFE (1 << 2) /* Overflow exception. */ +# define _FPU_MASK_DZE (1 << 1) /* Division by zero exception. */ +# define _FPU_MASK_IOE (1 << 0) /* Invalid operation exception. */ + +# define _FPU_MASK_FEA (1 << 15) /* Case for any exception. */ +# define _FPU_MASK_FEC (1 << 7) /* Flag for any exception. */ + +/* Flush denormalized numbers to zero. */ +# define _FPU_FLUSH_TZ 0x8000000 + +/* Rounding control. */ +# define _FPU_RC_NEAREST (0x0 << 24) /* RECOMMENDED. */ +# define _FPU_RC_ZERO (0x1 << 24) +# define _FPU_RC_UP (0x2 << 24) +# define _FPU_RC_DOWN (0x3 << 24) + +# define _FPU_RESERVED 0xf460ffc0 /* Reserved bits in cw. */ +# define _FPU_FPSR_RESERVED 0xffff4040 + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. */ + +# define _FPU_DEFAULT 0x00000000 +# define _FPU_FPSR_DEFAULT 0x00000000 + +/* IEEE: same as above, but exceptions. */ +# define _FPU_FPCR_IEEE 0x0000001F +# define _FPU_FPSR_IEEE 0x00000000 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +# if (__CSKY__ == 2) +# define _FPU_GETCW(cw) __asm__ volatile ("mfcr %0, cr<1, 2>" : "=a" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("mtcr %0, cr<1, 2>" : : "a" (cw)) +# define _FPU_GETFPSR(cw) __asm__ volatile ("mfcr %0, cr<2, 2>" : "=a" (cw)) +# define _FPU_SETFPSR(cw) __asm__ volatile ("mtcr %0, cr<2, 2>" : : "a" (cw)) +# else +# define _FPU_GETCW(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \ + " btsti %0, 31 \n" \ + " bt 1b \n" \ + " cprcr %0, cpcr1\n" : "=b" (cw)) + +# define _FPU_SETCW(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \ + " btsti r7, 31 \n" \ + " bt 1b \n" \ + " cpwcr %0, cpcr1 \n" \ + : : "b" (cw) : "r7") + +# define _FPU_GETFPSR(cw) __asm__ volatile ("1: cprcr %0, cpcr2 \n" \ + " btsti %0, 31 \n" \ + " bt 1b \n" \ + " cprcr %0, cpcr4\n" : "=b" (cw)) + +# define _FPU_SETFPSR(cw) __asm__ volatile ("1: cprcr r7, cpcr2 \n" \ + " btsti r7, 31 \n" \ + " bt 1b \n" \ + " cpwcr %0, cpcr4 \n" \ + : : "b" (cw) : "r7") +# endif /* __CSKY__ != 2 */ + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* !__csky_soft_float__ */ + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/kvx/bits/shm.h b/libc/sysdeps/linux/kvx/bits/shm.h new file mode 100644 index 000000000..bfb603499 --- /dev/null +++ b/libc/sysdeps/linux/kvx/bits/shm.h @@ -0,0 +1,87 @@ +/* + * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB + * in this tarball. + */ + +#ifndef _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ + __time_t shm_atime; /* time of last shmat() */ + __time_t shm_dtime; /* time of last shmdt() */ + __time_t shm_ctime; /* time of last change by shmctl() */ + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/linux/m68k/bits/fenv.h b/libc/sysdeps/linux/m68k/bits/fenv.h index b07f0ab51..37c5fe829 100644 --- a/libc/sysdeps/linux/m68k/bits/fenv.h +++ b/libc/sysdeps/linux/m68k/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,31 +11,38 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif +#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__ + /* Define bits representing the exception. We use the bit positions of the appropriate bits in the FPSR Accrued Exception Byte. */ enum { - FE_INEXACT = 1 << 3, -#define FE_INEXACT FE_INEXACT - FE_DIVBYZERO = 1 << 4, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_UNDERFLOW = 1 << 5, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 1 << 6, -#define FE_OVERFLOW FE_OVERFLOW - FE_INVALID = 1 << 7 -#define FE_INVALID FE_INVALID + FE_INEXACT = +# define FE_INEXACT (1 << 3) + FE_INEXACT, + FE_DIVBYZERO = +# define FE_DIVBYZERO (1 << 4) + FE_DIVBYZERO, + FE_UNDERFLOW = +# define FE_UNDERFLOW (1 << 5) + FE_UNDERFLOW, + FE_OVERFLOW = +# define FE_OVERFLOW (1 << 6) + FE_OVERFLOW, + FE_INVALID = +# define FE_INVALID (1 << 7) + FE_INVALID }; -#define FE_ALL_EXCEPT \ +# define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) /* The m68k FPU supports all of the four defined rounding modes. We use @@ -44,21 +50,45 @@ enum appropriate macros. */ enum { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 1 << 4, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 2 << 4, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 3 << 4 -#define FE_UPWARD FE_UPWARD + FE_TONEAREST = +# define FE_TONEAREST 0 + FE_TONEAREST, + FE_TOWARDZERO = +# define FE_TOWARDZERO (1 << 4) + FE_TOWARDZERO, + FE_DOWNWARD = +# define FE_DOWNWARD (2 << 4) + FE_DOWNWARD, + FE_UPWARD = +# define FE_UPWARD (3 << 4) + FE_UPWARD }; +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + +# define FE_ALL_EXCEPT 0 + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0 + FE_TONEAREST + }; + +#endif + /* Type representing exception flags. */ typedef unsigned int fexcept_t; +#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__ + /* Type representing floating-point environment. This structure corresponds to the layout of the block written by `fmovem'. */ typedef struct @@ -69,10 +99,30 @@ typedef struct } fenv_t; +#else + +/* Keep ABI compatibility with the type used in the generic + bits/fenv.h, formerly used for no-FPU ColdFire. */ +typedef struct + { + fexcept_t __excepts; + } +fenv_t; + +#endif + /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && (defined __HAVE_68881__ \ + || defined __HAVE_FPU__ \ + || defined __mcffpu__) /* Floating-point environment where none of the exceptions are masked. */ # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/m68k/bits/shm.h b/libc/sysdeps/linux/m68k/bits/shm.h new file mode 100644 index 000000000..aa1a72e54 --- /dev/null +++ b/libc/sysdeps/linux/m68k/bits/shm.h @@ -0,0 +1,108 @@ +/* Copyright (C) 1995,1996,1997,2000,2002,2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _SYS_SHM_H +# error "Never include <bits/shm.h> directly; use <sys/shm.h> instead." +#endif + +#include <bits/types.h> + +/* Permission flag for shmget. */ +#define SHM_R 0400 /* or S_IRUGO from <linux/stat.h> */ +#define SHM_W 0200 /* or S_IWUGO from <linux/stat.h> */ + +/* Flags for `shmat'. */ +#define SHM_RDONLY 010000 /* attach read-only else read-write */ +#define SHM_RND 020000 /* round attach address to SHMLBA */ +#define SHM_REMAP 040000 /* take-over region on attach */ + +/* Commands for `shmctl'. */ +#define SHM_LOCK 11 /* lock segment (root only) */ +#define SHM_UNLOCK 12 /* unlock segment (root only) */ + +__BEGIN_DECLS + +/* Segment low boundary address multiple. */ +#define SHMLBA (__getpagesize () << 2) +extern int __getpagesize (void) __THROW __attribute__ ((__const__)); + + +/* Type to count number of attaches. */ +typedef unsigned long int shmatt_t; + +/* Data structure describing a set of semaphores. */ +struct shmid_ds + { + struct ipc_perm shm_perm; /* operation permission struct */ + size_t shm_segsz; /* size of segment in bytes */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else + __time_t shm_atime; /* time of last shmat() */ + unsigned long int __uclibc_unused1; + __time_t shm_dtime; /* time of last shmdt() */ + unsigned long int __uclibc_unused2; + __time_t shm_ctime; /* time of last change by shmctl() */ + unsigned long int __uclibc_unused3; +#endif + __pid_t shm_cpid; /* pid of creator */ + __pid_t shm_lpid; /* pid of last shmop */ + shmatt_t shm_nattch; /* number of current attaches */ + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; + }; + +#ifdef __USE_MISC + +/* ipcs ctl commands */ +# define SHM_STAT 13 +# define SHM_INFO 14 + +/* shm_mode upper byte flags */ +# define SHM_DEST 01000 /* segment will be destroyed on last detach */ +# define SHM_LOCKED 02000 /* segment will not be swapped */ +# define SHM_HUGETLB 04000 /* segment is mapped via hugetlb */ +# define SHM_NORESERVE 010000 /* don't check for reservations */ + +struct shminfo + { + unsigned long int shmmax; + unsigned long int shmmin; + unsigned long int shmmni; + unsigned long int shmseg; + unsigned long int shmall; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; + unsigned long int __uclibc_unused3; + unsigned long int __uclibc_unused4; + }; + +struct shm_info + { + int used_ids; + unsigned long int shm_tot; /* total allocated shm */ + unsigned long int shm_rss; /* total resident shm */ + unsigned long int shm_swp; /* total swapped shm */ + unsigned long int swap_attempts; + unsigned long int swap_successes; + }; + +#endif /* __USE_MISC */ + +__END_DECLS diff --git a/libc/sysdeps/linux/m68k/bsd-_setjmp.S b/libc/sysdeps/linux/m68k/bsd-_setjmp.S index c963cccf5..eaabce8ed 100644 --- a/libc/sysdeps/linux/m68k/bsd-_setjmp.S +++ b/libc/sysdeps/linux/m68k/bsd-_setjmp.S @@ -13,7 +13,9 @@ _setjmp: moveal %sp@(4), %a0 movel %sp@(0), %a0@(JB_PC) moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS) -#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__ +#if defined(__mcffpu__) && defined(__UCLIBC_HAS_FPU__) + fmovemd %fp2-%fp7, %a0@(JB_FPREGS) +#elif defined(__HAVE_68881__) fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 diff --git a/libc/sysdeps/linux/m68k/bsd-setjmp.S b/libc/sysdeps/linux/m68k/bsd-setjmp.S index 9daf27713..7d76d192b 100644 --- a/libc/sysdeps/linux/m68k/bsd-setjmp.S +++ b/libc/sysdeps/linux/m68k/bsd-setjmp.S @@ -14,7 +14,9 @@ setjmp: moveal %sp@(4), %a0 movel %sp@(0), %a0@(JB_PC) moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS) -#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__ +#if defined(__mcffpu__) && defined(__UCLIBC_HAS_FPU__) + fmovemd %fp2-%fp7, %a0@(JB_FPREGS) +#elif defined(__HAVE_68881__) fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 diff --git a/libc/sysdeps/linux/m68k/fpu_control.h b/libc/sysdeps/linux/m68k/fpu_control.h index 35ad95e6d..c3a9c6326 100644 --- a/libc/sysdeps/linux/m68k/fpu_control.h +++ b/libc/sysdeps/linux/m68k/fpu_control.h @@ -1,6 +1,5 @@ /* 68k FPU control word definitions. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1996-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,8 +12,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H @@ -29,9 +28,9 @@ * 12 -> enable trap for OVFL exception * 11 -> enable trap for UNFL exception * 10 -> enable trap for DZ exception - * 9 -> enable trap for INEX2 exception - * 8 -> enable trap for INEX1 exception - * 7-6 -> Precision Control + * 9 -> enable trap for INEX2 exception (INEX on Coldfire) + * 8 -> enable trap for INEX1 exception (IDE on Coldfire) + * 7-6 -> Precision Control (only bit 6 is used on Coldfire) * 5-4 -> Rounding Control * 3-0 -> zero (read as 0, write as 0) * @@ -53,50 +52,66 @@ #include <features.h> +#if defined (__mcoldfire__) && !defined (__mcffpu__) + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +# define _FPU_GETCW(cw) ((cw) = 0) +# define _FPU_SETCW(cw) ((void) (cw)) + +#else + /* masking of interrupts */ -#define _FPU_MASK_BSUN 0x8000 -#define _FPU_MASK_SNAN 0x4000 -#define _FPU_MASK_OPERR 0x2000 -#define _FPU_MASK_OVFL 0x1000 -#define _FPU_MASK_UNFL 0x0800 -#define _FPU_MASK_DZ 0x0400 -#define _FPU_MASK_INEX1 0x0200 -#define _FPU_MASK_INEX2 0x0100 +# define _FPU_MASK_BSUN 0x8000 +# define _FPU_MASK_SNAN 0x4000 +# define _FPU_MASK_OPERR 0x2000 +# define _FPU_MASK_OVFL 0x1000 +# define _FPU_MASK_UNFL 0x0800 +# define _FPU_MASK_DZ 0x0400 +# define _FPU_MASK_INEX1 0x0200 +# define _FPU_MASK_INEX2 0x0100 /* precision control */ -#define _FPU_EXTENDED 0x00 /* RECOMMENDED */ -#define _FPU_DOUBLE 0x80 -#define _FPU_SINGLE 0x40 /* DO NOT USE */ +# ifdef __mcoldfire__ +# define _FPU_DOUBLE 0x00 +# else +# define _FPU_EXTENDED 0x00 /* RECOMMENDED */ +# define _FPU_DOUBLE 0x80 +# endif +# define _FPU_SINGLE 0x40 /* DO NOT USE */ /* rounding control */ -#define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ -#define _FPU_RC_ZERO 0x10 -#define _FPU_RC_DOWN 0x20 -#define _FPU_RC_UP 0x30 +# define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ +# define _FPU_RC_ZERO 0x10 +# define _FPU_RC_DOWN 0x20 +# define _FPU_RC_UP 0x30 -#define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ +# ifdef __mcoldfire__ +# define _FPU_RESERVED 0xFFFF800F +# else +# define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ +# endif /* Now two recommended fpucr */ /* The fdlibm code requires no interrupts for exceptions. Don't change the rounding mode, it would break long double I/O! */ -#define _FPU_DEFAULT 0x00000000 +# define _FPU_DEFAULT 0x00000000 /* IEEE: same as above, but exceptions. We must make it non-zero so that __setfpucw works. This bit will be ignored. */ -#define _FPU_IEEE 0x00000001 +# define _FPU_IEEE 0x00000001 + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("fmove%.l %0, %!" : : "dm" (cw)) +#endif /* Type of the control word. */ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) -#define _FPU_SETCW(cw) __asm__ __volatile__ ("fmove%.l %0, %!" : : "dm" (cw)) - -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif #endif /* _M68K_FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/m68k/setjmp.S b/libc/sysdeps/linux/m68k/setjmp.S index 5f05b8591..d10163ec6 100644 --- a/libc/sysdeps/linux/m68k/setjmp.S +++ b/libc/sysdeps/linux/m68k/setjmp.S @@ -14,7 +14,9 @@ __sigsetjmp: moveal %sp@(4), %a0 movel %sp@(0), %a0@(JB_PC) moveml %d2-%d7/%a2-%a7, %a0@(JB_REGS) -#if defined __HAVE_68881__ || defined __UCLIBC_HAS_FPU__ +#if defined(__mcffpu__) && defined (__UCLIBC_HAS_FPU__) + fmovemd %fp2-%fp7, %a0@(JB_FPREGS) +#elif defined(__HAVE_68881__) fmovemx %fp2-%fp7, %a0@(JB_FPREGS) #endif clrl %d0 diff --git a/libc/sysdeps/linux/mips/bits/fenv.h b/libc/sysdeps/linux/mips/bits/fenv.h index 944101f75..25ae4d9ca 100644 --- a/libc/sysdeps/linux/mips/bits/fenv.h +++ b/libc/sysdeps/linux/mips/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 1998-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,31 +11,38 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif +#ifdef __mips_hard_float + /* Define bits representing the exception. We use the bit positions of the appropriate bits in the FPU control word. */ enum { - FE_INEXACT = 0x04, -#define FE_INEXACT FE_INEXACT - FE_UNDERFLOW = 0x08, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 0x10, -#define FE_OVERFLOW FE_OVERFLOW - FE_DIVBYZERO = 0x20, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_INVALID = 0x40, -#define FE_INVALID FE_INVALID + FE_INEXACT = +# define FE_INEXACT 0x04 + FE_INEXACT, + FE_UNDERFLOW = +# define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_OVERFLOW = +# define FE_OVERFLOW 0x10 + FE_OVERFLOW, + FE_DIVBYZERO = +# define FE_DIVBYZERO 0x20 + FE_DIVBYZERO, + FE_INVALID = +# define FE_INVALID 0x40 + FE_INVALID, }; -#define FE_ALL_EXCEPT \ +# define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) /* The MIPS FPU supports all of the four defined rounding modes. We @@ -44,16 +50,38 @@ enum for the appropriate macros. */ enum { - FE_TONEAREST = 0x0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x1, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_UPWARD = 0x2, -#define FE_UPWARD FE_UPWARD - FE_DOWNWARD = 0x3 -#define FE_DOWNWARD FE_DOWNWARD + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST, + FE_TOWARDZERO = +# define FE_TOWARDZERO 0x1 + FE_TOWARDZERO, + FE_UPWARD = +# define FE_UPWARD 0x2 + FE_UPWARD, + FE_DOWNWARD = +# define FE_DOWNWARD 0x3 + FE_DOWNWARD }; +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST + }; + +# define FE_ALL_EXCEPT 0 + +#endif + /* Type representing exception flags. */ typedef unsigned short int fexcept_t; @@ -70,7 +98,13 @@ fenv_t; /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && defined __mips_hard_float /* Floating-point environment where none of the exception is masked. */ # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/mips/bits/msq.h b/libc/sysdeps/linux/mips/bits/msq.h index bcf1073e8..141b1ff9f 100644 --- a/libc/sysdeps/linux/mips/bits/msq.h +++ b/libc/sysdeps/linux/mips/bits/msq.h @@ -35,30 +35,58 @@ typedef unsigned long int msglen_t; /* Structure of record for one message inside the kernel. The type `struct msg' is opaque. */ +#if (__WORDSIZE == 32) && defined(__MIPSEL__) struct msqid_ds { struct ipc_perm msg_perm; /* structure describing operation permission */ -#if (__WORDSIZE == 32) && !defined(__MIPSEL__) - unsigned long __unused1; -#endif - __time_t msg_stime; /* time of last msgsnd command */ -#if (__WORDSIZE == 32) && defined(__MIPSEL__) - unsigned long __unused1; -#endif -#if (__WORDSIZE == 32) && !defined(__MIPSEL__) - unsigned long __unused2; -#endif - __time_t msg_rtime; /* time of last msgrcv command */ -#if (__WORDSIZE == 32) && defined(__MIPSEL__) - unsigned long __unused2; -#endif -#if (__WORDSIZE == 32) && !defined(__MIPSEL__) - unsigned long __unused3; -#endif - __time_t msg_ctime; /* time of last change */ -#if (__WORDSIZE == 32) && defined(__MIPSEL__) - unsigned long __unused3; -#endif +# if defined(__UCLIBC_USE_TIME64__) + unsigned long msg_stime_internal_1; /* time of last msgsnd command */ + unsigned long msg_stime_internal_2; + unsigned long msg_rtime_internal_1; /* time of last msgrcv command */ + unsigned long msg_rtime_internal_2; + unsigned long msg_ctime_internal_1; /* time of last change */ + unsigned long msg_ctime_internal_2; +# else + __time_t msg_stime; + unsigned long int __uclibc_unused1; + __time_t msg_rtime; + unsigned long int __uclibc_unused2; + __time_t msg_ctime; + unsigned long int __uclibc_unused3; +# endif + unsigned long int __msg_cbytes; /* current number of bytes on queue */ + msgqnum_t msg_qnum; /* number of messages currently on queue */ + msglen_t msg_qbytes; /* max number of bytes allowed on queue */ + __pid_t msg_lspid; /* pid of last msgsnd() */ + __pid_t msg_lrpid; /* pid of last msgrcv() */ + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; +# if defined(__UCLIBC_USE_TIME64__) + __time_t msg_stime; + __time_t msg_rtime; + __time_t msg_ctime; +# endif +}; + +#elif (__WORDSIZE == 32) && defined(__MIPSEB__) +struct msqid_ds +{ + struct ipc_perm msg_perm; /* structure describing operation permission */ +# if defined(__UCLIBC_USE_TIME64__) + unsigned long msg_stime_internal_2; /* time of last msgsnd command */ + unsigned long msg_stime_internal_1; + unsigned long msg_rtime_internal_2; /* time of last msgrcv command */ + unsigned long msg_rtime_internal_1; + unsigned long msg_ctime_internal_2; /* time of last change */ + unsigned long msg_ctime_internal_1; +# else + unsigned long int __uclibc_unused1; + __time_t msg_stime; + unsigned long int __uclibc_unused2; + __time_t msg_rtime; + unsigned long int __uclibc_unused3; + __time_t msg_ctime; +# endif unsigned long int __msg_cbytes; /* current number of bytes on queue */ msgqnum_t msg_qnum; /* number of messages currently on queue */ msglen_t msg_qbytes; /* max number of bytes allowed on queue */ @@ -66,8 +94,32 @@ struct msqid_ds __pid_t msg_lrpid; /* pid of last msgrcv() */ unsigned long int __uclibc_unused4; unsigned long int __uclibc_unused5; +# if defined(__UCLIBC_USE_TIME64__) + __time_t msg_stime; + __time_t msg_rtime; + __time_t msg_ctime; +# endif +}; + +#else + +struct msqid_ds +{ + struct ipc_perm msg_perm; /* structure describing operation permission */ + __time_t msg_stime; /* time of last msgsnd command */ + __time_t msg_rtime; /* time of last msgrcv command */ + __time_t msg_ctime; /* time of last change */ + unsigned long int __msg_cbytes; /* current number of bytes on queue */ + msgqnum_t msg_qnum; /* number of messages currently on queue */ + msglen_t msg_qbytes; /* max number of bytes allowed on queue */ + __pid_t msg_lspid; /* pid of last msgsnd() */ + __pid_t msg_lrpid; /* pid of last msgrcv() */ + unsigned long int __uclibc_unused4; + unsigned long int __uclibc_unused5; }; +#endif + #ifdef __USE_MISC # define msg_cbytes __msg_cbytes diff --git a/libc/sysdeps/linux/mips/bits/sem.h b/libc/sysdeps/linux/mips/bits/sem.h index 35eaa05c3..230d04868 100644 --- a/libc/sysdeps/linux/mips/bits/sem.h +++ b/libc/sysdeps/linux/mips/bits/sem.h @@ -38,22 +38,23 @@ struct semid_ds { struct ipc_perm sem_perm; /* operation permission struct */ -#if defined(__UCLIBC_USE_TIME64__) +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) unsigned long int __sem_otime_internal_1; /* last semop() time */ - unsigned long int __sem_otime_internal_2; unsigned long int __sem_ctime_internal_1; /* last time changed by semctl() */ - unsigned long int __sem_ctime_internal_2; #else __time_t sem_otime; /* last semop() time */ __time_t sem_ctime; /* last time changed by semctl() */ #endif unsigned long int sem_nsems; /* number of semaphores in set */ -#if defined(__UCLIBC_USE_TIME64__) +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + unsigned long int __sem_otime_internal_2; + unsigned long int __sem_ctime_internal_2; __time_t sem_otime; __time_t sem_ctime; -#endif +#else unsigned long int __uclibc_unused1; unsigned long int __uclibc_unused2; +#endif }; /* The user should define a union like the following to use it for arguments diff --git a/libc/sysdeps/linux/mips/bits/shm.h b/libc/sysdeps/linux/mips/bits/shm.h index bb87ba13d..1855a50b2 100644 --- a/libc/sysdeps/linux/mips/bits/shm.h +++ b/libc/sysdeps/linux/mips/bits/shm.h @@ -46,14 +46,32 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ - __time_t shm_atime; /* time of last shmat() */ - __time_t shm_dtime; /* time of last shmdt() */ - __time_t shm_ctime; /* time of last change by shmctl() */ +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + unsigned long int shm_atime_internal_1; /* time of last shmat() */ + unsigned long int shm_dtime_internal_1; /* time of last shmdt() */ + unsigned long int shm_ctime_internal_1; /* time of last change by shmctl() */ +#else + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __uclibc_unused1; - unsigned long int __uclibc_unused2; +#if (__WORDSIZE == 32) && defined(__UCLIBC_USE_TIME64__) + unsigned short int shm_atime_internal_2; /* time of last shmat() */ + unsigned short int shm_dtime_internal_2; /* time of last shmdt() */ + unsigned short int shm_ctime_internal_2; /* time of last change by shmctl() */ + unsigned short int __uclibc_unused1; + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else + unsigned short int __uclibc_unused1; + unsigned short int __uclibc_unused2; + unsigned short int __uclibc_unused3; + unsigned short int __uclibc_unused4; +#endif }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h index 13728ac55..64b42ffb1 100644 --- a/libc/sysdeps/linux/mips/bits/syscalls.h +++ b/libc/sysdeps/linux/mips/bits/syscalls.h @@ -184,7 +184,7 @@ ({ \ long _sys_result; \ \ - FORCE_FRAME_POINTER; \ + int* array = FORCE_FRAME_POINTER; \ { \ register long __v0 __asm__("$2") ncs_init; \ register long __a0 __asm__("$4") = (long) arg1; \ @@ -193,15 +193,16 @@ register long __a3 __asm__("$7") = (long) arg4; \ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ - "subu\t$29, 32\n\t" \ + "subu\t$29, 32\n\t" \ "sw\t%6, 16($29)\n\t" \ cs_init \ "syscall\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ + "addiu\t$29, 32\n\t" \ + "addiu\t%7, %7, 0\n\t" \ + ".set\treorder" \ : "=r" (__v0), "+r" (__a3) \ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ - "r" ((long)arg5) \ + "r" ((long)arg5), "r" (array) \ : __SYSCALL_CLOBBERS); \ err = __a3; \ _sys_result = __v0; \ @@ -213,7 +214,7 @@ ({ \ long _sys_result; \ \ - FORCE_FRAME_POINTER; \ + int* array = FORCE_FRAME_POINTER; \ { \ register long __v0 __asm__("$2") ncs_init; \ register long __a0 __asm__("$4") = (long) arg1; \ @@ -221,17 +222,18 @@ register long __a2 __asm__("$6") = (long) arg3; \ register long __a3 __asm__("$7") = (long) arg4; \ __asm__ __volatile__ ( \ - ".set\tnoreorder\n\t" \ - "subu\t$29, 32\n\t" \ + ".set\tnoreorder\n\t" \ + "subu\t$29, 32\n\t" \ "sw\t%6, 16($29)\n\t" \ "sw\t%7, 20($29)\n\t" \ cs_init \ "syscall\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ + "addiu\t$29, 32\n\t" \ + "addiu\t%8, %8, 0\n\t" \ + ".set\treorder" \ : "=r" (__v0), "+r" (__a3) \ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ - "r" ((long)arg5), "r" ((long)arg6) \ + "r" ((long)arg5), "r" ((long)arg6), "r" (array) \ : __SYSCALL_CLOBBERS); \ err = __a3; \ _sys_result = __v0; \ @@ -243,7 +245,7 @@ ({ \ long _sys_result; \ \ - FORCE_FRAME_POINTER; \ + int* array = FORCE_FRAME_POINTER; \ { \ register long __v0 __asm__("$2") ncs_init; \ register long __a0 __asm__("$4") = (long) arg1; \ @@ -252,17 +254,19 @@ register long __a3 __asm__("$7") = (long) arg4; \ __asm__ __volatile__ ( \ ".set\tnoreorder\n\t" \ - "subu\t$29, 32\n\t" \ + "subu\t$29, 32\n\t" \ "sw\t%6, 16($29)\n\t" \ "sw\t%7, 20($29)\n\t" \ "sw\t%8, 24($29)\n\t" \ cs_init \ "syscall\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ + "addiu\t$29, 32\n\t" \ + "addiu\t%9, %9, 0\n\t" \ + ".set\treorder" \ : "=r" (__v0), "+r" (__a3) \ : input, "r" (__a0), "r" (__a1), "r" (__a2), \ - "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \ + "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7), \ + "r" (array) \ : __SYSCALL_CLOBBERS); \ err = __a3; \ _sys_result = __v0; \ diff --git a/libc/sysdeps/linux/mips/fpu_control.h b/libc/sysdeps/linux/mips/fpu_control.h index f855af506..6aa05e4cf 100644 --- a/libc/sysdeps/linux/mips/fpu_control.h +++ b/libc/sysdeps/linux/mips/fpu_control.h @@ -1,7 +1,5 @@ /* FPU control word bits. Mips version. - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Olaf Flebbe and Ralf Baechle. + Copyright (C) 1996-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,8 +12,8 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H @@ -28,7 +26,10 @@ * causing unimplemented operation exception. This bit is only * available for MIPS III and newer. * 23 -> Condition bit - * 22-18 -> reserved (read as 0, write with 0) + * 22-21 -> reserved for architecture implementers + * 20 -> reserved (read as 0, write with 0) + * 19 -> IEEE 754-2008 non-arithmetic ABS.fmt and NEG.fmt enable + * 18 -> IEEE 754-2008 recommended NaN encoding enable * 17 -> cause bit for unimplemented operation * 16 -> cause bit for invalid exception * 15 -> cause bit for division by zero exception @@ -57,43 +58,74 @@ #include <features.h> -/* masking of interrupts */ +#ifdef __mips_soft_float + +#define _FPU_RESERVED 0xffffffff +#define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +#define _FPU_GETCW(cw) (cw) = 0 +#define _FPU_SETCW(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* __mips_soft_float */ + +/* Masks for interrupts. */ #define _FPU_MASK_V 0x0800 /* Invalid operation */ #define _FPU_MASK_Z 0x0400 /* Division by zero */ #define _FPU_MASK_O 0x0200 /* Overflow */ #define _FPU_MASK_U 0x0100 /* Underflow */ #define _FPU_MASK_I 0x0080 /* Inexact operation */ -/* flush denormalized numbers to zero */ +/* Flush denormalized numbers to zero. */ #define _FPU_FLUSH_TZ 0x1000000 -/* rounding control */ +/* IEEE 754-2008 compliance control. */ +#define _FPU_ABS2008 0x80000 +#define _FPU_NAN2008 0x40000 + +/* Rounding control. */ #define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ #define _FPU_RC_ZERO 0x1 #define _FPU_RC_UP 0x2 #define _FPU_RC_DOWN 0x3 +/* Mask for rounding control. */ +#define _FPU_RC_MASK 0x3 -#define _FPU_RESERVED 0xfe3c0000 /* Reserved bits in cw */ +#define _FPU_RESERVED 0xfe8c0000 /* Reserved bits in cw, incl ABS/NAN2008. */ /* The fdlibm code requires strict IEEE double precision arithmetic, and no interrupts for exceptions, rounding to nearest. */ +#ifdef __mips_nan2008 +# define _FPU_DEFAULT 0x000C0000 +#else +# define _FPU_DEFAULT 0x00000000 +#endif -#define _FPU_DEFAULT 0x00000000 - -/* IEEE: same as above, but exceptions */ -#define _FPU_IEEE 0x00000F80 +/* IEEE: same as above, but exceptions. */ +#ifdef __mips_nan2008 +# define _FPU_IEEE 0x000C0F80 +#else +# define _FPU_IEEE 0x00000F80 +#endif /* Type of the control word. */ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); /* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw)) -#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw)) +extern fpu_control_t __mips_fpu_getcw (void) __THROW; +extern void __mips_fpu_setcw (fpu_control_t) __THROW; +#ifdef __mips16 +# define _FPU_GETCW(cw) do { (cw) = __mips_fpu_getcw (); } while (0) +# define _FPU_SETCW(cw) __mips_fpu_setcw (cw) +#else +# define _FPU_GETCW(cw) __asm__ volatile ("cfc1 %0,$31" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("ctc1 %0,$31" : : "r" (cw)) +#endif -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +#endif /* __mips_soft_float */ #endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/or1k/bits/fenv.h b/libc/sysdeps/linux/or1k/bits/fenv.h new file mode 100644 index 000000000..4701946ff --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/fenv.h @@ -0,0 +1,84 @@ +/* Floating point environment, OpenRISC version. + Copyright (C) 2022-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +#ifdef __or1k_hard_float__ +/* Define bits representing exceptions in the FPCSR status word. */ +enum + { + FE_OVERFLOW = +#define FE_OVERFLOW (1 << 3) + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW (1 << 4) + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT (1 << 8) + FE_INEXACT, + FE_INVALID = +#define FE_INVALID (1 << 9) + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO (1 << 11) + FE_DIVBYZERO, + }; + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* Define bits representing rounding modes in the FPCSR Rmode field. */ +#define FE_TONEAREST (0x0 << 1) +#define FE_TOWARDZERO (0x1 << 1) +#define FE_UPWARD (0x2 << 1) +#define FE_DOWNWARD (0x3 << 1) + +#else + +/* In the soft-float case only rounding to nearest is supported, with + no exceptions. */ + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST + }; + +# define FE_ALL_EXCEPT 0 + +#endif /* __or1k_hard_float__ */ + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment. */ +typedef unsigned int fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1l) + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/or1k/fpu_control.h b/libc/sysdeps/linux/or1k/fpu_control.h new file mode 100644 index 000000000..9abde4f42 --- /dev/null +++ b/libc/sysdeps/linux/or1k/fpu_control.h @@ -0,0 +1,88 @@ +/* FPU control word bits. OpenRISC version. + Copyright (C) 2024-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +#ifndef __or1k_hard_float__ + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) + +#else /* __or1k_hard_float__ */ + +/* Layout of FPCSR: + + The bits of the FPCSR are defined as follows, this should help + explain how the masks below have come to be. + + +-----------+----------------------------+-----+----+ + | 32 - 12 | 11 10 9 8 7 6 5 4 3 | 2-1 | 0 | + +-----------+----------------------------+-----+----+ + | Reserved | DZ IN IV IX Z QN SN UN OV | RM | EE | + +-----------+----------------------------+-----+----+ + + Exception flags: + + DZ - divide by zero flag. + IN - infinite flag. + IV - invalid flag. + IX - inexact flag. + Z - zero flag. + QN - qnan flag. + SN - snan flag. + UN - underflow flag. + OV - overflow flag. + + Rounding modes: + + The FPCSR bits 2-1 labeled above as RM specify the rounding mode. + + 00 - round to nearest + 01 - round to zero + 10 - round to positive infinity + 11 - round to negative infinity + + Enabling exceptions: + + EE - set to enable FPU exceptions. + + */ + +# define _FPU_RESERVED 0xfffff000 +/* Default: rounding to nearest with exceptions disabled. */ +# define _FPU_DEFAULT 0 +/* IEEE: Same as above with exceptions enabled. */ +# define _FPU_IEEE (_FPU_DEFAULT | 1) + +# define _FPU_FPCSR_RM_MASK (0x3 << 1) + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ volatile ("l.mfspr %0,r0,20" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("l.mtspr r0,%0,20" : : "r" (cw)) + +#endif /* __or1k_hard_float__ */ + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/riscv32/bits/fenv.h b/libc/sysdeps/linux/riscv32/bits/fenv.h index a3f8031af..a6b828a76 100644 --- a/libc/sysdeps/linux/riscv32/bits/fenv.h +++ b/libc/sysdeps/linux/riscv32/bits/fenv.h @@ -64,10 +64,8 @@ typedef unsigned int fenv_t; /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((__const fenv_t *) -1) -#if __GLIBC_USE (IEC_60559_BFP_EXT) /* Type representing floating-point control modes. */ typedef unsigned int femode_t; /* Default floating-point control modes. */ # define FE_DFL_MODE ((const femode_t *) -1L) -#endif diff --git a/libc/sysdeps/linux/riscv32/bits/shm.h b/libc/sysdeps/linux/riscv32/bits/shm.h index 8a11c7050..9190c562b 100644 --- a/libc/sysdeps/linux/riscv32/bits/shm.h +++ b/libc/sysdeps/linux/riscv32/bits/shm.h @@ -37,12 +37,18 @@ struct shmid_ds { struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ +#if defined(__UCLIBC_USE_TIME64__) + __time_t shm_atime; + __time_t shm_dtime; + __time_t shm_ctime; +#else __time_t shm_atime; /* time of last shmat() */ unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ unsigned long int __uclibc_unused3; +#endif __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ diff --git a/libc/sysdeps/linux/riscv64/bits/fenv.h b/libc/sysdeps/linux/riscv64/bits/fenv.h index a3f8031af..a6b828a76 100644 --- a/libc/sysdeps/linux/riscv64/bits/fenv.h +++ b/libc/sysdeps/linux/riscv64/bits/fenv.h @@ -64,10 +64,8 @@ typedef unsigned int fenv_t; /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((__const fenv_t *) -1) -#if __GLIBC_USE (IEC_60559_BFP_EXT) /* Type representing floating-point control modes. */ typedef unsigned int femode_t; /* Default floating-point control modes. */ # define FE_DFL_MODE ((const femode_t *) -1L) -#endif diff --git a/libc/sysdeps/linux/riscv64/bits/shm.h b/libc/sysdeps/linux/riscv64/bits/shm.h index 8a11c7050..bfb603499 100644 --- a/libc/sysdeps/linux/riscv64/bits/shm.h +++ b/libc/sysdeps/linux/riscv64/bits/shm.h @@ -38,16 +38,13 @@ struct shmid_ds struct ipc_perm shm_perm; /* operation permission struct */ size_t shm_segsz; /* size of segment in bytes */ __time_t shm_atime; /* time of last shmat() */ - unsigned long int __uclibc_unused1; __time_t shm_dtime; /* time of last shmdt() */ - unsigned long int __uclibc_unused2; __time_t shm_ctime; /* time of last change by shmctl() */ - unsigned long int __uclibc_unused3; __pid_t shm_cpid; /* pid of creator */ __pid_t shm_lpid; /* pid of last shmop */ shmatt_t shm_nattch; /* number of current attaches */ - unsigned long int __uclibc_unused4; - unsigned long int __uclibc_unused5; + unsigned long int __uclibc_unused1; + unsigned long int __uclibc_unused2; }; #ifdef __USE_MISC diff --git a/libc/sysdeps/linux/sh/bits/fenv.h b/libc/sysdeps/linux/sh/bits/fenv.h index 38c303ff2..349e7ddde 100644 --- a/libc/sysdeps/linux/sh/bits/fenv.h +++ b/libc/sysdeps/linux/sh/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 1999-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,7 +12,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." @@ -24,34 +23,39 @@ of the appropriate bits in the FPU control word. */ enum { - FE_INEXACT = 0x04, -#define FE_INEXACT FE_INEXACT - FE_UNDERFLOW = 0x08, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 0x10, -#define FE_OVERFLOW FE_OVERFLOW - FE_DIVBYZERO = 0x20, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_INVALID = 0x40, -#define FE_INVALID FE_INVALID + FE_INEXACT = +#define FE_INEXACT 0x04 + FE_INEXACT, + FE_UNDERFLOW = +#define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_OVERFLOW = +#define FE_OVERFLOW 0x10 + FE_OVERFLOW, + FE_DIVBYZERO = +#define FE_DIVBYZERO 0x20 + FE_DIVBYZERO, + FE_INVALID = +#define FE_INVALID 0x40 + FE_INVALID, }; #define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) -/* The SH FPU supports all of the four defined rounding modes. We - use again the bit positions in the FPU control word as the values - for the appropriate macros. */ +/* The SH FPU supports two of the four defined rounding modes: round to nearest + and round to zero. We use again the bit positions in the FPU control word + as the values for the appropriate macros. */ enum { - FE_TONEAREST = 0x0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x1, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_UPWARD = 0x2, -#define FE_UPWARD FE_UPWARD - FE_DOWNWARD = 0x3 -#define FE_DOWNWARD FE_DOWNWARD + __FE_UNDEFINED = -1, + + FE_TONEAREST = +#define FE_TONEAREST 0x0 + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO 0x1 + FE_TOWARDZERO, }; @@ -68,4 +72,10 @@ typedef struct fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((fenv_t *) -1) +#define FE_DFL_ENV ((const fenv_t *) -1) + +/* Type representing floating-point control modes. */ +typedef unsigned int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/sh/fpu_control.h b/libc/sysdeps/linux/sh/fpu_control.h index 8143041fe..d5f401f91 100644 --- a/libc/sysdeps/linux/sh/fpu_control.h +++ b/libc/sysdeps/linux/sh/fpu_control.h @@ -1,6 +1,5 @@ /* FPU control word definitions. SH version. - Copyright (C) 1999, 2000, 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1999-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,14 +13,23 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H -#ifndef __SH4__ -#error This file is only correct for sh4 -#endif +#if !defined(__SH_FPU_ANY__) + +#define _FPU_RESERVED 0xffffffff +#define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +#define _FPU_GETCW(cw) (cw) = 0 +#define _FPU_SETCW(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else + +#include <features.h> /* masking of interrupts */ #define _FPU_MASK_VM 0x0800 /* Invalid operation */ @@ -48,16 +56,20 @@ typedef unsigned int fpu_control_t; #define _FPU_GETCW(cw) __asm__ ("sts fpscr,%0" : "=r" (cw)) #if defined __GNUC__ -/* GCC provides this function */ +__BEGIN_DECLS + +/* GCC provides this function. */ extern void __set_fpscr (unsigned long); #define _FPU_SETCW(cw) __set_fpscr ((cw)) #else #define _FPU_SETCW(cw) __asm__ ("lds %0,fpscr" : : "r" (cw)) #endif -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +__END_DECLS + +#endif /* __SH_FPU_ANY__ */ #endif /* _FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/sparc/bits/fenv.h b/libc/sysdeps/linux/sparc/bits/fenv.h index 79ab8cefa..83b32cc51 100644 --- a/libc/sysdeps/linux/sparc/bits/fenv.h +++ b/libc/sysdeps/linux/sparc/bits/fenv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1997-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -12,26 +12,34 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif +#include <bits/wordsize.h> + + /* Define bits representing the exception. We use the bit positions of the appropriate accrued exception bits from the FSR. */ enum { - FE_INVALID = (1 << 9), -#define FE_INVALID FE_INVALID - FE_OVERFLOW = (1 << 8), -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = (1 << 7), -#define FE_UNDERFLOW FE_UNDERFLOW - FE_DIVBYZERO = (1 << 6), -#define FE_DIVBYZERO FE_DIVBYZERO - FE_INEXACT = (1 << 5) -#define FE_INEXACT FE_INEXACT + FE_INVALID = +#define FE_INVALID (1 << 9) + FE_INVALID, + FE_OVERFLOW = +#define FE_OVERFLOW (1 << 8) + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW (1 << 7) + FE_UNDERFLOW, + FE_DIVBYZERO = +#define FE_DIVBYZERO (1 << 6) + FE_DIVBYZERO, + FE_INEXACT = +#define FE_INEXACT (1 << 5) + FE_INEXACT }; #define FE_ALL_EXCEPT \ @@ -42,14 +50,18 @@ enum for the appropriate macros. */ enum { - FE_TONEAREST = (0U << 30), -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = (1U << 30), -#define FE_TOWARDZERO FE_TOWARDZERO - FE_UPWARD = (2U << 30), -#define FE_UPWARD FE_UPWARD - FE_DOWNWARD = (3U << 30) -#define FE_DOWNWARD FE_DOWNWARD + FE_TONEAREST = +#define FE_TONEAREST (0 << 30) + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO (1 << 30) + FE_TOWARDZERO, + FE_UPWARD = +#define FE_UPWARD (-0x7fffffff - 1) /* (2 << 30) */ + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD (-0x40000000) /* (3 << 30) */ + FE_DOWNWARD }; #define __FE_ROUND_MASK (3U << 30) @@ -70,6 +82,8 @@ typedef unsigned long int fenv_t; # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif -/* For internal use only: access the fp state register. */ -#define __fenv_stfsr(X) __asm__ ("st %%fsr,%0" : "=m" (X)) -#define __fenv_ldfsr(X) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X)) +/* Type representing floating-point control modes. */ +typedef unsigned long int femode_t; + +/* Default floating-point control modes. */ +# define FE_DFL_MODE ((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/sparc/fpu_control.h b/libc/sysdeps/linux/sparc/fpu_control.h index 57f1dbb67..542f9fb1b 100644 --- a/libc/sysdeps/linux/sparc/fpu_control.h +++ b/libc/sysdeps/linux/sparc/fpu_control.h @@ -1,6 +1,5 @@ /* FPU control word bits. SPARC version. - Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. - Contributed by Miguel de Icaza + Copyright (C) 1997-2025 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -14,13 +13,14 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H 1 #include <features.h> +#include <bits/wordsize.h> /* masking of interrupts */ #define _FPU_MASK_IM 0x08000000 @@ -41,7 +41,7 @@ #define _FPU_RC_ZERO 0x40000000 #define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ -#define _FPU_RESERVED 0x30300000 /* Reserved bits in cw */ +#define _FPU_RESERVED 0x303e0000 /* Reserved bits in cw */ /* Now two recommended cw */ @@ -56,12 +56,20 @@ /* Type of the control word. */ typedef unsigned long int fpu_control_t; -#define _FPU_GETCW(cw) __asm__ ("st %%fsr,%0" : "=m" (*&cw)) -#define _FPU_SETCW(cw) __asm__ ("ld %0,%%fsr" : : "m" (*&cw)) +#if __WORDSIZE == 64 +# define _FPU_GETCW(cw) __asm__ __volatile__ ("stx %%fsr,%0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (*&cw)) +#else +# ifdef __leon__ + /* Prevent stfsr from being placed directly after other fp instruction. */ +# define _FPU_GETCW(cw) __asm__ __volatile__ ("nop; st %%fsr,%0" : "=m" (*&cw)) +# else +# define _FPU_GETCW(cw) __asm__ __volatile__ ("st %%fsr,%0" : "=m" (*&cw)) +# endif +# define _FPU_SETCW(cw) __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (*&cw)) +#endif -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif #endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/x86_64/crt1.S b/libc/sysdeps/linux/x86_64/crt1.S index 701cbf2f6..151aeffeb 100644 --- a/libc/sysdeps/linux/x86_64/crt1.S +++ b/libc/sysdeps/linux/x86_64/crt1.S @@ -83,11 +83,7 @@ _start: #ifdef L_rcrt1 pushq %rdi /* save rdi (but should be 0...) */ pushq %rdx /* store rdx (rtld_fini) */ - xorq %rcx, %rcx /* ensure rcx is 0 */ - addq _start@GOTPCREL(%rip), %rcx /* get offset of _start from beginning of file */ - movq _start@GOTPCREL(%rip), %rax /* get run time address of _start */ - subq %rcx, %rax /* calculate run time load offset */ - movq %rax, %rdi /* load offset -> param 1 */ + lea __ehdr_start(%rip), %rdi /* "Calculate" load address... */ call reloc_static_pie /* relocate dynamic addrs */ xorq %rax, %rax /* cleanup */ popq %rdx |