1999-08-01  Ulrich Drepper  <drepper@cygnus.com>

	* elf/dl-sym.c (_dl_sym): Always determine module of the caller to
	pass it to _dl_lookup_symbol.

	* elf/dl-error.c (_dl_signal_error): Optimize string generation a
	bit.  Reword message.

	* dlfcn/dlerror.c: Make code thread-safe.
This commit is contained in:
Ulrich Drepper 1999-08-01 19:24:38 +00:00
parent 7730a3b9d4
commit 4f2793d41f
4 changed files with 68 additions and 40 deletions

View File

@ -1,3 +1,13 @@
1999-08-01 Ulrich Drepper <drepper@cygnus.com>
* elf/dl-sym.c (_dl_sym): Always determine module of the caller to
pass it to _dl_lookup_symbol.
* elf/dl-error.c (_dl_signal_error): Optimize string generation a
bit. Reword message.
* dlfcn/dlerror.c: Make code thread-safe.
1999-07-31 Roland McGrath <roland@baalperazim.frob.com> 1999-07-31 Roland McGrath <roland@baalperazim.frob.com>
* hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): Fix msgt_size member * hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): Fix msgt_size member

View File

@ -1,5 +1,5 @@
/* Return error detail for failing <dlfcn.h> functions. /* Return error detail for failing <dlfcn.h> functions.
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@ -27,6 +27,7 @@
struct dl_action_result struct dl_action_result
{ {
int errcode; int errcode;
int returned;
char *errstring; char *errstring;
}; };
static struct dl_action_result last_result; static struct dl_action_result last_result;
@ -44,38 +45,41 @@ static void free_key_mem (void *mem);
char * char *
dlerror (void) dlerror (void)
{ {
static char *buf; char *buf;
struct dl_action_result *result; struct dl_action_result *result;
if (buf)
{
free (buf);
buf = NULL;
}
/* Get error string. */ /* Get error string. */
result = (struct dl_action_result *) __libc_getspecific (key); result = (struct dl_action_result *) __libc_getspecific (key);
if (result == NULL) if (result == NULL)
result = &last_result; result = &last_result;
if (! result->errstring) /* Test whether we already returned the string. */
return NULL; if (result->returned != 0)
{
if (result->errcode == 0) /* We can now free the string. */
buf = result->errstring; if (result->errstring != NULL)
{
free (result->errstring);
result->errstring = NULL;
}
buf = NULL;
}
else else
{ {
if (__asprintf (&buf, "%s: %s", buf = result->errstring;
result->errstring, strerror (result->errcode)) == -1) if (result->errcode != 0
buf = NULL; && __asprintf (&buf, "%s: %s",
result->errstring, strerror (result->errcode)) != -1)
{
/* We don't need the error string anymore. */
free (result->errstring);
result->errstring = buf;
}
/* We don't need the error string anymore. */ /* Mark the error as returned. */
free (result->errstring); result->returned = 1;
} }
/* Reset the error indicator. */
result->errstring = NULL;
return buf; return buf;
} }
@ -119,6 +123,9 @@ _dlerror_run (void (*operate) (void *), void *args)
result->errcode = _dl_catch_error (&result->errstring, operate, args); result->errcode = _dl_catch_error (&result->errstring, operate, args);
/* If no error we mark that no error string is available. */
result->returned = result->errstring == NULL;
return result->errstring != NULL; return result->errstring != NULL;
} }

View File

@ -1,5 +1,5 @@
/* Error handling for runtime dynamic linker. /* Error handling for runtime dynamic linker.
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Copyright (C) 1995, 1996, 1997, 1998, 1999 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
@ -75,12 +75,13 @@ _dl_signal_error (int errcode,
lcatch->errstring = malloc (objname_len + errstring_len); lcatch->errstring = malloc (objname_len + errstring_len);
if (lcatch->errstring != NULL) if (lcatch->errstring != NULL)
{ {
char *cp = lcatch->errstring;
if (objname_len > 0) if (objname_len > 0)
{ {
memcpy (lcatch->errstring, objname, objname_len - 2); cp = __mempcpy (cp, objname, objname_len - 2);
memcpy (lcatch->errstring + objname_len - 2, ": ", 2); cp = __mempcpy (cp, ": ", 2);
} }
memcpy (lcatch->errstring + objname_len, errstring, errstring_len); memcpy (cp, errstring, errstring_len);
} }
longjmp (lcatch->env, errcode ?: -1); longjmp (lcatch->env, errcode ?: -1);
} }
@ -89,7 +90,7 @@ _dl_signal_error (int errcode,
/* Lossage while resolving the program's own symbols is always fatal. */ /* Lossage while resolving the program's own symbols is always fatal. */
char buffer[1024]; char buffer[1024];
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>", _dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
": error in loading shared libraries: ", ": error while loading shared libraries: ",
objname ?: "", objname && *objname ? ": " : "", objname ?: "", objname && *objname ? ": " : "",
errstring, errcode ? ": " : "", errstring, errcode ? ": " : "",
(errcode (errcode

View File

@ -35,7 +35,7 @@ _dl_sym (void *handle, const char *name, void *who)
if (handle == RTLD_DEFAULT) if (handle == RTLD_DEFAULT)
/* Search the global scope. */ /* Search the global scope. */
loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0); loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
else if (handle == RTLD_NEXT) else
{ {
struct link_map *l, *match; struct link_map *l, *match;
ElfW(Addr) caller = (ElfW(Addr)) who; ElfW(Addr) caller = (ElfW(Addr)) who;
@ -46,22 +46,32 @@ _dl_sym (void *handle, const char *name, void *who)
if (caller >= l->l_addr && (!match || match->l_addr < l->l_addr)) if (caller >= l->l_addr && (!match || match->l_addr < l->l_addr))
match = l; match = l;
if (! match) if (handle != RTLD_NEXT)
_dl_signal_error (0, NULL, _("\ {
/* Search the scope of the given object. */
struct link_map *map = handle;
if (match == NULL)
/* If the address is not recognized the call comes from the
main program (we hope). */
match = _dl_loaded;
loadbase = _dl_lookup_symbol (name, match, &ref, map->l_local_scope,
0);
}
else
{
if (! match)
_dl_signal_error (0, NULL, _("\
RTLD_NEXT used in code not dynamically loaded")); RTLD_NEXT used in code not dynamically loaded"));
l = match; l = match;
while (l->l_loader) while (l->l_loader)
l = l->l_loader; l = l->l_loader;
loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope, loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
match); match);
} }
else
{
/* Search the scope of the given object. */
struct link_map *map = handle;
loadbase = _dl_lookup_symbol (name, map, &ref, map->l_local_scope, 0);
} }
if (loadbase) if (loadbase)