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