Re: [PATCH]mips: ldso: dlopen with flag RTLD_NOW should look up the symbols

Jean Lee <[email protected]>
Newsgroups gmane.comp.lib.uclibc.general
Message-ID <CALuKrvD_FS5MP2ux2TGXCmTh-e+zrSckhCQjR2WzRRC6EsbtNA@mail.gmail.com>
2015-03-15 20:16 GMT+08:00 Jean Lee <[email protected]>:

> > (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,
                        &current_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 };
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.