fstat(1): Move out vm_map traversal functions to libkvm.
authorzrj <rimvydas.jasinskas@gmail.com>
Sat, 6 Apr 2019 20:00:10 +0000 (23:00 +0300)
committerzrj <zrj@dragonflybsd.org>
Sun, 7 Apr 2019 19:19:46 +0000 (22:19 +0300)
For ports benefit.

Suggested-by: dillon
lib/libkvm/Makefile
lib/libkvm/kvm.h
lib/libkvm/kvm_vm_map.c [new file with mode: 0644]
usr.bin/fstat/fstat.c

index 153d111..4faf5a8 100644 (file)
@@ -8,7 +8,7 @@ LIB=    kvm
 SHLIBDIR?= /lib
 CFLAGS+=-I${SYSDIR}
 SRCS=  kvm.c kvm_${MACHINE_ARCH}.c kvm_file.c kvm_getloadavg.c \
-       kvm_getswapinfo.c kvm_proc.c kvm_util.c \
+       kvm_getswapinfo.c kvm_proc.c kvm_util.c kvm_vm_map.c \
        kern_kinfo.c kvm_minidump_${MACHINE_ARCH}.c
 INCS=  kvm.h
 
index ccd5d80..2a97d79 100644 (file)
@@ -47,6 +47,8 @@ struct kinfo_file;
 struct kinfo_proc;
 struct nchstats;
 struct proc;
+struct vm_map;
+struct vm_map_entry;
 
 struct kvm_swap {
        char    ksw_devname[32];
@@ -80,6 +82,12 @@ __ssize_t kvm_read (kvm_t *, unsigned long, void *, __size_t);
 char    *kvm_readstr (kvm_t *, u_long, char *, size_t *);
 __ssize_t kvm_uread (kvm_t *, pid_t, unsigned long, char *, __size_t);
 __ssize_t kvm_write (kvm_t *, unsigned long, const void *, __size_t);
+struct vm_map_entry *
+         kvm_vm_map_entry_first (kvm_t *, struct vm_map *,
+                                 struct vm_map_entry *);
+struct vm_map_entry *
+         kvm_vm_map_entry_next (kvm_t *, struct vm_map_entry *,
+                                struct vm_map_entry *);
 __END_DECLS
 
 #endif /* !_KVM_H_ */
diff --git a/lib/libkvm/kvm_vm_map.c b/lib/libkvm/kvm_vm_map.c
new file mode 100644 (file)
index 0000000..a83642c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019 The DragonFly Project.  All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@dragonflybsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Useful helper functions for vm_map_t parsing.
+ */
+
+#include <sys/user.h>
+#include <sys/param.h>
+#include <vm/vm.h>
+#include <vm/vm_map.h>
+
+#include "kvm.h"
+
+static int
+kreadent(kvm_t *kd, const void *kaddr, vm_map_entry_t copy)
+{
+       size_t nb;
+
+       nb = sizeof(*copy);
+
+       if (kvm_read(kd, (u_long)kaddr, (char *)copy, nb) == (ssize_t)nb)
+               return 1;
+
+       return 0;
+}
+
+/*
+ * Find and read first vm_map entry.
+ */
+vm_map_entry_t
+kvm_vm_map_entry_first(kvm_t *kd, vm_map_t map, vm_map_entry_t copy)
+{
+       vm_map_entry_t ken;
+
+       ken = map->rb_root.rbh_root;
+       if (ken == NULL)
+               return NULL;
+       if (!kreadent(kd, ken, copy))
+               return NULL;
+       while (copy->rb_entry.rbe_left) {
+               ken = copy->rb_entry.rbe_left;
+               if (!kreadent(kd, ken, copy))
+                       return NULL;
+       }
+       return ken;
+}
+
+/*
+ * Find and read next vm_map entry.
+ */
+vm_map_entry_t
+kvm_vm_map_entry_next(kvm_t *kd, vm_map_entry_t ken, vm_map_entry_t copy)
+{
+       vm_map_entry_t ken2;
+
+       if (copy->rb_entry.rbe_right) {
+               ken = copy->rb_entry.rbe_right;
+               if (!kreadent(kd, ken, copy))
+                       return NULL;
+               while (copy->rb_entry.rbe_left) {
+                       ken = copy->rb_entry.rbe_left;
+                       if (!kreadent(kd, ken, copy))
+                               return NULL;
+               }
+       } else {
+               if ((ken2 = copy->rb_entry.rbe_parent) == NULL)
+                       return NULL;
+               if (!kreadent(kd, ken2, copy))
+                       return NULL;
+               if (ken == copy->rb_entry.rbe_left) {
+                       ken = ken2;
+               } else {
+                       while (ken == copy->rb_entry.rbe_right) {
+                               ken = ken2;
+                               ken2 = copy->rb_entry.rbe_parent;
+                               if (!kreadent(kd, ken2, copy))
+                                       return NULL;
+                       }
+                       ken = ken2;
+               }
+       }
+       return ken;
+}
index 46f0164..7b84386 100644 (file)
@@ -94,7 +94,6 @@
 DEVS *devs;
 
 static void make_printable(char *buf, int len);
-static int kreadent(const void *kaddr, vm_map_entry_t copy);
 
 #ifdef notdef
 struct nlist nl[] = {
@@ -118,7 +117,6 @@ const char *Uname;
 char   *Comm;
 int    Pid;
 
-
 struct fdnode *ofiles;         /* buffer of pointers to file structures */
 int maxfiles;
 
@@ -389,60 +387,6 @@ dofiles(struct kinfo_proc *kp, struct proc *p)
        }
 }
 
-static
-vm_map_entry_t
-kinfo_vm_map_entry_first(vm_map_t map, vm_map_entry_t copy)
-{
-       vm_map_entry_t ken;
-
-       ken = map->rb_root.rbh_root;
-       if (ken == NULL)
-               return NULL;
-       if (!kreadent(ken, copy))
-               return NULL;
-       while (copy->rb_entry.rbe_left) {
-               ken = copy->rb_entry.rbe_left;
-               if (!kreadent(ken, copy))
-                       return NULL;
-       }
-       return ken;
-}
-
-static
-vm_map_entry_t
-kinfo_vm_map_entry_next(vm_map_entry_t ken, vm_map_entry_t copy)
-{
-       vm_map_entry_t ken2;
-
-       if (copy->rb_entry.rbe_right) {
-               ken = copy->rb_entry.rbe_right;
-               if (!kreadent(ken, copy))
-                       return NULL;
-               while (copy->rb_entry.rbe_left) {
-                       ken = copy->rb_entry.rbe_left;
-                       if (!kreadent(ken, copy))
-                               return NULL;
-               }
-       } else {
-               if ((ken2 = copy->rb_entry.rbe_parent) == NULL)
-                       return NULL;
-               if (!kreadent(ken2, copy))
-                       return NULL;
-               if (ken == copy->rb_entry.rbe_left) {
-                       ken = ken2;
-               } else {
-                       while (ken == copy->rb_entry.rbe_right) {
-                               ken = ken2;
-                               ken2 = copy->rb_entry.rbe_parent;
-                               if (!kreadent(ken2, copy))
-                                       return NULL;
-                       }
-                       ken = ken2;
-               }
-       }
-       return ken;
-}
-
 static void
 dommap(struct proc *p)
 {
@@ -461,9 +405,8 @@ dommap(struct proc *p)
        }
 
        map = &vmspace.vm_map;
-       for (ken = kinfo_vm_map_entry_first(map, &entry);
-            ken;
-            ken = kinfo_vm_map_entry_next(ken, &entry)) {
+       for (ken = kvm_vm_map_entry_first(kd, map, &entry);
+            ken; ken = kvm_vm_map_entry_next(kd, ken, &entry)) {
                if (entry.maptype == VM_MAPTYPE_SUBMAP)
                        continue;
 
@@ -1064,14 +1007,3 @@ kread(const void *kaddr, void *uaddr, size_t nbytes)
     else
        return(0);
 }
-
-static
-int
-kreadent(const void *kaddr, vm_map_entry_t copy)
-{
-       if (kread(kaddr, copy, sizeof(*copy)))
-               return 1;
-       dprintf(stderr, "can't read vm_map_entry at %p for pid %d\n",
-               kaddr, Pid);
-       return 0;
-}