This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
evolution fails always now
- From: Jack Howarth <howarth at bromo dot msbb dot uc dot edu>
- To: libc-alpha at sources dot redhat dot com, drepper at redhat dot com, jakub at redhat dot com
- Date: Thu, 26 Sep 2002 22:14:05 -0400 (EDT)
- Subject: evolution fails always now
Jakub,
Using your proposed patch I have built a glibc locally
and although it passes make check I find the prelinked
evolution fails with a segfault as before. Worse yet now even
unprelinked evolution segfaults the same way. I will install
this new patched glibc on entropy so you can debug there
against it.
Jack
ps Other than evolution segfaulting all the time now..
prelinked or unprelinked, everything else seems to run fine.
Oh here is the patch I applied...with a const and []
added to tags...
---------------------------------------------------------------------------
--- libc/elf/dl-addr.c.jj 2002-08-04 20:23:20.000000000 +0200
+++ libc/elf/dl-addr.c 2002-09-27 00:03:09.000000000 +0200
@@ -21,6 +21,13 @@
#include <stddef.h>
#include <ldsodefs.h>
+#ifndef VERSYMIDX
+# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
+#endif
+#ifndef ADDRIDX
+# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
+ + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
+#endif
int
internal_function
@@ -28,7 +35,7 @@ _dl_addr (const void *address, Dl_info *
{
const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
struct link_map *l, *match;
- const ElfW(Sym) *symtab, *matchsym;
+ const ElfW(Sym) *symtab, *matchsym, *symtabend;
const char *strtab;
ElfW(Word) strtabsize;
@@ -60,30 +67,55 @@ _dl_addr (const void *address, Dl_info *
/* Now we know what object the address lies in. */
info->dli_fname = match->l_name;
- info->dli_fbase = (void *) match->l_addr;
+ info->dli_fbase = (void *) match->l_map_start;
/* If this is the main program the information is incomplete. */
- if (__builtin_expect (info->dli_fbase == NULL, 0))
- {
- info->dli_fname = _dl_argv[0];
- info->dli_fbase = (void *) match->l_map_start;
- }
+ if (__builtin_expect (*info->dli_fname == '\0', 0))
+ info->dli_fname = _dl_argv[0];
symtab = (const void *) D_PTR (match, l_info[DT_SYMTAB]);
strtab = (const void *) D_PTR (match, l_info[DT_STRTAB]);
strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
- /* We assume that the string table follows the symbol table, because
- there is no way in ELF to know the size of the dynamic symbol table!! */
- for (matchsym = NULL; (void *) symtab < (void *) strtab; ++symtab)
- if (addr >= match->l_addr + symtab->st_value
- && ((symtab->st_size == 0 && addr == match->l_addr + symtab->st_value)
- || addr < match->l_addr + symtab->st_value + symtab->st_size)
- && symtab->st_name < strtabsize
- && (matchsym == NULL || matchsym->st_value < symtab->st_value)
- && (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
- || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK))
- matchsym = symtab;
+ if (match->l_name[0] != '\0')
+ /* We assume that the string table follows the symbol table, because
+ there is no way in ELF to know the size of the dynamic symbol table!! */
+ symtabend = (const ElfW(Sym) *) strtab;
+ else
+ {
+ /* Prelinking an executable might move strtab away from symtab. */
+ const static int tags[] = { DT_STRTAB, DT_JMPREL, DT_RELA, DT_REL, DT_HASH,
+ DT_INIT, DT_INIT_ARRAY, DT_FINI_ARRAY,
+ DT_PREINIT_ARRAY, ADDRIDX (DT_GNU_CONFLICT),
+ ADDRIDX (DT_GNU_LIBLIST), VERSYMIDX (DT_VERSYM),
+ VERSYMIDX (DT_VERDEF), VERSYMIDX (DT_VERNEED) };
+ int tag;
+
+ for (symtabend = (const ElfW(Sym) *) -1, tag = 0;
+ tag < sizeof (tags) / sizeof (tags[0]); tag++)
+ {
+ if (D_PTR (match, l_info[tags[tag]]) >= symtab
+ && D_PTR (match, l_info[tags[tag]]) < symtabend)
+ symtabend
+ = (const ElfW(Sym) *) D_PTR (match, l_info[tags[tag]]);
+ }
+ if (symtabend == (const ElfW(Sym) *) -1)
+ symtabend = symtab;
+ }
+
+ for (matchsym = NULL; symtab < symtabend; ++symtab)
+ {
+ if (symtab->st_name >= strtabsize)
+ break;
+ if (addr >= match->l_addr + symtab->st_value
+ && ((symtab->st_size == 0
+ && addr == match->l_addr + symtab->st_value)
+ || addr < match->l_addr + symtab->st_value + symtab->st_size)
+ && (matchsym == NULL || matchsym->st_value < symtab->st_value)
+ && (ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
+ || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK))
+ matchsym = symtab;
+ }
if (matchsym)
{