Compare commits

...
9 Commits
Author SHA1 Message Date
Petr Baudis 8bddf3f453 Fix fstat() not trying to call fxstat64() on sparc64
sparc64 fxstat implementation should follow the same code path as on
i386, first trying fxstat64() and falling back to fxstat() only when
it is not available. Otherwise, nanosecond times resolution will not
be available.

sparc64 is unlike other 64-bit architectures in that fxstat64() has
not been historically always available in the kernel.

Solution by hideaki@sogetthis.com.
2010-11-16 04:15:35 +01:00
Mike Frysinger fd5ba40413 Make sure GLRO(dl_pagesize) is initialized properly on all archs
After a recent change to __getpagesize(), GLRO(dl_pagesize) is required
to be set.  But that is only done at app init, and shared libraries
dlopened at runtime by static apps dont have their GLRO() state
initialized from the linux auxvec.

ia64/mips have long had similar behavior with their __getpagesize(), but
they have a DL_STATIC_INIT hook to sync some of the static GLRO() fields
to the dynamic GLRO() fields.  Now that common linux code requires
GLRO(dl_pagesize) to be set, common linux code now needs that
DL_STATIC_INIT hook.

This patch takes the ia64 logic and promotes it to common code.
2010-11-16 04:15:35 +01:00
Jan Kratochvil fb8fb8464c Fix incorrect backtrace unwinding through thread_start() on x86_64
Provide CFI for the outermost clone() to ensure proper unwinding stop
of gdb.
2010-11-16 03:47:22 +01:00
Petr Baudis c8e6e9e783 Allow aux_cache_file open()ing to fail silently even in the chroot mode.
The aux_cache fix of bug 11149 introduced a new bug - normally,
ldconfig -r never cares if the auxiliary cache is not available and
that is not a fatal problem, however this is not the case in case
of ldconfig -r when executed as non-root. In that case, ldconfig -r
fails hard unless var/cache/ldconfig/ exists within the chroot. This
patch fixes that.
2010-11-16 03:39:24 +01:00
Petr Baudis b321e863ac Make nscd load /etc/host.conf options in aicache
This patch makes sure _res_hconf is initialized before resolving is being done.

However, this would not be enough since nscd has its own _res_hconf due to
nscd/res_hconf.c; _res_hconf_init() would work on different _res_hconf instance
than the NSS routines. We just need to make sure nscd and glibc share the same
_res_hconf instance - this should not be a problem since users should run
matching versions of glibc and nscd anyway.
2010-11-16 02:50:21 +01:00
Petr Baudis b9be604a7b Fix multiple nss_compat initgroups() bugs
Compat initgroups() is completely broken; the code will always set
skip_initgroups_dyn to true, so initgroups() will never be actually
called, but due to the nature of the code, setgrent() won't be called
either - thus, subsequent invocations of initgroups() will not return
the NIS group list anymore.

This is a simple patch that makes sure skip_initgroups_dyn is set only
in case initgroups is not available; it also attempts to handle the
unavailability of other NSS interfaces better.
2010-11-16 02:50:20 +01:00
Michael Matz 31eb5a4c49 Add proper unwind information for x86_64 _fini
It is impossible to reliably unwind the stack above _fini() on x86_64 since no
unwind information is provided for it and it modifies a stack register. This
matters for gdb backtracing - if a process crashes within a destructor, it can
frequently be essential to look at why the program began terminating in the
first place.
2010-11-16 02:50:19 +01:00
Petr Baudis 9fcff7a79b Fix jn() precision problems around zero points of j0()
There appears to be a really nasty bug in jn() from fdlibm, which is
the foundation for most libm implementations (including glibc libm).
The zeroth-order j0() and first-order j1() cylindrical Bessel functions
are used to recursively generate the jn() value, but only the zeroth-order
Bessel function is used to normalize it; however, each of the functions
gets highly imprecise (approaching "bogus") near its zero point, making
the jn() value itself bogus.

But in fact, the zero points of j0() and j1() never coincide, thus j1()
should be used in case it is more precise than j0(). (That is, simply
when its value is further from zero.)

As an example, 2.4048255576957729_8 is the first zero of j0().
The proper value as calculated by Mathematica is 0.19899990535769...
However, jn() returns -inf on 64-bit arch, or 0.185007 on 32-bit arch.
With the proposed patch below, the returned value is 0.199000.

The fix is based on work by Steve Kargl and Tobias Burnus.
2010-11-16 02:50:16 +01:00
Jan Sembera 75134e4647 nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
When nscd host cache gets temporary error from nss, it should return
temporary error instead of permanent error to the application.
2010-11-16 02:38:24 +01:00
20 changed files with 204 additions and 114 deletions
+64
View File
@@ -1,3 +1,67 @@
2010-11-16 Petr Baudis <pasky@suse.cz>
[BZ #11155]
* sysdeps/unis/sysv/linux/sparc/sparc64/fxstat.c: Use i386 fxstat
with support for fxstat64 instead of generic fxstat version.
Solution by hideaki@sogetthis.com.
2010-08-18 Mike Frysinger <vapier@gentoo.org>
[BZ #11929]
* sysdeps/unix/sysv/linux/ia64/Makefile: Move dl-static addition to
sysdep vars for subdir==elf to ...
* sysdeps/unix/sysv/linux/Makefile: ... here.
* sysdeps/unix/sysv/linux/ia64/dl-static.c: Move file to ...
* sysdeps/unix/sysv/linux/dl-static.c: ... here.
* sysdeps/unix/sysv/linux/ia64/ldsodefs.h: Delete, and move the
DL_STATIC_INIT defines to ...
* sysdeps/unix/sysv/linux/ldsodefs.h: ... here.
* sysdeps/unix/sysv/linux/ia64/getpagesize.c: Delete.
2006-11-30 Jan Kratochvil <jan.kratochvil@redhat.com>
[BZ #6693]
* sysdeps/unix/sysv/linux/x86_64/clone.S: Provide CFI for the outermost
`clone' function to ensure proper unwinding stop of gdb.
2010-05-31 Petr Baudis <pasky@suse.cz>
[BZ #11149]
* elf/ldconfig.c (main): Allow aux_cache_file open()ing to fail
silently even in the chroot mode.
2010-08-19 Petr Baudis <pasky@suse.cz>
[BZ #11928]
* nscd/aicache.c (addhstaiX): Ensure _res_hconf has been initialized.
* resolv/res_hconf.c (_res_hconf): Do not redefine outside of libc.
2010-05-31 Petr Baudis <pasky@suse.cz>
[BZ #10085]
* nis/nss_compat/compat-initgroups.c (internal_getgrent_r): Fix
initialization of skip_initgroups_dyn.
2010-05-17 Michael Matz <matz@suse.de>
[BZ #11610]
* sysdeps/x86_64/elf/initfini.c (_fini): Add unwind information.
2010-05-12 Petr Baudis <pasky@suse.cz>
[BZ #11589]
* sysdeps/ieee754/dbl-64/e_jn.c: Compensate major precision loss
around j0() zero points by switching to j1().
* sysdeps/ieee754/flt-32/e_jnf.c: Likewise.
* sysdeps/ieee754/ldbl-128/e_jnl.c: Likewise.
* sysdeps/ieee754/ldbl-128ibm/e_jnl.c: Likewise.
* sysdeps/ieee754/ldbl-96/e_jnl.c: Likewise.
2010-06-01 Jan Sembera <jsembera@suse.cz>
[BZ #6812]
* nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
2010-11-11 Andreas Schwab <schwab@redhat.com>
* posix/fnmatch_loop.c (NEW_PATTERN): Fix use of alloca.
+4 -8
View File
@@ -1359,14 +1359,9 @@ main (int argc, char **argv)
const char *aux_cache_file = _PATH_LDCONFIG_AUX_CACHE;
if (opt_chroot)
{
aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
if (aux_cache_file == NULL)
error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"),
_PATH_LDCONFIG_AUX_CACHE);
}
aux_cache_file = chroot_canon (opt_chroot, aux_cache_file);
if (! opt_ignore_aux_cache)
if (! opt_ignore_aux_cache && aux_cache_file)
load_aux_cache (aux_cache_file);
else
init_aux_cache ();
@@ -1376,7 +1371,8 @@ main (int argc, char **argv)
if (opt_build_cache)
{
save_cache (cache_file);
save_aux_cache (aux_cache_file);
if (aux_cache_file)
save_aux_cache (aux_cache_file);
}
return 0;
+11 -8
View File
@@ -474,18 +474,21 @@ internal_getgrent_r (ent_t *ent, char *buffer, size_t buflen, const char *user,
/* If the selected module does not support getgrent_r or
initgroups_dyn, abort. We cannot find the needed group
entries. */
if (nss_getgrent_r == NULL && nss_initgroups_dyn == NULL)
if (nss_initgroups_dyn == NULL || nss_getgrgid_r == NULL)
{
if (nss_setgrent != NULL)
{
nss_setgrent (1);
ent->need_endgrent = true;
}
ent->skip_initgroups_dyn = true;
}
if (ent->skip_initgroups_dyn && nss_getgrent_r == NULL)
return NSS_STATUS_UNAVAIL;
ent->files = false;
if (nss_initgroups_dyn == NULL && nss_setgrent != NULL)
{
nss_setgrent (1);
ent->need_endgrent = true;
}
ent->skip_initgroups_dyn = true;
return getgrent_next_nss (ent, buffer, buflen, user, group,
start, size, groupsp, limit, errnop);
}
+3
View File
@@ -26,6 +26,7 @@
#include <time.h>
#include <unistd.h>
#include <sys/mman.h>
#include <resolv/res_hconf.h>
#include "dbg_log.h"
#include "nscd.h"
@@ -103,6 +104,8 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
if (__res_maybe_init (&_res, 0) == -1)
no_more = 1;
if (!_res_hconf.initialized)
_res_hconf_init ();
/* If we are looking for both IPv4 and IPv6 address we don't want
the lookup functions to automatically promote IPv4 addresses to
+26 -6
View File
@@ -77,6 +77,20 @@ static const hst_response_header notfound =
};
/* This is the standard reply in case of temporary error */
static const hst_response_header tryagain =
{
.version = NSCD_VERSION,
.found = 0,
.h_name_len = 0,
.h_aliases_cnt = 0,
.h_addrtype = -1,
.h_length = -1,
.h_addr_list_cnt = 0,
.error = TRY_AGAIN
};
static void
cache_addhst (struct database_dyn *db, int fd, request_header *req,
const void *key, struct hostent *hst, uid_t owner,
@@ -85,6 +99,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
{
bool all_written = true;
time_t t = time (NULL);
hst_response_header *errhdr;
/* We allocate all data in one memory block: the iov vector,
the response header and the dataset itself. */
@@ -112,15 +127,20 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
{
/* We have no data. This means we send the standard reply for this
case. */
ssize_t total = sizeof (notfound);
ssize_t total = sizeof (hst_response_header);
errhdr = (errval == EAGAIN) ? &tryagain : &notfound;
if (fd != -1 &&
TEMP_FAILURE_RETRY (send (fd, &notfound, total,
TEMP_FAILURE_RETRY (send (fd, errhdr, total,
MSG_NOSIGNAL)) != total)
all_written = false;
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
1);
if (errval == EAGAIN)
/* Don't store temporary resolver errors at all */
dataset = NULL;
else
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
IDX_result_data);
/* If we cannot permanently store the result, so be it. */
if (dataset != NULL)
{
@@ -490,7 +510,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
/* We set the error to indicate this is (possibly) a
temporary error and that it does not mean the entry
is not available at all. */
errval = EAGAIN;
h_errno = TRY_AGAIN;
break;
}
use_malloc = true;
@@ -502,7 +522,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
}
cache_addhst (db, fd, req, key, hst, uid, he, dh,
h_errno == TRY_AGAIN ? errval : 0, ttl);
h_errno == TRY_AGAIN ? EAGAIN : 0, ttl);
if (use_malloc)
free (buffer);
+2
View File
@@ -84,7 +84,9 @@ static const struct cmd
};
/* Structure containing the state. */
#ifndef NOT_IN_libc
struct hconf _res_hconf;
#endif
/* Skip white space. */
static const char *
+10 -1
View File
@@ -215,7 +215,16 @@ static double zero = 0.00000000000000000000e+00;
}
}
}
b = (t*__ieee754_j0(x)/b);
/* j0() and j1() suffer enormous loss of precision at and
* near zero; however, we know that their zero points never
* coincide, so just choose the one further away from zero.
*/
z = __ieee754_j0 (x);
w = __ieee754_j1 (x);
if (fabs (z) >= fabs (w))
b = (t * z / b);
else
b = (t * w / a);
}
}
if(sgn==1) return -b; else return b;
+10 -1
View File
@@ -165,7 +165,16 @@ static float zero = 0.0000000000e+00;
}
}
}
b = (t*__ieee754_j0f(x)/b);
/* j0() and j1() suffer enormous loss of precision at and
* near zero; however, we know that their zero points never
* coincide, so just choose the one further away from zero.
*/
z = __ieee754_j0f (x);
w = __ieee754_j1f (x);
if (fabsf (z) >= fabsf (w))
b = (t * z / b);
else
b = (t * w / a);
}
}
if(sgn==1) return -b; else return b;
+10 -1
View File
@@ -285,7 +285,16 @@ __ieee754_jnl (n, x)
}
}
}
b = (t * __ieee754_j0l (x) / b);
/* j0() and j1() suffer enormous loss of precision at and
* near zero; however, we know that their zero points never
* coincide, so just choose the one further away from zero.
*/
z = __ieee754_j0l (x);
w = __ieee754_j1l (x);
if (fabsl (z) >= fabsl (w))
b = (t * z / b);
else
b = (t * w / a);
}
}
if (sgn == 1)
+10 -1
View File
@@ -286,7 +286,16 @@ __ieee754_jnl (n, x)
}
}
}
b = (t * __ieee754_j0l (x) / b);
/* j0() and j1() suffer enormous loss of precision at and
* near zero; however, we know that their zero points never
* coincide, so just choose the one further away from zero.
*/
z = __ieee754_j0l (x);
w = __ieee754_j1l (x);
if (fabsl (z) >= fabsl (w))
b = (t * z / b);
else
b = (t * w / a);
}
}
if (sgn == 1)
+10 -1
View File
@@ -281,7 +281,16 @@ __ieee754_jnl (n, x)
}
}
}
b = (t * __ieee754_j0l (x) / b);
/* j0() and j1() suffer enormous loss of precision at and
* near zero; however, we know that their zero points never
* coincide, so just choose the one further away from zero.
*/
z = __ieee754_j0l (x);
w = __ieee754_j1l (x);
if (fabsl (z) >= fabsl (w))
b = (t * z / b);
else
b = (t * w / a);
}
}
if (sgn == 1)
+3 -1
View File
@@ -147,7 +147,9 @@ sysdep_routines += xstatconv internal_statvfs internal_statvfs64 \
endif
ifeq ($(subdir),elf)
sysdep-rtld-routines += dl-brk dl-sbrk
sysdep-dl-routines += dl-static
sysdep_routines += dl-static
sysdep-rtld-routines += dl-brk dl-sbrk dl-static
CPPFLAGS-lddlibc4 += -DNOT_IN_libc
endif
@@ -1,5 +1,5 @@
/* Variable initialization. IA-64 version.
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
/* Variable initialization.
Copyright (C) 2001, 2002, 2003, 2004, 2010 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
-6
View File
@@ -12,12 +12,6 @@ sysdep_headers += sys/io.h
sysdep_routines += ioperm clone2
endif
ifeq ($(subdir),elf)
sysdep-dl-routines += dl-static
sysdep_routines += $(sysdep-dl-routines)
sysdep-rtld-routines += $(sysdep-dl-routines)
endif
ifeq ($(subdir),rt)
librt-routines += rt-sysdep
endif
@@ -1,39 +0,0 @@
/* Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <assert.h>
#include <unistd.h>
#include <sys/param.h>
#include <ldsodefs.h>
#include <sysdep.h>
#include <sys/syscall.h>
/* Return the system page size. The return value will depend on how
the kernel is configured. A program must use this call to
determine the page size to ensure proper alignment for calls such
as mmap and friends. --davidm 99/11/30 */
int
__getpagesize ()
{
assert (GLRO(dl_pagesize) != 0);
return GLRO(dl_pagesize);
}
libc_hidden_def (__getpagesize)
weak_alias (__getpagesize, getpagesize)
-33
View File
@@ -1,33 +0,0 @@
/* Run-time dynamic linker data structures for loaded ELF shared objects. IA64.
Copyright (C) 2001 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _LDSODEFS_H
/* Get the real definitions. */
#include_next <ldsodefs.h>
/* Now define our stuff. */
/* We need special support to initialize DSO loaded for statically linked
binaries. */
extern void _dl_static_init (struct link_map *map);
#undef DL_STATIC_INIT
#define DL_STATIC_INIT(map) _dl_static_init (map)
#endif /* ldsodefs.h */
+6
View File
@@ -36,6 +36,12 @@ extern void _dl_aux_init (ElfW(auxv_t) *av) internal_function;
/* Initialization which is normally done by the dynamic linker. */
extern void _dl_non_dynamic_init (void) internal_function;
/* We need special support to initialize DSO loaded for statically linked
binaries. */
extern void _dl_static_init (struct link_map *map);
#undef DL_STATIC_INIT
#define DL_STATIC_INIT(map) _dl_static_init (map)
/* We can assume that the kernel always provides the AT_UID, AT_EUID,
AT_GID, and AT_EGID values in the auxiliary vector from 2.4.0 or so on. */
#if __ASSUME_AT_XID
@@ -1 +1 @@
#include "../../fxstat.c"
#include <sysdeps/unix/sysv/linux/i386/fxstat.c>
-4
View File
@@ -89,9 +89,6 @@ L(pseudo_end):
ret
L(thread_start):
cfi_startproc;
/* Clearing frame pointer is insufficient, use CFI. */
cfi_undefined (rip);
/* Clear the frame pointer. The ABI suggests this be done, to mark
the outermost frame obviously. */
xorl %ebp, %ebp
@@ -116,7 +113,6 @@ L(thread_start):
/* Call exit with return value from function call. */
movq %rax, %rdi
call HIDDEN_JUMPTARGET (_exit)
cfi_endproc;
cfi_startproc;
PSEUDO_END (BP_SYM (__clone))
+32 -1
View File
@@ -44,6 +44,25 @@
* crtn.s puts the corresponding function epilogues
in the .init and .fini sections. */
/* The unwind annotation for _fini is peculiar for good reasons:
(a) We need a real function that isn't constructed separately
(i.e. one which has a .size directive) in order to attach unwind
info to it. Hence _fini is a wrapper around _real_fini, the
former being a normal function, the latter being the first
instruction of the traditional _fini.
(b) We must not fiddle with the stack pointer in _real_fini,
as we wouldn't be able to describe the effects in unwind info
(c) some versions of GCC have no correct unwind info for
__do_global_dtors_aux, meaning they can't properly restore %rbp
(unwinding through it is possible but later up when we next
need %rbp we can't access it anymore)
Therefore we save/restore it in _fini for uses later up the call chain.
But we don't make the CFA use that register (that would lead to
the above problem)
(d) We want an 16-aligned stack pointer at _real_fini. Because of (a)
we can't align it in _real_fini, hence we do it in the caller by
subtracting 8, making in 8mod16 which the call then make 0mod16
again. */
__asm__ ("\n\
#include \"defs.h\"\n\
\n\
@@ -88,16 +107,28 @@ _init:\n\
.globl _fini\n\
.type _fini,@function\n\
_fini:\n\
.cfi_startproc\n\
push %rbp\n\
.cfi_def_cfa_offset 16\n\
.cfi_offset 6,-16\n\
subq $8, %rsp\n\
.cfi_def_cfa_offset 24\n\
call _real_fini\n\
addq $8, %rsp\n\
.cfi_def_cfa_offset 16\n\
pop %rbp\n\
ret\n\
.cfi_endproc\n\
ALIGN\n\
END_FINI\n\
.size _fini, .-_fini\n\
_real_fini:\n\
\n\
/*@_fini_PROLOG_ENDS*/\n\
call i_am_not_a_leaf@PLT\n\
\n\
/*@_fini_EPILOG_BEGINS*/\n\
.section .fini\n\
addq $8, %rsp\n\
ret\n\
END_FINI\n\
\n\