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 <email address hidden>
# 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; \
} \
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 <email address hidden>
# DP: Date: 2005-04-11
if [ $# -ne 2 ]; then if-mismatch -p2 < $0;; if-mismatch -R -p2 < $0;;
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch) patch -d "$2" -f --no-backup-
-unpatch) patch -d "$2" -f --no-backup-
*)
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. orig/glibc- 2.3.2/elf/ do-lookup. h build-tree/ glibc-2. 3.2/elf/ do-lookup. h orig/glibc- 2.3.2/elf/ do-lookup. h 2005-02-28 23:42:31.000000000 +0100 glibc-2. 3.2/elf/ do-lookup. h 2005-04-11 18:19:20.000000000 +0200 orig/glibc- 2.3.2/sysdeps/ mips/dl- machine. h build-tree/ glibc-2. 3.2/sysdeps/ mips/dl- machine. h orig/glibc- 2.3.2/sysdeps/ mips/dl- machine. h 2005-02-28 23:42:36.000000000 +0100 glibc-2. 3.2/sysdeps/ mips/dl- machine. h 2005-04-10 22:39:15.000000000 +0200 resolve (ElfW(Word) sym_ind ]->d_un. d_val; \ resolve (ElfW(Word) sym_ind versioned_ symbol( strtab + sym->st_name, l, \ CLASS_PLT, 0); \ _dl_lookup_ versioned_ symbol) (strtab \ CLASS_PLT, \ CLASS_PLT, \ ADD_DEPENDENCY) ; \ _dl_lookup_ symbol) (strtab + sym->st_name, l, &sym, \ CLASS_PLT, \ ADD_DEPENDENCY) ; \
diff -upr build-tree.
--- build-tree.
+++ build-tree/
@@ -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.
--- build-tree.
+++ build-tree/
@@ -347,5 +347,6 @@ __dl_runtime_
const ElfW(Word) gotsym \
= (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)
const ElfW(Sym) *sym = &symtab[sym_index]; \
+ lookup_t result; \
ElfW(Addr) value; \
\
@@ -363,30 +364,37 @@ __dl_runtime_
\
if (version->hash != 0) \
{ \
- value = _dl_lookup_
- &sym, l->l_scope, version,\
- ELF_RTYPE_
+ result = INTUSE(
+ + sym->st_name, \
+ l, &sym, \
+ l->l_scope, \
+ version, \
+ ELF_RTYPE_
+ 0);\
break; \
} \
/* Fall through. */ \
} \
case 0: \
- value = _dl_lookup_symbol (strtab + sym->st_name, l, &sym, \
- l->l_scope, ELF_RTYPE_
- DL_LOOKUP_
+ result = INTUSE(
+ l->l_scope, ELF_RTYPE_
+ DL_LOOKUP_
} \
\
- /* 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; \
} \