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>
* 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.
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.
The GNU C Library is free software; you can redistribute it and/or
@ -27,6 +27,7 @@
struct dl_action_result
{
int errcode;
int returned;
char *errstring;
};
static struct dl_action_result last_result;
@ -44,38 +45,41 @@ static void free_key_mem (void *mem);
char *
dlerror (void)
{
static char *buf;
char *buf;
struct dl_action_result *result;
if (buf)
{
free (buf);
buf = NULL;
}
/* Get error string. */
result = (struct dl_action_result *) __libc_getspecific (key);
if (result == NULL)
result = &last_result;
if (! result->errstring)
return NULL;
if (result->errcode == 0)
buf = result->errstring;
/* Test whether we already returned the string. */
if (result->returned != 0)
{
/* We can now free the string. */
if (result->errstring != NULL)
{
free (result->errstring);
result->errstring = NULL;
}
buf = NULL;
}
else
{
if (__asprintf (&buf, "%s: %s",
result->errstring, strerror (result->errcode)) == -1)
buf = NULL;
buf = result->errstring;
if (result->errcode != 0
&& __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. */
free (result->errstring);
/* Mark the error as returned. */
result->returned = 1;
}
/* Reset the error indicator. */
result->errstring = NULL;
return buf;
}
@ -119,6 +123,9 @@ _dlerror_run (void (*operate) (void *), void *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;
}

View File

@ -1,5 +1,5 @@
/* 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.
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);
if (lcatch->errstring != NULL)
{
char *cp = lcatch->errstring;
if (objname_len > 0)
{
memcpy (lcatch->errstring, objname, objname_len - 2);
memcpy (lcatch->errstring + objname_len - 2, ": ", 2);
cp = __mempcpy (cp, objname, objname_len - 2);
cp = __mempcpy (cp, ": ", 2);
}
memcpy (lcatch->errstring + objname_len, errstring, errstring_len);
memcpy (cp, errstring, errstring_len);
}
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. */
char buffer[1024];
_dl_sysdep_fatal (_dl_argv[0] ?: "<program name unknown>",
": error in loading shared libraries: ",
": error while loading shared libraries: ",
objname ?: "", objname && *objname ? ": " : "",
errstring, errcode ? ": " : "",
(errcode

View File

@ -35,7 +35,7 @@ _dl_sym (void *handle, const char *name, void *who)
if (handle == RTLD_DEFAULT)
/* Search the global scope. */
loadbase = _dl_lookup_symbol (name, NULL, &ref, _dl_global_scope, 0);
else if (handle == RTLD_NEXT)
else
{
struct link_map *l, *match;
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))
match = l;
if (! match)
_dl_signal_error (0, NULL, _("\
if (handle != RTLD_NEXT)
{
/* 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"));
l = match;
while (l->l_loader)
l = l->l_loader;
l = match;
while (l->l_loader)
l = l->l_loader;
loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
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);
loadbase = _dl_lookup_symbol_skip (name, l, &ref, l->l_local_scope,
match);
}
}
if (loadbase)