diff options
Diffstat (limited to 'libc')
41 files changed, 368 insertions, 116 deletions
diff --git a/libc/misc/internals/reloc_static_pie.c b/libc/misc/internals/reloc_static_pie.c index 81af7d666..cb2c4df87 100644 --- a/libc/misc/internals/reloc_static_pie.c +++ b/libc/misc/internals/reloc_static_pie.c @@ -21,7 +21,7 @@ #include <dl-elf.h> #include <ldso.h> -#if defined(__mips__) || defined(__xtensa__) +#if defined(__m68k__) || defined(__mips__) || defined(__xtensa__) #include <dl-startup.h> #endif diff --git a/libc/stdlib/malloc/memalign.c b/libc/stdlib/malloc/memalign.c index 665f20cfb..54f6dbc6c 100644 --- a/libc/stdlib/malloc/memalign.c +++ b/libc/stdlib/malloc/memalign.c @@ -11,6 +11,7 @@ * Written by Miles Bader <miles@gnu.org> */ +#include <errno.h> #include <stdlib.h> #include <unistd.h> #include <sys/mman.h> @@ -38,6 +39,11 @@ memalign (size_t alignment, size_t size) unsigned long tot_addr, tot_end_addr, addr, end_addr; struct heap_free_area **heap = &__malloc_heap; + if (unlikely(size > PTRDIFF_MAX)) { + __set_errno(ENOMEM); + return NULL; + } + /* Make SIZE something we like. */ size = HEAP_ADJUST_SIZE (size); diff --git a/libc/sysdeps/linux/aarch64/sys/ucontext.h b/libc/sysdeps/linux/aarch64/sys/ucontext.h index 5f75cbbf3..1a27f918b 100644 --- a/libc/sysdeps/linux/aarch64/sys/ucontext.h +++ b/libc/sysdeps/linux/aarch64/sys/ucontext.h @@ -45,10 +45,10 @@ typedef elf_fpregset_t fpregset_t; typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; __sigset_t uc_sigmask; unsigned char __reserved[128]; diff --git a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h index 7a97bb4d7..e874a4a9f 100644 --- a/libc/sysdeps/linux/common-generic/bits/kernel_stat.h +++ b/libc/sysdeps/linux/common-generic/bits/kernel_stat.h @@ -18,7 +18,7 @@ * However that requires more #ifndef in relevant wrappers, * further uglifying them */ -#define kernel_stat64 stat +#define kernel_stat64 stat64 #endif /* _BITS_STAT_STRUCT_H */ diff --git a/libc/sysdeps/linux/common/adjtimex.c b/libc/sysdeps/linux/common/adjtimex.c index f45d54371..2fd7977f6 100644 --- a/libc/sysdeps/linux/common/adjtimex.c +++ b/libc/sysdeps/linux/common/adjtimex.c @@ -9,8 +9,16 @@ #include <sys/syscall.h> #include <sys/timex.h> - +#if defined(__NR_adjtimex) _syscall1(int, adjtimex, struct timex *, buf) +#else +#include <time.h> +int adjtimex(struct timex *buf) +{ + return clock_adjtime(CLOCK_REALTIME, buf); +} +#endif + libc_hidden_def(adjtimex) weak_alias(adjtimex,__adjtimex) #if defined __UCLIBC_NTP_LEGACY__ diff --git a/libc/sysdeps/linux/common/bits/stab.def b/libc/sysdeps/linux/common/bits/stab.def index 8a2b8f39d..8d16c5c2c 100644 --- a/libc/sysdeps/linux/common/bits/stab.def +++ b/libc/sysdeps/linux/common/bits/stab.def @@ -17,7 +17,7 @@ <http://www.gnu.org/licenses/>. */ /* This contains contribution from Cygnus Support. */ - + /* Global variable. Only the name is significant. To find the address, look in the corresponding external symbol. */ __define_stab (N_GSYM, 0x20, "GSYM") @@ -177,7 +177,7 @@ __define_stab (N_NBLCS, 0xF8, "NBLCS") /* Second symbol entry containing a length-value for the preceding entry. The value is the length. */ __define_stab (N_LENG, 0xfe, "LENG") - + /* The above information, in matrix format. STAB MATRIX diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c index 4d787b9b7..b924d860b 100644 --- a/libc/sysdeps/linux/common/clock_gettime.c +++ b/libc/sysdeps/linux/common/clock_gettime.c @@ -11,10 +11,14 @@ #include <sys/syscall.h> #include <time.h> +#ifdef __VDSO_SUPPORT__ +#include "ldso.h" +#endif + #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64) #include "internal/time64_helpers.h" -int clock_gettime(clockid_t clock_id, struct timespec *tp) +int __libc_clock_gettime(clockid_t clock_id, struct timespec *tp) { struct __ts64_struct __ts64; int __ret = INLINE_SYSCALL(clock_gettime64, 2, clock_id, &__ts64); @@ -26,11 +30,14 @@ int clock_gettime(clockid_t clock_id, struct timespec *tp) return __ret; } #elif defined(__NR_clock_gettime) -_syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp) +int __libc_clock_gettime(clockid_t clock_id, struct timespec *tp) +{ + return INLINE_SYSCALL(clock_gettime, 2, clock_id, tp); +} #else # include <sys/time.h> -int clock_gettime(clockid_t clock_id, struct timespec* tp) +int __libc_clock_gettime(clockid_t clock_id, struct timespec* tp) { struct timeval tv; int retval = -1; @@ -53,3 +60,12 @@ int clock_gettime(clockid_t clock_id, struct timespec* tp) return retval; } #endif + +int clock_gettime(clockid_t clock_id, struct timespec *tp) +{ +#if defined(__VDSO_SUPPORT__) && defined(ARCH_VDSO_CLOCK_GETTIME) + return ARCH_VDSO_CLOCK_GETTIME(clock_id, tp); +#else + return __libc_clock_gettime(clock_id, tp); +#endif +} diff --git a/libc/sysdeps/linux/common/futimens.c b/libc/sysdeps/linux/common/futimens.c index 03e58f4b5..2f3d72420 100644 --- a/libc/sysdeps/linux/common/futimens.c +++ b/libc/sysdeps/linux/common/futimens.c @@ -8,7 +8,7 @@ #include <sys/syscall.h> #include <time.h> -#ifdef __NR_utimensat +#if defined(__NR_utimensat) || defined(__NR_utimensat_time64) /* To avoid superfluous warnings about passing NULL to the non-null annotated * 2nd param "__path" below, we bypass inclusion of sys/stat.h and use * a non annotated, local decl. diff --git a/libc/sysdeps/linux/common/futimesat.c b/libc/sysdeps/linux/common/futimesat.c index fd19fea7c..bf36550dd 100644 --- a/libc/sysdeps/linux/common/futimesat.c +++ b/libc/sysdeps/linux/common/futimesat.c @@ -7,6 +7,7 @@ */ #include <sys/syscall.h> +#include <sys/stat.h> #include <sys/time.h> #ifdef __NR_futimesat diff --git a/libc/sysdeps/linux/common/gettimeofday.c b/libc/sysdeps/linux/common/gettimeofday.c index ed18b2be5..9b29fe5a0 100755 --- a/libc/sysdeps/linux/common/gettimeofday.c +++ b/libc/sysdeps/linux/common/gettimeofday.c @@ -14,30 +14,18 @@ #include "ldso.h" #endif -#ifdef __VDSO_SUPPORT__ -typedef int (*gettimeofday_func)(struct timeval * tv, __timezone_ptr_t tz); -#endif - int gettimeofday(struct timeval * tv, __timezone_ptr_t tz) { - - #ifdef __VDSO_SUPPORT__ - if ( _dl__vdso_gettimeofday != 0 ){ - gettimeofday_func func= _dl__vdso_gettimeofday; - return func( tv, tz ); - - }else{ - _syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz) - } - #else - if (!tv) - return 0; - - struct timespec __ts; - int __ret = clock_gettime(CLOCK_REALTIME, &__ts); - tv->tv_sec = __ts.tv_sec; - tv->tv_usec = (suseconds_t)__ts.tv_nsec / 1000; - return __ret; - #endif + if (!tv) + return 0; +#if defined(__VDSO_SUPPORT__) && defined(ARCH_VDSO_GETTIMEOFDAY) + return ARCH_VDSO_GETTIMEOFDAY(tv, tz); +#else + struct timespec __ts; + int __ret = clock_gettime(CLOCK_REALTIME, &__ts); + tv->tv_sec = __ts.tv_sec; + tv->tv_usec = (suseconds_t)__ts.tv_nsec / 1000; + return __ret; +#endif } diff --git a/libc/sysdeps/linux/common/not-cancel.h b/libc/sysdeps/linux/common/not-cancel.h index 9d1588494..426edcc46 100644 --- a/libc/sysdeps/linux/common/not-cancel.h +++ b/libc/sysdeps/linux/common/not-cancel.h @@ -19,6 +19,7 @@ #include <sys/types.h> #include <sysdep.h> +#include <time.h> #ifdef NOT_IN_libc @@ -113,9 +114,10 @@ extern __typeof(pause) __pause_nocancel; #ifdef __NR_nanosleep # define nanosleep_not_cancel(requested_time, remaining) \ INLINE_SYSCALL (nanosleep, 2, requested_time, remaining) -/*#else +#else +extern int __nanosleep_nocancel (const struct timespec *requested_time, struct timespec *remaining); # define nanosleep_not_cancel(requested_time, remaining) \ - __nanosleep_nocancel (requested_time, remaining)*/ + __nanosleep_nocancel (requested_time, remaining) #endif #if 0 diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c index 7a446a589..f9d16d6c8 100644 --- a/libc/sysdeps/linux/common/pselect.c +++ b/libc/sysdeps/linux/common/pselect.c @@ -34,7 +34,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) { -#ifdef __NR_pselect6 +#if defined(__NR_pselect6) || defined(__NR_pselect6_time64) /* The Linux kernel can in some situations update the timeout value. * We do not want that so use a local variable. */ diff --git a/libc/sysdeps/linux/common/sys/epoll.h b/libc/sysdeps/linux/common/sys/epoll.h index 5551bed0d..5138d77a9 100644 --- a/libc/sysdeps/linux/common/sys/epoll.h +++ b/libc/sysdeps/linux/common/sys/epoll.h @@ -19,6 +19,7 @@ #define _SYS_EPOLL_H 1 #include <stdint.h> +#include <sys/ioctl.h> #include <sys/types.h> /* Get __sigset_t. */ @@ -87,6 +88,19 @@ struct epoll_event epoll_data_t data; /* User data variable */ } __EPOLL_PACKED; +struct epoll_params +{ + uint32_t busy_poll_usecs; + uint16_t busy_poll_budget; + uint8_t prefer_busy_poll; + + /* pad the struct to a multiple of 64bits */ + uint8_t __pad; +}; + +#define EPOLL_IOC_TYPE 0x8A +#define EPIOCSPARAMS _IOW(EPOLL_IOC_TYPE, 0x01, struct epoll_params) +#define EPIOCGPARAMS _IOR(EPOLL_IOC_TYPE, 0x02, struct epoll_params) __BEGIN_DECLS diff --git a/libc/sysdeps/linux/common/utime.c b/libc/sysdeps/linux/common/utime.c index e4ac0b269..c716388e8 100644 --- a/libc/sysdeps/linux/common/utime.c +++ b/libc/sysdeps/linux/common/utime.c @@ -9,7 +9,7 @@ #include <sys/syscall.h> #include <utime.h> -#if defined __NR_utimensat && !defined __NR_utime +#if (defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime # include <fcntl.h> # include <stddef.h> @@ -51,7 +51,7 @@ int utime(const char *file, const struct utimbuf *times) } #endif -#if (defined __NR_utimensat && !defined __NR_utime) || \ +#if ((defined(__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utime) || \ defined __NR_utime || defined __NR_utimes libc_hidden_def(utime) #endif diff --git a/libc/sysdeps/linux/common/utimensat.c b/libc/sysdeps/linux/common/utimensat.c index fa6f90e55..5816c7890 100644 --- a/libc/sysdeps/linux/common/utimensat.c +++ b/libc/sysdeps/linux/common/utimensat.c @@ -8,6 +8,7 @@ #include <sys/syscall.h> #include <sys/stat.h> +#include <stdint.h> #if defined(__UCLIBC_USE_TIME64__) #include "internal/time64_helpers.h" @@ -28,7 +29,7 @@ int utimensat(int fd, const char *path, const struct timespec times[2], int flag } }; - return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? &__times64 : 0, flags); + return INLINE_SYSCALL(utimensat_time64, 4, fd, path, times ? (uintptr_t) &__times64 : 0, flags); } #else _syscall4(int, utimensat, int, fd, const char *, path, const struct timespec *, times, int, flags) diff --git a/libc/sysdeps/linux/common/utimes.c b/libc/sysdeps/linux/common/utimes.c index e6fc578f3..a28594dfd 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_utimes +#if (defined (__NR_utimensat) || defined(__NR_utimensat_time64)) && !defined __NR_utimes # 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_utimes || defined __NR_utime +#if defined __NR_utimensat || defined __NR_utimensat_time64 || defined __NR_utimes || defined __NR_utime libc_hidden_def(utimes) #endif diff --git a/libc/sysdeps/linux/common/wait4.c b/libc/sysdeps/linux/common/wait4.c index cd042d5e7..486ffaab8 100644 --- a/libc/sysdeps/linux/common/wait4.c +++ b/libc/sysdeps/linux/common/wait4.c @@ -10,6 +10,7 @@ #include <sys/wait.h> #include <sys/resource.h> +#if defined(__NR_wait4) # define __NR___syscall_wait4 __NR_wait4 static __always_inline _syscall4(int, __syscall_wait4, __kernel_pid_t, pid, int *, status, int, opts, struct rusage *, rusage) @@ -32,6 +33,59 @@ pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage) return __syscall_wait4(pid, status, opts, rusage); #endif } + +#else +pid_t __wait4_nocancel(pid_t pid, int *status, int opts, struct rusage *rusage) +{ + idtype_t type; + int __res; + siginfo_t info; + + info.si_pid = 0; + + if (pid < -1) { + type = P_PGID; + pid = -pid; + } else if (pid == -1) { + type = P_ALL; + } else if (pid == 0) { + type = P_PGID; + } else { + type = P_PID; + } + + __res = INLINE_SYSCALL(waitid, 5, type, pid, &info, opts|WEXITED, rusage); + + if ( __res < 0 ) + return __res; + + if (info.si_pid && status) { + int sw = 0; + switch (info.si_code) { + case CLD_CONTINUED: + sw = 0xffff; + break; + case CLD_DUMPED: + sw = (info.si_status & 0x7f) | 0x80; + break; + case CLD_EXITED: + sw = (info.si_status & 0xff) << 8; + break; + case CLD_KILLED: + sw = info.si_status & 0x7f; + break; + case CLD_STOPPED: + case CLD_TRAPPED: + sw = (info.si_status << 8) + 0x7f; + break; + } + *status = sw; + } + + return info.si_pid; +} +#endif + #ifdef __USE_BSD strong_alias(__wait4_nocancel,wait4) #endif diff --git a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h index 3f5dab80c..1b866cb90 100644 --- a/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h +++ b/libc/sysdeps/linux/csky/bits/uClibc_arch_features.h @@ -17,9 +17,6 @@ /* can your target use syscall6() for mmap ? */ #undef __UCLIBC_MMAP_HAS_6_ARGS__ -/* does your target use statx */ -#define __UCLIBC_HAVE_STATX__ - #ifdef __CSKYABIV2__ #undef __UCLIBC_SYSCALL_ALIGN_64BIT__ #else diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c index cf6daa787..515ef99f2 100644 --- a/libc/sysdeps/linux/i386/sigaction.c +++ b/libc/sysdeps/linux/i386/sigaction.c @@ -31,15 +31,16 @@ extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden; extern void restore(void) __asm__ ("__restore") attribute_hidden; -/* If ACT is not NULL, change the action for SIG to *ACT. +/* If ACT is not NULL, change mask, handler and flags for SIG to ACT's If OACT is not NULL, put the old action for SIG in *OACT. */ int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { struct sigaction kact; if (act) { - memcpy(&kact, act, sizeof(kact)); - kact.sa_flags |= SA_RESTORER; + memcpy(&kact.sa_mask, &act->sa_mask, sizeof(sigset_t)); + kact.sa_handler = act->sa_handler; + kact.sa_flags = act->sa_flags; kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore; act = &kact; } diff --git a/libc/sysdeps/linux/nds32/Makefile.arch b/libc/sysdeps/linux/nds32/Makefile.arch index c7627b847..caf163844 100644 --- a/libc/sysdeps/linux/nds32/Makefile.arch +++ b/libc/sysdeps/linux/nds32/Makefile.arch @@ -2,6 +2,6 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. CSRC-y := brk.c prctl.c mremap.c -SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S sysdep.S +SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S vfork.S sysdep.S CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c swapcontext.c SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S diff --git a/libc/sysdeps/linux/nds32/bits/kernel_types.h b/libc/sysdeps/linux/nds32/bits/kernel_types.h index 6b142d2e5..1b6ae4d1b 100644 --- a/libc/sysdeps/linux/nds32/bits/kernel_types.h +++ b/libc/sysdeps/linux/nds32/bits/kernel_types.h @@ -14,13 +14,13 @@ typedef unsigned short __kernel_dev_t; typedef unsigned long __kernel_ino_t; -typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_mode_t; typedef unsigned short __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; -typedef int __kernel_ipc_pid_t; -typedef unsigned int __kernel_uid_t; -typedef unsigned int __kernel_gid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; @@ -34,11 +34,19 @@ typedef unsigned short __kernel_gid16_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; -typedef __kernel_uid_t __kernel_old_uid_t; -typedef __kernel_gid_t __kernel_old_gid_t; -typedef unsigned int __kernel_old_dev_t; +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef __kernel_dev_t __kernel_old_dev_t; typedef long __kernel_long_t; typedef unsigned long __kernel_ulong_t; __extension__ typedef long long __kernel_loff_t; +typedef struct { +#ifdef __USE_ALL + int val[2]; +#else + int __val[2]; +#endif +} __kernel_fsid_t; + #endif /* __ARCH_NDS32_POSIX_TYPES_H */ diff --git a/libc/sysdeps/linux/nds32/bits/syscalls.h b/libc/sysdeps/linux/nds32/bits/syscalls.h index 50e30db7d..a5cdda18a 100644 --- a/libc/sysdeps/linux/nds32/bits/syscalls.h +++ b/libc/sysdeps/linux/nds32/bits/syscalls.h @@ -37,7 +37,8 @@ #define Y(x) X(x) #define LIB_SYSCALL __NR_syscall -#define __issue_syscall(syscall_name) "syscall 0x0;\n" +#define __issue_syscall(syscall_name) \ +" syscall " Y(syscall_name) "; \n" #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u) diff --git a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h index 8499e99b4..5b85f4d23 100644 --- a/libc/sysdeps/linux/nds32/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/nds32/jmpbuf-unwind.h @@ -20,7 +20,7 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { - uintptr_t sp = &(regs)[0].__regs[__JMP_BUF_SP]; + uintptr_t sp = (uintptr_t) &(regs)[0].__regs[__JMP_BUF_SP]; return sp; } diff --git a/libc/sysdeps/linux/nds32/sys/ucontext.h b/libc/sysdeps/linux/nds32/sys/ucontext.h index ea86a3ad0..0d7422aab 100644 --- a/libc/sysdeps/linux/nds32/sys/ucontext.h +++ b/libc/sysdeps/linux/nds32/sys/ucontext.h @@ -36,10 +36,10 @@ typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { - unsigned long int __uc_flags; - struct ucontext_t *uc_link; + unsigned long int uc_flags; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; __sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/nds32/vfork.S b/libc/sysdeps/linux/nds32/vfork.S new file mode 100644 index 000000000..ab32135fc --- /dev/null +++ b/libc/sysdeps/linux/nds32/vfork.S @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2016-2017 Andes Technology, Inc. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + Contributed by Philip Blundell <philb@gnu.org>. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) +#ifdef PIC +.pic +#endif + +#ifdef __NR_vfork + syscall __NR_vfork + bltz $r0, 2f +1: + ret +2: + sltsi $r1, $r0, -4096 + bnez $r1, 1b; + +# ifdef __ASSUME_VFORK_SYSCALL +# ifdef PIC + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +# else + /* Check if vfork syscall is known at all. */ + li $r1, -ENOSYS + beq $r0, $r1, 1f + +# ifdef PIC +3: + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL + /* If we don't have vfork, fork is close enough. */ + syscall __NR_fork + bgez $r0, 1f + sltsi $r1, $r0, -4096 + bnez $r1, 1f + +# ifdef PIC + b 3b +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: + ret + +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif + +PSEUDO_END (__vfork) +weak_alias (__vfork, vfork) +libc_hidden_def (vfork) diff --git a/libc/sysdeps/linux/riscv32/crt1.S b/libc/sysdeps/linux/riscv32/crt1.S index 15aa0763c..5e33046d4 100644 --- a/libc/sysdeps/linux/riscv32/crt1.S +++ b/libc/sysdeps/linux/riscv32/crt1.S @@ -45,9 +45,6 @@ .globl _start .type _start,%function - .weak _init - .weak _fini - _start: call .Lload_gp mv a5, a0 /* rtld_fini. */ @@ -55,9 +52,9 @@ _start: la a0, main REG_L a1, 0(sp) /* argc. */ addi a2, sp, SZREG /* argv. */ + mv a3, zero + mv a4, zero andi sp, sp, ALMASK /* Align stack. */ - lla a3, _init - lla a4, _fini mv a6, sp /* stack_end. */ tail __uClibc_main@plt diff --git a/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h b/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h index 2e5f37f10..fb5d65ddd 100644 --- a/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h +++ b/libc/sysdeps/linux/riscv32/jmpbuf-unwind.h @@ -23,8 +23,8 @@ /* Test if longjmp to JMPBUF would unwind the frame containing a local variable at ADDRESS. */ -#define _JMPBUF_UNWINDS(jmpbuf, address, demangle) \ - ((void *) (address) < (void *) demangle ((jmpbuf)[0].__sp)) +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) ((jmpbuf)[0].__sp)) #define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) @@ -33,9 +33,6 @@ static inline uintptr_t __attribute__ ((unused)) _jmpbuf_sp (__jmp_buf regs) { uintptr_t sp = regs[0].__sp; -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (sp); -#endif return sp; } diff --git a/libc/sysdeps/linux/riscv32/sys/ucontext.h b/libc/sysdeps/linux/riscv32/sys/ucontext.h index 2893ff359..308ccb8c2 100644 --- a/libc/sysdeps/linux/riscv32/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv32/sys/ucontext.h @@ -83,10 +83,10 @@ typedef struct mcontext_t } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the diff --git a/libc/sysdeps/linux/riscv64/crt1.S b/libc/sysdeps/linux/riscv64/crt1.S index 15aa0763c..5e33046d4 100644 --- a/libc/sysdeps/linux/riscv64/crt1.S +++ b/libc/sysdeps/linux/riscv64/crt1.S @@ -45,9 +45,6 @@ .globl _start .type _start,%function - .weak _init - .weak _fini - _start: call .Lload_gp mv a5, a0 /* rtld_fini. */ @@ -55,9 +52,9 @@ _start: la a0, main REG_L a1, 0(sp) /* argc. */ addi a2, sp, SZREG /* argv. */ + mv a3, zero + mv a4, zero andi sp, sp, ALMASK /* Align stack. */ - lla a3, _init - lla a4, _fini mv a6, sp /* stack_end. */ tail __uClibc_main@plt diff --git a/libc/sysdeps/linux/riscv64/sys/ucontext.h b/libc/sysdeps/linux/riscv64/sys/ucontext.h index 2893ff359..308ccb8c2 100644 --- a/libc/sysdeps/linux/riscv64/sys/ucontext.h +++ b/libc/sysdeps/linux/riscv64/sys/ucontext.h @@ -83,10 +83,10 @@ typedef struct mcontext_t } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __uc_flags; - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the diff --git a/libc/sysdeps/linux/sparc/Makefile.arch b/libc/sysdeps/linux/sparc/Makefile.arch index d34624f36..c9529b344 100644 --- a/libc/sysdeps/linux/sparc/Makefile.arch +++ b/libc/sysdeps/linux/sparc/Makefile.arch @@ -6,7 +6,7 @@ # CSRC-y := brk.c __syscall_error.c sigaction.c -SSRC-y := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S \ +SSRC-y := __longjmp.S setjmp.S sigreturn_stub.S bsd-setjmp.S bsd-_setjmp.S \ syscall.S urem.S udiv.S umul.S sdiv.S rem.S pipe.S fork.S vfork.S clone.S CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c diff --git a/libc/sysdeps/linux/sparc/sigaction.c b/libc/sysdeps/linux/sparc/sigaction.c index 7895e3acd..447943e3a 100644 --- a/libc/sysdeps/linux/sparc/sigaction.c +++ b/libc/sysdeps/linux/sparc/sigaction.c @@ -30,8 +30,8 @@ _syscall5(int, rt_sigaction, int, a, int, b, int, c, int, d, int, e) -static void __rt_sigreturn_stub(void); -static void __sigreturn_stub(void); +void __rt_sigreturn_stub(void); +void __sigreturn_stub(void); int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { @@ -75,24 +75,3 @@ libc_hidden_weak(sigaction) # endif #endif - -static void -__rt_sigreturn_stub(void) -{ - __asm__( - "mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn) - ); -} -static void -__sigreturn_stub(void) -{ - __asm__( - "mov %0, %%g1\n\t" - "ta 0x10\n\t" - : /* no outputs */ - : "i" (__NR_sigreturn) - ); -} diff --git a/libc/sysdeps/linux/sparc/sigreturn_stub.S b/libc/sysdeps/linux/sparc/sigreturn_stub.S new file mode 100644 index 000000000..33f51409b --- /dev/null +++ b/libc/sysdeps/linux/sparc/sigreturn_stub.S @@ -0,0 +1,14 @@ +#include <sysdep.h> + + nop + nop + +ENTRY_NOCFI (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x10 +END_NOCFI (__rt_sigreturn_stub) + +ENTRY_NOCFI (__sigreturn_stub) + mov __NR_sigreturn, %g1 + ta 0x10 +END_NOCFI (__sigreturn_stub) diff --git a/libc/sysdeps/linux/sparc/sysdep.h b/libc/sysdeps/linux/sparc/sysdep.h index c3897ec08..761d21454 100644 --- a/libc/sysdeps/linux/sparc/sysdep.h +++ b/libc/sysdeps/linux/sparc/sysdep.h @@ -17,6 +17,15 @@ C_LABEL(name) \ cfi_startproc; +#define ENTRY_NOCFI(name) \ + .align 4; \ + .global C_SYMBOL_NAME(name); \ + .type name, @function; \ +C_LABEL(name) + +#define END_NOCFI(name) \ + .size name, . - name + #define END(name) \ cfi_endproc; \ .size name, . - name diff --git a/libc/sysdeps/linux/sparc64/Makefile.arch b/libc/sysdeps/linux/sparc64/Makefile.arch index 37b539b3b..cc4000b78 100644 --- a/libc/sysdeps/linux/sparc64/Makefile.arch +++ b/libc/sysdeps/linux/sparc64/Makefile.arch @@ -5,7 +5,7 @@ CSRC-y := __syscall_error.c sigaction.c SSRC-y := __longjmp.S setjmp.S bsd-setjmp.S bsd-_setjmp.S brk.S fork.S \ - syscall.S pipe.S vfork.S clone.S + syscall.S pipe.S vfork.S clone.S sigreturn_stub.S CSRC-y += $(addprefix soft-fp/, \ qp_add.c qp_cmp.c qp_cmpe.c qp_div.c qp_dtoq.c qp_feq.c qp_fge.c \ diff --git a/libc/sysdeps/linux/sparc64/sigaction.c b/libc/sysdeps/linux/sparc64/sigaction.c index d8aaad0fb..b28fa659a 100644 --- a/libc/sysdeps/linux/sparc64/sigaction.c +++ b/libc/sysdeps/linux/sparc64/sigaction.c @@ -26,7 +26,7 @@ /* SPARC 64bit userland requires a kernel that has rt signals anyway. */ -static void __rt_sigreturn_stub (void); +void __rt_sigreturn_stub (void); int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { @@ -67,11 +67,3 @@ libc_hidden_weak(sigaction) # endif #endif -static void -__rt_sigreturn_stub (void) -{ - __asm__ ("mov %0, %%g1\n\t" - "ta 0x6d\n\t" - : /* no outputs */ - : "i" (__NR_rt_sigreturn)); -} diff --git a/libc/sysdeps/linux/sparc64/sigreturn_stub.S b/libc/sysdeps/linux/sparc64/sigreturn_stub.S new file mode 100644 index 000000000..a5c9bb47f --- /dev/null +++ b/libc/sysdeps/linux/sparc64/sigreturn_stub.S @@ -0,0 +1,10 @@ +#include <sysdep.h> + + nop + nop + +ENTRY_NOCFI (__rt_sigreturn_stub) + mov __NR_rt_sigreturn, %g1 + ta 0x6d +END_NOCFI (__rt_sigreturn_stub) + diff --git a/libc/sysdeps/linux/sparc64/sysdep.h b/libc/sysdeps/linux/sparc64/sysdep.h index 31008c34b..5a4c36348 100644 --- a/libc/sysdeps/linux/sparc64/sysdep.h +++ b/libc/sysdeps/linux/sparc64/sysdep.h @@ -83,6 +83,15 @@ C_LABEL(name) \ cfi_endproc; \ .size name, . - name +#define ENTRY_NOCFI(name) \ + .align 4; \ + .global C_SYMBOL_NAME(name); \ + .type name, @function; \ +C_LABEL(name) + +#define END_NOCFI(name) \ + .size name, . - name + #define LOC(name) .L##name #undef PSEUDO diff --git a/libc/sysdeps/linux/tile/sys/ucontext.h b/libc/sysdeps/linux/tile/sys/ucontext.h index ed2c27b58..068da8c4a 100644 --- a/libc/sysdeps/linux/tile/sys/ucontext.h +++ b/libc/sysdeps/linux/tile/sys/ucontext.h @@ -82,10 +82,10 @@ typedef struct } mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { unsigned long int __ctx(uc_flags); - struct ucontext_t *uc_link; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h index b99928b1e..bfcd571d2 100644 --- a/libc/sysdeps/linux/xtensa/bits/xtensa-config.h +++ b/libc/sysdeps/linux/xtensa/bits/xtensa-config.h @@ -32,21 +32,41 @@ macros. */ #undef XCHAL_HAVE_NSA +#ifdef __XCHAL_HAVE_NSA +#define XCHAL_HAVE_NSA __XCHAL_HAVE_NSA +#else #define XCHAL_HAVE_NSA 1 +#endif #undef XCHAL_HAVE_LOOPS +#ifdef __XCHAL_HAVE_LOOPS +#define XCHAL_HAVE_LOOPS __XCHAL_HAVE_LOOPS +#else #define XCHAL_HAVE_LOOPS 1 +#endif /* Assume the maximum number of AR registers. This currently only affects the __window_spill function, and it is always safe to flush extra. */ #undef XCHAL_NUM_AREGS +#ifdef __XCHAL_NUM_AREGS +#define XCHAL_NUM_AREGS __XCHAL_NUM_AREGS +#else #define XCHAL_NUM_AREGS 64 +#endif #undef XCHAL_HAVE_S32C1I +#ifdef __XCHAL_HAVE_S32C1I +#define XCHAL_HAVE_S32C1I __XCHAL_HAVE_S32C1I +#else #define XCHAL_HAVE_S32C1I 1 +#endif #undef XCHAL_HAVE_EXCLUSIVE +#ifdef __XCHAL_HAVE_EXCLUSIVE +#define XCHAL_HAVE_EXCLUSIVE __XCHAL_HAVE_EXCLUSIVE +#else #define XCHAL_HAVE_EXCLUSIVE 0 +#endif #endif /* !XTENSA_CONFIG_H */ diff --git a/libc/sysdeps/linux/xtensa/crti.S b/libc/sysdeps/linux/xtensa/crti.S index ba804eb45..43e66e308 100644 --- a/libc/sysdeps/linux/xtensa/crti.S +++ b/libc/sysdeps/linux/xtensa/crti.S @@ -3,6 +3,7 @@ .section .init .align 4 .global _init + .hidden _init .type _init, @function _init: #if defined(__XTENSA_WINDOWED_ABI__) @@ -17,6 +18,7 @@ _init: .section .fini .align 4 .global _fini + .hidden _fini .type _fini, @function _fini: #if defined(__XTENSA_WINDOWED_ABI__) |