Use kinfo_getvmmap from -luser.

Signed-off-by: Richard Henderson <[email protected]>
---
 common-user/selfmap.c   | 41 ++++++++++++++++++++++++++++++++++++++++-
 common-user/meson.build |  5 +++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/common-user/selfmap.c b/common-user/selfmap.c
index a1b88dee66..151d066801 100644
--- a/common-user/selfmap.c
+++ b/common-user/selfmap.c
@@ -9,6 +9,10 @@
 #include "qemu/osdep.h"
 #include "qemu/cutils.h"
 #include "user/selfmap.h"
+#ifdef __FreeBSD__
+#include <libutil.h>
+#include <sys/user.h>
+#endif
 
 IntervalTreeRoot *read_self_maps(void)
 {
@@ -80,9 +84,44 @@ IntervalTreeRoot *read_self_maps(void)
     g_strfreev(lines);
     g_free(maps);
 
+    return root;
+#elif defined(__FreeBSD__)
+    int n = 0;
+    struct kinfo_vmentry *entries = kinfo_getvmmap(getpid(), &n);
+    IntervalTreeRoot *root;
+
+    if (!entries) {
+        return NULL;
+    }
+    root = g_new0(IntervalTreeRoot, 1);
+
+    for (int i = 0; i < n; ++i) {
+        struct kinfo_vmentry *k = &entries[i];
+        size_t path_len = strnlen(k->kve_path, sizeof(k->kve_path)) + 1;
+        MapInfo *e = g_malloc0(sizeof(*e) + path_len);
+
+        e->itree.start = k->kve_start;
+        e->itree.last = k->kve_end - 1;
+
+        /* ??? The rest of these fields are only used in linux-user. */
+        e->dev = k->kve_vn_fsid_freebsd11;
+        e->inode = k->kve_vn_fileid;
+        e->offset = k->kve_offset;
+        e->is_read = k->kve_protection & KVME_PROT_READ;
+        e->is_write = k->kve_protection & KVME_PROT_WRITE;
+        e->is_exec = k->kve_protection & KVME_PROT_EXEC;
+        e->is_priv = k->kve_flags & KVME_FLAG_COW;
+        if (path_len) {
+            e->path = memcpy(e + 1, k->kve_path, path_len);
+        }
+
+        interval_tree_insert(&e->itree, root);
+    }
+
+    free(entries);
     return root;
 #else
-    return NULL;
+# error
 #endif
 }
 
diff --git a/common-user/meson.build b/common-user/meson.build
index 831a7273fb..5e041de55e 100644
--- a/common-user/meson.build
+++ b/common-user/meson.build
@@ -10,3 +10,8 @@ user_ss.add(files(
   'safe-syscall-error.c',
   'selfmap.c',
 ))
+
+if host_os == 'freebsd'
+  libutil = cc.find_library('util', required: true)
+  user_ss.add(libutil)
+endif
-- 
2.43.0


Reply via email to