diff options
Diffstat (limited to 'src/internal')
-rw-r--r-- | src/internal/aio_impl.h | 9 | ||||
-rw-r--r-- | src/internal/atomic.h | 17 | ||||
-rw-r--r-- | src/internal/complex_impl.h | 22 | ||||
-rw-r--r-- | src/internal/dynlink.h | 17 | ||||
-rw-r--r-- | src/internal/emulate_wait4.c | 55 | ||||
-rw-r--r-- | src/internal/floatscan.c | 5 | ||||
-rw-r--r-- | src/internal/fork_impl.h | 21 | ||||
-rw-r--r-- | src/internal/ksigaction.h | 5 | ||||
-rw-r--r-- | src/internal/libc.h | 9 | ||||
-rw-r--r-- | src/internal/libm.h | 233 | ||||
-rw-r--r-- | src/internal/locale_impl.h | 2 | ||||
-rw-r--r-- | src/internal/malloc_impl.h | 46 | ||||
-rw-r--r-- | src/internal/pthread_impl.h | 44 | ||||
-rw-r--r-- | src/internal/shgetc.c | 2 | ||||
-rw-r--r-- | src/internal/stdio_impl.h | 2 | ||||
-rw-r--r-- | src/internal/syscall.h | 201 |
16 files changed, 526 insertions, 164 deletions
diff --git a/src/internal/aio_impl.h b/src/internal/aio_impl.h new file mode 100644 index 00000000..a8657665 --- /dev/null +++ b/src/internal/aio_impl.h @@ -0,0 +1,9 @@ +#ifndef AIO_IMPL_H +#define AIO_IMPL_H + +extern hidden volatile int __aio_fut; + +extern hidden int __aio_close(int); +extern hidden void __aio_atfork(int); + +#endif diff --git a/src/internal/atomic.h b/src/internal/atomic.h index f938879b..8f71c8cd 100644 --- a/src/internal/atomic.h +++ b/src/internal/atomic.h @@ -194,7 +194,7 @@ static inline void a_store(volatile int *p, int v) #ifndef a_barrier #define a_barrier a_barrier -static void a_barrier() +static inline void a_barrier() { volatile int tmp = 0; a_cas(&tmp, 0, 0); @@ -315,4 +315,19 @@ static inline int a_clz_64(uint64_t x) } #endif +#ifndef a_clz_32 +#define a_clz_32 a_clz_32 +static inline int a_clz_32(uint32_t x) +{ + x >>= 1; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return 31-a_ctz_32(x); +} +#endif + #endif diff --git a/src/internal/complex_impl.h b/src/internal/complex_impl.h new file mode 100644 index 00000000..51fb298a --- /dev/null +++ b/src/internal/complex_impl.h @@ -0,0 +1,22 @@ +#ifndef _COMPLEX_IMPL_H +#define _COMPLEX_IMPL_H + +#include <complex.h> +#include "libm.h" + +#undef __CMPLX +#undef CMPLX +#undef CMPLXF +#undef CMPLXL + +#define __CMPLX(x, y, t) \ + ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) + +#define CMPLX(x, y) __CMPLX(x, y, double) +#define CMPLXF(x, y) __CMPLX(x, y, float) +#define CMPLXL(x, y) __CMPLX(x, y, long double) + +hidden double complex __ldexp_cexp(double complex,int); +hidden float complex __ldexp_cexpf(float complex,int); + +#endif diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h index cbe0a6fe..40c743e2 100644 --- a/src/internal/dynlink.h +++ b/src/internal/dynlink.h @@ -28,6 +28,7 @@ typedef Elf64_Sym Sym; enum { REL_NONE = 0, REL_SYMBOLIC = -100, + REL_USYMBOLIC, REL_GOT, REL_PLT, REL_RELATIVE, @@ -72,6 +73,10 @@ struct fdpic_dummy_loadmap { #define DL_NOMMU_SUPPORT 0 #endif +#ifndef TLSDESC_BACKWARDS +#define TLSDESC_BACKWARDS 0 +#endif + #if !DL_FDPIC #define IS_RELATIVE(x,s) ( \ (R_TYPE(x) == REL_RELATIVE) || \ @@ -91,11 +96,14 @@ struct fdpic_dummy_loadmap { #define DT_DEBUG_INDIRECT 0 #endif +#ifndef DT_DEBUG_INDIRECT_REL +#define DT_DEBUG_INDIRECT_REL 0 +#endif + #define AUX_CNT 32 -#define DYN_CNT 32 +#define DYN_CNT 37 typedef void (*stage2_func)(unsigned char *, size_t *); -typedef _Noreturn void (*stage3_func)(size_t *); hidden void *__dlsym(void *restrict, const char *restrict, void *restrict); @@ -105,4 +113,9 @@ hidden void __dl_vseterr(const char *, va_list); hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic(); +hidden extern int __malloc_replaced; +hidden extern int __aligned_alloc_replaced; +hidden void __malloc_donate(char *, char *); +hidden int __malloc_allzerop(void *); + #endif diff --git a/src/internal/emulate_wait4.c b/src/internal/emulate_wait4.c new file mode 100644 index 00000000..f6303412 --- /dev/null +++ b/src/internal/emulate_wait4.c @@ -0,0 +1,55 @@ +#include <sys/wait.h> +#include "syscall.h" + +#ifndef SYS_wait4 +hidden long __emulate_wait4(int pid, int *status, int options, void *kru, int cp) +{ + idtype_t t; + int r; + siginfo_t info; + + info.si_pid = 0; + if (pid < -1) { + t = P_PGID; + pid = -pid; + } else if (pid == -1) { + t = P_ALL; + } else if (pid == 0) { + t = P_PGID; + } else { + t = P_PID; + } + + if (cp) r = __syscall_cp(SYS_waitid, t, pid, &info, options|WEXITED, kru); + else r = __syscall(SYS_waitid, t, pid, &info, options|WEXITED, kru); + + if (r<0) return r; + + 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: + /* see ptrace(2); the high bits of si_status can contain */ + /* PTRACE_EVENT_ values which must be preserved */ + sw = (info.si_status << 8) + 0x7f; + break; + } + *status = sw; + } + + return info.si_pid; +} +#endif diff --git a/src/internal/floatscan.c b/src/internal/floatscan.c index 278bf250..8c0828fc 100644 --- a/src/internal/floatscan.c +++ b/src/internal/floatscan.c @@ -33,9 +33,6 @@ #define MASK (KMAX-1) -#define CONCAT2(x,y) x ## y -#define CONCAT(x,y) CONCAT2(x,y) - static long long scanexp(FILE *f, int pok) { int c; @@ -301,7 +298,7 @@ static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int po y -= bias; if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) { - if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) { + if (fabsl(y) >= 2/LDBL_EPSILON) { if (denormal && bits==LDBL_MANT_DIG+e2-emin) denormal = 0; y *= 0.5; diff --git a/src/internal/fork_impl.h b/src/internal/fork_impl.h new file mode 100644 index 00000000..f995fce2 --- /dev/null +++ b/src/internal/fork_impl.h @@ -0,0 +1,21 @@ +#include <features.h> + +extern hidden volatile int *const __at_quick_exit_lockptr; +extern hidden volatile int *const __atexit_lockptr; +extern hidden volatile int *const __gettext_lockptr; +extern hidden volatile int *const __locale_lockptr; +extern hidden volatile int *const __random_lockptr; +extern hidden volatile int *const __sem_open_lockptr; +extern hidden volatile int *const __stdio_ofl_lockptr; +extern hidden volatile int *const __syslog_lockptr; +extern hidden volatile int *const __timezone_lockptr; + +extern hidden volatile int *const __bump_lockptr; + +extern hidden volatile int *const __vmlock_lockptr; + +hidden void __malloc_atfork(int); +hidden void __ldso_atfork(int); +hidden void __pthread_key_atfork(int); + +hidden void __post_Fork(int); diff --git a/src/internal/ksigaction.h b/src/internal/ksigaction.h index 8ebd5938..ef333f33 100644 --- a/src/internal/ksigaction.h +++ b/src/internal/ksigaction.h @@ -6,8 +6,13 @@ struct k_sigaction { void (*handler)(int); unsigned long flags; +#ifdef SA_RESTORER void (*restorer)(void); +#endif unsigned mask[2]; +#ifndef SA_RESTORER + void *unused; +#endif }; hidden void __restore(), __restore_rt(); diff --git a/src/internal/libc.h b/src/internal/libc.h index ac97dc7e..619bba86 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -18,10 +18,11 @@ struct tls_module { }; struct __libc { - int can_do_threads; - int threaded; - int secure; - volatile int threads_minus_1; + char can_do_threads; + char threaded; + char secure; + volatile signed char need_locks; + int threads_minus_1; size_t *auxv; struct tls_module *tls_head; size_t tls_size, tls_align, tls_cnt; diff --git a/src/internal/libm.h b/src/internal/libm.h index fd916277..72ad17d8 100644 --- a/src/internal/libm.h +++ b/src/internal/libm.h @@ -1,23 +1,11 @@ -/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - #ifndef _LIBM_H #define _LIBM_H #include <stdint.h> #include <float.h> #include <math.h> -#include <complex.h> #include <endian.h> +#include "fp_arch.h" #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN @@ -71,124 +59,196 @@ union ldshape { #error Unsupported long double representation #endif +/* Support non-nearest rounding mode. */ +#define WANT_ROUNDING 1 +/* Support signaling NaNs. */ +#define WANT_SNAN 0 + +#if WANT_SNAN +#error SNaN is unsupported +#else +#define issignalingf_inline(x) 0 +#define issignaling_inline(x) 0 +#endif + +#ifndef TOINT_INTRINSICS +#define TOINT_INTRINSICS 0 +#endif + +#if TOINT_INTRINSICS +/* Round x to nearest int in all rounding modes, ties have to be rounded + consistently with converttoint so the results match. If the result + would be outside of [-2^31, 2^31-1] then the semantics is unspecified. */ +static double_t roundtoint(double_t); + +/* Convert x to nearest int in all rounding modes, ties have to be rounded + consistently with roundtoint. If the result is not representible in an + int32_t then the semantics is unspecified. */ +static int32_t converttoint(double_t); +#endif + +/* Helps static branch prediction so hot path can be better optimized. */ +#ifdef __GNUC__ +#define predict_true(x) __builtin_expect(!!(x), 1) +#define predict_false(x) __builtin_expect(x, 0) +#else +#define predict_true(x) (x) +#define predict_false(x) (x) +#endif + +/* Evaluate an expression as the specified type. With standard excess + precision handling a type cast or assignment is enough (with + -ffloat-store an assignment is required, in old compilers argument + passing and return statement may not drop excess precision). */ + +static inline float eval_as_float(float x) +{ + float y = x; + return y; +} + +static inline double eval_as_double(double x) +{ + double y = x; + return y; +} + +/* fp_barrier returns its input, but limits code transformations + as if it had a side-effect (e.g. observable io) and returned + an arbitrary value. */ + +#ifndef fp_barrierf +#define fp_barrierf fp_barrierf +static inline float fp_barrierf(float x) +{ + volatile float y = x; + return y; +} +#endif + +#ifndef fp_barrier +#define fp_barrier fp_barrier +static inline double fp_barrier(double x) +{ + volatile double y = x; + return y; +} +#endif + +#ifndef fp_barrierl +#define fp_barrierl fp_barrierl +static inline long double fp_barrierl(long double x) +{ + volatile long double y = x; + return y; +} +#endif + +/* fp_force_eval ensures that the input value is computed when that's + otherwise unused. To prevent the constant folding of the input + expression, an additional fp_barrier may be needed or a compilation + mode that does so (e.g. -frounding-math in gcc). Then it can be + used to evaluate an expression for its fenv side-effects only. */ + +#ifndef fp_force_evalf +#define fp_force_evalf fp_force_evalf +static inline void fp_force_evalf(float x) +{ + volatile float y; + y = x; +} +#endif + +#ifndef fp_force_eval +#define fp_force_eval fp_force_eval +static inline void fp_force_eval(double x) +{ + volatile double y; + y = x; +} +#endif + +#ifndef fp_force_evall +#define fp_force_evall fp_force_evall +static inline void fp_force_evall(long double x) +{ + volatile long double y; + y = x; +} +#endif + #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ - volatile float __x; \ - __x = (x); \ + fp_force_evalf(x); \ } else if (sizeof(x) == sizeof(double)) { \ - volatile double __x; \ - __x = (x); \ + fp_force_eval(x); \ } else { \ - volatile long double __x; \ - __x = (x); \ + fp_force_evall(x); \ } \ } while(0) -/* Get two 32 bit ints from a double. */ +#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i +#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f +#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i +#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f + #define EXTRACT_WORDS(hi,lo,d) \ do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (hi) = __u.i >> 32; \ - (lo) = (uint32_t)__u.i; \ + uint64_t __u = asuint64(d); \ + (hi) = __u >> 32; \ + (lo) = (uint32_t)__u; \ } while (0) -/* Get the more significant 32 bit int from a double. */ #define GET_HIGH_WORD(hi,d) \ do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (hi) = __u.i >> 32; \ + (hi) = asuint64(d) >> 32; \ } while (0) -/* Get the less significant 32 bit int from a double. */ #define GET_LOW_WORD(lo,d) \ do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - (lo) = (uint32_t)__u.i; \ + (lo) = (uint32_t)asuint64(d); \ } while (0) -/* Set a double from two 32 bit ints. */ #define INSERT_WORDS(d,hi,lo) \ do { \ - union {double f; uint64_t i;} __u; \ - __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \ - (d) = __u.f; \ + (d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \ } while (0) -/* Set the more significant 32 bits of a double from an int. */ #define SET_HIGH_WORD(d,hi) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - __u.i &= 0xffffffff; \ - __u.i |= (uint64_t)(hi) << 32; \ - (d) = __u.f; \ -} while (0) + INSERT_WORDS(d, hi, (uint32_t)asuint64(d)) -/* Set the less significant 32 bits of a double from an int. */ #define SET_LOW_WORD(d,lo) \ -do { \ - union {double f; uint64_t i;} __u; \ - __u.f = (d); \ - __u.i &= 0xffffffff00000000ull; \ - __u.i |= (uint32_t)(lo); \ - (d) = __u.f; \ -} while (0) + INSERT_WORDS(d, asuint64(d)>>32, lo) -/* Get a 32 bit int from a float. */ #define GET_FLOAT_WORD(w,d) \ do { \ - union {float f; uint32_t i;} __u; \ - __u.f = (d); \ - (w) = __u.i; \ + (w) = asuint(d); \ } while (0) -/* Set a float from a 32 bit int. */ #define SET_FLOAT_WORD(d,w) \ do { \ - union {float f; uint32_t i;} __u; \ - __u.i = (w); \ - (d) = __u.f; \ + (d) = asfloat(w); \ } while (0) -#undef __CMPLX -#undef CMPLX -#undef CMPLXF -#undef CMPLXL - -#define __CMPLX(x, y, t) \ - ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z) - -#define CMPLX(x, y) __CMPLX(x, y, double) -#define CMPLXF(x, y) __CMPLX(x, y, float) -#define CMPLXL(x, y) __CMPLX(x, y, long double) - -/* fdlibm kernel functions */ - hidden int __rem_pio2_large(double*,double*,int,int,int); hidden int __rem_pio2(double,double*); hidden double __sin(double,double,int); hidden double __cos(double,double); hidden double __tan(double,double,int); -hidden double __expo2(double); -hidden double complex __ldexp_cexp(double complex,int); +hidden double __expo2(double,double); hidden int __rem_pio2f(float,double*); hidden float __sindf(double); hidden float __cosdf(double); hidden float __tandf(double,int); -hidden float __expo2f(float); -hidden float complex __ldexp_cexpf(float complex,int); +hidden float __expo2f(float,float); hidden int __rem_pio2l(long double, long double *); hidden long double __sinl(long double, long double, int); hidden long double __cosl(long double, long double); hidden long double __tanl(long double, long double, int); -/* polynomial evaluation */ hidden long double __polevll(long double, const long double *, int); hidden long double __p1evll(long double, const long double *, int); @@ -196,4 +256,19 @@ extern int __signgam; hidden double __lgamma_r(double, int *); hidden float __lgammaf_r(float, int *); +/* error handling functions */ +hidden float __math_xflowf(uint32_t, float); +hidden float __math_uflowf(uint32_t); +hidden float __math_oflowf(uint32_t); +hidden float __math_divzerof(uint32_t); +hidden float __math_invalidf(float); +hidden double __math_xflow(uint32_t, double); +hidden double __math_uflow(uint32_t); +hidden double __math_oflow(uint32_t); +hidden double __math_divzero(uint32_t); +hidden double __math_invalid(double); +#if LDBL_MANT_DIG != DBL_MANT_DIG +hidden long double __math_invalidl(long double); +#endif + #endif diff --git a/src/internal/locale_impl.h b/src/internal/locale_impl.h index 741a71c4..4431a92e 100644 --- a/src/internal/locale_impl.h +++ b/src/internal/locale_impl.h @@ -15,6 +15,8 @@ struct __locale_map { const struct __locale_map *next; }; +extern hidden volatile int __locale_lock[1]; + extern hidden const struct __locale_map __c_dot_utf8; extern hidden const struct __locale_struct __c_locale; extern hidden const struct __locale_struct __c_dot_utf8_locale; diff --git a/src/internal/malloc_impl.h b/src/internal/malloc_impl.h deleted file mode 100644 index 59785a7f..00000000 --- a/src/internal/malloc_impl.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef MALLOC_IMPL_H -#define MALLOC_IMPL_H - -#include <sys/mman.h> - -hidden void *__expand_heap(size_t *); - -hidden void __malloc_donate(char *, char *); - -hidden void *__memalign(size_t, size_t); - -struct chunk { - size_t psize, csize; - struct chunk *next, *prev; -}; - -struct bin { - volatile int lock[2]; - struct chunk *head; - struct chunk *tail; -}; - -#define SIZE_ALIGN (4*sizeof(size_t)) -#define SIZE_MASK (-SIZE_ALIGN) -#define OVERHEAD (2*sizeof(size_t)) -#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN) -#define DONTCARE 16 -#define RECLAIM 163840 - -#define CHUNK_SIZE(c) ((c)->csize & -2) -#define CHUNK_PSIZE(c) ((c)->psize & -2) -#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c))) -#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c))) -#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD) -#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD) -#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head)) - -#define C_INUSE ((size_t)1) - -#define IS_MMAPPED(c) !((c)->csize & (C_INUSE)) - -hidden void __bin_chunk(struct chunk *); - -hidden extern int __malloc_replaced; - -#endif diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 9b001421..de2b9d8b 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -11,16 +11,25 @@ #include "atomic.h" #include "futex.h" +#include "pthread_arch.h" + #define pthread __pthread struct pthread { /* Part 1 -- these fields may be external or * internal (accessed via asm) ABI. Do not change. */ struct pthread *self; +#ifndef TLS_ABOVE_TP uintptr_t *dtv; +#endif struct pthread *prev, *next; /* non-ABI */ uintptr_t sysinfo; - uintptr_t canary, canary2; +#ifndef TLS_ABOVE_TP +#ifdef CANARY_PAD + uintptr_t canary_pad; +#endif + uintptr_t canary; +#endif /* Part 2 -- implementation details, non-ABI. */ int tid; @@ -43,6 +52,7 @@ struct pthread { long off; volatile void *volatile pending; } robust_list; + int h_errno_val; volatile int timer_id; locale_t locale; volatile int killlock[1]; @@ -51,21 +61,19 @@ struct pthread { /* Part 3 -- the positions of these fields relative to * the end of the structure is external and internal ABI. */ - uintptr_t canary_at_end; - uintptr_t *dtv_copy; +#ifdef TLS_ABOVE_TP + uintptr_t canary; + uintptr_t *dtv; +#endif }; enum { - DT_EXITING = 0, + DT_EXITED = 0, + DT_EXITING, DT_JOINABLE, DT_DETACHED, }; -struct __timer { - int timerid; - pthread_t thread; -}; - #define __SU (sizeof(size_t)/sizeof(int)) #define _a_stacksize __u.__s[0] @@ -98,16 +106,22 @@ struct __timer { #define _b_waiters2 __u.__vi[4] #define _b_inst __u.__p[3] -#include "pthread_arch.h" - -#ifndef CANARY -#define CANARY canary +#ifndef TP_OFFSET +#define TP_OFFSET 0 #endif #ifndef DTP_OFFSET #define DTP_OFFSET 0 #endif +#ifdef TLS_ABOVE_TP +#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + TP_OFFSET) +#define __pthread_self() ((pthread_t)(__get_tp() - sizeof(struct __pthread) - TP_OFFSET)) +#else +#define TP_ADJ(p) (p) +#define __pthread_self() ((pthread_t)__get_tp()) +#endif + #ifndef tls_mod_off_t #define tls_mod_off_t size_t #endif @@ -125,7 +139,6 @@ struct __timer { 0x80000000 }) void *__tls_get_addr(tls_mod_off_t *); -hidden void *__tls_get_new(tls_mod_off_t *); hidden int __init_tp(void *); hidden void *__copy_tls(unsigned char *); hidden void __reset_tls(); @@ -142,7 +155,6 @@ hidden int __pthread_key_delete_impl(pthread_key_t); extern hidden volatile size_t __pthread_tsd_size; extern hidden void *__pthread_tsd_main[]; -extern hidden volatile int __aio_fut; extern hidden volatile int __eintr_valid_flag; hidden int __clone(int (*)(void *), void *, int, void *, ...); @@ -177,6 +189,8 @@ hidden void __tl_sync(pthread_t); extern hidden volatile int __thread_list_lock; +extern hidden volatile int __abort_lock[1]; + extern hidden unsigned __default_stacksize; extern hidden unsigned __default_guardsize; diff --git a/src/internal/shgetc.c b/src/internal/shgetc.c index a4a9c633..7455d2f0 100644 --- a/src/internal/shgetc.c +++ b/src/internal/shgetc.c @@ -32,6 +32,6 @@ int __shgetc(FILE *f) else f->shend = f->rend; f->shcnt = f->buf - f->rpos + cnt; - if (f->rpos[-1] != c) f->rpos[-1] = c; + if (f->rpos <= f->buf) f->rpos[-1] = c; return c; } diff --git a/src/internal/stdio_impl.h b/src/internal/stdio_impl.h index d7398f59..0b2438d6 100644 --- a/src/internal/stdio_impl.h +++ b/src/internal/stdio_impl.h @@ -60,8 +60,6 @@ hidden size_t __stdout_write(FILE *, const unsigned char *, size_t); hidden off_t __stdio_seek(FILE *, off_t, int); hidden int __stdio_close(FILE *); -hidden size_t __string_read(FILE *, unsigned char *, size_t); - hidden int __toread(FILE *); hidden int __towrite(FILE *); diff --git a/src/internal/syscall.h b/src/internal/syscall.h index 2e810db0..2d8a5c13 100644 --- a/src/internal/syscall.h +++ b/src/internal/syscall.h @@ -2,6 +2,7 @@ #define _INTERNAL_SYSCALL_H #include <features.h> +#include <errno.h> #include <sys/syscall.h> #include "syscall_arch.h" @@ -32,6 +33,7 @@ hidden long __syscall_ret(unsigned long), #define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) #define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) #define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) +#define __syscall7(n,a,b,c,d,e,f,g) __syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g)) #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,) @@ -42,8 +44,8 @@ hidden long __syscall_ret(unsigned long), #define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) #define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) -#define socketcall __socketcall -#define socketcall_cp __socketcall_cp +#define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f)) +#define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f)) #define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0) #define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0) @@ -56,15 +58,22 @@ hidden long __syscall_ret(unsigned long), #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) -#ifndef SYSCALL_USE_SOCKETCALL -#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_##nm, a, b, c, d, e, f) -#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f) -#else -#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_socketcall, __SC_##nm, \ - ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f })) -#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_socketcall, __SC_##nm, \ - ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f })) +static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f) +{ + long r; + if (cp) r = __syscall_cp(sys, a, b, c, d, e, f); + else r = __syscall(sys, a, b, c, d, e, f); + if (r != -ENOSYS) return r; +#ifdef SYS_socketcall + if (cp) r = __syscall_cp(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f})); + else r = __syscall(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f})); #endif + return r; +} +#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \ + __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) +#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \ + __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) /* fixup legacy 16-bit junk */ @@ -192,6 +201,128 @@ hidden long __syscall_ret(unsigned long), #define SYS_sendfile SYS_sendfile64 #endif +#ifdef SYS_timer_settime32 +#define SYS_timer_settime SYS_timer_settime32 +#endif + +#ifdef SYS_timer_gettime32 +#define SYS_timer_gettime SYS_timer_gettime32 +#endif + +#ifdef SYS_timerfd_settime32 +#define SYS_timerfd_settime SYS_timerfd_settime32 +#endif + +#ifdef SYS_timerfd_gettime32 +#define SYS_timerfd_gettime SYS_timerfd_gettime32 +#endif + +#ifdef SYS_clock_settime32 +#define SYS_clock_settime SYS_clock_settime32 +#endif + +#ifdef SYS_clock_gettime32 +#define SYS_clock_gettime SYS_clock_gettime32 +#endif + +#ifdef SYS_clock_getres_time32 +#define SYS_clock_getres SYS_clock_getres_time32 +#endif + +#ifdef SYS_clock_nanosleep_time32 +#define SYS_clock_nanosleep SYS_clock_nanosleep_time32 +#endif + +#ifdef SYS_gettimeofday_time32 +#define SYS_gettimeofday SYS_gettimeofday_time32 +#endif + +#ifdef SYS_settimeofday_time32 +#define SYS_settimeofday SYS_settimeofday_time32 +#endif + +/* Ensure that the plain syscall names are defined even for "time64-only" + * archs. These facilitate callers passing null time arguments, and make + * tests for establishing which to use/fallback-to more consistent when + * they do need to be called with time arguments. */ + +#ifndef SYS_clock_gettime +#define SYS_clock_gettime SYS_clock_gettime64 +#endif + +#ifndef SYS_clock_settime +#define SYS_clock_settime SYS_clock_settime64 +#endif + +#ifndef SYS_clock_adjtime +#define SYS_clock_adjtime SYS_clock_adjtime64 +#endif + +#ifndef SYS_clock_getres +#define SYS_clock_getres SYS_clock_getres_time64 +#endif + +#ifndef SYS_clock_nanosleep +#define SYS_clock_nanosleep SYS_clock_nanosleep_time64 +#endif + +#ifndef SYS_timer_gettime +#define SYS_timer_gettime SYS_timer_gettime64 +#endif + +#ifndef SYS_timer_settime +#define SYS_timer_settime SYS_timer_settime64 +#endif + +#ifndef SYS_timerfd_gettime +#define SYS_timerfd_gettime SYS_timerfd_gettime64 +#endif + +#ifndef SYS_timerfd_settime +#define SYS_timerfd_settime SYS_timerfd_settime64 +#endif + +#ifndef SYS_utimensat +#define SYS_utimensat SYS_utimensat_time64 +#endif + +#ifndef SYS_pselect6 +#define SYS_pselect6 SYS_pselect6_time64 +#endif + +#ifndef SYS_ppoll +#define SYS_ppoll SYS_ppoll_time64 +#endif + +#ifndef SYS_recvmmsg +#define SYS_recvmmsg SYS_recvmmsg_time64 +#endif + +#ifndef SYS_mq_timedsend +#define SYS_mq_timedsend SYS_mq_timedsend_time64 +#endif + +#ifndef SYS_mq_timedreceive +#define SYS_mq_timedreceive SYS_mq_timedreceive_time64 +#endif + +/* SYS_semtimedop omitted because SYS_ipc may provide it */ + +#ifndef SYS_rt_sigtimedwait +#define SYS_rt_sigtimedwait SYS_rt_sigtimedwait_time64 +#endif + +#ifndef SYS_futex +#define SYS_futex SYS_futex_time64 +#endif + +#ifndef SYS_sched_rr_get_interval +#define SYS_sched_rr_get_interval SYS_sched_rr_get_interval_time64 +#endif + + + + /* socketcall calls */ #define __SC_socket 1 @@ -215,6 +346,33 @@ hidden long __syscall_ret(unsigned long), #define __SC_recvmmsg 19 #define __SC_sendmmsg 20 +/* This is valid only because all socket syscalls are made via + * socketcall, which always fills unused argument slots with zeros. */ +#ifndef SYS_accept +#define SYS_accept SYS_accept4 +#endif + +#ifndef SO_RCVTIMEO_OLD +#define SO_RCVTIMEO_OLD 20 +#endif +#ifndef SO_SNDTIMEO_OLD +#define SO_SNDTIMEO_OLD 21 +#endif + +#define SO_TIMESTAMP_OLD 29 +#define SO_TIMESTAMPNS_OLD 35 +#define SO_TIMESTAMPING_OLD 37 +#define SCM_TIMESTAMP_OLD SO_TIMESTAMP_OLD +#define SCM_TIMESTAMPNS_OLD SO_TIMESTAMPNS_OLD +#define SCM_TIMESTAMPING_OLD SO_TIMESTAMPING_OLD + +#ifndef SIOCGSTAMP_OLD +#define SIOCGSTAMP_OLD 0x8906 +#endif +#ifndef SIOCGSTAMPNS_OLD +#define SIOCGSTAMPNS_OLD 0x8907 +#endif + #ifdef SYS_open #define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) #define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) @@ -233,6 +391,29 @@ hidden long __syscall_ret(unsigned long), #define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) #define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) +#ifdef SYS_pause +#define __sys_pause() __syscall(SYS_pause) +#define __sys_pause_cp() __syscall_cp(SYS_pause) +#else +#define __sys_pause() __syscall(SYS_ppoll, 0, 0, 0, 0) +#define __sys_pause_cp() __syscall_cp(SYS_ppoll, 0, 0, 0, 0) +#endif + +#define sys_pause() __syscall_ret(__sys_pause()) +#define sys_pause_cp() __syscall_ret(__sys_pause_cp()) + +#ifdef SYS_wait4 +#define __sys_wait4(a,b,c,d) __syscall(SYS_wait4,a,b,c,d) +#define __sys_wait4_cp(a,b,c,d) __syscall_cp(SYS_wait4,a,b,c,d) +#else +hidden long __emulate_wait4(int, int *, int, void *, int); +#define __sys_wait4(a,b,c,d) __emulate_wait4(a,b,c,d,0) +#define __sys_wait4_cp(a,b,c,d) __emulate_wait4(a,b,c,d,1) +#endif + +#define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d)) +#define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d)) + hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); hidden void *__vdsosym(const char *, const char *); |