From f12d4f4455912d028aab1941add6ded3c8f07572 Mon Sep 17 00:00:00 2001 From: zrj Date: Sat, 6 Apr 2019 23:00:10 +0300 Subject: [PATCH] fstat(1): Move out vm_map traversal functions to libkvm. For ports benefit. Suggested-by: dillon --- lib/libkvm/Makefile | 2 +- lib/libkvm/kvm.h | 8 +++ lib/libkvm/kvm_vm_map.c | 115 ++++++++++++++++++++++++++++++++++++++++ usr.bin/fstat/fstat.c | 72 +------------------------ 4 files changed, 126 insertions(+), 71 deletions(-) create mode 100644 lib/libkvm/kvm_vm_map.c diff --git a/lib/libkvm/Makefile b/lib/libkvm/Makefile index 153d111618..4faf5a8ede 100644 --- a/lib/libkvm/Makefile +++ b/lib/libkvm/Makefile @@ -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 diff --git a/lib/libkvm/kvm.h b/lib/libkvm/kvm.h index ccd5d80f1d..2a97d797a3 100644 --- a/lib/libkvm/kvm.h +++ b/lib/libkvm/kvm.h @@ -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 index 0000000000..a83642c497 --- /dev/null +++ b/lib/libkvm/kvm_vm_map.c @@ -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 + * + * 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 +#include +#include +#include + +#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; +} diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c index 46f0164792..7b84386bdc 100644 --- a/usr.bin/fstat/fstat.c +++ b/usr.bin/fstat/fstat.c @@ -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; -} -- 2.41.0