mirror of
git://sourceware.org/git/glibc.git
synced 2026-09-09 11:58:23 +08:00
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9559080132 | ||
|
|
7aaf74a47f | ||
|
|
bb18aaeae7 | ||
|
|
c2934dc5e0 | ||
|
|
8e9c9f8f71 | ||
|
|
fcf3bc5b09 | ||
|
|
4545280f9c | ||
|
|
e1449bcd91 | ||
|
|
49ca74fb26 | ||
|
|
b76e856d84 | ||
|
|
b4edac208d | ||
|
|
6d981a99c3 | ||
|
|
8f1bdcb971 | ||
|
|
2a6098d404 | ||
|
|
a5760bbb50 | ||
|
|
6a714e4858 | ||
|
|
ce3e26b03a | ||
|
|
0371345ce8 | ||
|
|
cca8558113 | ||
|
|
9ef1578132 |
+2
-2
@@ -612,7 +612,7 @@ comma = ,
|
||||
sysdep-library-path = \
|
||||
$(subst $(empty) ,:,$(strip $(patsubst -Wl$(comma)-rpath-link=%, %,\
|
||||
$(filter -Wl$(comma)-rpath-link=%,\
|
||||
$(sysdep-LDFLAGS)))))
|
||||
$(sysdep-LDFLAGS)))) $(common-objpfx)/dlfcn)
|
||||
# $(run-via-rtld-prefix) is a command that, when prepended to the name
|
||||
# of a program built with the newly built library, produces a command
|
||||
# that, executed on the host for which the library is built, runs that
|
||||
@@ -1032,7 +1032,7 @@ all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
|
||||
stdlib stdio-common libio malloc string wcsmbs time dirent \
|
||||
grp pwd posix io termios resource misc socket sysvipc gmon \
|
||||
gnulib iconv iconvdata wctype manual shadow gshadow po argp \
|
||||
crypt localedata timezone rt conform debug \
|
||||
crypt localedata rt conform debug \
|
||||
$(add-on-subdirs) dlfcn elf
|
||||
|
||||
ifndef avoid-generated
|
||||
|
||||
@@ -105,6 +105,7 @@ install-symbolic-link: subdir_install
|
||||
rm -f $(symbolic-link-list)
|
||||
|
||||
install:
|
||||
dont-bother-with-destdir:
|
||||
-test ! -x $(common-objpfx)elf/ldconfig || LC_ALL=C LANGUAGE=C \
|
||||
$(common-objpfx)elf/ldconfig $(addprefix -r ,$(install_root)) \
|
||||
$(slibdir) $(libdir)
|
||||
|
||||
+1
-1
@@ -421,7 +421,7 @@ CFLAGS-ldconfig.c = $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \
|
||||
-D'SLIBDIR="$(slibdir)"' -DIS_IN_ldconfig=1
|
||||
CFLAGS-dl-cache.c = $(SYSCONF-FLAGS)
|
||||
CFLAGS-cache.c = $(SYSCONF-FLAGS)
|
||||
CFLAGS-rtld.c = $(SYSCONF-FLAGS)
|
||||
CFLAGS-rtld.c += $(SYSCONF-FLAGS)
|
||||
|
||||
CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
|
||||
-DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld)
|
||||
|
||||
@@ -35,7 +35,7 @@ GCONV_PATH=$codir/iconvdata
|
||||
export GCONV_PATH
|
||||
|
||||
# We have to have some directories in the library path.
|
||||
LIBPATH=$codir:$codir/iconvdata
|
||||
LIBPATH=$codir:$codir/iconvdata:$codir/dlfcn
|
||||
|
||||
# How the start the iconv(1) program.
|
||||
ICONV='$codir/elf/ld.so --library-path $LIBPATH --inhibit-rpath ${from}.so \
|
||||
|
||||
+4
-3
@@ -336,10 +336,11 @@
|
||||
# define __USE_REENTRANT 1
|
||||
#endif
|
||||
|
||||
#if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
|
||||
# undef _FORTIFY_SOURCE
|
||||
#endif
|
||||
#if defined _FORTIFY_SOURCE && _FORTIFY_SOURCE > 0
|
||||
# if !defined __OPTIMIZE__ || __OPTIMIZE__ <= 0
|
||||
# warning _FORTIFY_SOURCE requires compiling with optimization (-O)
|
||||
# elif !__GNUC_PREREQ (4, 1)
|
||||
# if !__GNUC_PREREQ (4, 1)
|
||||
# warning _FORTIFY_SOURCE requires GCC 4.1 or later
|
||||
# elif _FORTIFY_SOURCE > 1
|
||||
# define __USE_FORTIFY_LEVEL 2
|
||||
|
||||
@@ -204,6 +204,42 @@ CONCAT(TABLE,_iterate) (struct TABLE *t,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* GCC ATM seems to do a poor job with pointers to nested functions passed
|
||||
to inlined functions. Help it a little bit with this hack. */
|
||||
#define wchead_table_iterate(tp, fn) \
|
||||
do \
|
||||
{ \
|
||||
struct wchead_table *t = (tp); \
|
||||
uint32_t index1; \
|
||||
for (index1 = 0; index1 < t->level1_size; index1++) \
|
||||
{ \
|
||||
uint32_t lookup1 = t->level1[index1]; \
|
||||
if (lookup1 != ((uint32_t) ~0)) \
|
||||
{ \
|
||||
uint32_t lookup1_shifted = lookup1 << t->q; \
|
||||
uint32_t index2; \
|
||||
for (index2 = 0; index2 < (1 << t->q); index2++) \
|
||||
{ \
|
||||
uint32_t lookup2 = t->level2[index2 + lookup1_shifted]; \
|
||||
if (lookup2 != ((uint32_t) ~0)) \
|
||||
{ \
|
||||
uint32_t lookup2_shifted = lookup2 << t->p; \
|
||||
uint32_t index3; \
|
||||
for (index3 = 0; index3 < (1 << t->p); index3++) \
|
||||
{ \
|
||||
struct element_t *lookup3 \
|
||||
= t->level3[index3 + lookup2_shifted]; \
|
||||
if (lookup3 != NULL) \
|
||||
fn ((((index1 << t->q) + index2) << t->p) + index3, \
|
||||
lookup3); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NO_ADD_LOCALE
|
||||
|
||||
+15
-7
@@ -371,6 +371,15 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0))
|
||||
{
|
||||
uintptr_t adj;
|
||||
#if _STACK_GROWS_DOWN
|
||||
char * stackaddr = (char *) attr->stackaddr;
|
||||
#else
|
||||
/* Assume the same layout as the _STACK_GROWS_DOWN case,
|
||||
with struct pthread at the top of the stack block.
|
||||
Later we adjust the guard location and stack address
|
||||
to match the _STACK_GROWS_UP case. */
|
||||
char * stackaddr = (char *) attr->stackaddr + attr->stacksize;
|
||||
#endif
|
||||
|
||||
/* If the user also specified the size of the stack make sure it
|
||||
is large enough. */
|
||||
@@ -380,11 +389,11 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
|
||||
/* Adjust stack size for alignment of the TLS block. */
|
||||
#if TLS_TCB_AT_TP
|
||||
adj = ((uintptr_t) attr->stackaddr - TLS_TCB_SIZE)
|
||||
adj = ((uintptr_t) stackaddr - TLS_TCB_SIZE)
|
||||
& __static_tls_align_m1;
|
||||
assert (size > adj + TLS_TCB_SIZE);
|
||||
#elif TLS_DTV_AT_TP
|
||||
adj = ((uintptr_t) attr->stackaddr - __static_tls_size)
|
||||
adj = ((uintptr_t) stackaddr - __static_tls_size)
|
||||
& __static_tls_align_m1;
|
||||
assert (size > adj);
|
||||
#endif
|
||||
@@ -394,10 +403,10 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
the stack. It is the user's responsibility to do this if it
|
||||
is wanted. */
|
||||
#if TLS_TCB_AT_TP
|
||||
pd = (struct pthread *) ((uintptr_t) attr->stackaddr
|
||||
pd = (struct pthread *) ((uintptr_t) stackaddr
|
||||
- TLS_TCB_SIZE - adj);
|
||||
#elif TLS_DTV_AT_TP
|
||||
pd = (struct pthread *) (((uintptr_t) attr->stackaddr
|
||||
pd = (struct pthread *) (((uintptr_t) stackaddr
|
||||
- __static_tls_size - adj)
|
||||
- TLS_PRE_TCB_SIZE);
|
||||
#endif
|
||||
@@ -409,7 +418,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
pd->specific[0] = pd->specific_1stblock;
|
||||
|
||||
/* Remember the stack-related values. */
|
||||
pd->stackblock = (char *) attr->stackaddr - size;
|
||||
pd->stackblock = (char *) stackaddr - size;
|
||||
pd->stackblock_size = size;
|
||||
|
||||
/* This is a user-provided stack. It will not be queued in the
|
||||
@@ -635,7 +644,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
char *guard = mem + (((size - guardsize) / 2) & ~pagesize_m1);
|
||||
#elif _STACK_GROWS_DOWN
|
||||
char *guard = mem;
|
||||
# elif _STACK_GROWS_UP
|
||||
#elif _STACK_GROWS_UP
|
||||
char *guard = (char *) (((uintptr_t) pd - guardsize) & ~pagesize_m1);
|
||||
#endif
|
||||
if (mprotect (guard, guardsize, PROT_NONE) != 0)
|
||||
@@ -731,7 +740,6 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
||||
*stack = stacktop;
|
||||
#elif _STACK_GROWS_UP
|
||||
*stack = pd->stackblock;
|
||||
assert (*stack > 0);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -32,7 +32,11 @@ __pthread_attr_getstack (attr, stackaddr, stacksize)
|
||||
iattr = (struct pthread_attr *) attr;
|
||||
|
||||
/* Store the result. */
|
||||
#ifdef _STACK_GROWS_DOWN
|
||||
*stackaddr = (char *) iattr->stackaddr - iattr->stacksize;
|
||||
#else
|
||||
*stackaddr = (char *) iattr->stackaddr;
|
||||
#endif
|
||||
*stacksize = iattr->stacksize;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -48,7 +48,11 @@ __pthread_attr_setstack (attr, stackaddr, stacksize)
|
||||
#endif
|
||||
|
||||
iattr->stacksize = stacksize;
|
||||
#if _STACK_GROWS_DOWN
|
||||
iattr->stackaddr = (char *) stackaddr + stacksize;
|
||||
#else
|
||||
iattr->stackaddr = (char *) stackaddr;
|
||||
#endif
|
||||
iattr->flags |= ATTR_FLAG_STACKADDR;
|
||||
|
||||
return 0;
|
||||
@@ -81,7 +85,11 @@ __old_pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
|
||||
# endif
|
||||
|
||||
iattr->stacksize = stacksize;
|
||||
#if _STACK_GROWS_DOWN
|
||||
iattr->stackaddr = (char *) stackaddr + stacksize;
|
||||
#else
|
||||
iattr->stackaddr = (char *) stackaddr;
|
||||
#endif
|
||||
iattr->flags |= ATTR_FLAG_STACKADDR;
|
||||
|
||||
return 0;
|
||||
|
||||
+17
-4
@@ -401,13 +401,26 @@ start_thread (void *arg)
|
||||
#ifdef _STACK_GROWS_DOWN
|
||||
char *sp = CURRENT_STACK_FRAME;
|
||||
size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
|
||||
#else
|
||||
# error "to do"
|
||||
#endif
|
||||
assert (freesize < pd->stackblock_size);
|
||||
if (freesize > PTHREAD_STACK_MIN)
|
||||
__madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
|
||||
|
||||
#else
|
||||
/* Page aligned start of memory to free (higher than or equal
|
||||
to current sp plus the minimum stack size). */
|
||||
void *freeblock = (void*)((size_t)(CURRENT_STACK_FRAME
|
||||
+ PTHREAD_STACK_MIN
|
||||
+ pagesize_m1)
|
||||
& ~pagesize_m1);
|
||||
char *free_end = (char *) (((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
|
||||
/* Is there any space to free? */
|
||||
if (free_end > (char *)freeblock)
|
||||
{
|
||||
size_t freesize = (size_t)(free_end - (char *)freeblock);
|
||||
assert (freesize < pd->stackblock_size);
|
||||
__madvise (freeblock, freesize, MADV_DONTNEED);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If the thread is detached free the TCB. */
|
||||
if (IS_DETACHED (pd))
|
||||
/* Free the TCB. */
|
||||
|
||||
@@ -60,7 +60,11 @@ pthread_getattr_np (thread_id, attr)
|
||||
if (__builtin_expect (thread->stackblock != NULL, 1))
|
||||
{
|
||||
iattr->stacksize = thread->stackblock_size;
|
||||
#ifdef _STACK_GROWS_DOWN
|
||||
iattr->stackaddr = (char *) thread->stackblock + iattr->stacksize;
|
||||
#else
|
||||
iattr->stackaddr = (char *) thread->stackblock;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -129,12 +133,17 @@ pthread_getattr_np (thread_id, attr)
|
||||
stack extension request. */
|
||||
iattr->stacksize = (iattr->stacksize
|
||||
& -(intptr_t) GLRO(dl_pagesize));
|
||||
|
||||
#if _STACK_GROWS_DOWN
|
||||
/* The limit might be too high. */
|
||||
if ((size_t) iattr->stacksize
|
||||
> (size_t) iattr->stackaddr - last_to)
|
||||
iattr->stacksize = (size_t) iattr->stackaddr - last_to;
|
||||
|
||||
#else
|
||||
/* The limit might be too high. */
|
||||
if ((size_t) iattr->stacksize
|
||||
> to - (size_t) iattr->stackaddr)
|
||||
iattr->stacksize = to - (size_t) iattr->stackaddr;
|
||||
#endif
|
||||
/* We succeed and no need to look further. */
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
@@ -260,7 +260,8 @@ __pthread_mutex_trylock (mutex)
|
||||
private), 0, 0);
|
||||
|
||||
if (INTERNAL_SYSCALL_ERROR_P (e, __err)
|
||||
&& INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
|
||||
&& ((INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
|
||||
|| (INTERNAL_SYSCALL_ERRNO (e, __err) == EAGAIN)))
|
||||
{
|
||||
THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
{ \
|
||||
status = lll_futex_timed_wait (futexaddr, oldval, timeout, \
|
||||
LLL_PRIVATE); \
|
||||
if (status != -EWOULDBLOCK) \
|
||||
if (status != -EWOULDBLOCK && status != -EAGAIN) \
|
||||
break; \
|
||||
\
|
||||
oldval = *futexaddr; \
|
||||
@@ -65,7 +65,7 @@
|
||||
else if (status == -ETIMEDOUT) \
|
||||
result = EAGAIN; \
|
||||
else \
|
||||
assert (status == 0 || status == -EWOULDBLOCK); \
|
||||
assert (status == 0 || status == -EWOULDBLOCK || status == -EAGAIN);\
|
||||
\
|
||||
pthread_mutex_lock (&__aio_requests_mutex); \
|
||||
} \
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
{ \
|
||||
status = lll_futex_timed_wait (futexaddr, oldval, timeout, \
|
||||
LLL_PRIVATE); \
|
||||
if (status != -EWOULDBLOCK) \
|
||||
if (status != -EWOULDBLOCK && status != -EAGAIN) \
|
||||
break; \
|
||||
\
|
||||
oldval = *futexaddr; \
|
||||
@@ -66,7 +66,7 @@
|
||||
else if (status == -ETIMEDOUT) \
|
||||
result = EAGAIN; \
|
||||
else \
|
||||
assert (status == 0 || status == -EWOULDBLOCK); \
|
||||
assert (status == 0 || status == -EWOULDBLOCK || status == -EAGAIN);\
|
||||
\
|
||||
pthread_mutex_lock (&__gai_requests_mutex); \
|
||||
} \
|
||||
|
||||
@@ -94,7 +94,7 @@ sem_timedwait (sem_t *sem, const struct timespec *abstime)
|
||||
rt.tv_sec = sec;
|
||||
rt.tv_nsec = nsec;
|
||||
err = do_futex_timed_wait(isem, &rt);
|
||||
if (err != 0 && err != -EWOULDBLOCK)
|
||||
if (err != 0 && err != -EWOULDBLOCK && err != -EAGAIN)
|
||||
{
|
||||
__set_errno (-err);
|
||||
err = -1;
|
||||
|
||||
@@ -67,7 +67,7 @@ __new_sem_wait (sem_t *sem)
|
||||
while (1)
|
||||
{
|
||||
err = do_futex_wait(isem);
|
||||
if (err != 0 && err != -EWOULDBLOCK)
|
||||
if (err != 0 && err != -EWOULDBLOCK && err != -EAGAIN)
|
||||
{
|
||||
__set_errno (-err);
|
||||
err = -1;
|
||||
@@ -112,7 +112,7 @@ __old_sem_wait (sem_t *sem)
|
||||
/* Disable asynchronous cancellation. */
|
||||
__pthread_disable_asynccancel (oldtype);
|
||||
}
|
||||
while (err == 0 || err == -EWOULDBLOCK);
|
||||
while (err == 0 || err == -EWOULDBLOCK || err == -EAGAIN);
|
||||
|
||||
__set_errno (-err);
|
||||
return -1;
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ test_wrapper_env=$1; shift
|
||||
logfile=$common_objpfx/nptl/tst-tls6.out
|
||||
|
||||
# We have to find libc and nptl
|
||||
library_path=${common_objpfx}:${common_objpfx}nptl
|
||||
library_path=${common_objpfx}:${common_objpfx}nptl:${common_objpfx}/dlfcn
|
||||
tst_tls5="${test_via_rtld_prefix} ${common_objpfx}/nptl/tst-tls5"
|
||||
|
||||
LC_ALL=C
|
||||
|
||||
@@ -73,7 +73,7 @@ ENTRY (__longjmp)
|
||||
add a2, a2, a3
|
||||
ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
|
||||
# else
|
||||
# ifdef PIC
|
||||
# ifdef SHARED
|
||||
ldr a2, 1f
|
||||
ldr a3, .Lrtld_global_ro
|
||||
0: add a2, pc, a2
|
||||
@@ -126,7 +126,7 @@ ENTRY (__longjmp)
|
||||
.Lrtld_local_ro:
|
||||
.long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
|
||||
# else
|
||||
# ifdef PIC
|
||||
# ifdef SHARED
|
||||
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
|
||||
.Lrtld_global_ro:
|
||||
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
|
||||
|
||||
@@ -54,7 +54,7 @@ ENTRY (__sigsetjmp)
|
||||
add a3, a3, a4
|
||||
ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET]
|
||||
# else
|
||||
# ifdef PIC
|
||||
# ifdef SHARED
|
||||
ldr a3, 1f
|
||||
ldr a4, .Lrtld_global_ro
|
||||
0: add a3, pc, a3
|
||||
@@ -110,7 +110,7 @@ ENTRY (__sigsetjmp)
|
||||
.Lrtld_local_ro:
|
||||
.long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF)
|
||||
# else
|
||||
# ifdef PIC
|
||||
# ifdef SHARED
|
||||
1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS
|
||||
.Lrtld_global_ro:
|
||||
.long C_SYMBOL_NAME(_rtld_global_ro)(GOT)
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
* 10 x 64-bit fprs in this order:
|
||||
- fr12-fr21 (callee saves)
|
||||
Note: We have 8 bytes of free space for future uses. */
|
||||
typedef union
|
||||
typedef union __jmp_buf_internal
|
||||
{
|
||||
struct __jmp_buf_internal_tag
|
||||
{
|
||||
|
||||
@@ -29,8 +29,8 @@ feholdexcept (fenv_t *envp)
|
||||
/* Store the environment. */
|
||||
bufptr = clear.buf;
|
||||
__asm__ (
|
||||
"fstd,ma %%fr0,8(%1)\n"
|
||||
: "=m" (clear), "+r" (bufptr) : : "%r0");
|
||||
"fstd %%fr0,0(%1)\n"
|
||||
: "=m" (clear) : "r" (bufptr) : "%r0");
|
||||
memcpy (envp, &clear.env, sizeof (fenv_t));
|
||||
|
||||
/* Clear exception queues */
|
||||
@@ -44,7 +44,7 @@ feholdexcept (fenv_t *envp)
|
||||
Thus we start bufptr at the end and work backwards */
|
||||
bufptr = (unsigned long long *)((unsigned int)(clear.buf) + sizeof(unsigned int)*4);
|
||||
__asm__ (
|
||||
"fldd,mb -8(%0),%%fr0\n"
|
||||
"fldd 0(%0),%%fr0\n"
|
||||
: : "r" (bufptr), "m" (clear) : "%r0");
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -33,7 +33,7 @@ fesetenv (const fenv_t *envp)
|
||||
we want to use from the environment specified by the parameter. */
|
||||
bufptr = temp.buf;
|
||||
__asm__ (
|
||||
"fstd,ma %%fr0,8(%1)\n"
|
||||
"fstd %%fr0,0(%1)\n"
|
||||
: "=m" (temp) : "r" (bufptr) : "%r0");
|
||||
|
||||
temp.env.__status_word &= ~(FE_ALL_EXCEPT
|
||||
@@ -54,7 +54,7 @@ fesetenv (const fenv_t *envp)
|
||||
we take advantage of that to load in reverse order so fr0
|
||||
is loaded last and T-Bit is enabled. */
|
||||
__asm__ (
|
||||
"fldd,mb -8(%1),%%fr0\n"
|
||||
"fldd 0(%1),%%fr0\n"
|
||||
: : "m" (temp), "r" (bufptr) : "%r0" );
|
||||
|
||||
/* Success. */
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
int
|
||||
pthread_spin_init (pthread_spinlock_t *lock, int pshared)
|
||||
{
|
||||
int tmp = 0;
|
||||
/* This should be a memory barrier to newer compilers */
|
||||
__asm__ __volatile__ ("stw,ma %1,0(%0)"
|
||||
: : "r" (lock), "r" (tmp) : "memory");
|
||||
/* The LWS-CAS operation on hppa is a synthetic atomic operation
|
||||
that doesn't provide the type of coherency that we need. Therefore
|
||||
we force that coherency by using LWS-CAS again. */
|
||||
atomic_exchange_rel (lock, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
int
|
||||
pthread_spin_unlock (pthread_spinlock_t *lock)
|
||||
{
|
||||
int tmp = 0;
|
||||
/* This should be a memory barrier to newer compilers */
|
||||
__asm__ __volatile__ ("stw,ma %1,0(%0)"
|
||||
: : "r" (lock), "r" (tmp) : "memory");
|
||||
/* The LWS-CAS operation on hppa is a synthetic atomic operation
|
||||
that doesn't provide the type of coherency that we need. Therefore
|
||||
we force that coherency by using LWS-CAS again. */
|
||||
atomic_exchange_rel (lock, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -61,42 +61,46 @@ typedef uintmax_t uatomic_max_t;
|
||||
|
||||
#if __ASSUME_LWS_CAS
|
||||
/* The only basic operation needed is compare and exchange. */
|
||||
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
volatile int lws_errno; \
|
||||
volatile int lws_ret; \
|
||||
asm volatile( \
|
||||
"0: \n\t" \
|
||||
"copy %2, %%r26 \n\t" \
|
||||
"copy %3, %%r25 \n\t" \
|
||||
"copy %4, %%r24 \n\t" \
|
||||
"ble " _LWS "(%%sr2, %%r0) \n\t" \
|
||||
"ldi " _LWS_CAS ", %%r20 \n\t" \
|
||||
"ldi " _ASM_EAGAIN ", %%r24 \n\t" \
|
||||
"cmpb,=,n %%r24, %%r21, 0b \n\t" \
|
||||
"nop \n\t" \
|
||||
"ldi " _ASM_EDEADLOCK ", %%r25 \n\t" \
|
||||
"cmpb,=,n %%r25, %%r21, 0b \n\t" \
|
||||
"nop \n\t" \
|
||||
"stw %%r28, %0 \n\t" \
|
||||
"stw %%r21, %1 \n\t" \
|
||||
: "=m" (lws_ret), "=m" (lws_errno) \
|
||||
: "r" (mem), "r" (oldval), "r" (newval) \
|
||||
: _LWS_CLOBBER \
|
||||
); \
|
||||
\
|
||||
if(lws_errno == -EFAULT || lws_errno == -ENOSYS) \
|
||||
ABORT_INSTRUCTION; \
|
||||
\
|
||||
lws_ret; \
|
||||
})
|
||||
static int __attribute__((noinline))
|
||||
__atomic_compare_and_exchange_val_acq (int mem, int newval, int oldval)
|
||||
{
|
||||
volatile int lws_errno;
|
||||
volatile int lws_ret;
|
||||
asm volatile(
|
||||
"0: \n\t"
|
||||
"copy %2, %%r26 \n\t"
|
||||
"copy %3, %%r25 \n\t"
|
||||
"copy %4, %%r24 \n\t"
|
||||
"ble " _LWS "(%%sr2, %%r0) \n\t"
|
||||
"ldi " _LWS_CAS ", %%r20 \n\t"
|
||||
"ldi " _ASM_EAGAIN ", %%r24 \n\t"
|
||||
"cmpb,=,n %%r24, %%r21, 0b \n\t"
|
||||
"nop \n\t"
|
||||
"ldi " _ASM_EDEADLOCK ", %%r25 \n\t"
|
||||
"cmpb,=,n %%r25, %%r21, 0b \n\t"
|
||||
"nop \n\t"
|
||||
"stw %%r28, %0 \n\t"
|
||||
"stw %%r21, %1 \n\t"
|
||||
: "=m" (lws_ret), "=m" (lws_errno)
|
||||
: "r" (mem), "r" (oldval), "r" (newval)
|
||||
: _LWS_CLOBBER
|
||||
);
|
||||
|
||||
if (lws_errno == -EFAULT || lws_errno == -ENOSYS)
|
||||
ABORT_INSTRUCTION;
|
||||
|
||||
return lws_ret;
|
||||
}
|
||||
# define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
|
||||
((__typeof__(oldval)) \
|
||||
__atomic_compare_and_exchange_val_acq ((int)mem, (int)newval, (int)oldval))
|
||||
|
||||
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
|
||||
({ \
|
||||
int ret; \
|
||||
__typeof__(oldval) ret; \
|
||||
ret = atomic_compare_and_exchange_val_acq(mem, newval, oldval); \
|
||||
/* Return 1 if it was already acquired. */ \
|
||||
(ret != (int)oldval); \
|
||||
(ret != oldval); \
|
||||
})
|
||||
#else
|
||||
# error __ASSUME_LWS_CAS is required to build glibc.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define O_NONBLOCK 00200004 /* HPUX has separate NDELAY & NONBLOCK */
|
||||
#define __O_DSYNC 01000000
|
||||
#define __O_RSYNC 02000000 /* HPUX only */
|
||||
#define __O_SYNC 01000000
|
||||
#define __O_SYNC 00100000
|
||||
#define O_SYNC (__O_SYNC|__O_DSYNC)
|
||||
|
||||
#define O_BLKSEEK 00000100 /* HPUX only */
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <errno.h>
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "spawn_int.h"
|
||||
|
||||
@@ -35,17 +36,24 @@ posix_spawn_file_actions_addopen (posix_spawn_file_actions_t *file_actions,
|
||||
if (fd < 0 || fd >= maxfd)
|
||||
return EBADF;
|
||||
|
||||
char *path_copy = strdup (path);
|
||||
if (path_copy == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
/* Allocate more memory if needed. */
|
||||
if (file_actions->__used == file_actions->__allocated
|
||||
&& __posix_spawn_file_actions_realloc (file_actions) != 0)
|
||||
/* This can only mean we ran out of memory. */
|
||||
return ENOMEM;
|
||||
{
|
||||
/* This can only mean we ran out of memory. */
|
||||
free (path_copy);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
/* Add the new value. */
|
||||
rec = &file_actions->__actions[file_actions->__used];
|
||||
rec->tag = spawn_do_open;
|
||||
rec->action.open_action.fd = fd;
|
||||
rec->action.open_action.path = path;
|
||||
rec->action.open_action.path = path_copy;
|
||||
rec->action.open_action.oflag = oflag;
|
||||
rec->action.open_action.mode = mode;
|
||||
|
||||
|
||||
@@ -18,11 +18,29 @@
|
||||
#include <spawn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Initialize data structure for file attribute for `spawn' call. */
|
||||
#include "spawn_int.h"
|
||||
|
||||
/* Deallocate the file actions. */
|
||||
int
|
||||
posix_spawn_file_actions_destroy (posix_spawn_file_actions_t *file_actions)
|
||||
{
|
||||
/* Free the memory allocated. */
|
||||
/* Free the paths in the open actions. */
|
||||
for (int i = 0; i < file_actions->__used; ++i)
|
||||
{
|
||||
struct __spawn_action *sa = &file_actions->__actions[i];
|
||||
switch (sa->tag)
|
||||
{
|
||||
case spawn_do_open:
|
||||
free (sa->action.open_action.path);
|
||||
break;
|
||||
case spawn_do_close:
|
||||
case spawn_do_dup2:
|
||||
/* No cleanup required. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the array of actions. */
|
||||
free (file_actions->__actions);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ struct __spawn_action
|
||||
struct
|
||||
{
|
||||
int fd;
|
||||
const char *path;
|
||||
char *path;
|
||||
int oflag;
|
||||
mode_t mode;
|
||||
} open_action;
|
||||
|
||||
+9
-1
@@ -168,6 +168,7 @@ do_test (int argc, char *argv[])
|
||||
char fd2name[18];
|
||||
char fd3name[18];
|
||||
char fd4name[18];
|
||||
char *name3_copy;
|
||||
char *spargv[12];
|
||||
int i;
|
||||
|
||||
@@ -222,9 +223,15 @@ do_test (int argc, char *argv[])
|
||||
if (posix_spawn_file_actions_addclose (&actions, fd1) != 0)
|
||||
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addclose");
|
||||
/* We want to open the third file. */
|
||||
if (posix_spawn_file_actions_addopen (&actions, fd3, name3,
|
||||
name3_copy = strdup (name3);
|
||||
if (name3_copy == NULL)
|
||||
error (EXIT_FAILURE, errno, "strdup");
|
||||
if (posix_spawn_file_actions_addopen (&actions, fd3, name3_copy,
|
||||
O_RDONLY, 0666) != 0)
|
||||
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_addopen");
|
||||
/* Overwrite the name to check that a copy has been made. */
|
||||
memset (name3_copy, 'X', strlen (name3_copy));
|
||||
|
||||
/* We dup the second descriptor. */
|
||||
fd4 = MAX (2, MAX (fd1, MAX (fd2, fd3))) + 1;
|
||||
if (posix_spawn_file_actions_adddup2 (&actions, fd2, fd4) != 0)
|
||||
@@ -253,6 +260,7 @@ do_test (int argc, char *argv[])
|
||||
/* Cleanup. */
|
||||
if (posix_spawn_file_actions_destroy (&actions) != 0)
|
||||
error (EXIT_FAILURE, errno, "posix_spawn_file_actions_destroy");
|
||||
free (name3_copy);
|
||||
|
||||
/* Wait for the child. */
|
||||
if (waitpid (pid, &status, 0) != pid)
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <bits/libc-lock.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
/* The following bit is copied from res_data.c (where it is #ifdef'ed
|
||||
@@ -95,6 +96,20 @@ int
|
||||
__res_maybe_init (res_state resp, int preinit)
|
||||
{
|
||||
if (resp->options & RES_INIT) {
|
||||
static time_t last_mtime, last_check;
|
||||
time_t now;
|
||||
struct stat statbuf;
|
||||
|
||||
time (&now);
|
||||
if (now != last_check) {
|
||||
last_check = now;
|
||||
if (stat (_PATH_RESCONF, &statbuf) == 0 && last_mtime != statbuf.st_mtime) {
|
||||
last_mtime = statbuf.st_mtime;
|
||||
atomicinclock (lock);
|
||||
atomicinc (__res_initstamp);
|
||||
atomicincunlock (lock);
|
||||
}
|
||||
}
|
||||
if (__res_initstamp != resp->_u._ext.initstamp) {
|
||||
if (resp->nscount > 0)
|
||||
__res_iclose (resp, true);
|
||||
|
||||
+1
-1
@@ -463,7 +463,7 @@ send_again:
|
||||
while (inlen < 0 && errno == EINTR);
|
||||
if (inlen < 0)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
if (errno == EWOULDBLOCK || errno == EAGAIN)
|
||||
continue;
|
||||
cu->cu_error.re_errno = errno;
|
||||
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||
|
||||
@@ -447,19 +447,21 @@ __sin (double x)
|
||||
}
|
||||
else
|
||||
{
|
||||
double t;
|
||||
if (a > 0)
|
||||
{
|
||||
m = 1;
|
||||
t = a;
|
||||
db = da;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = 0;
|
||||
a = -a;
|
||||
t = -a;
|
||||
db = -da;
|
||||
}
|
||||
u.x = big + a;
|
||||
y = a - (u.x - big);
|
||||
u.x = big + t;
|
||||
y = t - (u.x - big);
|
||||
res = do_sin (u, y, db, &cor);
|
||||
cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
|
||||
retval = ((res == res + cor) ? ((m) ? res : -res)
|
||||
@@ -671,19 +673,21 @@ __cos (double x)
|
||||
}
|
||||
else
|
||||
{
|
||||
double t;
|
||||
if (a > 0)
|
||||
{
|
||||
m = 1;
|
||||
t = a;
|
||||
db = da;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = 0;
|
||||
a = -a;
|
||||
t = -a;
|
||||
db = -da;
|
||||
}
|
||||
u.x = big + a;
|
||||
y = a - (u.x - big);
|
||||
u.x = big + t;
|
||||
y = t - (u.x - big);
|
||||
res = do_sin (u, y, db, &cor);
|
||||
cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
|
||||
retval = ((res == res + cor) ? ((m) ? res : -res)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
/* Using the hidden attribute here does not change the code but it
|
||||
helps to avoid warnings. */
|
||||
extern void restore_rt (void) asm ("__restore_rt") attribute_hidden;
|
||||
extern void restore_rt (void) asm ("__restore_rt") __attribute__((__visibility__("hidden")));
|
||||
|
||||
|
||||
/* If ACT is not NULL, change the action for SIG to *ACT.
|
||||
|
||||
Reference in New Issue
Block a user