aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2016-12-06 04:20:32 +0000
committerMark Johnston <markj@FreeBSD.org>2016-12-06 04:20:32 +0000
commitd42df2a44793413692a006e46faad87ec7b9e34f (patch)
treebdea9504a1c76f02abf7bfe4afa19d8c47dddf8a
parent07a9c2e65d5f2f21cc9783e33dd94a5ce8cc592d (diff)
downloadsrc-d42df2a44793413692a006e46faad87ec7b9e34f.tar.gz
src-d42df2a44793413692a006e46faad87ec7b9e34f.zip
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.
Notes
Notes: svn path=/head/; revision=309595
-rw-r--r--cddl/lib/libdtrace/libproc_compat.h2
-rw-r--r--lib/libproc/libproc.h1
-rw-r--r--lib/libproc/proc_sym.c47
-rw-r--r--lib/libproc/tests/proc_test.c41
4 files changed, 34 insertions, 57 deletions
diff --git a/cddl/lib/libdtrace/libproc_compat.h b/cddl/lib/libdtrace/libproc_compat.h
index 8704b820df58..0bb9e05424b7 100644
--- a/cddl/lib/libdtrace/libproc_compat.h
+++ b/cddl/lib/libdtrace/libproc_compat.h
@@ -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
diff --git a/lib/libproc/libproc.h b/lib/libproc/libproc.h
index 5798a3b4b58d..25f8aa62f12b 100644
--- a/lib/libproc/libproc.h
+++ b/lib/libproc/libproc.h
@@ -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 *);
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c
index cb950f2cb3dc..0f42111f6c16 100644
--- a/lib/libproc/proc_sym.c
+++ b/lib/libproc/proc_sym.c
@@ -274,31 +274,6 @@ proc_objname(struct proc_handle *p, uintptr_t addr, char *objname,
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, const char *name)
{
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, const char *name)
(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 *
diff --git a/lib/libproc/tests/proc_test.c b/lib/libproc/tests/proc_test.c
index dbaace84f5a8..4143bdcbffce 100644
--- a/lib/libproc/tests/proc_test.c
+++ b/lib/libproc/tests/proc_test.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014, 2015 Mark Johnston <markj@FreeBSD.org>
+ * Copyright (c) 2014-2016 Mark Johnston <markj@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, GElf_Sym *sym, const char *symname,
"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);