Author: markj
Date: Fri Dec 27 23:00:56 2013
New Revision: 259972
URL: http://svnweb.freebsd.org/changeset/base/259972

Log:
  MFC r258000:
  Consistently add the relocation offset only when the ELF type is not
  ET_EXEC. This fixes several problems with the DTrace pid provider not
  being able to match probes.

Modified:
  stable/10/lib/libproc/proc_sym.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libproc/proc_sym.c
==============================================================================
--- stable/10/lib/libproc/proc_sym.c    Fri Dec 27 22:59:16 2013        
(r259971)
+++ stable/10/lib/libproc/proc_sym.c    Fri Dec 27 23:00:56 2013        
(r259972)
@@ -284,7 +284,10 @@ proc_addr2sym(struct proc_handle *p, uin
                 * Calculate the address mapped to the virtual memory
                 * by rtld.
                 */
-               rsym = map->pr_vaddr + sym.st_value;
+               if (ehdr.e_type != ET_EXEC)
+                       rsym = map->pr_vaddr + sym.st_value;
+               else
+                       rsym = sym.st_value;
                if (addr >= rsym && addr < rsym + sym.st_size) {
                        s = elf_strptr(e, dynsymstridx, sym.st_name);
                        if (s) {
@@ -309,8 +312,6 @@ symtab:
         * Iterate over the Symbols Table to find the symbol.
         * Then look up the string name in STRTAB (.dynstr)
         */
-       if (symtabscn == NULL)
-               goto err2;
        if ((data = elf_getdata(symtabscn, NULL)) == NULL) {
                DPRINTFX("ERROR: elf_getdata() failed: %s", elf_errmsg(-1));
                goto err2;
@@ -465,7 +466,8 @@ proc_name2sym(struct proc_handle *p, con
                        s = elf_strptr(e, dynsymstridx, sym.st_name);
                        if (s && strcmp(s, symbol) == 0) {
                                memcpy(symcopy, &sym, sizeof(sym));
-                               symcopy->st_value = map->pr_vaddr + 
sym.st_value;
+                               if (ehdr.e_type != ET_EXEC)
+                                       symcopy->st_value += map->pr_vaddr;
                                error = 0;
                                goto out;
                        }
@@ -475,20 +477,21 @@ proc_name2sym(struct proc_handle *p, con
         * Iterate over the Symbols Table to find the symbol.
         * Then look up the string name in STRTAB (.dynstr)
         */
-       if (symtabscn == NULL)
-               goto err2;
        if ((data = elf_getdata(symtabscn, NULL))) {
                i = 0;
                while (gelf_getsym(data, i++, &sym) != NULL) {
                        s = elf_strptr(e, symtabstridx, sym.st_name);
                        if (s && strcmp(s, symbol) == 0) {
                                memcpy(symcopy, &sym, sizeof(sym));
+                               if (ehdr.e_type != ET_EXEC)
+                                       symcopy->st_value += map->pr_vaddr;
                                error = 0;
                                goto out;
                        }
                }
        }
 out:
+       DPRINTFX("found addr 0x%lx for %s", symcopy->st_value, symbol);
 err2:
        elf_end(e);
 err1:
@@ -509,6 +512,7 @@ proc_iter_symbyaddr(struct proc_handle *
        prmap_t *map;
        Elf_Scn *scn, *foundscn = NULL;
        Elf_Data *data;
+       GElf_Ehdr ehdr;
        GElf_Shdr shdr;
        GElf_Sym sym;
        unsigned long stridx = -1;
@@ -525,6 +529,10 @@ proc_iter_symbyaddr(struct proc_handle *
                DPRINTFX("ERROR: elf_begin() failed: %s", elf_errmsg(-1));
                goto err1;
        }
+       if (gelf_getehdr(e, &ehdr) == NULL) {
+               DPRINTFX("ERROR: gelf_getehdr() failed: %s", elf_errmsg(-1));
+               goto err2;
+       }
        /*
         * Find the section we are looking for.
         */
@@ -575,7 +583,8 @@ proc_iter_symbyaddr(struct proc_handle *
                    (mask & TYPE_FILE) == 0)
                        continue;
                s = elf_strptr(e, stridx, sym.st_name);
-               sym.st_value += map->pr_vaddr;
+               if (ehdr.e_type != ET_EXEC)
+                       sym.st_value += map->pr_vaddr;
                (*func)(cd, &sym, s);
        }
        error = 0;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to