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.
This commit is contained in:
parent
07a9c2e65d
commit
d42df2a447
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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 (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 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 (strcmp(name, "a.out") == 0)
|
||||
return (_proc_addr2map(p, p->exec_map->pr_vaddr));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
prmap_t *
|
||||
|
@ -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,38 +152,6 @@ 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_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 "
|
||||
"this properly.");
|
||||
}
|
||||
ATF_TC_BODY(map_alias_obj2map, tc)
|
||||
{
|
||||
struct proc_handle *phdl;
|
||||
prmap_t *map1, *map2;
|
||||
|
||||
phdl = start_prog(tc, false);
|
||||
|
||||
/* Initialize the rtld_db handle. */
|
||||
(void)proc_rdagent(phdl);
|
||||
|
||||
/* Ensure that "target_prog" and "a.out" return the same map. */
|
||||
map1 = proc_obj2map(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);
|
||||
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);
|
||||
|
||||
ATF_CHECK_EQ_MSG(proc_continue(phdl), 0, "failed to resume execution");
|
||||
|
||||
proc_free(phdl);
|
||||
}
|
||||
|
||||
ATF_TC(map_alias_name2map);
|
||||
ATF_TC_HEAD(map_alias_name2map, tc)
|
||||
{
|
||||
@ -216,6 +184,35 @@ ATF_TC_BODY(map_alias_name2map, tc)
|
||||
proc_free(phdl);
|
||||
}
|
||||
|
||||
ATF_TC(map_prefix_name2map);
|
||||
ATF_TC_HEAD(map_prefix_name2map, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr",
|
||||
"Verify that proc_name2map() returns prefix matches of the "
|
||||
"basename of loaded objects if no full matches are found.");
|
||||
}
|
||||
ATF_TC_BODY(map_prefix_name2map, tc)
|
||||
{
|
||||
struct proc_handle *phdl;
|
||||
prmap_t *map1, *map2;
|
||||
|
||||
phdl = start_prog(tc, false);
|
||||
|
||||
/* Initialize the rtld_db handle. */
|
||||
(void)proc_rdagent(phdl);
|
||||
|
||||
/* 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");
|
||||
|
||||
proc_free(phdl);
|
||||
}
|
||||
|
||||
ATF_TC(map_alias_name2sym);
|
||||
ATF_TC_HEAD(map_alias_name2sym, tc)
|
||||
{
|
||||
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user