Author: markj
Date: Tue Dec  6 04:20:32 2016
New Revision: 309595
URL: https://svnweb.freebsd.org/changeset/base/309595

Log:
  libproc: Match prefixes when looking up mapped object by name.
  
  When looking up an object by name, allow prefix matches if no direct match
  is found. This allows one to, for example, match libc entry probes with:
  
   # dtrace -n 'pid$target:libc.so::entry' -c ./foo
  
  instead of requiring "libc.so.7" or a glob.
  
  Also remove proc_obj2map() as it currently just duplicates the
  functionality of proc_name2map(). It's supposed to take a Solaris
  link-map ID as a paramter, but support for this isn't implemented and
  isn't required to support DTrace's pid provider.

Modified:
  head/cddl/lib/libdtrace/libproc_compat.h
  head/lib/libproc/libproc.h
  head/lib/libproc/proc_sym.c
  head/lib/libproc/tests/proc_test.c

Modified: head/cddl/lib/libdtrace/libproc_compat.h
==============================================================================
--- head/cddl/lib/libdtrace/libproc_compat.h    Tue Dec  6 04:19:08 2016        
(r309594)
+++ head/cddl/lib/libdtrace/libproc_compat.h    Tue Dec  6 04:20:32 2016        
(r309595)
@@ -44,7 +44,7 @@
 #define        Pdelbkpt proc_bkptdel
 #define        Pgrab_error strerror
 #define        Plmid(p, a, l) (-1)
-#define        Plmid_to_map(p, l, o) proc_obj2map((p), (o))
+#define        Plmid_to_map(p, l, o) proc_name2map(p, o)
 #define        Plookup_by_addr proc_addr2sym
 #define        Pname_to_ctf(p, obj) (ctf_file_t *)proc_name2ctf(p, obj)
 #define        Pname_to_map proc_name2map

Modified: head/lib/libproc/libproc.h
==============================================================================
--- head/lib/libproc/libproc.h  Tue Dec  6 04:19:08 2016        (r309594)
+++ head/lib/libproc/libproc.h  Tue Dec  6 04:20:32 2016        (r309595)
@@ -128,7 +128,6 @@ __BEGIN_DECLS
 prmap_t *proc_addr2map(struct proc_handle *, uintptr_t);
 prmap_t *proc_name2map(struct proc_handle *, const char *);
 char   *proc_objname(struct proc_handle *, uintptr_t, char *, size_t);
-prmap_t *proc_obj2map(struct proc_handle *, const char *);
 int    proc_iter_objs(struct proc_handle *, proc_map_f *, void *);
 int    proc_iter_symbyaddr(struct proc_handle *, const char *, int,
            int, proc_sym_f *, void *);

Modified: head/lib/libproc/proc_sym.c
==============================================================================
--- head/lib/libproc/proc_sym.c Tue Dec  6 04:19:08 2016        (r309594)
+++ head/lib/libproc/proc_sym.c Tue Dec  6 04:20:32 2016        (r309595)
@@ -274,31 +274,6 @@ proc_objname(struct proc_handle *p, uint
        return (NULL);
 }
 
-/*
- * Currently just returns the first mapping of the named object, effectively
- * what Plmid_to_map(p, PR_LMID_EVERY, objname) does in illumos libproc.
- */
-prmap_t *
-proc_obj2map(struct proc_handle *p, const char *objname)
-{
-       char path[PATH_MAX], *base;
-       prmap_t *map;
-       size_t i;
-
-       map = NULL;
-       for (i = 0; i < p->nmappings; i++) {
-               strlcpy(path, p->mappings[i].map.pr_mapname, sizeof(path));
-               base = basename(path);
-               if (strcmp(base, objname) == 0) {
-                       map = &p->mappings[i].map;
-                       break;
-               }
-       }
-       if (map == NULL && strcmp(objname, "a.out") == 0 && p->exec_map != NULL)
-               map = p->exec_map;
-       return (map);
-}
-
 int
 proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd)
 {
@@ -468,9 +443,10 @@ _proc_name2map(struct proc_handle *p, co
 {
        char path[MAXPATHLEN], *base;
        struct map_info *mapping;
-       size_t i;
+       size_t i, len;
 
-       mapping = NULL;
+       if ((len = strlen(name)) == 0)
+               return (NULL);
        if (p->nmappings == 0)
                if (proc_rdagent(p) == NULL)
                        return (NULL);
@@ -479,13 +455,18 @@ _proc_name2map(struct proc_handle *p, co
                (void)strlcpy(path, mapping->map.pr_mapname, sizeof(path));
                base = basename(path);
                if (strcmp(base, name) == 0)
-                       break;
+                       return (mapping);
+       }
+       /* If we didn't find a match, try matching prefixes of the basename. */
+       for (i = 0; i < p->nmappings; i++) {
+               strlcpy(path, p->mappings[i].map.pr_mapname, sizeof(path));
+               base = basename(path);
+               if (strncmp(base, name, len) == 0)
+                       return (&p->mappings[i]);
        }
-       if (i == p->nmappings)
-               mapping = NULL;
-       if (mapping == NULL && strcmp(name, "a.out") == 0)
-               mapping = _proc_addr2map(p, p->exec_map->pr_vaddr);
-       return (mapping);
+       if (strcmp(name, "a.out") == 0)
+               return (_proc_addr2map(p, p->exec_map->pr_vaddr));
+       return (NULL);
 }
 
 prmap_t *

Modified: head/lib/libproc/tests/proc_test.c
==============================================================================
--- head/lib/libproc/tests/proc_test.c  Tue Dec  6 04:19:08 2016        
(r309594)
+++ head/lib/libproc/tests/proc_test.c  Tue Dec  6 04:20:32 2016        
(r309595)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2014, 2015 Mark Johnston <ma...@freebsd.org>
+ * Copyright (c) 2014-2016 Mark Johnston <ma...@freebsd.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -152,15 +152,15 @@ verify_bkpt(struct proc_handle *phdl, GE
            "expected map name '%s' doesn't match '%s'", mapname, mapbname);
 }
 
-ATF_TC(map_alias_obj2map);
-ATF_TC_HEAD(map_alias_obj2map, tc)
+ATF_TC(map_alias_name2map);
+ATF_TC_HEAD(map_alias_name2map, tc)
 {
        atf_tc_set_md_var(tc, "descr",
            "Callers are supposed to be able to use \"a.out\" as an alias for "
-           "the program executable. Make sure that proc_obj2map() handles "
+           "the program executable. Make sure that proc_name2map() handles "
            "this properly.");
 }
-ATF_TC_BODY(map_alias_obj2map, tc)
+ATF_TC_BODY(map_alias_name2map, tc)
 {
        struct proc_handle *phdl;
        prmap_t *map1, *map2;
@@ -171,10 +171,10 @@ ATF_TC_BODY(map_alias_obj2map, tc)
        (void)proc_rdagent(phdl);
 
        /* Ensure that "target_prog" and "a.out" return the same map. */
-       map1 = proc_obj2map(phdl, target_prog_file);
+       map1 = proc_name2map(phdl, target_prog_file);
        ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'",
            target_prog_file);
-       map2 = proc_obj2map(phdl, aout_object);
+       map2 = proc_name2map(phdl, aout_object);
        ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'",
            aout_object);
        ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);
@@ -184,15 +184,14 @@ ATF_TC_BODY(map_alias_obj2map, tc)
        proc_free(phdl);
 }
 
-ATF_TC(map_alias_name2map);
-ATF_TC_HEAD(map_alias_name2map, tc)
+ATF_TC(map_prefix_name2map);
+ATF_TC_HEAD(map_prefix_name2map, tc)
 {
        atf_tc_set_md_var(tc, "descr",
-           "Callers are supposed to be able to use \"a.out\" as an alias for "
-           "the program executable. Make sure that proc_name2map() handles "
-           "this properly.");
+           "Verify that proc_name2map() returns prefix matches of the "
+           "basename of loaded objects if no full matches are found.");
 }
-ATF_TC_BODY(map_alias_name2map, tc)
+ATF_TC_BODY(map_prefix_name2map, tc)
 {
        struct proc_handle *phdl;
        prmap_t *map1, *map2;
@@ -202,13 +201,11 @@ ATF_TC_BODY(map_alias_name2map, tc)
        /* Initialize the rtld_db handle. */
        (void)proc_rdagent(phdl);
 
-       /* Ensure that "target_prog" and "a.out" return the same map. */
-       map1 = proc_name2map(phdl, target_prog_file);
-       ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for '%s'",
-           target_prog_file);
-       map2 = proc_name2map(phdl, aout_object);
-       ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for '%s'",
-           aout_object);
+       /* Make sure that "ld-elf" and "ld-elf.so" return the same map. */
+       map1 = proc_name2map(phdl, "ld-elf");
+       ATF_REQUIRE_MSG(map1 != NULL, "failed to look up map for 'ld-elf'");
+       map2 = proc_name2map(phdl, "ld-elf.so");
+       ATF_REQUIRE_MSG(map2 != NULL, "failed to look up map for 'ld-elf.so'");
        ATF_CHECK_EQ(strcmp(map1->pr_mapname, map2->pr_mapname), 0);
 
        ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
@@ -315,7 +312,7 @@ ATF_TC_BODY(symbol_lookup_fail, tc)
        /* Initialize the rtld_db handle. */
        (void)proc_rdagent(phdl);
 
-       map = proc_obj2map(phdl, target_prog_file);
+       map = proc_name2map(phdl, target_prog_file);
        ATF_REQUIRE_MSG(map != NULL, "failed to look up map for '%s'",
            target_prog_file);
 
@@ -376,8 +373,8 @@ ATF_TC_BODY(signal_forward, tc)
 ATF_TP_ADD_TCS(tp)
 {
 
-       ATF_TP_ADD_TC(tp, map_alias_obj2map);
        ATF_TP_ADD_TC(tp, map_alias_name2map);
+       ATF_TP_ADD_TC(tp, map_prefix_name2map);
        ATF_TP_ADD_TC(tp, map_alias_name2sym);
        ATF_TP_ADD_TC(tp, symbol_lookup);
        ATF_TP_ADD_TC(tp, symbol_lookup_fail);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to