diff options
| author | Mark Johnston <markj@FreeBSD.org> | 2020-05-12 17:00:47 +0000 |
|---|---|---|
| committer | Mark Johnston <markj@FreeBSD.org> | 2020-05-12 17:00:47 +0000 |
| commit | 13c2d789fb9a51414705158210983a4f3094d886 (patch) | |
| tree | 77edc0e222988e90075d644ec5ae44befbb9cb0c /lib | |
| parent | 46701f31bec2f1ccb8768d0cda91b36f9ec9c5d8 (diff) | |
Notes
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/librtld_db/rtld_db.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/lib/librtld_db/rtld_db.c b/lib/librtld_db/rtld_db.c index 6f13148967a0..fc4ad8f4834b 100644 --- a/lib/librtld_db/rtld_db.c +++ b/lib/librtld_db/rtld_db.c @@ -160,9 +160,12 @@ rd_err_e rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data) { struct kinfo_vmentry *kves, *kve; + const char *path; + uint64_t fileid; rd_loadobj_t rdl; rd_err_e ret; - int cnt, i, lastvn; + uintptr_t base; + int cnt, i; DPRINTF("%s\n", __func__); @@ -171,27 +174,38 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data) return (RD_ERR); } + base = 0; + fileid = 0; + path = NULL; ret = RD_OK; - lastvn = 0; for (i = 0; i < cnt; i++) { - kve = kves + i; - if (kve->kve_type == KVME_TYPE_VNODE) - lastvn = i; + kve = &kves[i]; + /* + * Cache the base offset of the file mapping. The kve_offset + * field gives the file offset of a particular mapping into the + * file, but we want the mapping offset relative to the base + * mapping. + */ + if (kve->kve_type == KVME_TYPE_VNODE && + kve->kve_vn_fileid != fileid) { + base = kve->kve_start; + fileid = kve->kve_vn_fileid; + path = kve->kve_path; + } memset(&rdl, 0, sizeof(rdl)); /* * Map the kinfo_vmentry struct to the rd_loadobj structure. */ rdl.rdl_saddr = kve->kve_start; rdl.rdl_eaddr = kve->kve_end; - rdl.rdl_offset = kve->kve_offset; + rdl.rdl_offset = kve->kve_start - base; if (kve->kve_protection & KVME_PROT_READ) rdl.rdl_prot |= RD_RDL_R; if (kve->kve_protection & KVME_PROT_WRITE) rdl.rdl_prot |= RD_RDL_W; if (kve->kve_protection & KVME_PROT_EXEC) rdl.rdl_prot |= RD_RDL_X; - strlcpy(rdl.rdl_path, kves[lastvn].kve_path, - sizeof(rdl.rdl_path)); + strlcpy(rdl.rdl_path, path, sizeof(rdl.rdl_path)); if ((*cb)(&rdl, clnt_data) != 0) { ret = RD_ERR; break; |
