|
|
b9ba6d |
2010-10-26 Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* elf/rtld.c (dl_main): Move assertion after the point where rtld map
|
|
|
b9ba6d |
is added to the list.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
2010-10-20 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
|
|
|
b9ba6d |
Ulrich Drepper <drepper@gmail.com>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
* elf/dl-object.c (_dl_new_object): Don't append the new object to
|
|
|
b9ba6d |
the global list here. Move code to...
|
|
|
b9ba6d |
(_dl_add_to_namespace_list): ...here. New function.
|
|
|
b9ba6d |
* elf/rtld.c (dl_main): Invoke _dl_add_to_namespace_list.
|
|
|
b9ba6d |
* sysdeps/generic/ldsodefs.h (_dl_add_to_namespace_list): Declare.
|
|
|
b9ba6d |
* elf/dl-load.c (lose): Don't remove the element from the list.
|
|
|
b9ba6d |
(_dl_map_object_from_fd): Invoke _dl_add_to_namespace_list.
|
|
|
b9ba6d |
(_dl_map_object): Likewise.
|
|
|
b9ba6d |
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/elf/dl-load.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/elf/dl-load.c
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/elf/dl-load.c
|
|
|
b9ba6d |
@@ -797,22 +797,7 @@ lose (int code, int fd, const char *name
|
|
|
b9ba6d |
/* The file might already be closed. */
|
|
|
b9ba6d |
if (fd != -1)
|
|
|
b9ba6d |
(void) __close (fd);
|
|
|
b9ba6d |
- if (l != NULL)
|
|
|
b9ba6d |
- {
|
|
|
b9ba6d |
- /* We modify the list of loaded objects. */
|
|
|
b9ba6d |
- __rtld_lock_lock_recursive (GL(dl_load_write_lock));
|
|
|
b9ba6d |
- /* Remove the stillborn object from the list and free it. */
|
|
|
b9ba6d |
- assert (l->l_next == NULL);
|
|
|
b9ba6d |
- if (l->l_prev == NULL)
|
|
|
b9ba6d |
- /* No other module loaded. This happens only in the static library,
|
|
|
b9ba6d |
- or in rtld under --verify. */
|
|
|
b9ba6d |
- GL(dl_ns)[l->l_ns]._ns_loaded = NULL;
|
|
|
b9ba6d |
- else
|
|
|
b9ba6d |
- l->l_prev->l_next = NULL;
|
|
|
b9ba6d |
- --GL(dl_ns)[l->l_ns]._ns_nloaded;
|
|
|
b9ba6d |
- free (l);
|
|
|
b9ba6d |
- __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
|
|
|
b9ba6d |
- }
|
|
|
b9ba6d |
+ free (l);
|
|
|
b9ba6d |
free (realname);
|
|
|
b9ba6d |
|
|
|
b9ba6d |
if (r != NULL)
|
|
|
b9ba6d |
@@ -897,6 +882,9 @@ _dl_map_object_from_fd (const char *name
|
|
|
b9ba6d |
never be unloaded. */
|
|
|
b9ba6d |
__close (fd);
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+ /* Add the map for the mirrored object to the object list. */
|
|
|
b9ba6d |
+ _dl_add_to_namespace_list (l, nsid);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
return l;
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
#endif
|
|
|
b9ba6d |
@@ -1491,6 +1479,9 @@ cannot enable executable stack as shared
|
|
|
b9ba6d |
add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
|
|
|
b9ba6d |
+ l->l_info[DT_SONAME]->d_un.d_val));
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+ /* Now that the object is fully initialized add it to the object list. */
|
|
|
b9ba6d |
+ _dl_add_to_namespace_list (l, nsid);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
#ifdef SHARED
|
|
|
b9ba6d |
/* Auditing checkpoint: we have a new object. */
|
|
|
b9ba6d |
if (__builtin_expect (GLRO(dl_naudit) > 0, 0)
|
|
|
b9ba6d |
@@ -2215,7 +2206,7 @@ _dl_map_object (struct link_map *loader,
|
|
|
b9ba6d |
have. */
|
|
|
b9ba6d |
static const Elf_Symndx dummy_bucket = STN_UNDEF;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
- /* Enter the new object in the list of loaded objects. */
|
|
|
b9ba6d |
+ /* Allocate a new object map. */
|
|
|
b9ba6d |
if ((name_copy = local_strdup (name)) == NULL
|
|
|
b9ba6d |
|| (l = _dl_new_object (name_copy, name, type, loader,
|
|
|
b9ba6d |
mode, nsid)) == NULL)
|
|
|
b9ba6d |
@@ -2233,6 +2224,9 @@ _dl_map_object (struct link_map *loader,
|
|
|
b9ba6d |
l->l_nbuckets = 1;
|
|
|
b9ba6d |
l->l_relocated = 1;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+ /* Enter the object in the object list. */
|
|
|
b9ba6d |
+ _dl_add_to_namespace_list (l, nsid);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
return l;
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
else if (found_other_class)
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/elf/dl-object.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/elf/dl-object.c
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/elf/dl-object.c
|
|
|
b9ba6d |
@@ -26,16 +26,41 @@
|
|
|
b9ba6d |
#include <assert.h>
|
|
|
b9ba6d |
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+/* Add the new link_map NEW to the end of the namespace list. */
|
|
|
b9ba6d |
+void
|
|
|
b9ba6d |
+internal_function
|
|
|
b9ba6d |
+_dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
|
|
|
b9ba6d |
+{
|
|
|
b9ba6d |
+ /* We modify the list of loaded objects. */
|
|
|
b9ba6d |
+ __rtld_lock_lock_recursive (GL(dl_load_write_lock));
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ if (GL(dl_ns)[nsid]._ns_loaded != NULL)
|
|
|
b9ba6d |
+ {
|
|
|
b9ba6d |
+ struct link_map *l = GL(dl_ns)[nsid]._ns_loaded;
|
|
|
b9ba6d |
+ while (l->l_next != NULL)
|
|
|
b9ba6d |
+ l = l->l_next;
|
|
|
b9ba6d |
+ new->l_prev = l;
|
|
|
b9ba6d |
+ /* new->l_next = NULL; Would be necessary but we use calloc. */
|
|
|
b9ba6d |
+ l->l_next = new;
|
|
|
b9ba6d |
+ }
|
|
|
b9ba6d |
+ else
|
|
|
b9ba6d |
+ GL(dl_ns)[nsid]._ns_loaded = new;
|
|
|
b9ba6d |
+ ++GL(dl_ns)[nsid]._ns_nloaded;
|
|
|
b9ba6d |
+ new->l_serial = GL(dl_load_adds);
|
|
|
b9ba6d |
+ ++GL(dl_load_adds);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+ __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
|
|
|
b9ba6d |
+}
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
/* Allocate a `struct link_map' for a new object being loaded,
|
|
|
b9ba6d |
and enter it into the _dl_loaded list. */
|
|
|
b9ba6d |
-
|
|
|
b9ba6d |
struct link_map *
|
|
|
b9ba6d |
internal_function
|
|
|
b9ba6d |
_dl_new_object (char *realname, const char *libname, int type,
|
|
|
b9ba6d |
struct link_map *loader, int mode, Lmid_t nsid)
|
|
|
b9ba6d |
{
|
|
|
b9ba6d |
struct link_map *l;
|
|
|
b9ba6d |
- int idx;
|
|
|
b9ba6d |
size_t libname_len = strlen (libname) + 1;
|
|
|
b9ba6d |
struct link_map *new;
|
|
|
b9ba6d |
struct libname_list *newname;
|
|
|
b9ba6d |
@@ -93,31 +118,12 @@ _dl_new_object (char *realname, const ch
|
|
|
b9ba6d |
new->l_scope = new->l_scope_mem;
|
|
|
b9ba6d |
new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
|
|
|
b9ba6d |
|
|
|
b9ba6d |
- /* We modify the list of loaded objects. */
|
|
|
b9ba6d |
- __rtld_lock_lock_recursive (GL(dl_load_write_lock));
|
|
|
b9ba6d |
-
|
|
|
b9ba6d |
/* Counter for the scopes we have to handle. */
|
|
|
b9ba6d |
- idx = 0;
|
|
|
b9ba6d |
+ int idx = 0;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
if (GL(dl_ns)[nsid]._ns_loaded != NULL)
|
|
|
b9ba6d |
- {
|
|
|
b9ba6d |
- l = GL(dl_ns)[nsid]._ns_loaded;
|
|
|
b9ba6d |
- while (l->l_next != NULL)
|
|
|
b9ba6d |
- l = l->l_next;
|
|
|
b9ba6d |
- new->l_prev = l;
|
|
|
b9ba6d |
- /* new->l_next = NULL; Would be necessary but we use calloc. */
|
|
|
b9ba6d |
- l->l_next = new;
|
|
|
b9ba6d |
-
|
|
|
b9ba6d |
- /* Add the global scope. */
|
|
|
b9ba6d |
- new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
|
|
|
b9ba6d |
- }
|
|
|
b9ba6d |
- else
|
|
|
b9ba6d |
- GL(dl_ns)[nsid]._ns_loaded = new;
|
|
|
b9ba6d |
- ++GL(dl_ns)[nsid]._ns_nloaded;
|
|
|
b9ba6d |
- new->l_serial = GL(dl_load_adds);
|
|
|
b9ba6d |
- ++GL(dl_load_adds);
|
|
|
b9ba6d |
-
|
|
|
b9ba6d |
- __rtld_lock_unlock_recursive (GL(dl_load_write_lock));
|
|
|
b9ba6d |
+ /* Add the global scope. */
|
|
|
b9ba6d |
+ new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
/* If we have no loader the new object acts as it. */
|
|
|
b9ba6d |
if (loader == NULL)
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/elf/rtld.c
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/elf/rtld.c
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/elf/rtld.c
|
|
|
b9ba6d |
@@ -1108,11 +1108,15 @@ of this helper program; chances are you
|
|
|
b9ba6d |
main_map = _dl_new_object ((char *) "", "", lt_executable, NULL,
|
|
|
b9ba6d |
__RTLD_OPENEXEC, LM_ID_BASE);
|
|
|
b9ba6d |
assert (main_map != NULL);
|
|
|
b9ba6d |
- assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded);
|
|
|
b9ba6d |
main_map->l_phdr = phdr;
|
|
|
b9ba6d |
main_map->l_phnum = phnum;
|
|
|
b9ba6d |
main_map->l_entry = *user_entry;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+ /* Even though the link map is not yet fully initialized we can add
|
|
|
b9ba6d |
+ it to the map list since there are no possible users running yet. */
|
|
|
b9ba6d |
+ _dl_add_to_namespace_list (main_map, LM_ID_BASE);
|
|
|
b9ba6d |
+ assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
/* At this point we are in a bit of trouble. We would have to
|
|
|
b9ba6d |
fill in the values for l_dev and l_ino. But in general we
|
|
|
b9ba6d |
do not know where the file is. We also do not handle AT_EXECFD
|
|
|
b9ba6d |
@@ -1380,6 +1384,9 @@ of this helper program; chances are you
|
|
|
b9ba6d |
l->l_libname->name = memcpy (copy, dsoname, len);
|
|
|
b9ba6d |
}
|
|
|
b9ba6d |
|
|
|
b9ba6d |
+ /* Add the vDSO to the object list. */
|
|
|
b9ba6d |
+ _dl_add_to_namespace_list (l, LM_ID_BASE);
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
/* Rearrange the list so this DSO appears after rtld_map. */
|
|
|
b9ba6d |
assert (l->l_next == NULL);
|
|
|
b9ba6d |
assert (l->l_prev == main_map);
|
|
|
b9ba6d |
Index: glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
|
|
|
b9ba6d |
===================================================================
|
|
|
b9ba6d |
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/generic/ldsodefs.h
|
|
|
b9ba6d |
+++ glibc-2.12-2-gc4ccff1/sysdeps/generic/ldsodefs.h
|
|
|
b9ba6d |
@@ -891,8 +891,11 @@ extern lookup_t _dl_lookup_symbol_x (con
|
|
|
b9ba6d |
extern ElfW(Addr) _dl_symbol_value (struct link_map *map, const char *name)
|
|
|
b9ba6d |
internal_function;
|
|
|
b9ba6d |
|
|
|
b9ba6d |
-/* Allocate a `struct link_map' for a new object being loaded,
|
|
|
b9ba6d |
- and enter it into the _dl_main_map list. */
|
|
|
b9ba6d |
+/* Add the new link_map NEW to the end of the namespace list. */
|
|
|
b9ba6d |
+extern void _dl_add_to_namespace_list (struct link_map *new, Lmid_t nsid)
|
|
|
b9ba6d |
+ internal_function attribute_hidden;
|
|
|
b9ba6d |
+
|
|
|
b9ba6d |
+/* Allocate a `struct link_map' for a new object being loaded. */
|
|
|
b9ba6d |
extern struct link_map *_dl_new_object (char *realname, const char *libname,
|
|
|
b9ba6d |
int type, struct link_map *loader,
|
|
|
b9ba6d |
int mode, Lmid_t nsid)
|