check_match() relies on checking for (sym->st_value == 0) to see if the
symbol is undefined. This works reasonably well on most architectures,
such as ARM or i386:
$ readelf -s /lib32/libcap.so.2 | grep -E "\<malloc\>"
17:
00000000 0 FUNC GLOBAL DEFAULT UND malloc@GLIBC_2.0 (2)
However, on MIPS, libbfd puts nonzero data in the st_value field to
facilitate resetting the symbol's GOT entry if the library that defines
the symbol gets unloaded:
$ mipsel-linux-readelf -s libfoo.so | grep -E "\<malloc\>"
74:
00003140 0 FUNC GLOBAL DEFAULT UND malloc
This can cause check_match to report a false positive when examining the
external symbol reference. Consequently dlsym() will return a bad pointer
to the caller.
Use the special MIPS logic from glibc-ports-2.13 to avoid this situation.
Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
+#ifdef ARCH_SKIP_RELOC
+ if (ARCH_SKIP_RELOC(type_class, sym))
+ return NULL;
+#endif
if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0)
return NULL;
if (_dl_strcmp(strtab + sym->st_name, undef_name) != 0)
return NULL;
*(ElfW(Addr) *)(dpnt->d_un.d_ptr) = (ElfW(Addr)) debug_addr; \
} while (0)
*(ElfW(Addr) *)(dpnt->d_un.d_ptr) = (ElfW(Addr)) debug_addr; \
} while (0)
+#define ARCH_SKIP_RELOC(type_class, sym) \
+ ((sym)->st_shndx == SHN_UNDEF && !((sym)->st_other & STO_MIPS_PLT))
+
/* Initialization sequence for the application/library GOT. */
#define INIT_GOT(GOT_BASE,MODULE) \
do { \
/* Initialization sequence for the application/library GOT. */
#define INIT_GOT(GOT_BASE,MODULE) \
do { \