This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)
     {




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]