1998-03-05  Ulrich Drepper  <drepper@cygnus.com>

	* elf/rtld.c: Speed up processing of environment variables.  Do
	only one run on the environment by avoiding to call getenv.
	* sysdeps/generic/dl-sysdep.c (_dl_next_ld_env_entry): New
	function.  Used by patch above.

1998-03-05 10:25  Ulrich Drepper  <drepper@cygnus.com>

	* nss/getXXbyYY_r.c: Don't try to contact nscd every time when it
	failed.  Only do this every NSS_NSCD_RETRY times.
	* nss/nsswitch.c: Define __nss_nscd_not_available, used by above
	change.
	* nscd/nscd_getgr_r.c (__nscd_getgr_r): Return 2 if contacting the
	daemon failed.
	* nscd/nscd_getpw_r.c (__nscd_getpw_r): Likewise.

1998-03-05  Ulrich Drepper  <drepper@cygnus.com>

	* nss/nsswitch.c (nss_lookup_function): Don't modify errno if NSS
	module cannot be found.  Reported by Andreas Jaeger.

1998-03-05 11:40  Franz Sirl <Franz.Sirl-kernel@lauterbach.com>

	* nscd/nscd_getgr_r.c: Change char to int to avoid compiler warning
	on platforms which default to unsigned chars.
	* nscd/nscd_getpw_r.c: Likewise.
	* sysdeps/unix/sysv/linux/powerpc/sysdep.h: Undefine L before
	defining it.

1998-03-05  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* elf/Makefile (install-bin): Change = to += for sprof to install
	ldd also.
This commit is contained in:
Ulrich Drepper 1998-03-05 14:03:24 +00:00
parent 2eb45444a7
commit ea27835442
12 changed files with 214 additions and 56 deletions

View File

@ -1,3 +1,38 @@
1998-03-05 Ulrich Drepper <drepper@cygnus.com>
* elf/rtld.c: Speed up processing of environment variables. Do
only one run on the environment by avoiding to call getenv.
* sysdeps/generic/dl-sysdep.c (_dl_next_ld_env_entry): New
function. Used by patch above.
1998-03-05 10:25 Ulrich Drepper <drepper@cygnus.com>
* nss/getXXbyYY_r.c: Don't try to contact nscd every time when it
failed. Only do this every NSS_NSCD_RETRY times.
* nss/nsswitch.c: Define __nss_nscd_not_available, used by above
change.
* nscd/nscd_getgr_r.c (__nscd_getgr_r): Return 2 if contacting the
daemon failed.
* nscd/nscd_getpw_r.c (__nscd_getpw_r): Likewise.
1998-03-05 Ulrich Drepper <drepper@cygnus.com>
* nss/nsswitch.c (nss_lookup_function): Don't modify errno if NSS
module cannot be found. Reported by Andreas Jaeger.
1998-03-05 11:40 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
* nscd/nscd_getgr_r.c: Change char to int to avoid compiler warning
on platforms which default to unsigned chars.
* nscd/nscd_getpw_r.c: Likewise.
* sysdeps/unix/sysv/linux/powerpc/sysdep.h: Undefine L before
defining it.
1998-03-05 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* elf/Makefile (install-bin): Change = to += for sprof to install
ldd also.
1998-03-04 16:12 H.J. Lu <hjl@gnu.org> 1998-03-04 16:12 H.J. Lu <hjl@gnu.org>
* libio/strops.c (_IO_str_seekoff): Handle MODE == 0. * libio/strops.c (_IO_str_seekoff): Handle MODE == 0.

7
NEWS
View File

@ -54,6 +54,11 @@ Version 2.1
* The localedata addon is now part of glibc. * The localedata addon is now part of glibc.
* An implementation of profiling shared libraries was added by Ulrich Drepper. * An implementation of profiling shared libraries was added by Ulrich Drepper.
* Thorsten Kukuk provided an implementation for a caching daemon for NSS
(nscd).
* Tim Waugh provided an implementation of the POSIX.2 wordexp function family.
Version 2.0.5 Version 2.0.5
@ -503,7 +508,7 @@ Version 1.06
`make dvi' will produce a DVI file of the printed manual. `make dvi' will produce a DVI file of the printed manual.
`make info' will produce Info files that you can read on line using C-h i `make info' will produce Info files that you can read on line using C-h i
in Emacs or the `info' program. in Emacs or the `info' program.
Please send comments on the manual to bug-glibc-manual@prep.ai.mit.edu. Please send comments on the manual to bug-glibc-manual@gnu.org.
* The library now supports SVR4 on i386s (i386-unknown-sysv4). * The library now supports SVR4 on i386s (i386-unknown-sysv4).

View File

@ -73,9 +73,9 @@ GNU libc at http://www.gnu.org/software/libc/libc.html.
The GNU C Library is completely documented by the Texinfo manual found The GNU C Library is completely documented by the Texinfo manual found
in the `manual/' subdirectory. The manual is still being updated and in the `manual/' subdirectory. The manual is still being updated and
contains some known errors and omissions; we regret that we do not have contains some known errors and omissions; we regret that we do not
the resources to work on the manual as much as we would like. Please have the resources to work on the manual as much as we would like.
send comments on the manual to <bug-glibc-manual@prep.ai.mit.edu>, and Please send comments on the manual to <bug-glibc-manual@gnu.org>, and
not to the library bug-reporting address. not to the library bug-reporting address.
The file NOTES contains a description of the feature-test macros used The file NOTES contains a description of the feature-test macros used

View File

@ -61,7 +61,7 @@ generated += ldd
endif endif
others = sprof others = sprof
install-bin = sprof install-bin += sprof
ifeq (yes,$(has-ldconfig)) ifeq (yes,$(has-ldconfig))
others-static += ldconfig others-static += ldconfig

View File

@ -53,6 +53,15 @@ static void print_unresolved (int errcode, const char *objname,
static void print_missing_version (int errcode, const char *objname, static void print_missing_version (int errcode, const char *objname,
const char *errsting); const char *errsting);
/* This is a list of all the modes the dynamic loader can be in. */
enum mode { normal, list, verify, trace };
/* Process all environments variables the dynamic linker must recognize.
Since all of them start with `LD_' we are a bit smarter while finding
all the entries. */
static void process_envvars (enum mode *modep, int *lazyp);
int _dl_argc; int _dl_argc;
char **_dl_argv; char **_dl_argv;
const char *_dl_rpath; const char *_dl_rpath;
@ -147,7 +156,6 @@ _dl_start (void *arg)
return _dl_sysdep_start (arg, &dl_main); return _dl_sysdep_start (arg, &dl_main);
} }
/* Now life is peachy; we can do all normal operations. /* Now life is peachy; we can do all normal operations.
On to the real work. */ On to the real work. */
@ -260,7 +268,7 @@ dl_main (const ElfW(Phdr) *phdr,
const ElfW(Phdr) *ph; const ElfW(Phdr) *ph;
struct link_map *main_map; struct link_map *main_map;
int lazy; int lazy;
enum { normal, list, verify, trace } mode; enum mode mode;
struct link_map **preloads; struct link_map **preloads;
unsigned int npreloads; unsigned int npreloads;
const char *preloadlist; const char *preloadlist;
@ -268,41 +276,8 @@ dl_main (const ElfW(Phdr) *phdr,
char *file; char *file;
int has_interp = 0; int has_interp = 0;
/* Test whether we want to see the content of the auxiliary array passed /* Process the environment variable which control the behaviour. */
up from the kernel. */ process_envvars (&mode, &lazy);
if (getenv ("LD_SHOW_AUXV") != NULL)
_dl_show_auxv ();
mode = getenv ("LD_TRACE_LOADED_OBJECTS") != NULL ? trace : normal;
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
/* LAZY is determined by the environment variable LD_WARN and
LD_BIND_NOW if we trace the binary. */
if (mode == trace)
lazy = (_dl_verbose
? (*(getenv ("LD_BIND_NOW") ?: "") == '\0' ? 1 : 0) : -1);
else
lazy = !__libc_enable_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
/* See whether we want to use profiling. */
_dl_profile = getenv ("LD_PROFILE");
if (_dl_profile != NULL)
if (_dl_profile[0] == '\0')
/* An empty string is of not much help. Disable profiling. */
_dl_profile = NULL;
else
{
/* OK, we have the name of a shared object we want to
profile. It's up to the user to provide a good name, it
must match the file name or soname of one of the loaded
objects. Now let's see where we are supposed to place the
result. */
_dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
/* This is the default place. */
_dl_profile_output = "/var/tmp";
}
/* Set up a flag which tells we are just starting. */ /* Set up a flag which tells we are just starting. */
_dl_starting_up = 1; _dl_starting_up = 1;
@ -930,3 +905,95 @@ print_missing_version (int errcode __attribute__ ((unused)),
_dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>", ": ", _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>", ": ",
objname, ": ", errstring, "\n", NULL); objname, ": ", errstring, "\n", NULL);
} }
/* Process all environments variables the dynamic linker must recognize.
Since all of them start with `LD_' we are a bit smarter while finding
all the entries. */
static void
process_envvars (enum mode *modep, int *lazyp)
{
char **runp = NULL;
char *envline;
enum mode mode = normal;
int bind_now = 0;
/* This is the default place for profiling data file. */
_dl_profile_output = "/var/tmp";
while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
{
int result;
/* Do we bind early? */
result = strncmp (&envline[3], "BIND_NOW=", 9);
if (result == 0)
{
bind_now = 1;
continue;
}
if (result < 0)
continue;
/* Which shared object shall be profiled. */
result = strncmp (&envline[3], "PROFILE=", 8);
if (result == 0)
{
_dl_profile = &envline[11];
if (*_dl_profile == '\0')
_dl_profile = NULL;
continue;
}
if (result < 0)
continue;
/* Where to place the profiling data file. */
result = strncmp (&envline[3], "PROFILE_OUTPUT=", 15);
if (result == 0)
{
_dl_profile_output = &envline[18];
if (*_dl_profile_output == '\0')
_dl_profile_output = "/var/tmp";
continue;
}
if (result < 0)
continue;
/* Test whether we want to see the content of the auxiliary
array passed up from the kernel. */
result = strncmp (&envline[3], "SHOW_AUXV=", 10);
if (result == 0)
{
_dl_show_auxv ();
continue;
}
if (result < 0)
continue;
/* The mode of the dynamic linker can be set. */
result = strncmp (&envline[3], "TRACE_LOADED_OBJECTS=", 21);
if (result == 0)
{
mode = trace;
continue;
}
if (result < 0)
continue;
/* Warning level, verbose or not. */
result = strncmp (&envline[3], "WARN=", 5);
if (result == 0)
{
_dl_verbose = envline[8] != '\0';
continue;
}
}
/* LAZY is determined by the environment variable LD_WARN and
LD_BIND_NOW if we trace the binary. */
if (mode == trace)
*lazyp = _dl_verbose ? !bind_now : -1;
else
*lazyp = !__libc_enable_secure && !bind_now;
*modep = mode;
}

View File

@ -377,7 +377,7 @@ doesn't tell you, that's a bug in the manual. Report that too! If the
function's behavior disagrees with the manual, then either the library function's behavior disagrees with the manual, then either the library
or the manual has a bug, so report the disagreement. If you find any or the manual has a bug, so report the disagreement. If you find any
errors or omissions in this manual, please report them to the Internet errors or omissions in this manual, please report them to the Internet
address @email{bug-glibc-manual@@prep.ai.mit.edu}. address @email{bug-glibc-manual@@gnu.org}.
@node Source Layout @node Source Layout
@appendixsec Adding New Functions @appendixsec Adding New Functions

View File

@ -48,7 +48,7 @@ __nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
size_t buflen) size_t buflen)
{ {
char *p = buffer; char *p = buffer;
char plen; int plen;
plen = snprintf (buffer, buflen, "%d", gid); plen = snprintf (buffer, buflen, "%d", gid);
if (plen == -1) if (plen == -1)
@ -98,7 +98,8 @@ __nscd_getgr_r (const char *key, request_type type, struct group *resultbuf,
ssize_t nbytes; ssize_t nbytes;
if (sock == -1) if (sock == -1)
return 1; /* Returning two signals that contacting the daemon failed. */
return 2;
req.version = NSCD_VERSION; req.version = NSCD_VERSION;
req.type = type; req.type = type;

View File

@ -48,7 +48,7 @@ __nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf, char *buffer,
size_t buflen) size_t buflen)
{ {
char *p = buffer; char *p = buffer;
char plen; int plen;
plen = snprintf (buffer, buflen, "%d", uid); plen = snprintf (buffer, buflen, "%d", uid);
if (plen == -1) if (plen == -1)
@ -98,7 +98,8 @@ __nscd_getpw_r (const char *key, request_type type, struct passwd *resultbuf,
ssize_t nbytes; ssize_t nbytes;
if (sock == -1) if (sock == -1)
return 1; /* Returning two signals that contacting the daemon failed. */
return 2;
req.version = NSCD_VERSION; req.version = NSCD_VERSION;
req.type = type; req.type = type;

View File

@ -88,6 +88,12 @@ extern struct __res_state _res;
/* The lookup function for the first entry of this service. */ /* The lookup function for the first entry of this service. */
extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp); extern int DB_LOOKUP_FCT (service_user **nip, const char *name, void **fctp);
/* Nonzero if the NSCD is not available. This variable will be increased
whenever we try to use the NSCD but see it is not avilable. So we
can recheck the presence every once in a while. */
extern int __nss_nscd_not_available;
/* Interval in which we transfer retry to contact the NSCD. */
#define NSS_NSCD_RETRY 100
int int
@ -111,11 +117,21 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
#endif #endif
#ifdef USE_NSCD #ifdef USE_NSCD
nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen H_ERRNO_VAR); if (__nss_nscd_not_available && ++__nss_nscd_not_available > NSS_NSCD_RETRY)
if (nscd_status < 1) __nss_nscd_not_available = 0;
if (!__nss_nscd_not_available)
{ {
*result = nscd_status == 0 ? resbuf : NULL; nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen
return nscd_status; H_ERRNO_VAR);
if (nscd_status < 1)
{
*result = nscd_status == 0 ? resbuf : NULL;
return nscd_status;
}
if (nscd_status == 2)
/* This return value indicates that contacting the server failed. */
__nss_nscd_not_available = 1;
} }
#endif #endif
@ -152,7 +168,7 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen, status = (*fct) (ADD_VARIABLES, resbuf, buffer, buflen,
__errno_location () H_ERRNO_VAR); __errno_location () H_ERRNO_VAR);
/* The the status is NSS_STATUS_TRYAGAIN and errno is ERANGE the /* The status is NSS_STATUS_TRYAGAIN and errno is ERANGE the
provided buffer is too small. In this case we should give provided buffer is too small. In this case we should give
the user the possibility to enlarge the buffer and we should the user the possibility to enlarge the buffer and we should
not simply go on with the next service (even if the TRYAGAIN not simply go on with the next service (even if the TRYAGAIN

View File

@ -69,6 +69,9 @@ static struct
__libc_lock_define_initialized (static, lock) __libc_lock_define_initialized (static, lock)
/* Nonzero if no NSCD is available. */
int __nss_nscd_not_available;
#if !defined DO_STATIC_NSS || defined PIC #if !defined DO_STATIC_NSS || defined PIC
/* String with revision number of the shared object files. */ /* String with revision number of the shared object files. */
static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15; static const char *const __nss_shlib_revision = LIBNSS_FILES_SO + 15;
@ -380,7 +383,7 @@ nss_lookup_function (service_user *ni, const char *fct_name)
/* Load the shared library. */ /* Load the shared library. */
size_t shlen = (7 + strlen (ni->library->name) + 3 size_t shlen = (7 + strlen (ni->library->name) + 3
+ strlen (__nss_shlib_revision) + 1); + strlen (__nss_shlib_revision) + 1);
int saved_errno = errno;
struct do_open_args args; struct do_open_args args;
args.shlib_name = __alloca (shlen); args.shlib_name = __alloca (shlen);
args.ni = ni; args.ni = ni;
@ -393,8 +396,11 @@ nss_lookup_function (service_user *ni, const char *fct_name)
__nss_shlib_revision); __nss_shlib_revision);
if (nss_dlerror_run (do_open, &args) != 0) if (nss_dlerror_run (do_open, &args) != 0)
/* Failed to load the library. */ {
ni->library->lib_handle = (void *) -1l; /* Failed to load the library. */
ni->library->lib_handle = (void *) -1l;
__set_errno (saved_errno);
}
} }
if (ni->library->lib_handle == (void *) -1l) if (ni->library->lib_handle == (void *) -1l)

View File

@ -243,3 +243,29 @@ _dl_show_auxv (void)
break; break;
} }
} }
/* Walk through the environment of the process and return all entries
starting with `LD_'. */
char *
_dl_next_ld_env_entry (char ***position)
{
char **current = *position;
char *result = NULL;
if (current == NULL)
/* We start over. */
current = _environ;
while (result == NULL && *current != NULL)
{
if ((*current)[0] == 'L' && (*current)[1] == 'D' && (*current)[2] == '_')
result = *current;
++current;
}
/* Save current position for next visit. */
*position = current;
return result;
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1992, 1997 Free Software Foundation, Inc. /* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -138,6 +138,7 @@
END (name) END (name)
/* Local labels stripped out by the linker. */ /* Local labels stripped out by the linker. */
#undef L
#define L(x) .L##x #define L(x) .L##x
#endif /* ASSEMBLER */ #endif /* ASSEMBLER */