librtld_db: Handle shlibs with discontiguous mappings.

Some shared libraries specify mappings that leave a gap (actually a
MAP_GUARD mapping) in between the file mappings (libcrypto.so was
the one I found), and this would cause rd_loadobj_iter() to report
the mapping info incorrectly, leaving out rdl_path and misreporting
rdl_offset for file mappings after the gap.  Fix rd_loadobj_iter()
to handle this situation.

Reviewed by:	markj
Sponsored by:	Netflix
Differential Revision:	https://reviews.freebsd.org/D32950
This commit is contained in:
Chuck Silvers 2021-12-03 11:03:32 -08:00
parent ae04d30451
commit dfd00261c9

View File

@ -165,6 +165,7 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data)
rd_loadobj_t rdl;
rd_err_e ret;
uintptr_t base;
uint32_t offset;
int cnt, i;
DPRINTF("%s\n", __func__);
@ -190,11 +191,12 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data)
if (kve->kve_vn_fileid != fileid) {
base = kve->kve_start;
fileid = kve->kve_vn_fileid;
path = kve->kve_path;
}
path = kve->kve_path;
offset = kve->kve_start - base;
} else {
base = 0;
path = NULL;
offset = 0;
}
memset(&rdl, 0, sizeof(rdl));
/*
@ -202,7 +204,7 @@ rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data)
*/
rdl.rdl_saddr = kve->kve_start;
rdl.rdl_eaddr = kve->kve_end;
rdl.rdl_offset = kve->kve_start - base;
rdl.rdl_offset = offset;
if (kve->kve_protection & KVME_PROT_READ)
rdl.rdl_prot |= RD_RDL_R;
if (kve->kve_protection & KVME_PROT_WRITE)