[PATCH]mips: ldso: dlopen with flag RTLD_NOW should look up the symbols
Jean Lee
xiaoyur347 at gmail.com
Mon Mar 16 05:28:36 UTC 2015
2015-03-15 20:16 GMT+08:00 Jean Lee <xiaoyur347 at gmail.com>:
> > (1)mipsel-linux-gnu 4.8.4(compiled by Broadcom)
> > mipsel-linux-gnu-gcc 4.8.4
> > binutils 2.24 (GNU ld (GNU Binutils) 2.24.0.20140801 Linaro 2014.08)
> > libc 2.18-2013.10
> > It's not uclibc.
>
> I do further test in this platform.
> (1) If dlopen with flag RTLD_NOW, the result is:
> open ./libtest_mips.so fail. ./libtest_mips.so: undefined symbol:
> not_exist_function
> And the program continues running.
> (2) If dlopen with flag RTLD_LAZY, the result is:
> ./mips_test: symbol lookup error: ./libtest_mips.so: undefined symbol:
> not_exist_function
> And the program exits.
>
> So I guess eglibc may do something more for mips dlopen.
> Does anyone know it?
>
I lookup the eglic source 2.18, and find these difference, maybe it is
useful for MIPS dlopen bug. See the biggest comment below.
diff -u http://www.eglibc.org/svn/branches/eglibc-2_18/libc/elf/dl-lookup.c
http://www.eglibc.org/svn/branches/eglibc-2_18/libc/ports/sysdeps/mips/dl-lookup.c
--- /opt/tool/eglibc/elf/dl-lookup.c 2015-03-15 20:32:46.862824714 +0800
+++ /opt/tool/eglibc/ports/sysdeps/mips/dl-lookup.c 2015-03-16
13:17:09.981423929 +0800
@@ -1,4 +1,5 @@
/* Look up a symbol in the loaded objects.
+ MIPS/Linux version - special handling of non-PIC undefined symbol rules.
Copyright (C) 1995-2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -110,9 +111,10 @@
continue;
/* Print some debugging info if wanted. */
- if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_SYMBOLS, 0))
+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0))
_dl_debug_printf ("symbol=%s; lookup in file=%s [%lu]\n",
- undef_name, DSO_FILENAME (map->l_name),
+ undef_name,
+ DSO_FILENAME (map->l_name),
map->l_ns);
/* If the hash table is empty there is nothing to do here. */
@@ -131,8 +133,24 @@
{
unsigned int stt = ELFW(ST_TYPE) (sym->st_info);
assert (ELF_RTYPE_CLASS_PLT == 1);
+ /* The semantics of zero/non-zero values of undefined symbols
+ differs depending on whether the non-PIC ABI is in use.
+ Under the non-PIC ABI, a non-zero value indicates that
+ there is an address reference to the symbol and thus it
+ must always be resolved (except when resolving a jump slot
+ relocation) to the PLT entry whose address is provided as
+ the symbol's value; a zero value indicates that this
+ canonical-address behaviour is not required. Yet under the
+ classic MIPS psABI, a zero value indicates that there is an
+ address reference to the function and the dynamic linker
+ must resolve the symbol immediately upon loading. To avoid
+ conflict, symbols for which the dynamic linker must assume
+ the non-PIC ABI semantics are marked with the STO_MIPS_PLT
+ flag. */
if (__builtin_expect ((sym->st_value == 0 /* No value. */
&& stt != STT_TLS)
+ || (sym->st_shndx == SHN_UNDEF
+ && !(sym->st_other & STO_MIPS_PLT))
|| (type_class & (sym->st_shndx ==
SHN_UNDEF)),
0))
return NULL;
@@ -414,7 +432,7 @@
hash table. */
if (__builtin_expect (tab->size, 0))
{
- assert (GLRO_dl_debug_mask & DL_DEBUG_PRELINK);
+ assert (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK);
__rtld_lock_unlock_recursive (tab->lock);
goto success;
}
@@ -663,7 +681,7 @@
}
/* Display information if we are debugging. */
- if (__builtin_expect (GLRO_dl_debug_mask & DL_DEBUG_FILES, 0))
+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
_dl_debug_printf ("\
\nfile=%s [%lu]; needed by %s [%lu] (relocation dependency)\n\n",
DSO_FILENAME (map->l_name),
@@ -838,7 +856,7 @@
if (__builtin_expect (current_value.m->l_used == 0, 0))
current_value.m->l_used = 1;
- if (__builtin_expect (GLRO_dl_debug_mask
+ if (__builtin_expect (GLRO(dl_debug_mask)
& (DL_DEBUG_BINDINGS|DL_DEBUG_PRELINK), 0))
_dl_debug_bindings (undef_name, undef_map, ref,
¤t_value, version, type_class, protected);
@@ -903,7 +921,7 @@
{
const char *reference_name = undef_map->l_name;
- if (GLRO_dl_debug_mask & DL_DEBUG_BINDINGS)
+ if (GLRO(dl_debug_mask) & DL_DEBUG_BINDINGS)
{
_dl_debug_printf ("binding file %s [%lu] to %s [%lu]: %s symbol
`%s'",
DSO_FILENAME (reference_name),
@@ -917,7 +935,7 @@
_dl_debug_printf_c ("\n");
}
#ifdef SHARED
- if (GLRO_dl_debug_mask & DL_DEBUG_PRELINK)
+ if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
{
int conflict = 0;
struct sym_val val = { NULL, NULL };
More information about the uClibc
mailing list