Nickolai Zeldovich wrote:
The attached patch makes dladdr() return 0 when it cannot find a matching symbol. The current behavior of returning 1 makes it impossible for callers to know whether the supplied Dl_info buffer has been filled in with meaningful data.

Nickolai.



Hi Nickolai,
I had a look at your patch.
According to what man page says on dladdr (on my MacOSX, I'll check on Linux 
too)

ERRORS
     If an image containing addr cannot be found, dladdr() returns 0.  On suc-
     cess, a non-zero value is returned.

     If the image containing addr is found, but no nearest symbol was found,
     the dli_sname and dli_saddr fields are set to NULL.

your patch seems not be correct. Indeed dladdr should be fixed in a better
way by setting dli_sname and dli_saddr to NULL whn symbol hasn't been found,
and setting always dli_fname and dli_fbase (if there is an object in which
the addr lies in).
This behavior is the same as glibc.

Attached patch tries to fix it. The GNU_HASH part needs to be fixed accordingly.

Anyway, thanks for pointing it out

Any comments ?

Cheers,
Carmelo
Fix dladdr by filling with NULL dlinfo entries related to
symbol name and symbol address. If the object in which the address 
lies in has been found, then the dinfo fields dli_fname and dli_fbase
have to be filled indipendently of the symbol matching.

Signed-off-by: Carmelo Amoroso <[EMAIL PROTECTED]>

Index: ldso/libdl/libdl.c
===================================================================
--- ldso/libdl/libdl.c  (revision 20633)
+++ ldso/libdl/libdl.c  (working copy)
@@ -723,8 +723,11 @@
                _dl_if_debug_print("Module \"%s\" at %p\n",
                                   tpnt->libname, 
DL_LOADADDR_BASE(tpnt->loadaddr));
 
-               if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address, tpnt, pelf))
+               if (DL_ADDR_IN_LOADADDR((ElfW(Addr)) __address, tpnt, pelf)) {
                        pelf = tpnt;
+                       /* Found, stop looping */
+                       break;
+               }
        }
 
        if (!pelf) {
@@ -739,9 +742,12 @@
                char *strtab;
                ElfW(Sym) *symtab;
                unsigned int hn, si, sn, sf;
-               ElfW(Addr) sa;
+               ElfW(Addr) sa = 0;
 
-               sa = 0;
+               /* Set the info for the object the address lies in */
+               __info->dli_fname = pelf->libname;
+               __info->dli_fbase = (void *) DL_LOADADDR_BASE(pelf->loadaddr);
+
                symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
                strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
 
@@ -763,10 +769,14 @@
                }
 
                if (sf) {
-                       __info->dli_fname = pelf->libname;
-                       __info->dli_fbase = (void *) 
DL_LOADADDR_BASE(pelf->loadaddr);
+                       /* A nearest symbol has been found; fill the entries */
                        __info->dli_sname = strtab + symtab[sn].st_name;
                        __info->dli_saddr = (void *)sa;
+               } else {
+                       /* No symbol found, fill entries with NULL value,
+                       only the containing object will be returned. */
+                       __info->dli_sname = NULL;
+                       __info->dli_saddr = NULL;
                }
                return 1;
        }
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to