common-user: Implement read_self_maps for FreeBSD

Use sysctl to fetch the vm map of the current process.

Reviewed-by: Helge Deller <deller@gmx.de>
Reviewed-by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson
2026-05-30 00:00:19 -07:00
parent 544f4c5b68
commit c418250409

View File

@@ -9,6 +9,10 @@
#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "user/selfmap.h"
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#include <sys/user.h>
#endif
IntervalTreeRoot *read_self_maps(void)
{
@@ -80,9 +84,48 @@ IntervalTreeRoot *read_self_maps(void)
g_strfreev(lines);
g_free(maps);
return root;
#elif defined(__FreeBSD__)
int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid() };
size_t len = 0;
g_autofree void *buf = NULL;
IntervalTreeRoot *root;
/* Probe for buffer size. */
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0) {
return NULL;
}
buf = g_malloc(len);
if (sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) < 0) {
return NULL;
}
root = g_new0(IntervalTreeRoot, 1);
for (size_t i = 0; i < len; ) {
struct kinfo_vmentry *k = buf + i;
MapInfo *e = g_new0(MapInfo, 1);
e->itree.start = k->kve_start;
e->itree.last = k->kve_end - 1;
/*
* TODO: The rest of the fields in MapInfo are used by linux-user
* for the implementation of open_self_maps(). These fields are
* quite specific to the textual format of /proc/self/maps.
*
* We may need something different to emulate KERN_PROC_VMMAP
* in bsd-user, but so far they're unused -- leave them zeroed.
*/
interval_tree_insert(&e->itree, root);
i += k->kve_structsize;
}
return root;
#else
return NULL;
# error
#endif
}