xref: /dragonfly/lib/libkvm/kvm_vm_map.c (revision f12d4f44)
1*f12d4f44Szrj /*
2*f12d4f44Szrj  * Copyright (c) 2019 The DragonFly Project.  All rights reserved.
3*f12d4f44Szrj  *
4*f12d4f44Szrj  * This code is derived from software contributed to The DragonFly Project
5*f12d4f44Szrj  * by Matthew Dillon <dillon@dragonflybsd.org>
6*f12d4f44Szrj  *
7*f12d4f44Szrj  * Redistribution and use in source and binary forms, with or without
8*f12d4f44Szrj  * modification, are permitted provided that the following conditions
9*f12d4f44Szrj  * are met:
10*f12d4f44Szrj  *
11*f12d4f44Szrj  * 1. Redistributions of source code must retain the above copyright
12*f12d4f44Szrj  *    notice, this list of conditions and the following disclaimer.
13*f12d4f44Szrj  * 2. Redistributions in binary form must reproduce the above copyright
14*f12d4f44Szrj  *    notice, this list of conditions and the following disclaimer in
15*f12d4f44Szrj  *    the documentation and/or other materials provided with the
16*f12d4f44Szrj  *    distribution.
17*f12d4f44Szrj  * 3. Neither the name of The DragonFly Project nor the names of its
18*f12d4f44Szrj  *    contributors may be used to endorse or promote products derived
19*f12d4f44Szrj  *    from this software without specific, prior written permission.
20*f12d4f44Szrj  *
21*f12d4f44Szrj  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22*f12d4f44Szrj  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23*f12d4f44Szrj  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24*f12d4f44Szrj  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25*f12d4f44Szrj  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26*f12d4f44Szrj  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27*f12d4f44Szrj  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28*f12d4f44Szrj  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29*f12d4f44Szrj  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30*f12d4f44Szrj  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31*f12d4f44Szrj  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32*f12d4f44Szrj  * SUCH DAMAGE.
33*f12d4f44Szrj  */
34*f12d4f44Szrj 
35*f12d4f44Szrj /*
36*f12d4f44Szrj  * Useful helper functions for vm_map_t parsing.
37*f12d4f44Szrj  */
38*f12d4f44Szrj 
39*f12d4f44Szrj #include <sys/user.h>
40*f12d4f44Szrj #include <sys/param.h>
41*f12d4f44Szrj #include <vm/vm.h>
42*f12d4f44Szrj #include <vm/vm_map.h>
43*f12d4f44Szrj 
44*f12d4f44Szrj #include "kvm.h"
45*f12d4f44Szrj 
46*f12d4f44Szrj static int
kreadent(kvm_t * kd,const void * kaddr,vm_map_entry_t copy)47*f12d4f44Szrj kreadent(kvm_t *kd, const void *kaddr, vm_map_entry_t copy)
48*f12d4f44Szrj {
49*f12d4f44Szrj 	size_t nb;
50*f12d4f44Szrj 
51*f12d4f44Szrj 	nb = sizeof(*copy);
52*f12d4f44Szrj 
53*f12d4f44Szrj 	if (kvm_read(kd, (u_long)kaddr, (char *)copy, nb) == (ssize_t)nb)
54*f12d4f44Szrj 		return 1;
55*f12d4f44Szrj 
56*f12d4f44Szrj 	return 0;
57*f12d4f44Szrj }
58*f12d4f44Szrj 
59*f12d4f44Szrj /*
60*f12d4f44Szrj  * Find and read first vm_map entry.
61*f12d4f44Szrj  */
62*f12d4f44Szrj vm_map_entry_t
kvm_vm_map_entry_first(kvm_t * kd,vm_map_t map,vm_map_entry_t copy)63*f12d4f44Szrj kvm_vm_map_entry_first(kvm_t *kd, vm_map_t map, vm_map_entry_t copy)
64*f12d4f44Szrj {
65*f12d4f44Szrj 	vm_map_entry_t ken;
66*f12d4f44Szrj 
67*f12d4f44Szrj 	ken = map->rb_root.rbh_root;
68*f12d4f44Szrj 	if (ken == NULL)
69*f12d4f44Szrj 		return NULL;
70*f12d4f44Szrj 	if (!kreadent(kd, ken, copy))
71*f12d4f44Szrj 		return NULL;
72*f12d4f44Szrj 	while (copy->rb_entry.rbe_left) {
73*f12d4f44Szrj 		ken = copy->rb_entry.rbe_left;
74*f12d4f44Szrj 		if (!kreadent(kd, ken, copy))
75*f12d4f44Szrj 			return NULL;
76*f12d4f44Szrj 	}
77*f12d4f44Szrj 	return ken;
78*f12d4f44Szrj }
79*f12d4f44Szrj 
80*f12d4f44Szrj /*
81*f12d4f44Szrj  * Find and read next vm_map entry.
82*f12d4f44Szrj  */
83*f12d4f44Szrj vm_map_entry_t
kvm_vm_map_entry_next(kvm_t * kd,vm_map_entry_t ken,vm_map_entry_t copy)84*f12d4f44Szrj kvm_vm_map_entry_next(kvm_t *kd, vm_map_entry_t ken, vm_map_entry_t copy)
85*f12d4f44Szrj {
86*f12d4f44Szrj 	vm_map_entry_t ken2;
87*f12d4f44Szrj 
88*f12d4f44Szrj 	if (copy->rb_entry.rbe_right) {
89*f12d4f44Szrj 		ken = copy->rb_entry.rbe_right;
90*f12d4f44Szrj 		if (!kreadent(kd, ken, copy))
91*f12d4f44Szrj 			return NULL;
92*f12d4f44Szrj 		while (copy->rb_entry.rbe_left) {
93*f12d4f44Szrj 			ken = copy->rb_entry.rbe_left;
94*f12d4f44Szrj 			if (!kreadent(kd, ken, copy))
95*f12d4f44Szrj 				return NULL;
96*f12d4f44Szrj 		}
97*f12d4f44Szrj 	} else {
98*f12d4f44Szrj 		if ((ken2 = copy->rb_entry.rbe_parent) == NULL)
99*f12d4f44Szrj 			return NULL;
100*f12d4f44Szrj 		if (!kreadent(kd, ken2, copy))
101*f12d4f44Szrj 			return NULL;
102*f12d4f44Szrj 		if (ken == copy->rb_entry.rbe_left) {
103*f12d4f44Szrj 			ken = ken2;
104*f12d4f44Szrj 		} else {
105*f12d4f44Szrj 			while (ken == copy->rb_entry.rbe_right) {
106*f12d4f44Szrj 				ken = ken2;
107*f12d4f44Szrj 				ken2 = copy->rb_entry.rbe_parent;
108*f12d4f44Szrj 				if (!kreadent(kd, ken2, copy))
109*f12d4f44Szrj 					return NULL;
110*f12d4f44Szrj 			}
111*f12d4f44Szrj 			ken = ken2;
112*f12d4f44Szrj 		}
113*f12d4f44Szrj 	}
114*f12d4f44Szrj 	return ken;
115*f12d4f44Szrj }
116