@samitouri / QOSamiQemu / commits / c418250409

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>

Richard Henderson committed May 30, 2026 at 00:00 UTC c418250409e7357f8d59742dbe28ef9823585989
1 file changed +44 -1
common-user/selfmap.c
+44 -1
@@ -9,6 +9,10 @@
9 #include "qemu/osdep.h"
10 #include "qemu/cutils.h"
11 #include "user/selfmap.h"
12 +#ifdef __FreeBSD__
13 +#include <sys/sysctl.h>
14 +#include <sys/user.h>
15 +#endif
16
17 IntervalTreeRoot *read_self_maps(void)
18 {
@@ -80,9 +84,48 @@ IntervalTreeRoot *read_self_maps(void)
84 g_strfreev(lines);
85 g_free(maps);
86
87 + return root;
88 +#elif defined(__FreeBSD__)
89 + int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid() };
90 + size_t len = 0;
91 + g_autofree void *buf = NULL;
92 + IntervalTreeRoot *root;
93 +
94 + /* Probe for buffer size. */
95 + if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0) {
96 + return NULL;
97 + }
98 +
99 + buf = g_malloc(len);
100 + if (sysctl(mib, ARRAY_SIZE(mib), buf, &len, NULL, 0) < 0) {
101 + return NULL;
102 + }
103 +
104 + root = g_new0(IntervalTreeRoot, 1);
105 +
106 + for (size_t i = 0; i < len; ) {
107 + struct kinfo_vmentry *k = buf + i;
108 + MapInfo *e = g_new0(MapInfo, 1);
109 +
110 + e->itree.start = k->kve_start;
111 + e->itree.last = k->kve_end - 1;
112 +
113 + /*
114 + * TODO: The rest of the fields in MapInfo are used by linux-user
115 + * for the implementation of open_self_maps(). These fields are
116 + * quite specific to the textual format of /proc/self/maps.
117 + *
118 + * We may need something different to emulate KERN_PROC_VMMAP
119 + * in bsd-user, but so far they're unused -- leave them zeroed.
120 + */
121 +
122 + interval_tree_insert(&e->itree, root);
123 + i += k->kve_structsize;
124 + }
125 +
126 return root;
127 #else
85 - return NULL;
128 +# error
129 #endif
130 }
131