+1998-10-07 Ulrich Drepper <drepper@cygnus.com>
+
+ * elf/dl-open.c (_dl_global_scope_alloc): Make global.
+ (dl_open_worker): Use realloc, not malloc to resize array.
+ * elf/rtld.c (_dl_initial_searchlist): New variable.
+ (_dl_main): Copy content of _dl_main_searchlist to
+ _dl_initial_searchlist.
+ * elf/ldsodefs.h: Add declarations for _dl_initial_searchlist and
+ _dl_global_scope_alloc.
+ * elf/Versions [libc, GLIBC_2.1]: Add _dl_initial_searchlist.
+ * elf/dl-close.c (_dl_close): When removing object with global
+ scope remove allocated searchlist if no dynamically loaded object
+ is on it anymore.
+ * elf/dl-support.c (_dl_initial_searchlist): Renamed from fake_scope.
+ (_dl_global_scope, _dl_main_searchlist): Use _dl_initial_searchlist.
+
+ * malloc/mtrace.c (tr_where): Don't print space in location string,
+ print it afterwards. Print better symbol name information.
+
1998-10-06 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* manual/filesys.texi (Setting Permissions): Fix example for
GLIBC_2.1 {
# global variables
_dl_profile; _dl_profile_map; _dl_profile_output; _dl_start_profile;
- _dl_loaded; _dl_main_searchlist; _dl_fpu_control;
+ _dl_loaded; _dl_main_searchlist; _dl_fpu_control; _dl_initial_searchlist;
# functions used in other libraries
_dl_mcount; _dl_mcount_wrapper; _dl_mcount_wrapper_check; _dl_unload_cache;
++cnt;
}
--_dl_main_searchlist->r_nlist;
+ if (_dl_main_searchlist->r_nlist
+ == _dl_initial_searchlist.r_nlist)
+ {
+ /* All object dynamically loaded by the program are
+ unloaded. Free the memory allocated for the global
+ scope variable. */
+ struct link_map **old = _dl_main_searchlist->r_list;
+
+ /* Put the old map in. */
+ _dl_main_searchlist->r_list = _dl_initial_searchlist.r_list;
+ /* Signal that the old map is used. */
+ _dl_global_scope_alloc = 0;
+
+ /* Now free the old map. */
+ free (old);
+ }
}
/* We can unmap all the maps at once. We determined the
extern char **__environ;
-static size_t _dl_global_scope_alloc;
+/* This is zero at program start to signal that the global scope map is
+ allocated by rtld. Later it keeps the size of the map. It might be
+ reset if in _dl_close if the last global object is removed. */
+size_t _dl_global_scope_alloc;
/* During the program run we must not modify the global data of
/* We have to extend the existing array of link maps in the
main map. */
new_global = (struct link_map **)
- malloc ((_dl_global_scope_alloc + 8) * sizeof (struct link_map *));
+ realloc (_dl_main_searchlist->r_list,
+ ((_dl_global_scope_alloc + 8)
+ * sizeof (struct link_map *)));
if (new_global == NULL)
goto nomem;
struct link_map *_dl_loaded;
/* Fake scope. In dynamically linked binaries this is the scope of the
- main application but here we don't have something like this. So
+ main application but here we don't have something like this. So
create a fake scope containing nothing. */
-static struct r_scope_elem fake_scope;
+struct r_scope_elem _dl_initial_searchlist;
/* Variable which can be used in lookup to process the global scope. */
-struct r_scope_elem *_dl_global_scope[2] = { &fake_scope, NULL };
+struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL };
/* This is a global pointer to this structure which is public. It is
used by dlopen/dlclose to add and remove objects from what is regarded
to be the global scope. */
-struct r_scope_elem *_dl_main_searchlist = &fake_scope;
+struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
static void non_dynamic_init (void) __attribute__ ((unused));
extern struct r_scope_elem *_dl_global_scope[2];
/* Direct pointer to the searchlist of the main object. */
extern struct r_scope_elem *_dl_main_searchlist;
+/* Copy of the content of `_dl_main_searchlist'. */
+extern struct r_scope_elem _dl_initial_searchlist;
+/* This is zero at program start to signal that the global scope map is
+ allocated by rtld. Later it keeps the size of the map. It might be
+ reset if in _dl_close if the last global object is removed. */
+extern size_t _dl_global_scope_alloc;
/* Allocate a `struct link_map' for a new object being loaded,
and enter it into the _dl_main_map list. */
struct link_map *_dl_loaded;
/* Pointer to the l_searchlist element of the link map of the main object. */
struct r_scope_elem *_dl_main_searchlist;
+/* Copy of the content of `_dl_main_searchlist'. */
+struct r_scope_elem _dl_initial_searchlist;
/* Array which is used when looking up in the global scope. */
struct r_scope_elem *_dl_global_scope[2];
_dl_main_searchlist = &_dl_loaded->l_searchlist;
_dl_global_scope[0] = &_dl_loaded->l_searchlist;
+ /* Safe the information about the original global scope list since
+ we need it in the memory handling later. */
+ _dl_initial_searchlist = *_dl_main_searchlist;
+
{
/* Initialize _r_debug. */
struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr);
Dl_info info;
if (_dl_addr (caller, &info))
{
- fprintf (mallstream, "@ %s%s%s%s%s[%p]",
+ char *buf = (char *) "";
+ if (info.dli_sname && info.dli_sname[0])
+ {
+ size_t len = strlen (info.dli_sname) + 22;
+ buf = alloca (len);
+ if (caller >= (const __ptr_t) info.dli_saddr)
+ snprintf (buf, len, "(%s+0x%x)", info.dli_sname,
+ caller - (const __ptr_t) info.dli_saddr);
+ else
+ snprintf (buf, len, "(%s-0x%x)", info.dli_sname,
+ (const __ptr_t) info.dli_saddr - caller);
+ }
+
+ fprintf (mallstream, "@ %s%s%s[%p] ",
info.dli_fname ?: "", info.dli_fname ? ":" : "",
- info.dli_sname ? "(" : "",
- info.dli_sname ?: "", info.dli_sname ? ") " : " ",
- caller);
+ buf, caller);
}
else
#endif