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