[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#265678: Fix/Workaround for broken symbol resolving on mips/mipsel



tags 265678 +patch
thanks

ld.so for mips/mipsel resolves symbols to the lazy evaluation stub of
in between libraries. The stubs aren't marked by anything beyond the
section information, but their symbols are SHN_UNDEF.

The appended patch works around this by ignoring SHN_UNDEF symbols in
the resolver lookup function. It may break copy relocations on other
architectures, so it should be mips specific. It also includes a
INTUSE cleanup which is unrelated to this bug.

I built and installed the resulting libc on several mips machines,
fakeroot works, no ill effects observed so far.


Thiemo


#! /bin/sh -e

# All lines beginning with `# DP:' are a description of the patch.
# DP: Description: Workaround invalid resolving of lazy evaluation stubs
# DP: Author: Thiemo Seufer <ths@debian.org>
# DP: Date:  2005-04-11

if [ $# -ne 2 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch) patch -d "$2" -f --no-backup-if-mismatch -p2 < $0;;
    -unpatch) patch -d "$2" -f --no-backup-if-mismatch -R -p2 < $0;;
    *)
	echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
	exit 1
esac
exit 0

# append the patch here and adjust the -p? flag in the patch calls.
diff -upr build-tree.orig/glibc-2.3.2/elf/do-lookup.h build-tree/glibc-2.3.2/elf/do-lookup.h
--- build-tree.orig/glibc-2.3.2/elf/do-lookup.h	2005-02-28 23:42:31.000000000 +0100
+++ build-tree/glibc-2.3.2/elf/do-lookup.h	2005-04-11 18:19:20.000000000 +0200
@@ -209,6 +209,11 @@ FCT (const char *undef_name, unsigned lo
 		}
 	      /* FALLTHROUGH */
 	    case STB_GLOBAL:
+	      /* HACK: MIPS marks its lazy evaluation stubs with SHN_UNDEF
+		 symbols, we skip them. */
+	      if (sym->st_shndx == SHN_UNDEF)
+		break;
+
 	      /* Global definition.  Just what we need.  */
 	      result->s = sym;
 	      result->m = map;
diff -upr build-tree.orig/glibc-2.3.2/sysdeps/mips/dl-machine.h build-tree/glibc-2.3.2/sysdeps/mips/dl-machine.h
--- build-tree.orig/glibc-2.3.2/sysdeps/mips/dl-machine.h	2005-02-28 23:42:36.000000000 +0100
+++ build-tree/glibc-2.3.2/sysdeps/mips/dl-machine.h	2005-04-10 22:39:15.000000000 +0200
@@ -347,5 +347,6 @@ __dl_runtime_resolve (ElfW(Word) sym_ind
   const ElfW(Word) gotsym						      \
     = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;	      \
   const ElfW(Sym) *sym = &symtab[sym_index];				      \
+  lookup_t result;							      \
   ElfW(Addr) value;							      \
 									      \
@@ -363,30 +364,37 @@ __dl_runtime_resolve (ElfW(Word) sym_ind
 									      \
 	    if (version->hash != 0)					      \
 	      {								      \
-		value = _dl_lookup_versioned_symbol(strtab + sym->st_name, l, \
-						    &sym, l->l_scope, version,\
-						    ELF_RTYPE_CLASS_PLT, 0);  \
+		result = INTUSE(_dl_lookup_versioned_symbol) (strtab	      \
+							      + sym->st_name, \
+							      l, &sym,	      \
+							      l->l_scope,     \
+							      version,	      \
+							      ELF_RTYPE_CLASS_PLT,\
+							      0);\
 		break;							      \
 	      }								      \
 	    /* Fall through.  */					      \
 	  }								      \
 	case 0:								      \
-	  value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym,	      \
-				     l->l_scope, ELF_RTYPE_CLASS_PLT,	      \
-				     DL_LOOKUP_ADD_DEPENDENCY);		      \
+	  result = INTUSE(_dl_lookup_symbol) (strtab + sym->st_name, l, &sym, \
+					      l->l_scope, ELF_RTYPE_CLASS_PLT,\
+					      DL_LOOKUP_ADD_DEPENDENCY);      \
 	}								      \
 									      \
-      /* Currently value contains the base load address of the object	      \
-	 that defines sym.  Now add in the symbol offset.  */		      \
-      value = (sym ? value + sym->st_value : 0);			      \
+      /* Currently result contains the base load address (or link map)	      \
+	 of the object that defines sym.  Now add in the symbol		      \
+	 offset.  */							      \
+      value = (sym ? result + sym->st_value : 0);			      \
     }									      \
   else									      \
-    /* We already found the symbol.  The module (and therefore its load	      \
-       address) is also known.  */					      \
-    value = l->l_addr + sym->st_value;					      \
+    {									      \
+      /* We already found the symbol.  The module (and therefore its load     \
+         address) is also known.  */					      \
+      value = l->l_addr + sym->st_value;				      \
+    }									      \
 									      \
   /* Apply the relocation with that value.  */				      \
-  *(got + local_gotno + sym_index - gotsym) = value;			      \
+  *(got + local_gotno + sym_index - gotsym) = value;	 		      \
 									      \
   return value;								      \
 }									      \



Reply to: