Esempio n. 1
0
int
proc_iter_objs(struct proc_handle *p, proc_map_f *func, void *cd)
{
	size_t i;
	rd_loadobj_t *rdl;
	prmap_t map;
	char path[MAXPATHLEN];
	char last[MAXPATHLEN];

	if (p->nobjs == 0)
		return (-1);
	memset(last, 0, sizeof(last));
	for (i = 0; i < p->nobjs; i++) {
		rdl = &p->rdobjs[i];
		proc_rdl2prmap(rdl, &map);
		basename_r(rdl->rdl_path, path);
		/*
		 * We shouldn't call the callback twice with the same object.
		 * To do that we are assuming the fact that if there are
		 * repeated object names (i.e. different mappings for the
		 * same object) they occur next to each other.
		 */
		if (strcmp(path, last) == 0)
			continue;
		(*func)(cd, &map, path);
		strlcpy(last, path, sizeof(last));
	}

	return (0);
}
Esempio n. 2
0
prmap_t *
proc_obj2map(struct proc_handle *p, const char *objname)
{
	size_t i;
	prmap_t *map;
	rd_loadobj_t *rdl;
	char path[MAXPATHLEN];

	rdl = NULL;
	for (i = 0; i < p->nobjs; i++) {
		basename_r(p->rdobjs[i].rdl_path, path);
		if (strcmp(path, objname) == 0) {
			rdl = &p->rdobjs[i];
			break;
		}
	}
	if (rdl == NULL) {
		if (strcmp(objname, "a.out") == 0 && p->rdexec != NULL)
			rdl = p->rdexec;
		else
			return (NULL);
	}

	if ((map = malloc(sizeof(*map))) == NULL)
		return (NULL);
	proc_rdl2prmap(rdl, map);
	return (map);
}
Esempio n. 3
0
prmap_t *
proc_name2map(struct proc_handle *p, const char *name)
{
	size_t i;
	int cnt;
	prmap_t *map;
	char tmppath[MAXPATHLEN];
	struct kinfo_vmentry *kves, *kve;
	rd_loadobj_t *rdl;

	/*
	 * If we haven't iterated over the list of loaded objects,
	 * librtld_db isn't yet initialized and it's very likely
	 * that librtld_db called us. We need to do the heavy
	 * lifting here to find the symbol librtld_db is looking for.
	 */
	if (p->nobjs == 0) {
		if ((kves = kinfo_getvmmap(proc_getpid(p), &cnt)) == NULL)
			return (NULL);
		for (i = 0; i < (size_t)cnt; i++) {
			kve = kves + i;
			basename_r(kve->kve_path, tmppath);
			if (strcmp(tmppath, name) == 0) {
				map = proc_addr2map(p, kve->kve_start);
				free(kves);
				return (map);
			}
		}
		free(kves);
		return (NULL);
	}
	if (name == NULL || strcmp(name, "a.out") == 0) {
		map = proc_addr2map(p, p->rdobjs[0].rdl_saddr);
		return (map);
	}
	for (i = 0; i < p->nobjs; i++) {
		rdl = &p->rdobjs[i];
		basename_r(rdl->rdl_path, tmppath);
		if (strcmp(tmppath, name) == 0) {
			if ((map = malloc(sizeof(*map))) == NULL)
				return (NULL);
			proc_rdl2prmap(rdl, map);
			return (map);
		}
	}

	return (NULL);
}
Esempio n. 4
0
prmap_t *
proc_obj2map(struct proc_handle *p, const char *objname)
{
	size_t i;
	prmap_t *map;
	rd_loadobj_t *rdl;
	char path[MAXPATHLEN];

	for (i = 0; i < p->nobjs; i++) {
		rdl = &p->rdobjs[i];
		basename_r(rdl->rdl_path, path);
		if (strcmp(path, objname) == 0) {
			if ((map = malloc(sizeof(*map))) == NULL)
				return (NULL);
			proc_rdl2prmap(rdl, map);
			return (map);
		}
	}
	return (NULL);
}
Esempio n. 5
0
prmap_t *
proc_addr2map(struct proc_handle *p, uintptr_t addr)
{
	size_t i;
	int cnt, lastvn = 0;
	prmap_t *map;
	rd_loadobj_t *rdl;
	struct kinfo_vmentry *kves, *kve;

	/*
	 * If we don't have a cache of listed objects, we need to query
	 * it ourselves.
	 */
	if (p->nobjs == 0) {
		if ((kves = kinfo_getvmmap(p->pid, &cnt)) == NULL)
			return (NULL);
		for (i = 0; i < (size_t)cnt; i++) {
			kve = kves + i;
			if (kve->kve_type == KVME_TYPE_VNODE)
				lastvn = i;
			if (addr >= kve->kve_start && addr <= kve->kve_end) {
				if ((map = malloc(sizeof(*map))) == NULL) {
					free(kves);
					return (NULL);
				}
				map->pr_vaddr = kve->kve_start;
				map->pr_size = kve->kve_end - kve->kve_start;
				map->pr_offset = kve->kve_offset;
				map->pr_mflags = 0;
				if (kve->kve_protection & KVME_PROT_READ)
					map->pr_mflags |= MA_READ;
				if (kve->kve_protection & KVME_PROT_WRITE)
					map->pr_mflags |= MA_WRITE;
				if (kve->kve_protection & KVME_PROT_EXEC)
					map->pr_mflags |= MA_EXEC;
				if (kve->kve_flags & KVME_FLAG_COW)
					map->pr_mflags |= MA_COW;
				if (kve->kve_flags & KVME_FLAG_NEEDS_COPY)
					map->pr_mflags |= MA_NEEDS_COPY;
				if (kve->kve_flags & KVME_FLAG_NOCOREDUMP)
					map->pr_mflags |= MA_NOCOREDUMP;
				strlcpy(map->pr_mapname, kves[lastvn].kve_path,
				    sizeof(map->pr_mapname));
				free(kves);
				return (map);
			}
		}
		free(kves);
		return (NULL);
	}

	for (i = 0; i < p->nobjs; i++) {
		rdl = &p->rdobjs[i];
		if (addr >= rdl->rdl_saddr && addr <= rdl->rdl_eaddr) {
			if ((map = malloc(sizeof(*map))) == NULL)
				return (NULL);
			proc_rdl2prmap(rdl, map);
			return (map);
		}
	}
	return (NULL);
}