xref: /netbsd-src/usr.bin/pmap/main.c (revision 1da4c46ed0de732d01036cf4d69281e0f9b593e5)
1*1da4c46eSmlelstv /*	$NetBSD: main.c,v 1.30 2022/08/21 07:46:52 mlelstv Exp $ */
2a26b7f4dSatatat 
3a26b7f4dSatatat /*
4b840e629Sad  * Copyright (c) 2002, 2003, 2020 The NetBSD Foundation, Inc.
5a26b7f4dSatatat  * All rights reserved.
6a26b7f4dSatatat  *
7a26b7f4dSatatat  * This code is derived from software contributed to The NetBSD Foundation
8a26b7f4dSatatat  * by Andrew Brown.
9a26b7f4dSatatat  *
10a26b7f4dSatatat  * Redistribution and use in source and binary forms, with or without
11a26b7f4dSatatat  * modification, are permitted provided that the following conditions
12a26b7f4dSatatat  * are met:
13a26b7f4dSatatat  * 1. Redistributions of source code must retain the above copyright
14a26b7f4dSatatat  *    notice, this list of conditions and the following disclaimer.
15a26b7f4dSatatat  * 2. Redistributions in binary form must reproduce the above copyright
16a26b7f4dSatatat  *    notice, this list of conditions and the following disclaimer in the
17a26b7f4dSatatat  *    documentation and/or other materials provided with the distribution.
18a26b7f4dSatatat  *
19a26b7f4dSatatat  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20a26b7f4dSatatat  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21a26b7f4dSatatat  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a26b7f4dSatatat  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23a26b7f4dSatatat  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24a26b7f4dSatatat  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25a26b7f4dSatatat  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26a26b7f4dSatatat  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27a26b7f4dSatatat  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28a26b7f4dSatatat  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29a26b7f4dSatatat  * POSSIBILITY OF SUCH DAMAGE.
30a26b7f4dSatatat  */
31a26b7f4dSatatat 
32a26b7f4dSatatat #include <sys/cdefs.h>
33a26b7f4dSatatat #ifndef lint
34*1da4c46eSmlelstv __RCSID("$NetBSD: main.c,v 1.30 2022/08/21 07:46:52 mlelstv Exp $");
35a26b7f4dSatatat #endif
36a26b7f4dSatatat 
37a26b7f4dSatatat #include <sys/param.h>
38a26b7f4dSatatat 
39a26b7f4dSatatat #ifndef __NetBSD_Version__
40a26b7f4dSatatat #error go away, you fool
41a26b7f4dSatatat #elif (__NetBSD_Version__ < 105000000)
42a26b7f4dSatatat #error only works with uvm
43a26b7f4dSatatat #endif
44a26b7f4dSatatat 
45a26b7f4dSatatat #include <fcntl.h>
46a26b7f4dSatatat #include <errno.h>
47a26b7f4dSatatat #include <unistd.h>
48a26b7f4dSatatat #include <limits.h>
49a26b7f4dSatatat #include <string.h>
502fa13d15Schristos #include <signal.h>
51093dea82Schristos #include <util.h>
52a26b7f4dSatatat 
53a26b7f4dSatatat #include "pmap.h"
54a26b7f4dSatatat #include "main.h"
55a26b7f4dSatatat 
56a26b7f4dSatatat struct cache_head lcache;
57a26b7f4dSatatat void *uvm_vnodeops, *uvm_deviceops, *aobj_pager, *ubc_pager;
58b840e629Sad struct vm_map *kmem_map, *phys_map, *exec_map, *pager_map;
59b840e629Sad struct vm_map *st_map, *pt_map, *module_map, *buf_map;
60b840e629Sad u_long kernel_map_addr;
612242d20aSatatat int debug, verbose, recurse, page_size;
62a26b7f4dSatatat int print_all, print_map, print_maps, print_solaris, print_ddb;
63*1da4c46eSmlelstv int tree;
64a26b7f4dSatatat rlim_t maxssiz;
65a26b7f4dSatatat 
66a26b7f4dSatatat struct nlist ksyms[] = {
674d749375Slukem 	{ "_maxsmap", 0, 0, 0, 0 },
68a26b7f4dSatatat #define NL_MAXSSIZ		0
694d749375Slukem 	{ "_uvm_vnodeops", 0, 0, 0, 0 },
70a26b7f4dSatatat #define NL_UVM_VNODEOPS		1
714d749375Slukem 	{ "_uvm_deviceops", 0, 0, 0, 0 },
72a26b7f4dSatatat #define NL_UVM_DEVICEOPS	2
734d749375Slukem 	{ "_aobj_pager", 0, 0, 0, 0 },
74a26b7f4dSatatat #define NL_AOBJ_PAGER		3
754d749375Slukem 	{ "_ubc_pager", 0, 0, 0, 0 },
76a26b7f4dSatatat #define NL_UBC_PAGER		4
774d749375Slukem 	{ "_kernel_map", 0, 0, 0, 0 },
78a26b7f4dSatatat #define NL_KERNEL_MAP		5
794d749375Slukem 	{ NULL, 0, 0, 0, 0 }
80a26b7f4dSatatat };
81a26b7f4dSatatat 
82a26b7f4dSatatat struct nlist kmaps[] = {
834d749375Slukem 	{ "_kmem_map", 0, 0, 0, 0 },
846d45c1cdSatatat #define NL_kmem_map		0
854d749375Slukem 	{ "_phys_map", 0, 0, 0, 0 },
86b840e629Sad #define NL_phys_map		1
874d749375Slukem 	{ "_exec_map", 0, 0, 0, 0 },
88b840e629Sad #define NL_exec_map		2
894d749375Slukem 	{ "_pager_map", 0, 0, 0, 0 },
90b840e629Sad #define NL_pager_map		3
914d749375Slukem 	{ "_st_map", 0, 0, 0, 0 },
92b840e629Sad #define NL_st_map		4
934d749375Slukem 	{ "_pt_map", 0, 0, 0, 0 },
94b840e629Sad #define NL_pt_map		5
95b840e629Sad 	{ "_module_map", 0, 0, 0, 0 },
96b840e629Sad #define NL_module_map		6
974d749375Slukem 	{ "_buf_map", 0, 0, 0, 0 },
98b840e629Sad #define NL_buf_map		7
994d749375Slukem 	{ NULL, 0, 0, 0, 0 },
100a26b7f4dSatatat };
101a26b7f4dSatatat 
102a8894079Satatat #define VMSPACE_ADDRESS		1
103a8894079Satatat #define VM_MAP_ADDRESS		2
104a8894079Satatat #define VM_MAP_ENTRY_ADDRESS	3
105a8894079Satatat #define AMAP_ADDRESS		4
106a8894079Satatat 
107a26b7f4dSatatat void check_fd(int);
108a26b7f4dSatatat void load_symbols(kvm_t *);
1094d749375Slukem void cache_enter(u_long, struct namecache *);
110a26b7f4dSatatat 
111a26b7f4dSatatat int
main(int argc,char * argv[])112a26b7f4dSatatat main(int argc, char *argv[])
113a26b7f4dSatatat {
114a26b7f4dSatatat 	kvm_t *kd;
115a26b7f4dSatatat 	pid_t pid;
116a960d513Sjym 	uid_t uid;
117a8894079Satatat 	int which, many, ch, rc;
118a26b7f4dSatatat 	char errbuf[_POSIX2_LINE_MAX + 1];
119a26b7f4dSatatat 	struct kinfo_proc2 *kproc;
120a8894079Satatat 	char *kmem, *kernel, *t;
12180f8e56aSatatat 	gid_t egid;
122a8894079Satatat 	struct kbit kbit, *vmspace;
123a8894079Satatat 	u_long address;
12480f8e56aSatatat 
125951bbd42Schs 	uid = getuid();
12680f8e56aSatatat 	egid = getegid();
12780f8e56aSatatat 	if (setegid(getgid()) == -1)
12880f8e56aSatatat 		err(1, "failed to reset privileges");
129a26b7f4dSatatat 
130a26b7f4dSatatat 	check_fd(STDIN_FILENO);
131a26b7f4dSatatat 	check_fd(STDOUT_FILENO);
132a26b7f4dSatatat 	check_fd(STDERR_FILENO);
133a26b7f4dSatatat 
134a26b7f4dSatatat 	pid = -1;
135a8894079Satatat 	which = verbose = debug = 0;
136a26b7f4dSatatat 	print_all = print_map = print_maps = print_solaris = print_ddb = 0;
137*1da4c46eSmlelstv 	tree = 0;
138a26b7f4dSatatat 	recurse = 0;
139a26b7f4dSatatat 	kmem = kernel = NULL;
140a8894079Satatat 	address = 0;
141a8894079Satatat 	vmspace = &kbit;
142a26b7f4dSatatat 
143*1da4c46eSmlelstv 	while ((ch = getopt(argc, argv, "A:aD:dE:lM:mN:Pp:RrS:stV:vx")) != -1) {
144a26b7f4dSatatat 		switch (ch) {
145a8894079Satatat 		case 'A':
146a8894079Satatat 		case 'E':
147a8894079Satatat 		case 'S':
148a8894079Satatat 		case 'V':
149a8894079Satatat 			if (which != 0)
150a8894079Satatat 				errx(1, "use only one of -A, -E, -S, or -V");
151a8894079Satatat 			errno = 0;
152a8894079Satatat 			address = strtoul(optarg, &t, 0);
153a8894079Satatat 			if (*t != '\0')
154a8894079Satatat 				errx(1, "%s is not a valid address", optarg);
155a8894079Satatat 			if (errno != 0)
156a8894079Satatat 				err(1, "%s is not a valid address", optarg);
157a8894079Satatat 			switch (ch) {
158a8894079Satatat 			case 'A':	which = AMAP_ADDRESS;		break;
159a8894079Satatat 			case 'E':	which = VM_MAP_ENTRY_ADDRESS;	break;
160a8894079Satatat 			case 'S':	which = VMSPACE_ADDRESS;	break;
161a8894079Satatat 			case 'V':	which = VM_MAP_ADDRESS;		break;
162a8894079Satatat 			}
163a8894079Satatat 			break;
164a26b7f4dSatatat 		case 'a':
165a26b7f4dSatatat 			print_all = 1;
166a26b7f4dSatatat 			break;
167a26b7f4dSatatat 		case 'd':
168a26b7f4dSatatat 			print_ddb = 1;
169a26b7f4dSatatat 			break;
170a26b7f4dSatatat 		case 'D':
171a8894079Satatat 			errno = 0;
172a8894079Satatat 			debug = strtoul(optarg, &t, 0);
173a8894079Satatat 			if (*t != '\0')
174a8894079Satatat 				errx(1, "%s is not a valid number", optarg);
175a8894079Satatat 			if (errno != 0)
176a8894079Satatat 				err(1, "%s is not a valid number", optarg);
177a26b7f4dSatatat 			break;
178a26b7f4dSatatat 		case 'l':
179a26b7f4dSatatat 			print_maps = 1;
180a26b7f4dSatatat 			break;
181a26b7f4dSatatat 		case 'm':
182a26b7f4dSatatat 			print_map = 1;
183a26b7f4dSatatat 			break;
184a26b7f4dSatatat 		case 'M':
185a26b7f4dSatatat 			kmem = optarg;
186a26b7f4dSatatat 			break;
187a26b7f4dSatatat 		case 'N':
188a26b7f4dSatatat 			kernel = optarg;
189a26b7f4dSatatat 			break;
190a26b7f4dSatatat 		case 'p':
191a8894079Satatat 			errno = 0;
192a8894079Satatat 			pid = strtol(optarg, &t, 0);
193a8894079Satatat 			if (pid < 0)
194a8894079Satatat 				errno = EINVAL;
195a8894079Satatat 			if (*t != '\0')
196a8894079Satatat 				errx(1, "%s is not a valid pid", optarg);
197a8894079Satatat 			if (errno != 0)
198a8894079Satatat 				err(1, "%s is not a valid pid", optarg);
199a26b7f4dSatatat 			break;
200a26b7f4dSatatat 		case 'P':
201a26b7f4dSatatat 			pid = getpid();
202a26b7f4dSatatat 			break;
203a26b7f4dSatatat 		case 'R':
204a26b7f4dSatatat 			recurse = 1;
205a26b7f4dSatatat 			break;
206a26b7f4dSatatat 		case 's':
207a26b7f4dSatatat 			print_solaris = 1;
208a26b7f4dSatatat 			break;
209*1da4c46eSmlelstv 		case 't':
210*1da4c46eSmlelstv 			tree = 1;
211*1da4c46eSmlelstv 			break;
212a26b7f4dSatatat 		case 'v':
213a26b7f4dSatatat 			verbose++;
214a26b7f4dSatatat 			break;
215a26b7f4dSatatat 		case 'r':
216a26b7f4dSatatat 		case 'x':
217a26b7f4dSatatat 			errx(1, "-%c option not implemented, sorry", optopt);
218a26b7f4dSatatat 			/*NOTREACHED*/
219a26b7f4dSatatat 		case '?':
220a26b7f4dSatatat 		default:
221*1da4c46eSmlelstv 			fprintf(stderr, "usage: %s [-adlmPRstv] [-A address] "
222a8894079Satatat 				"[-D number] [-E address] [-M core]\n"
223817f471bSwiz 				"\t[-N system] [-p pid] [-S address] "
224817f471bSwiz 				"[-V address] [pid ...]\n",
225a26b7f4dSatatat 				getprogname());
226a26b7f4dSatatat 			exit(1);
227a26b7f4dSatatat 		}
228a26b7f4dSatatat 	}
229a26b7f4dSatatat 	argc -= optind;
230a26b7f4dSatatat 	argv += optind;
231a26b7f4dSatatat 
232a26b7f4dSatatat 	/* more than one "process" to dump? */
233a26b7f4dSatatat 	many = (argc > 1 - (pid == -1 ? 0 : 1)) ? 1 : 0;
234a26b7f4dSatatat 
235a26b7f4dSatatat 	/* apply default */
236a26b7f4dSatatat 	if (print_all + print_map + print_maps + print_solaris +
237a26b7f4dSatatat 	    print_ddb == 0)
238a26b7f4dSatatat 		print_solaris = 1;
239a26b7f4dSatatat 
240951bbd42Schs 	if ((kernel != NULL || kmem != NULL || address != 0 ||
241951bbd42Schs 	     print_ddb || debug) && uid != 0)
242951bbd42Schs 		errx(1, "one or more options specified is restricted to root");
243951bbd42Schs 
244951bbd42Schs 	/* get privs back since it appears to be safe. */
24580f8e56aSatatat 	rc = setegid(egid);
24680f8e56aSatatat 	if (rc == -1)
24780f8e56aSatatat 		err(1, "failed to reset privileges");
24880f8e56aSatatat 
249a26b7f4dSatatat 	/* start by opening libkvm */
250a26b7f4dSatatat 	kd = kvm_openfiles(kernel, kmem, NULL, O_RDONLY, errbuf);
251535d7095Satatat 
252535d7095Satatat 	/* we're completely done with privileges now */
253535d7095Satatat 	rc = setgid(getgid());
254535d7095Satatat 	if (rc == -1)
255535d7095Satatat 		err(1, "failed to reset privileges");
256535d7095Satatat 
257535d7095Satatat 	/* print the kvm_open error, if any */
258a26b7f4dSatatat 	errbuf[_POSIX2_LINE_MAX] = '\0';
259a26b7f4dSatatat 	if (kd == NULL)
260a26b7f4dSatatat 		errx(1, "%s", errbuf);
261a26b7f4dSatatat 
262a26b7f4dSatatat 	/* get "bootstrap" addresses from kernel */
263a26b7f4dSatatat 	load_symbols(kd);
264a26b7f4dSatatat 
265a8894079Satatat 	if (address) {
266a8894079Satatat 		struct kbit kbit2, *at = &kbit2;
267a8894079Satatat 
268a8894079Satatat 		memset(vmspace, 0, sizeof(*vmspace));
269a8894079Satatat 		A(at) = address;
2709fa51823Satatat 		S(at) = (size_t)-1;
271a8894079Satatat 
272a8894079Satatat 		switch (which) {
273a8894079Satatat 		    case VMSPACE_ADDRESS:
274a8894079Satatat 			/* (kd, kproc, vmspace, thing) */
275a8894079Satatat 			(*process_map)(kd, NULL, at, "vm_map");
276a8894079Satatat 			break;
277a8894079Satatat 		    case VM_MAP_ADDRESS:
278a8894079Satatat 			/* (kd, proc, vmspace, vm_map, thing) */
279a8894079Satatat 			(*dump_vm_map)(kd, NULL, vmspace, at, "vm_map");
280a8894079Satatat 			break;
281a8894079Satatat 		    case VM_MAP_ENTRY_ADDRESS:
282a8894079Satatat 			/* (kd, proc, vmspace, vm_map_entry, 0) */
283a8894079Satatat 			(*dump_vm_map_entry)(kd, NULL, vmspace, at, 0);
284a8894079Satatat 			break;
285a8894079Satatat 		    case AMAP_ADDRESS:
286a8894079Satatat 			/* (kd, amap) */
287a8894079Satatat 			(*dump_amap)(kd, at);
288a8894079Satatat 			break;
289a8894079Satatat 		}
290a8894079Satatat 		exit(0);
291a8894079Satatat 	}
292a26b7f4dSatatat 
293a26b7f4dSatatat 	do {
294a26b7f4dSatatat 		if (pid == -1) {
295a26b7f4dSatatat 			if (argc == 0)
296a26b7f4dSatatat 				pid = getppid();
297a26b7f4dSatatat 			else {
298a8894079Satatat 				errno = 0;
299a8894079Satatat 				pid = strtol(argv[0], &t, 0);
300a8894079Satatat 				if (pid < 0)
301a8894079Satatat 					errno = EINVAL;
302a8894079Satatat 				if (*t != '\0')
303a8894079Satatat 					errx(1, "%s is not a valid pid",
304a8894079Satatat 					    argv[0]);
305a8894079Satatat 				if (errno != 0)
306a8894079Satatat 					err(1, "%s is not a valid pid",
307a8894079Satatat 					    argv[0]);
308a26b7f4dSatatat 				argv++;
309a26b7f4dSatatat 				argc--;
310a26b7f4dSatatat 			}
311a26b7f4dSatatat 		}
312a26b7f4dSatatat 
313a960d513Sjym 		errno = 0;
314a26b7f4dSatatat 		/* find the process id */
315a960d513Sjym 		if (pid == 0) {
316a26b7f4dSatatat 			kproc = NULL;
317a960d513Sjym 			if (uid != 0) {
318a960d513Sjym 				/* only root can print kernel mappings */
319a960d513Sjym 				errno = EPERM;
320a960d513Sjym 			}
321a960d513Sjym 		} else {
322a26b7f4dSatatat 			kproc = kvm_getproc2(kd, KERN_PROC_PID, pid,
323a26b7f4dSatatat 			    sizeof(struct kinfo_proc2), &rc);
324a26b7f4dSatatat 			if (kproc == NULL || rc == 0) {
325a26b7f4dSatatat 				errno = ESRCH;
326a960d513Sjym 			} else if (uid != 0 && uid != kproc->p_uid) {
327a960d513Sjym 				/*
328a960d513Sjym 				 * only the real owner of the process and
329a960d513Sjym 				 * root can print process mappings
330a960d513Sjym 				 */
331a960d513Sjym 				errno = EPERM;
332a960d513Sjym 			}
333a960d513Sjym 		}
334a960d513Sjym 
335a960d513Sjym 		if (errno != 0) {
336a26b7f4dSatatat 			warn("%d", pid);
337a26b7f4dSatatat 			pid = -1;
338a26b7f4dSatatat 			continue;
339a26b7f4dSatatat 		}
340a26b7f4dSatatat 
341a26b7f4dSatatat 		/* dump it */
342a26b7f4dSatatat 		if (many) {
34316bd0851Sjym 			if (kproc != NULL)
344a26b7f4dSatatat 				printf("process %d:\n", kproc->p_pid);
345a26b7f4dSatatat 			else
346a26b7f4dSatatat 				printf("kernel:\n");
347a26b7f4dSatatat 		}
348a26b7f4dSatatat 
349a8894079Satatat 		(*process_map)(kd, kproc, vmspace, NULL);
350a26b7f4dSatatat 		pid = -1;
351a26b7f4dSatatat 	} while (argc > 0);
352a26b7f4dSatatat 
353a26b7f4dSatatat 	/* done.  go away. */
354a26b7f4dSatatat 	rc = kvm_close(kd);
355a26b7f4dSatatat 	if (rc == -1)
356a26b7f4dSatatat 		err(1, "kvm_close");
357a26b7f4dSatatat 
358a26b7f4dSatatat 	return (0);
359a26b7f4dSatatat }
360a26b7f4dSatatat 
361a26b7f4dSatatat void
check_fd(int fd)362a26b7f4dSatatat check_fd(int fd)
363a26b7f4dSatatat {
364a26b7f4dSatatat 	struct stat st;
365a26b7f4dSatatat 	int n;
366a26b7f4dSatatat 
367a26b7f4dSatatat 	if (fstat(fd, &st) == -1) {
368a26b7f4dSatatat 		(void)close(fd);
369a26b7f4dSatatat 		n = open("/dev/null", O_RDWR);
370a26b7f4dSatatat 		if (n == fd || n == -1)
371a26b7f4dSatatat 			/* we're either done or we can do no more */
372a26b7f4dSatatat 			return;
373a26b7f4dSatatat 		/* if either of these fail, there's not much we can do */
374a26b7f4dSatatat 		(void)dup2(n, fd);
375a26b7f4dSatatat 		(void)close(n);
376a26b7f4dSatatat 		/* XXX should we exit if it fails? */
377a26b7f4dSatatat 	}
378a26b7f4dSatatat }
379a26b7f4dSatatat 
380a26b7f4dSatatat void
load_symbols(kvm_t * kd)381a26b7f4dSatatat load_symbols(kvm_t *kd)
382a26b7f4dSatatat {
3832242d20aSatatat 	int rc, i, mib[2];
384d614a583She 	size_t sz;
385a26b7f4dSatatat 
386a26b7f4dSatatat 	rc = kvm_nlist(kd, &ksyms[0]);
387a26b7f4dSatatat 	if (rc != 0) {
388a26b7f4dSatatat 		for (i = 0; ksyms[i].n_name != NULL; i++)
389a26b7f4dSatatat 			if (ksyms[i].n_value == 0)
3903535ff5eSatatat 				warnx("symbol %s: not found", ksyms[i].n_name);
391a26b7f4dSatatat 		exit(1);
392a26b7f4dSatatat 	}
393a26b7f4dSatatat 
394a26b7f4dSatatat 	uvm_vnodeops =	(void*)ksyms[NL_UVM_VNODEOPS].n_value;
395a26b7f4dSatatat 	uvm_deviceops =	(void*)ksyms[NL_UVM_DEVICEOPS].n_value;
396a26b7f4dSatatat 	aobj_pager =	(void*)ksyms[NL_AOBJ_PAGER].n_value;
397a26b7f4dSatatat 	ubc_pager =	(void*)ksyms[NL_UBC_PAGER].n_value;
398a26b7f4dSatatat 
399a26b7f4dSatatat 	_KDEREF(kd, ksyms[NL_MAXSSIZ].n_value, &maxssiz,
400a26b7f4dSatatat 		sizeof(maxssiz));
401a26b7f4dSatatat 	_KDEREF(kd, ksyms[NL_KERNEL_MAP].n_value, &kernel_map_addr,
402a26b7f4dSatatat 		sizeof(kernel_map_addr));
403a26b7f4dSatatat 
404a26b7f4dSatatat 	/*
405a26b7f4dSatatat 	 * Some of these may be missing from some platforms, for
406a26b7f4dSatatat 	 * example sparc, sh3, and most powerpc platforms don't
4076d45c1cdSatatat 	 * have a "phys_map", etc.
408a26b7f4dSatatat 	 */
409a26b7f4dSatatat 	(void)kvm_nlist(kd, &kmaps[0]);
4106d45c1cdSatatat 
411a068aea2Satatat #define get_map_address(m) do {\
4127afae692Syamt 	if (kmaps[__CONCAT(NL_,m)].n_value != 0) \
4137afae692Syamt 		_KDEREF(kd, kmaps[__CONCAT(NL_,m)].n_value, &m, sizeof(m)); \
4149fa51823Satatat 	} while (0/*CONSTCOND*/)
4156d45c1cdSatatat 
4166d45c1cdSatatat 	get_map_address(kmem_map);
4176d45c1cdSatatat 	get_map_address(phys_map);
4186d45c1cdSatatat 	get_map_address(exec_map);
4196d45c1cdSatatat 	get_map_address(pager_map);
4206d45c1cdSatatat 	get_map_address(st_map);
4216d45c1cdSatatat 	get_map_address(pt_map);
422b840e629Sad 	get_map_address(module_map);
423a068aea2Satatat 	get_map_address(buf_map);
4242242d20aSatatat 
4252242d20aSatatat 	mib[0] = CTL_HW;
4262242d20aSatatat 	mib[1] = HW_PAGESIZE;
427d614a583She 	sz = sizeof(page_size);
428d614a583She 	if (sysctl(&mib[0], 2, &page_size, &sz, NULL, 0) == -1)
4292242d20aSatatat 		err(1, "sysctl: hw.pagesize");
4306d45c1cdSatatat }
4316d45c1cdSatatat 
4326d45c1cdSatatat const char *
mapname(void * addr)4336d45c1cdSatatat mapname(void *addr)
4346d45c1cdSatatat {
4356d45c1cdSatatat 
4366d45c1cdSatatat 	if (addr == (void*)kernel_map_addr)
4376d45c1cdSatatat 		return ("kernel_map");
4386d45c1cdSatatat 	else if (addr == kmem_map)
4396d45c1cdSatatat 		return ("kmem_map");
4406d45c1cdSatatat 	else if (addr == phys_map)
4416d45c1cdSatatat 		return ("phys_map");
4426d45c1cdSatatat 	else if (addr == exec_map)
4436d45c1cdSatatat 		return ("exec_map");
4446d45c1cdSatatat 	else if (addr == pager_map)
4456d45c1cdSatatat 		return ("pager_map");
4466d45c1cdSatatat 	else if (addr == st_map)
4476d45c1cdSatatat 		return ("st_map");
4486d45c1cdSatatat 	else if (addr == pt_map)
4496d45c1cdSatatat 		return ("pt_map");
450b840e629Sad 	else if (addr == module_map)
451b840e629Sad 		return ("module_map");
452a068aea2Satatat 	else if (addr == buf_map)
453a068aea2Satatat 		return ("buf_map");
4546d45c1cdSatatat 	else
4556d45c1cdSatatat 		return (NULL);
456a26b7f4dSatatat }
457