diff options
Diffstat (limited to 'libc/misc')
| -rw-r--r-- | libc/misc/Makefile.in | 3 | ||||
| -rw-r--r-- | libc/misc/auxvt/Makefile.in | 23 | ||||
| -rwxr-xr-x | libc/misc/auxvt/getauxval.c | 44 | ||||
| -rw-r--r-- | libc/misc/elf/dl-support.c | 19 | ||||
| -rw-r--r-- | libc/misc/fnmatch/fnmatch_loop.c | 3 | ||||
| -rw-r--r-- | libc/misc/getloadavg/Makefile | 13 | ||||
| -rw-r--r-- | libc/misc/getloadavg/Makefile.in | 23 | ||||
| -rw-r--r-- | libc/misc/getloadavg/getloadavg.c | 41 | ||||
| -rw-r--r-- | libc/misc/internals/Makefile.in | 3 | ||||
| -rw-r--r-- | libc/misc/internals/__uClibc_main.c | 27 | ||||
| -rw-r--r-- | libc/misc/internals/reloc_static_pie.c | 115 | ||||
| -rw-r--r-- | libc/misc/internals/tempname.c | 3 | ||||
| -rw-r--r-- | libc/misc/regex/regex_internal.h | 2 | ||||
| -rw-r--r-- | libc/misc/sysvipc/ipc.h | 9 | ||||
| -rw-r--r-- | libc/misc/sysvipc/msgq.c | 21 | ||||
| -rw-r--r-- | libc/misc/sysvipc/sem.c | 23 | ||||
| -rw-r--r-- | libc/misc/sysvipc/shm.c | 19 | ||||
| -rw-r--r-- | libc/misc/time/time.c | 11 | ||||
| -rw-r--r-- | libc/misc/wchar/wchar.c | 3 | 
19 files changed, 371 insertions, 34 deletions
| diff --git a/libc/misc/Makefile.in b/libc/misc/Makefile.in index e45002e60..caf7f1391 100644 --- a/libc/misc/Makefile.in +++ b/libc/misc/Makefile.in @@ -5,7 +5,9 @@  # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.  # +  include $(top_srcdir)libc/misc/assert/Makefile.in +include $(top_srcdir)libc/misc/auxvt/Makefile.in  include $(top_srcdir)libc/misc/ctype/Makefile.in  include $(top_srcdir)libc/misc/dirent/Makefile.in  include $(top_srcdir)libc/misc/error/Makefile.in @@ -14,6 +16,7 @@ include $(top_srcdir)libc/misc/file/Makefile.in  include $(top_srcdir)libc/misc/fnmatch/Makefile.in  include $(top_srcdir)libc/misc/ftw/Makefile.in  include $(top_srcdir)libc/misc/fts/Makefile.in +include $(top_srcdir)libc/misc/getloadavg/Makefile.in  include $(top_srcdir)libc/misc/glob/Makefile.in  include $(top_srcdir)libc/misc/internals/Makefile.in  include $(top_srcdir)libc/misc/locale/Makefile.in diff --git a/libc/misc/auxvt/Makefile.in b/libc/misc/auxvt/Makefile.in new file mode 100644 index 000000000..142ade10c --- /dev/null +++ b/libc/misc/auxvt/Makefile.in @@ -0,0 +1,23 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +subdirs += libc/misc/auxvt + +CSRC-y := getauxval.c + +MISC_AUXVT_DIR := $(top_srcdir)libc/misc/auxvt +MISC_AUXVT_OUT := $(top_builddir)libc/misc/auxvt + +MISC_AUXVT_SRC := $(patsubst %.c,$(MISC_AUXVT_DIR)/%.c,$(CSRC-y)) +MISC_AUXVT_OBJ := $(patsubst %.c,$(MISC_AUXVT_OUT)/%.o,$(CSRC-y)) + +libc-y += $(MISC_AUXVT_OBJ) + +objclean-y += CLEAN_libc/misc/auxvt + +CLEAN_libc/misc/auxvt: +	$(do_rm) $(addprefix $(MISC_AUXVT_OUT)/*., o os) diff --git a/libc/misc/auxvt/getauxval.c b/libc/misc/auxvt/getauxval.c new file mode 100755 index 000000000..7610b7e5c --- /dev/null +++ b/libc/misc/auxvt/getauxval.c @@ -0,0 +1,44 @@ +/*  Copyright (C) 2022     Ramin Seyed Moussavi + *  An getauxval() function compatible with the glibc auxv.h + *  that is used by uClibc-ng. + * + *  This library is free software; you can redistribute it and/or + *  modify it under the terms of the GNU Library General Public + *  License as published by the Free Software Foundation; either + *  version 2 of the License, or (at your option) any later version. + * + *  This 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 + *  Library General Public License for more details. + * + *  You should have received a copy of the GNU Library General Public + *  License along with this library; if not, see + *  <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> +#include <ldso.h> +#include <sys/auxv.h> + +unsigned long int __getauxval (unsigned long int __type) +{ +	// 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; +	} + +	// 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; +} + +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/fnmatch/fnmatch_loop.c b/libc/misc/fnmatch/fnmatch_loop.c index fdd451d43..025510de6 100644 --- a/libc/misc/fnmatch/fnmatch_loop.c +++ b/libc/misc/fnmatch/fnmatch_loop.c @@ -620,7 +620,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,  		    if (c == L('-') && *p != L(']'))  		      { -#if _LIBC +#ifdef _LIBC  			/* We have to find the collation sequence  			   value for C.  Collation sequence is nothing  			   we can regularly access.  The sequence @@ -917,7 +917,6 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end,  		  }  		else if (c == L('[') && *p == L('.'))  		  { -		    ++p;  		    while (1)  		      {  			c = *++p; diff --git a/libc/misc/getloadavg/Makefile b/libc/misc/getloadavg/Makefile new file mode 100644 index 000000000..4a8f4a072 --- /dev/null +++ b/libc/misc/getloadavg/Makefile @@ -0,0 +1,13 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +top_srcdir=../../../ +top_builddir=../../../ +all: objs +include $(top_builddir)Rules.mak +include Makefile.in +include $(top_srcdir)Makerules diff --git a/libc/misc/getloadavg/Makefile.in b/libc/misc/getloadavg/Makefile.in new file mode 100644 index 000000000..3c8ca24f0 --- /dev/null +++ b/libc/misc/getloadavg/Makefile.in @@ -0,0 +1,23 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. +# + +subdirs += libc/misc/getloadavg + +CSRC-y := getloadavg.c + +MISC_GETLOADAVG_DIR := $(top_srcdir)libc/misc/getloadavg +MISC_GETLOADAVG_OUT := $(top_builddir)libc/misc/getloadavg + +MISC_GETLOADAVG_SRC := $(patsubst %.c,$(MISC_GETLOADAVG_DIR)/%.c,$(CSRC-y)) +MISC_GETLOADAVG_OBJ := $(patsubst %.c,$(MISC_GETLOADAVG_OUT)/%.o,$(CSRC-y)) + +libc-y += $(MISC_GETLOADAVG_OBJ) + +objclean-y += CLEAN_libc/misc/getloadavg + +CLEAN_libc/misc/getloadavg: +	$(do_rm) $(addprefix $(MISC_GETLOADAVG_OUT)/*., o os) diff --git a/libc/misc/getloadavg/getloadavg.c b/libc/misc/getloadavg/getloadavg.c new file mode 100644 index 000000000..0d98119a9 --- /dev/null +++ b/libc/misc/getloadavg/getloadavg.c @@ -0,0 +1,41 @@ +/* + * Copyright © 2005-2020 Rich Felker, et al. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Imported from musl C library + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif /* _GNU_SOURCE */ +#include <stdlib.h> +#include <sys/sysinfo.h> + +int getloadavg(double *a, int n) +{ +	struct sysinfo si; +	if (n <= 0) return n ? -1 : 0; +	sysinfo(&si); +	if (n > 3) n = 3; +	for (int i=0; i<n; i++) +		a[i] = 1.0/(1<<SI_LOAD_SHIFT) * si.loads[i]; +	return n; +} diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in index a8e4e36f9..908b18321 100644 --- a/libc/misc/internals/Makefile.in +++ b/libc/misc/internals/Makefile.in @@ -17,7 +17,7 @@ MISC_INTERNALS_SRC := $(patsubst %.c,$(MISC_INTERNALS_DIR)/%.c,$(CSRC-y))  MISC_INTERNALS_OBJ := $(patsubst %.c,$(MISC_INTERNALS_OUT)/%.o,$(CSRC-y))  CFLAGS-__uClibc_main.c := $(SSP_DISABLE_FLAGS) - +CFLAGS-reloc_static_pie.c := $(SSP_DISABLE_FLAGS) -DL_rcrt1  libc-y += $(MISC_INTERNALS_OBJ)  ifneq ($(UCLIBC_FORMAT_SHARED_FLAT),y) @@ -34,6 +34,7 @@ libc-static-$(UCLIBC_FORMAT_FLAT_SEP_DATA) += \  libc-static-$(UCLIBC_FORMAT_SHARED_FLAT) += \    $(MISC_INTERNALS_OUT)/shared_flat_initfini.o \    $(MISC_INTERNALS_OUT)/shared_flat_add_library.o +libc-static-$(STATIC_PIE) += $(MISC_INTERNALS_OUT)/reloc_static_pie.o  libc-shared-$(UCLIBC_FORMAT_SHARED_FLAT) += \    $(MISC_INTERNALS_OUT)/shared_flat_initfini.os \    $(MISC_INTERNALS_OUT)/shared_flat_add_library.os diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index affa0ce0a..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; @@ -109,7 +111,7 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av);   * in or linker will disregard these weaks.   */ -static int __pthread_return_0 (pthread_mutex_t *unused) { return 0; } +static int __pthread_return_0 (pthread_mutex_t *unused) { (void)unused; return 0; }  weak_alias (__pthread_return_0, __pthread_mutex_lock)  weak_alias (__pthread_return_0, __pthread_mutex_trylock)  weak_alias (__pthread_return_0, __pthread_mutex_unlock) @@ -117,6 +119,7 @@ weak_alias (__pthread_return_0, __pthread_mutex_unlock)  int weak_function  __pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)  { +        (void)mutex; (void)attr;          return 0;  } @@ -372,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__ @@ -398,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 @@ -430,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 new file mode 100644 index 000000000..3bbdef18e --- /dev/null +++ b/libc/misc/internals/reloc_static_pie.c @@ -0,0 +1,115 @@ +/* Support for relocating static PIE. +   Copyright (C) 2017-2022 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 +   <https://www.gnu.org/licenses/>.  */ +#define IS_IN_rtld      // force inline function calls +#include <link.h> +#include <elf.h> +#include <dl-elf.h> + +#include <ldso.h> +#if defined(__m68k__) || defined(__mips__) || defined(__xtensa__) +#include <dl-startup.h> +#endif + +extern ElfW(Addr) _dl_load_base; + +void +reloc_static_pie (ElfW(Addr) load_addr); + +void +reloc_static_pie(ElfW(Addr) load_addr) +{ +    int indx; +    ElfW(Addr) got; +    ElfW(Dyn) *dpnt; +    struct elf_resolve tpnt_tmp; +	struct elf_resolve *tpnt = &tpnt_tmp; + +    DL_BOOT_COMPUTE_GOT(got); +    DL_BOOT_COMPUTE_DYN(dpnt, got, (DL_LOADADDR_TYPE)load_addr); + +    _dl_memset(tpnt, 0, sizeof(struct elf_resolve)); +    tpnt->loadaddr = load_addr; +    tpnt->dynamic_addr = dpnt; + +    __dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL, load_addr); + +#if defined(PERFORM_BOOTSTRAP_GOT) +	/* some arches (like MIPS) we have to tweak the GOT before relocations */ +	PERFORM_BOOTSTRAP_GOT(tpnt); +#endif + +#if !defined(__FDPIC__) +    DL_RELOCATE_RELR(tpnt); +#endif + +#if defined(ELF_MACHINE_PLTREL_OVERLAP) +# define INDX_MAX 1 +#else +# define INDX_MAX 2 +#endif + +    for (indx = 0; indx < INDX_MAX; indx++) { +        unsigned long rel_addr, rel_size; +        ElfW(Word) relative_count = tpnt->dynamic_info[DT_RELCONT_IDX]; + +        rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : +                           tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]); +        rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : +			               tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]); + +        if (!rel_addr) +            continue; + +        if((0 == indx) && relative_count) { +			rel_size -= relative_count * sizeof(ELF_RELOC); +            elf_machine_relative(load_addr, rel_addr, relative_count); +			rel_addr += relative_count * sizeof(ELF_RELOC); +        } + +#ifdef ARCH_NEEDS_BOOTSTRAP_RELOCS +			{ +				ELF_RELOC *rpnt; +				unsigned int i; +				ElfW(Sym) *sym; +				unsigned long symbol_addr; +				int symtab_index; +				unsigned long *reloc_addr; + +				/* Now parse the relocation information */ +				rpnt = (ELF_RELOC *) rel_addr; +				for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) { +					reloc_addr = (unsigned long *) DL_RELOC_ADDR(load_addr, (unsigned long)rpnt->r_offset); +					symtab_index = ELF_R_SYM(rpnt->r_info); +					symbol_addr = 0; +					sym = NULL; +					if (symtab_index) { +						ElfW(Sym) *symtab; +						symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB]; +						sym = &symtab[symtab_index]; +						symbol_addr = (unsigned long) DL_RELOC_ADDR(load_addr, sym->st_value); +					} +					/* Use this machine-specific macro to perform the actual relocation.  */ +					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/internals/tempname.c b/libc/misc/internals/tempname.c index d3a8ccbd8..f9b714a68 100644 --- a/libc/misc/internals/tempname.c +++ b/libc/misc/internals/tempname.c @@ -218,7 +218,8 @@ int attribute_hidden __gen_tempname (char *tmpl, int kind, int flags,  			    /* Give up now. */  			    return -1;  		    } else -			fd = 0; +			/* File already exists, so return with non-zero value */ +			return -1;  		}  	    case __GT_FILE:  		fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | flags, mode); diff --git a/libc/misc/regex/regex_internal.h b/libc/misc/regex/regex_internal.h index 5d9154fa0..c0f61d4ce 100644 --- a/libc/misc/regex/regex_internal.h +++ b/libc/misc/regex/regex_internal.h @@ -58,7 +58,7 @@  #define gettext(msgid)       (msgid)  #define gettext_noop(String) String -#if (defined MB_CUR_MAX && HAVE_LOCALE_H && HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_WCRTOMB && HAVE_MBRTOWC && HAVE_WCSCOLL) +#if (defined MB_CUR_MAX && defined HAVE_LOCALE_H && defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_WCRTOMB && defined HAVE_MBRTOWC && defined HAVE_WCSCOLL)  # define RE_ENABLE_I18N  #endif 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 64be1cae0..66f86f53c 100644 --- a/libc/misc/sysvipc/sem.c +++ b/libc/misc/sysvipc/sem.c @@ -23,6 +23,9 @@  #include "ipc.h" +#if defined(__UCLIBC_USE_TIME64__) +#include "internal/time64_helpers.h" +#endif  #ifdef L_semctl  /* Return identifier for array of NSEMS semaphores associated with @@ -53,7 +56,17 @@ int semctl(int semid, int semnum, int cmd, ...)      arg = va_arg (ap, union semun);      va_end (ap);  #ifdef __NR_semctl -    return __semctl(semid, semnum, cmd | __IPC_64, arg.__pad); +    int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad); +#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      return __syscall_ipc(IPCOP_semctl, semid, semnum, cmd|__IPC_64, &arg, NULL);  #endif @@ -90,7 +103,13 @@ int semop (int semid, struct sembuf *sops, size_t nsops)  #ifdef L_semtimedop -#ifdef __NR_semtimedop +#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64) +int semtimedop(int semid, struct sembuf *sops, size_t nsops, const struct timespec *timeout) +{ +    return INLINE_SYSCALL(semtimedop_time64, 4, semid, sops, nsops, TO_TS64_P(timeout)); +} + +#elif defined(__NR_semtimedop)  _syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)  #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/misc/time/time.c b/libc/misc/time/time.c index cd189169a..b6a5b097d 100644 --- a/libc/misc/time/time.c +++ b/libc/misc/time/time.c @@ -1311,7 +1311,7 @@ ISO_LOOP:  			j = (i & 128) ? 100: 12;  			if (i & 64) { -				field_val /= j;; +				field_val /= j;  			}  			if (i & 32) {  				field_val %= j; @@ -2478,9 +2478,16 @@ DST_CORRECT:  							+ p[3]) + p[7])));  DST_CORRECT: +#if defined(__UCLIBC_USE_TIME64__) +	if (((unsigned long long)(secs - LLONG_MIN)) +		> (((unsigned long long)LLONG_MAX) - LLONG_MIN) +		) +#else  	if (((unsigned long long)(secs - LONG_MIN))  		> (((unsigned long long)LONG_MAX) - LONG_MIN) -		) { +		) +#endif +	{  		t = ((time_t)(-1));  		goto DONE;  	} diff --git a/libc/misc/wchar/wchar.c b/libc/misc/wchar/wchar.c index 201f30772..782b67f93 100644 --- a/libc/misc/wchar/wchar.c +++ b/libc/misc/wchar/wchar.c @@ -781,6 +781,7 @@ size_t wcsnrtombs(char *__restrict dst, const wchar_t **__restrict src,  	size_t count;  	int incr;  	char buf[MB_LEN_MAX]; +	(void)ps;  #ifdef __CTYPE_HAS_UTF_8_LOCALES  	if (ENCODING == __ctype_encoding_utf8) { @@ -1297,7 +1298,7 @@ iconv_t weak_function iconv_open(const char *tocode, const char *fromcode)  int weak_function iconv_close(iconv_t cd)  { -	free(cd); +	free((void *) cd);  	return 0;  } | 
