This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hi!
LD_DEBUG=statistics someprog leads to segfaults with current glibc.
The problem is that print_statistics doesn't check for NULL _ns_loaded
namespaces and happily dereferences it.
While looking into it, I have noticed the num_relative_relocations
computation doesn't match what do-rel.h is actually doing, particularly
on !ELF_MACHINE_REL_RELATIVE RELA architectures it is processing relative
relocations even if l_addr == 0, but the library is not prelinked.
2004-11-13 Jakub Jelinek <jakub@redhat.com>
* elf/rtld.c (print_statistics): Avoid segfaults if not all namespaces
are used. Fix computation of num_relative_relocations on RELA
architectures other than IA-64 and Alpha.
--- libc/elf/rtld.c.jj 2004-11-09 12:26:41.000000000 +0100
+++ libc/elf/rtld.c 2004-11-13 18:56:32.574028935 +0100
@@ -2336,19 +2336,29 @@ print_statistics (hp_timing_t *rtld_tota
unsigned long int num_relative_relocations = 0;
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
{
+ if (GL(dl_ns)[ns]._ns_loaded == NULL)
+ continue;
+
struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist;
for (unsigned int i = 0; i < scope->r_nlist; i++)
{
struct link_map *l = scope->r_list [i];
- if (!l->l_addr)
- continue;
-
- if (l->l_info[VERSYMIDX (DT_RELCOUNT)])
+ if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)])
num_relative_relocations
+= l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
- if (l->l_info[VERSYMIDX (DT_RELACOUNT)])
+#ifndef ELF_MACHINE_REL_RELATIVE
+ /* Relative relocations are processed on these architectures if
+ library is loaded to different address than p_vaddr or
+ if not prelinked. */
+ if ((l->l_addr != 0 || !map->l_info[VALIDX(DT_GNU_PRELINKED)])
+ && l->l_info[VERSYMIDX (DT_RELACOUNT)])
+#else
+ /* On e.g. IA-64 or Alpha, relative relocations are processed
+ only if library is loaded to different address than p_vaddr. */
+ if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)])
+#endif
num_relative_relocations
+= l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
}
Jakub
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |