1 1.58 ad /* $NetBSD: pmap.c,v 1.58 2023/09/09 18:27:59 ad Exp $ */ 2 1.1 atatat 3 1.1 atatat /* 4 1.58 ad * Copyright (c) 2002, 2003, 2020, 2023 The NetBSD Foundation, Inc. 5 1.1 atatat * All rights reserved. 6 1.1 atatat * 7 1.1 atatat * This code is derived from software contributed to The NetBSD Foundation 8 1.1 atatat * by Andrew Brown. 9 1.1 atatat * 10 1.1 atatat * Redistribution and use in source and binary forms, with or without 11 1.1 atatat * modification, are permitted provided that the following conditions 12 1.1 atatat * are met: 13 1.1 atatat * 1. Redistributions of source code must retain the above copyright 14 1.1 atatat * notice, this list of conditions and the following disclaimer. 15 1.1 atatat * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 atatat * notice, this list of conditions and the following disclaimer in the 17 1.1 atatat * documentation and/or other materials provided with the distribution. 18 1.1 atatat * 19 1.1 atatat * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 atatat * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 atatat * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 atatat * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 atatat * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 atatat * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 atatat * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 atatat * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 atatat * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 atatat * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 atatat * POSSIBILITY OF SUCH DAMAGE. 30 1.1 atatat */ 31 1.1 atatat 32 1.1 atatat #include <sys/cdefs.h> 33 1.1 atatat #ifndef lint 34 1.58 ad __RCSID("$NetBSD: pmap.c,v 1.58 2023/09/09 18:27:59 ad Exp $"); 35 1.1 atatat #endif 36 1.1 atatat 37 1.1 atatat #include <string.h> 38 1.52 christos #include <util.h> 39 1.1 atatat 40 1.10 atatat #include "pmap.h" 41 1.10 atatat #include "main.h" 42 1.10 atatat 43 1.14 atatat static void dump_vm_anon(kvm_t *, struct vm_anon **, int); 44 1.10 atatat static char *findname(kvm_t *, struct kbit *, struct kbit *, struct kbit *, 45 1.10 atatat struct kbit *, struct kbit *); 46 1.55 ad static int search_cache(kvm_t *, struct vnode *, char **, char *, size_t); 47 1.1 atatat 48 1.57 mlelstv /* when recursing or printing tree, output is indented */ 49 1.57 mlelstv #define indent(n) ((n) * ((recurse > 1 ? recurse - 1 : 0)) + depth) 50 1.13 atatat #define rwx (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE) 51 1.57 mlelstv static int depth; 52 1.13 atatat 53 1.13 atatat int heapfound; 54 1.4 atatat 55 1.6 atatat void 56 1.40 yamt process_map(kvm_t *kd, struct kinfo_proc2 *proc, 57 1.15 atatat struct kbit *vmspace, const char *thing) 58 1.1 atatat { 59 1.15 atatat struct kbit kbit, *vm_map = &kbit; 60 1.1 atatat 61 1.15 atatat if (proc) { 62 1.1 atatat heapfound = 0; 63 1.1 atatat A(vmspace) = (u_long)proc->p_vmspace; 64 1.1 atatat S(vmspace) = sizeof(struct vmspace); 65 1.1 atatat thing = "proc->p_vmspace.vm_map"; 66 1.21 atatat } else if (S(vmspace) == (size_t)-1) { 67 1.15 atatat heapfound = 0; 68 1.15 atatat /* A(vmspace) set by caller */ 69 1.15 atatat S(vmspace) = sizeof(struct vmspace); 70 1.15 atatat /* object identified by caller */ 71 1.1 atatat } else { 72 1.1 atatat heapfound = 1; /* but really, do kernels have a heap? */ 73 1.1 atatat A(vmspace) = 0; 74 1.1 atatat S(vmspace) = 0; 75 1.1 atatat thing = "kernel_map"; 76 1.1 atatat } 77 1.1 atatat 78 1.1 atatat S(vm_map) = sizeof(struct vm_map); 79 1.15 atatat 80 1.15 atatat if (S(vmspace) != 0) { 81 1.15 atatat KDEREF(kd, vmspace); 82 1.10 atatat A(vm_map) = A(vmspace) + offsetof(struct vmspace, vm_map); 83 1.1 atatat memcpy(D(vm_map, vm_map), &D(vmspace, vmspace)->vm_map, 84 1.1 atatat S(vm_map)); 85 1.1 atatat } else { 86 1.16 atatat memset(vmspace, 0, sizeof(*vmspace)); 87 1.1 atatat A(vm_map) = kernel_map_addr; 88 1.1 atatat KDEREF(kd, vm_map); 89 1.1 atatat } 90 1.4 atatat 91 1.40 yamt dump_vm_map(kd, proc, vmspace, vm_map, thing); 92 1.4 atatat } 93 1.4 atatat 94 1.15 atatat void 95 1.40 yamt dump_vm_map(kvm_t *kd, struct kinfo_proc2 *proc, 96 1.15 atatat struct kbit *vmspace, struct kbit *vm_map, const char *mname) 97 1.4 atatat { 98 1.4 atatat struct kbit kbit[2], *header, *vm_map_entry; 99 1.4 atatat size_t total; 100 1.4 atatat 101 1.21 atatat if (S(vm_map) == (size_t)-1) { 102 1.15 atatat heapfound = 1; 103 1.15 atatat S(vm_map) = sizeof(struct vm_map); 104 1.15 atatat KDEREF(kd, vm_map); 105 1.15 atatat } 106 1.15 atatat 107 1.4 atatat header = &kbit[0]; 108 1.4 atatat vm_map_entry = &kbit[1]; 109 1.4 atatat A(header) = 0; 110 1.4 atatat A(vm_map_entry) = 0; 111 1.4 atatat 112 1.10 atatat A(header) = A(vm_map) + offsetof(struct vm_map, header); 113 1.10 atatat S(header) = sizeof(struct vm_map_entry); 114 1.10 atatat memcpy(D(header, vm_map_entry), &D(vm_map, vm_map)->header, S(header)); 115 1.10 atatat 116 1.15 atatat if (S(vmspace) != 0 && (debug & PRINT_VMSPACE)) { 117 1.10 atatat printf("proc->p_vmspace %p = {", P(vmspace)); 118 1.10 atatat printf(" vm_refcnt = %d,", D(vmspace, vmspace)->vm_refcnt); 119 1.10 atatat printf(" vm_shm = %p,\n", D(vmspace, vmspace)->vm_shm); 120 1.10 atatat printf(" vm_rssize = %d,", D(vmspace, vmspace)->vm_rssize); 121 1.54 christos printf(" vm_rssmax = %d,", D(vmspace, vmspace)->vm_rssmax); 122 1.10 atatat printf(" vm_tsize = %d,", D(vmspace, vmspace)->vm_tsize); 123 1.10 atatat printf(" vm_dsize = %d,\n", D(vmspace, vmspace)->vm_dsize); 124 1.10 atatat printf(" vm_ssize = %d,", D(vmspace, vmspace)->vm_ssize); 125 1.10 atatat printf(" vm_taddr = %p,", D(vmspace, vmspace)->vm_taddr); 126 1.10 atatat printf(" vm_daddr = %p,\n", D(vmspace, vmspace)->vm_daddr); 127 1.10 atatat printf(" vm_maxsaddr = %p,", 128 1.10 atatat D(vmspace, vmspace)->vm_maxsaddr); 129 1.53 kamil printf(" vm_minsaddr = %p,\n", 130 1.10 atatat D(vmspace, vmspace)->vm_minsaddr); 131 1.53 kamil printf(" vm_aslr_delta_mmap = %#zx }\n", 132 1.53 kamil D(vmspace, vmspace)->vm_aslr_delta_mmap); 133 1.10 atatat } 134 1.10 atatat 135 1.1 atatat if (debug & PRINT_VM_MAP) { 136 1.7 atatat printf("%*s%s %p = {", indent(2), "", mname, P(vm_map)); 137 1.1 atatat printf(" pmap = %p,\n", D(vm_map, vm_map)->pmap); 138 1.4 atatat printf("%*s lock = <struct lock>,", indent(2), ""); 139 1.1 atatat printf(" header = <struct vm_map_entry>,"); 140 1.1 atatat printf(" nentries = %d,\n", D(vm_map, vm_map)->nentries); 141 1.44 uebayasi printf("%*s size = %#"PRIxVSIZE",", indent(2), "", 142 1.4 atatat D(vm_map, vm_map)->size); 143 1.1 atatat printf(" ref_count = %d,", D(vm_map, vm_map)->ref_count); 144 1.4 atatat printf("%*s hint = %p,", indent(2), "", 145 1.4 atatat D(vm_map, vm_map)->hint); 146 1.4 atatat printf("%*s first_free = %p,", indent(2), "", 147 1.4 atatat D(vm_map, vm_map)->first_free); 148 1.53 kamil printf(" flags = %#x <%s%s%s%s%s >,\n", D(vm_map, vm_map)->flags, 149 1.1 atatat D(vm_map, vm_map)->flags & VM_MAP_PAGEABLE ? " PAGEABLE" : "", 150 1.1 atatat D(vm_map, vm_map)->flags & VM_MAP_WIREFUTURE ? " WIREFUTURE" : "", 151 1.6 atatat #ifdef VM_MAP_DYING 152 1.11 atatat D(vm_map, vm_map)->flags & VM_MAP_DYING ? " DYING" : 153 1.6 atatat #endif 154 1.11 atatat "", 155 1.6 atatat #ifdef VM_MAP_TOPDOWN 156 1.11 atatat D(vm_map, vm_map)->flags & VM_MAP_TOPDOWN ? " TOPDOWN" : 157 1.1 atatat #endif 158 1.53 kamil "", 159 1.53 kamil #ifdef VM_MAP_WANTVA 160 1.53 kamil D(vm_map, vm_map)->flags & VM_MAP_WANTVA ? " WANTVA" : 161 1.53 kamil #endif 162 1.11 atatat ""); 163 1.31 yamt printf("%*s timestamp = %u }\n", indent(2), "", 164 1.31 yamt D(vm_map, vm_map)->timestamp); 165 1.1 atatat } 166 1.1 atatat if (print_ddb) { 167 1.13 atatat const char *name = mapname(P(vm_map)); 168 1.5 atatat 169 1.47 tsutsui printf("%*s%s %p: [%#"PRIxVADDR"->%#"PRIxVADDR"]\n", indent(2), "", 170 1.4 atatat recurse < 2 ? "MAP" : "SUBMAP", P(vm_map), 171 1.25 chs vm_map_min(D(vm_map, vm_map)), 172 1.25 chs vm_map_max(D(vm_map, vm_map))); 173 1.53 kamil printf("\t%*s#ent=%d, sz=%"PRIxVSIZE", ref=%d, version=%d, flags=%#x\n", 174 1.4 atatat indent(2), "", D(vm_map, vm_map)->nentries, 175 1.4 atatat D(vm_map, vm_map)->size, D(vm_map, vm_map)->ref_count, 176 1.4 atatat D(vm_map, vm_map)->timestamp, D(vm_map, vm_map)->flags); 177 1.4 atatat printf("\t%*spmap=%p(resident=<unknown>)\n", indent(2), "", 178 1.4 atatat D(vm_map, vm_map)->pmap); 179 1.5 atatat if (verbose && name != NULL) 180 1.5 atatat printf("\t%*s([ %s ])\n", indent(2), "", name); 181 1.1 atatat } 182 1.1 atatat 183 1.40 yamt dump_vm_map_entry(kd, proc, vmspace, header, 1); 184 1.1 atatat 185 1.4 atatat /* 186 1.4 atatat * we're not recursing into a submap, so print headers 187 1.4 atatat */ 188 1.4 atatat if (recurse < 2) { 189 1.4 atatat /* headers */ 190 1.1 atatat #ifdef DISABLED_HEADERS 191 1.4 atatat if (print_map) 192 1.4 atatat printf("%-*s %-*s rwx RWX CPY NCP I W A\n", 193 1.4 atatat (int)sizeof(long) * 2 + 2, "Start", 194 1.4 atatat (int)sizeof(long) * 2 + 2, "End"); 195 1.4 atatat if (print_maps) 196 1.4 atatat printf("%-*s %-*s rwxp %-*s Dev Inode File\n", 197 1.4 atatat (int)sizeof(long) * 2 + 0, "Start", 198 1.4 atatat (int)sizeof(long) * 2 + 0, "End", 199 1.4 atatat (int)sizeof(long) * 2 + 0, "Offset"); 200 1.4 atatat if (print_solaris) 201 1.4 atatat printf("%-*s %*s Protection File\n", 202 1.4 atatat (int)sizeof(long) * 2 + 0, "Start", 203 1.4 atatat (int)sizeof(int) * 2 - 1, "Size "); 204 1.1 atatat #endif 205 1.4 atatat if (print_all) 206 1.4 atatat printf("%-*s %-*s %*s %-*s rwxpc RWX I/W/A Dev %*s" 207 1.4 atatat " - File\n", 208 1.4 atatat (int)sizeof(long) * 2, "Start", 209 1.4 atatat (int)sizeof(long) * 2, "End", 210 1.4 atatat (int)sizeof(int) * 2, "Size ", 211 1.4 atatat (int)sizeof(long) * 2, "Offset", 212 1.4 atatat (int)sizeof(int) * 2, "Inode"); 213 1.4 atatat } 214 1.1 atatat 215 1.1 atatat /* these are the "sub entries" */ 216 1.57 mlelstv if (tree) 217 1.57 mlelstv total = dump_vm_map_tree(kd, proc, vmspace, 218 1.57 mlelstv vm_map, vm_map_entry); 219 1.57 mlelstv else 220 1.57 mlelstv total = dump_vm_map_list(kd, proc, vmspace, 221 1.57 mlelstv header, vm_map_entry); 222 1.57 mlelstv 223 1.57 mlelstv /* 224 1.57 mlelstv * we're not recursing into a submap, so print totals 225 1.57 mlelstv */ 226 1.57 mlelstv if (recurse < 2) { 227 1.57 mlelstv if (print_solaris) 228 1.57 mlelstv printf("%-*s %8luK\n", 229 1.57 mlelstv (int)sizeof(void *) * 2 - 2, " total", 230 1.57 mlelstv (unsigned long)total); 231 1.57 mlelstv if (print_all) 232 1.57 mlelstv printf("%-*s %9luk\n", 233 1.57 mlelstv (int)sizeof(void *) * 4 - 1, " total", 234 1.57 mlelstv (unsigned long)total); 235 1.57 mlelstv } 236 1.57 mlelstv } 237 1.57 mlelstv 238 1.57 mlelstv size_t 239 1.57 mlelstv dump_vm_map_node(kvm_t *kd, int lvl, struct kinfo_proc2 *proc, 240 1.57 mlelstv struct kbit *vmspace, struct kbit *vm_map_entry, 241 1.57 mlelstv struct vm_map_entry *node) 242 1.57 mlelstv { 243 1.57 mlelstv struct vm_map_entry *left, *right; 244 1.57 mlelstv size_t total; 245 1.57 mlelstv u_long addr; 246 1.57 mlelstv 247 1.57 mlelstv if (node == NULL) 248 1.57 mlelstv return 0; 249 1.57 mlelstv 250 1.57 mlelstv total = 0; 251 1.57 mlelstv addr = (u_long)node; 252 1.57 mlelstv A(vm_map_entry) = addr; 253 1.57 mlelstv S(vm_map_entry) = sizeof(struct vm_map_entry); 254 1.57 mlelstv KDEREF(kd, vm_map_entry); 255 1.57 mlelstv 256 1.57 mlelstv left = (struct vm_map_entry *)D(vm_map_entry, vm_map_entry)->rb_node.rb_left; 257 1.57 mlelstv right = (struct vm_map_entry *)D(vm_map_entry, vm_map_entry)->rb_node.rb_right; 258 1.57 mlelstv 259 1.57 mlelstv total += dump_vm_map_entry(kd, proc, vmspace, vm_map_entry, 0); 260 1.57 mlelstv 261 1.57 mlelstv depth += 2; 262 1.57 mlelstv 263 1.57 mlelstv total += dump_vm_map_node(kd, lvl+1, proc, vmspace, vm_map_entry, left); 264 1.57 mlelstv total += dump_vm_map_node(kd, lvl+1, proc, vmspace, vm_map_entry, right); 265 1.57 mlelstv 266 1.57 mlelstv depth -= 2; 267 1.57 mlelstv 268 1.57 mlelstv return total; 269 1.57 mlelstv } 270 1.57 mlelstv 271 1.57 mlelstv size_t 272 1.57 mlelstv dump_vm_map_tree(kvm_t *kd, struct kinfo_proc2 *proc, 273 1.57 mlelstv struct kbit *vmspace, struct kbit *vm_map, struct kbit *vm_map_entry) 274 1.57 mlelstv { 275 1.57 mlelstv struct vm_map_entry *root; 276 1.57 mlelstv u_long addr; 277 1.57 mlelstv 278 1.57 mlelstv /* these are the "sub entries" */ 279 1.57 mlelstv root = (struct vm_map_entry *)D(vm_map, vm_map)->rb_tree.rbt_root; 280 1.57 mlelstv 281 1.57 mlelstv addr = (u_long)root; 282 1.57 mlelstv A(vm_map_entry) = addr; 283 1.57 mlelstv S(vm_map_entry) = sizeof(struct vm_map_entry); 284 1.57 mlelstv KDEREF(kd, vm_map_entry); 285 1.57 mlelstv 286 1.57 mlelstv depth = 0; 287 1.57 mlelstv 288 1.57 mlelstv return dump_vm_map_node(kd, 0, proc, vmspace, vm_map_entry, root); 289 1.57 mlelstv } 290 1.57 mlelstv 291 1.57 mlelstv size_t 292 1.57 mlelstv dump_vm_map_list(kvm_t *kd, struct kinfo_proc2 *proc, 293 1.57 mlelstv struct kbit *vmspace, struct kbit *header, struct kbit *vm_map_entry) 294 1.57 mlelstv { 295 1.57 mlelstv struct vm_map_entry *last, *next; 296 1.57 mlelstv size_t total; 297 1.57 mlelstv u_long addr, end; 298 1.57 mlelstv 299 1.1 atatat total = 0; 300 1.4 atatat next = D(header, vm_map_entry)->next; 301 1.1 atatat last = P(header); 302 1.10 atatat end = 0; 303 1.1 atatat 304 1.4 atatat while (next != 0 && next != last) { 305 1.4 atatat addr = (u_long)next; 306 1.1 atatat A(vm_map_entry) = addr; 307 1.1 atatat S(vm_map_entry) = sizeof(struct vm_map_entry); 308 1.1 atatat KDEREF(kd, vm_map_entry); 309 1.4 atatat next = D(vm_map_entry, vm_map_entry)->next; 310 1.10 atatat 311 1.10 atatat if (end == 0) 312 1.10 atatat end = D(vm_map_entry, vm_map_entry)->start; 313 1.10 atatat else if (verbose > 1 && 314 1.10 atatat end != D(vm_map_entry, vm_map_entry)->start) 315 1.14 atatat printf("%*s[%lu pages / %luK]\n", indent(2), "", 316 1.14 atatat (D(vm_map_entry, vm_map_entry)->start - end) / 317 1.14 atatat page_size, 318 1.14 atatat (D(vm_map_entry, vm_map_entry)->start - end) / 319 1.14 atatat 1024); 320 1.40 yamt total += dump_vm_map_entry(kd, proc, vmspace, vm_map_entry, 0); 321 1.10 atatat 322 1.10 atatat end = D(vm_map_entry, vm_map_entry)->end; 323 1.1 atatat } 324 1.1 atatat 325 1.57 mlelstv return total; 326 1.1 atatat } 327 1.1 atatat 328 1.15 atatat size_t 329 1.40 yamt dump_vm_map_entry(kvm_t *kd, struct kinfo_proc2 *proc, struct kbit *vmspace, 330 1.15 atatat struct kbit *vm_map_entry, int ishead) 331 1.1 atatat { 332 1.1 atatat struct kbit kbit[3]; 333 1.1 atatat struct kbit *uvm_obj, *vp, *vfs; 334 1.1 atatat struct vm_map_entry *vme; 335 1.1 atatat size_t sz; 336 1.1 atatat char *name; 337 1.1 atatat dev_t dev; 338 1.1 atatat ino_t inode; 339 1.1 atatat 340 1.21 atatat if (S(vm_map_entry) == (size_t)-1) { 341 1.15 atatat heapfound = 1; 342 1.15 atatat S(vm_map_entry) = sizeof(struct vm_map_entry); 343 1.15 atatat KDEREF(kd, vm_map_entry); 344 1.15 atatat } 345 1.15 atatat 346 1.1 atatat uvm_obj = &kbit[0]; 347 1.1 atatat vp = &kbit[1]; 348 1.1 atatat vfs = &kbit[2]; 349 1.1 atatat 350 1.1 atatat A(uvm_obj) = 0; 351 1.1 atatat A(vp) = 0; 352 1.1 atatat A(vfs) = 0; 353 1.1 atatat 354 1.1 atatat vme = D(vm_map_entry, vm_map_entry); 355 1.1 atatat 356 1.1 atatat if ((ishead && (debug & PRINT_VM_MAP_HEADER)) || 357 1.1 atatat (!ishead && (debug & PRINT_VM_MAP_ENTRY))) { 358 1.4 atatat printf("%*s%s %p = {", indent(2), "", 359 1.4 atatat ishead ? "vm_map.header" : "vm_map_entry", 360 1.1 atatat P(vm_map_entry)); 361 1.1 atatat printf(" prev = %p,", vme->prev); 362 1.1 atatat printf(" next = %p,\n", vme->next); 363 1.44 uebayasi printf("%*s start = %#"PRIxVADDR",", indent(2), "", vme->start); 364 1.44 uebayasi printf(" end = %#"PRIxVADDR",", vme->end); 365 1.1 atatat printf(" object.uvm_obj/sub_map = %p,\n", vme->object.uvm_obj); 366 1.57 mlelstv printf("%*s gap = %#"PRIxVSIZE",", indent(2), "", vme->gap); 367 1.57 mlelstv printf(" maxgap = %#"PRIxVSIZE",\n", vme->maxgap); 368 1.8 thorpej printf("%*s offset = %" PRIx64 ",", indent(2), "", 369 1.8 thorpej vme->offset); 370 1.53 kamil printf(" etype = %#x <%s%s%s%s >,", vme->etype, 371 1.11 atatat UVM_ET_ISOBJ(vme) ? " OBJ" : "", 372 1.11 atatat UVM_ET_ISSUBMAP(vme) ? " SUBMAP" : "", 373 1.11 atatat UVM_ET_ISCOPYONWRITE(vme) ? " COW" : "", 374 1.11 atatat UVM_ET_ISNEEDSCOPY(vme) ? " NEEDSCOPY" : ""); 375 1.53 kamil printf(" protection = %#x,\n", vme->protection); 376 1.53 kamil printf("%*s max_protection = %#x,", indent(2), "", 377 1.4 atatat vme->max_protection); 378 1.1 atatat printf(" inheritance = %d,", vme->inheritance); 379 1.1 atatat printf(" wired_count = %d,\n", vme->wired_count); 380 1.53 kamil printf("%*s aref = { ar_pageoff = %#x, ar_amap = %p },", 381 1.6 atatat indent(2), "", vme->aref.ar_pageoff, vme->aref.ar_amap); 382 1.6 atatat printf(" advice = %d,\n", vme->advice); 383 1.53 kamil printf("%*s flags = %#x <%s%s%s > }\n", indent(2), "", 384 1.6 atatat vme->flags, 385 1.24 yamt vme->flags & UVM_MAP_KERNEL ? " KERNEL" : "", 386 1.48 para vme->flags & UVM_MAP_STATIC ? " STATIC" : "", 387 1.22 matt vme->flags & UVM_MAP_NOMERGE ? " NOMERGE" : ""); 388 1.1 atatat } 389 1.1 atatat 390 1.14 atatat if ((debug & PRINT_VM_AMAP) && (vme->aref.ar_amap != NULL)) { 391 1.14 atatat struct kbit akbit, *amap; 392 1.14 atatat 393 1.14 atatat amap = &akbit; 394 1.14 atatat P(amap) = vme->aref.ar_amap; 395 1.14 atatat S(amap) = sizeof(struct vm_amap); 396 1.14 atatat KDEREF(kd, amap); 397 1.40 yamt dump_amap(kd, amap); 398 1.14 atatat } 399 1.14 atatat 400 1.1 atatat if (ishead) 401 1.1 atatat return (0); 402 1.1 atatat 403 1.1 atatat A(vp) = 0; 404 1.1 atatat A(uvm_obj) = 0; 405 1.1 atatat 406 1.1 atatat if (vme->object.uvm_obj != NULL) { 407 1.1 atatat P(uvm_obj) = vme->object.uvm_obj; 408 1.1 atatat S(uvm_obj) = sizeof(struct uvm_object); 409 1.1 atatat KDEREF(kd, uvm_obj); 410 1.1 atatat if (UVM_ET_ISOBJ(vme) && 411 1.1 atatat UVM_OBJ_IS_VNODE(D(uvm_obj, uvm_object))) { 412 1.1 atatat P(vp) = P(uvm_obj); 413 1.1 atatat S(vp) = sizeof(struct vnode); 414 1.1 atatat KDEREF(kd, vp); 415 1.1 atatat } 416 1.1 atatat } 417 1.1 atatat 418 1.19 fvdl A(vfs) = 0; 419 1.1 atatat 420 1.1 atatat if (P(vp) != NULL && D(vp, vnode)->v_mount != NULL) { 421 1.1 atatat P(vfs) = D(vp, vnode)->v_mount; 422 1.1 atatat S(vfs) = sizeof(struct mount); 423 1.1 atatat KDEREF(kd, vfs); 424 1.1 atatat D(vp, vnode)->v_mount = D(vfs, mount); 425 1.1 atatat } 426 1.1 atatat 427 1.1 atatat /* 428 1.1 atatat * dig out the device number and inode number from certain 429 1.1 atatat * file system types. 430 1.1 atatat */ 431 1.1 atatat #define V_DATA_IS(vp, type, d, i) do { \ 432 1.1 atatat struct kbit data; \ 433 1.1 atatat P(&data) = D(vp, vnode)->v_data; \ 434 1.1 atatat S(&data) = sizeof(*D(&data, type)); \ 435 1.1 atatat KDEREF(kd, &data); \ 436 1.1 atatat dev = D(&data, type)->d; \ 437 1.1 atatat inode = D(&data, type)->i; \ 438 1.1 atatat } while (0/*CONSTCOND*/) 439 1.1 atatat 440 1.1 atatat dev = 0; 441 1.1 atatat inode = 0; 442 1.1 atatat 443 1.1 atatat if (A(vp) && 444 1.1 atatat D(vp, vnode)->v_type == VREG && 445 1.1 atatat D(vp, vnode)->v_data != NULL) { 446 1.1 atatat switch (D(vp, vnode)->v_tag) { 447 1.1 atatat case VT_UFS: 448 1.1 atatat case VT_LFS: 449 1.1 atatat case VT_EXT2FS: 450 1.1 atatat V_DATA_IS(vp, inode, i_dev, i_number); 451 1.1 atatat break; 452 1.1 atatat case VT_ISOFS: 453 1.1 atatat V_DATA_IS(vp, iso_node, i_dev, i_number); 454 1.1 atatat break; 455 1.39 ad default: 456 1.1 atatat break; 457 1.1 atatat } 458 1.1 atatat } 459 1.1 atatat 460 1.1 atatat name = findname(kd, vmspace, vm_map_entry, vp, vfs, uvm_obj); 461 1.1 atatat 462 1.1 atatat if (print_map) { 463 1.47 tsutsui printf("%*s%#"PRIxVADDR" %#"PRIxVADDR" %c%c%c %c%c%c %s %s %d %d %d", 464 1.4 atatat indent(2), "", 465 1.1 atatat vme->start, vme->end, 466 1.1 atatat (vme->protection & VM_PROT_READ) ? 'r' : '-', 467 1.1 atatat (vme->protection & VM_PROT_WRITE) ? 'w' : '-', 468 1.1 atatat (vme->protection & VM_PROT_EXECUTE) ? 'x' : '-', 469 1.1 atatat (vme->max_protection & VM_PROT_READ) ? 'r' : '-', 470 1.1 atatat (vme->max_protection & VM_PROT_WRITE) ? 'w' : '-', 471 1.1 atatat (vme->max_protection & VM_PROT_EXECUTE) ? 'x' : '-', 472 1.12 atatat UVM_ET_ISCOPYONWRITE(vme) ? "COW" : "NCOW", 473 1.12 atatat UVM_ET_ISNEEDSCOPY(vme) ? "NC" : "NNC", 474 1.1 atatat vme->inheritance, vme->wired_count, 475 1.1 atatat vme->advice); 476 1.1 atatat if (verbose) { 477 1.1 atatat if (inode) 478 1.42 christos printf(" %llu,%llu %llu", 479 1.42 christos (unsigned long long)major(dev), 480 1.42 christos (unsigned long long)minor(dev), 481 1.27 christos (unsigned long long)inode); 482 1.1 atatat if (name[0]) 483 1.1 atatat printf(" %s", name); 484 1.1 atatat } 485 1.1 atatat printf("\n"); 486 1.1 atatat } 487 1.1 atatat 488 1.4 atatat if (print_maps) { 489 1.44 uebayasi printf("%*s%0*"PRIxVADDR"-%0*"PRIxVADDR" %c%c%c%c %0*" PRIx64 " %02llx:%02llx %llu %s\n", 490 1.4 atatat indent(2), "", 491 1.1 atatat (int)sizeof(void *) * 2, vme->start, 492 1.1 atatat (int)sizeof(void *) * 2, vme->end, 493 1.1 atatat (vme->protection & VM_PROT_READ) ? 'r' : '-', 494 1.1 atatat (vme->protection & VM_PROT_WRITE) ? 'w' : '-', 495 1.1 atatat (vme->protection & VM_PROT_EXECUTE) ? 'x' : '-', 496 1.12 atatat UVM_ET_ISCOPYONWRITE(vme) ? 'p' : 's', 497 1.1 atatat (int)sizeof(void *) * 2, 498 1.8 thorpej vme->offset, 499 1.42 christos (unsigned long long)major(dev), 500 1.42 christos (unsigned long long)minor(dev), 501 1.42 christos (unsigned long long)inode, 502 1.3 atatat (name[0] != ' ') || verbose ? name : ""); 503 1.4 atatat } 504 1.1 atatat 505 1.1 atatat if (print_ddb) { 506 1.53 kamil printf("%*s - %p: %#"PRIxVADDR"->%#"PRIxVADDR": obj=%p/%#" PRIx64 ", amap=%p/%d\n", 507 1.4 atatat indent(2), "", 508 1.1 atatat P(vm_map_entry), vme->start, vme->end, 509 1.8 thorpej vme->object.uvm_obj, vme->offset, 510 1.1 atatat vme->aref.ar_amap, vme->aref.ar_pageoff); 511 1.4 atatat printf("\t%*ssubmap=%c, cow=%c, nc=%c, prot(max)=%d/%d, inh=%d, " 512 1.1 atatat "wc=%d, adv=%d\n", 513 1.4 atatat indent(2), "", 514 1.11 atatat UVM_ET_ISSUBMAP(vme) ? 'T' : 'F', 515 1.11 atatat UVM_ET_ISCOPYONWRITE(vme) ? 'T' : 'F', 516 1.11 atatat UVM_ET_ISNEEDSCOPY(vme) ? 'T' : 'F', 517 1.1 atatat vme->protection, vme->max_protection, 518 1.1 atatat vme->inheritance, vme->wired_count, vme->advice); 519 1.3 atatat if (verbose) { 520 1.4 atatat printf("\t%*s", indent(2), ""); 521 1.3 atatat if (inode) 522 1.42 christos printf("(dev=%llu,%llu ino=%llu [%s] [%p])\n", 523 1.42 christos (unsigned long long)major(dev), 524 1.42 christos (unsigned long long)minor(dev), 525 1.27 christos (unsigned long long)inode, name, P(vp)); 526 1.3 atatat else if (name[0] == ' ') 527 1.4 atatat printf("(%s)\n", &name[2]); 528 1.3 atatat else 529 1.4 atatat printf("(%s)\n", name); 530 1.3 atatat } 531 1.1 atatat } 532 1.1 atatat 533 1.1 atatat sz = 0; 534 1.1 atatat if (print_solaris) { 535 1.1 atatat char prot[30]; 536 1.1 atatat 537 1.1 atatat prot[0] = '\0'; 538 1.1 atatat prot[1] = '\0'; 539 1.1 atatat if (vme->protection & VM_PROT_READ) 540 1.17 itojun strlcat(prot, "/read", sizeof(prot)); 541 1.1 atatat if (vme->protection & VM_PROT_WRITE) 542 1.17 itojun strlcat(prot, "/write", sizeof(prot)); 543 1.1 atatat if (vme->protection & VM_PROT_EXECUTE) 544 1.17 itojun strlcat(prot, "/exec", sizeof(prot)); 545 1.1 atatat 546 1.1 atatat sz = (size_t)((vme->end - vme->start) / 1024); 547 1.4 atatat printf("%*s%0*lX %6luK %-15s %s\n", 548 1.4 atatat indent(2), "", 549 1.1 atatat (int)sizeof(void *) * 2, 550 1.1 atatat (unsigned long)vme->start, 551 1.1 atatat (unsigned long)sz, 552 1.1 atatat &prot[1], 553 1.1 atatat name); 554 1.1 atatat } 555 1.1 atatat 556 1.1 atatat if (print_all) { 557 1.1 atatat sz = (size_t)((vme->end - vme->start) / 1024); 558 1.56 chs printf("%*s%0*"PRIxVADDR"-%0*"PRIxVADDR" %7luk %0*" PRIx64 " %c%c%c%c%c (%c%c%c) %d/%d/%d %02llu:%02llu %7llu - %s\n", 559 1.4 atatat indent(2), "", 560 1.1 atatat (int)sizeof(void *) * 2, 561 1.1 atatat vme->start, 562 1.1 atatat (int)sizeof(void *) * 2, 563 1.1 atatat vme->end - (vme->start != vme->end ? 1 : 0), 564 1.1 atatat (unsigned long)sz, 565 1.1 atatat (int)sizeof(void *) * 2, 566 1.8 thorpej vme->offset, 567 1.1 atatat (vme->protection & VM_PROT_READ) ? 'r' : '-', 568 1.1 atatat (vme->protection & VM_PROT_WRITE) ? 'w' : '-', 569 1.1 atatat (vme->protection & VM_PROT_EXECUTE) ? 'x' : '-', 570 1.12 atatat UVM_ET_ISCOPYONWRITE(vme) ? 'p' : 's', 571 1.12 atatat UVM_ET_ISNEEDSCOPY(vme) ? '+' : '-', 572 1.1 atatat (vme->max_protection & VM_PROT_READ) ? 'r' : '-', 573 1.1 atatat (vme->max_protection & VM_PROT_WRITE) ? 'w' : '-', 574 1.1 atatat (vme->max_protection & VM_PROT_EXECUTE) ? 'x' : '-', 575 1.1 atatat vme->inheritance, 576 1.1 atatat vme->wired_count, 577 1.1 atatat vme->advice, 578 1.42 christos (unsigned long long)major(dev), 579 1.42 christos (unsigned long long)minor(dev), 580 1.42 christos (unsigned long long)inode, 581 1.56 chs name); 582 1.1 atatat } 583 1.1 atatat 584 1.1 atatat /* no access allowed, don't count space */ 585 1.1 atatat if ((vme->protection & rwx) == 0) 586 1.1 atatat sz = 0; 587 1.1 atatat 588 1.11 atatat if (recurse && UVM_ET_ISSUBMAP(vme)) { 589 1.7 atatat struct kbit mkbit, *submap; 590 1.4 atatat 591 1.4 atatat recurse++; 592 1.7 atatat submap = &mkbit; 593 1.4 atatat P(submap) = vme->object.sub_map; 594 1.4 atatat S(submap) = sizeof(*vme->object.sub_map); 595 1.4 atatat KDEREF(kd, submap); 596 1.40 yamt dump_vm_map(kd, proc, vmspace, submap, "submap"); 597 1.4 atatat recurse--; 598 1.4 atatat } 599 1.4 atatat 600 1.1 atatat return (sz); 601 1.14 atatat } 602 1.14 atatat 603 1.15 atatat void 604 1.40 yamt dump_amap(kvm_t *kd, struct kbit *amap) 605 1.14 atatat { 606 1.14 atatat struct vm_anon **am_anon; 607 1.14 atatat int *am_slots; 608 1.14 atatat int *am_bckptr; 609 1.14 atatat int *am_ppref; 610 1.43 lukem size_t l; 611 1.43 lukem int i, r, e; 612 1.15 atatat 613 1.21 atatat if (S(amap) == (size_t)-1) { 614 1.15 atatat heapfound = 1; 615 1.16 atatat S(amap) = sizeof(struct vm_amap); 616 1.15 atatat KDEREF(kd, amap); 617 1.15 atatat } 618 1.14 atatat 619 1.31 yamt printf("%*s amap %p = { am_ref = %d, " 620 1.53 kamil "am_flags = %#x,\n" 621 1.14 atatat "%*s am_maxslot = %d, am_nslot = %d, am_nused = %d, " 622 1.14 atatat "am_slots = %p,\n" 623 1.14 atatat "%*s am_bckptr = %p, am_anon = %p, am_ppref = %p }\n", 624 1.14 atatat indent(2), "", 625 1.14 atatat P(amap), 626 1.14 atatat D(amap, amap)->am_ref, 627 1.14 atatat D(amap, amap)->am_flags, 628 1.14 atatat indent(2), "", 629 1.14 atatat D(amap, amap)->am_maxslot, 630 1.14 atatat D(amap, amap)->am_nslot, 631 1.14 atatat D(amap, amap)->am_nused, 632 1.14 atatat D(amap, amap)->am_slots, 633 1.14 atatat indent(2), "", 634 1.14 atatat D(amap, amap)->am_bckptr, 635 1.14 atatat D(amap, amap)->am_anon, 636 1.14 atatat D(amap, amap)->am_ppref); 637 1.14 atatat 638 1.14 atatat if (!(debug & DUMP_VM_AMAP_DATA)) 639 1.14 atatat return; 640 1.14 atatat 641 1.14 atatat /* 642 1.14 atatat * Assume that sizeof(struct vm_anon *) >= sizeof(size_t) and 643 1.14 atatat * allocate that amount of space. 644 1.14 atatat */ 645 1.52 christos am_anon = ecalloc(D(amap, amap)->am_maxslot, sizeof(*am_anon)); 646 1.52 christos l = D(amap, amap)->am_maxslot * sizeof(*am_anon); 647 1.14 atatat _KDEREF(kd, (u_long)D(amap, amap)->am_anon, am_anon, l); 648 1.14 atatat 649 1.52 christos l = D(amap, amap)->am_maxslot * sizeof(*am_bckptr); 650 1.52 christos am_bckptr = ecalloc(D(amap, amap)->am_maxslot, sizeof(*am_bckptr)); 651 1.14 atatat _KDEREF(kd, (u_long)D(amap, amap)->am_bckptr, am_bckptr, l); 652 1.14 atatat 653 1.52 christos l = D(amap, amap)->am_maxslot * sizeof(*am_slots); 654 1.52 christos am_slots = ecalloc(D(amap, amap)->am_maxslot, sizeof(*am_slots)); 655 1.14 atatat _KDEREF(kd, (u_long)D(amap, amap)->am_slots, am_slots, l); 656 1.14 atatat 657 1.14 atatat if (D(amap, amap)->am_ppref != NULL && 658 1.14 atatat D(amap, amap)->am_ppref != PPREF_NONE) { 659 1.52 christos am_ppref = ecalloc( 660 1.52 christos D(amap, amap)->am_maxslot, sizeof(*am_ppref)); 661 1.52 christos l = D(amap, amap)->am_maxslot * sizeof(*am_ppref); 662 1.14 atatat _KDEREF(kd, (u_long)D(amap, amap)->am_ppref, am_ppref, l); 663 1.14 atatat } else { 664 1.14 atatat am_ppref = NULL; 665 1.14 atatat } 666 1.14 atatat 667 1.14 atatat printf(" page# %9s %8s", "am_bckptr", "am_slots"); 668 1.14 atatat if (am_ppref) 669 1.14 atatat printf(" %8s ", "am_ppref"); 670 1.14 atatat printf(" %10s\n", "am_anon"); 671 1.14 atatat 672 1.21 atatat l = r = 0; 673 1.14 atatat e = verbose > 1 ? D(amap, amap)->am_maxslot : D(amap, amap)->am_nslot; 674 1.14 atatat for (i = 0; i < e; i++) { 675 1.14 atatat printf(" %4lx", (unsigned long)i); 676 1.14 atatat 677 1.14 atatat if (am_anon[i] || verbose > 1) 678 1.14 atatat printf(" %8x", am_bckptr[i]); 679 1.14 atatat else 680 1.14 atatat printf(" %8s", "-"); 681 1.14 atatat 682 1.14 atatat if (i < D(amap, amap)->am_nused || verbose > 1) 683 1.14 atatat printf(" %8x", am_slots[i]); 684 1.14 atatat else 685 1.14 atatat printf(" %8s", "-"); 686 1.14 atatat 687 1.14 atatat if (am_ppref) { 688 1.14 atatat if (l == 0 || r || verbose > 1) 689 1.14 atatat printf(" %8d", am_ppref[i]); 690 1.14 atatat else 691 1.14 atatat printf(" %8s", "-"); 692 1.14 atatat r = 0; 693 1.14 atatat if (l == 0) { 694 1.14 atatat if (am_ppref[i] > 0) { 695 1.14 atatat r = am_ppref[i] - 1; 696 1.14 atatat l = 1; 697 1.14 atatat } else { 698 1.14 atatat r = -am_ppref[i] - 1; 699 1.14 atatat l = am_ppref[i + 1]; 700 1.14 atatat } 701 1.14 atatat printf(" (%4ld @ %4ld)", (long)l, (long)r); 702 1.14 atatat r = (l > 1) ? 1 : 0; 703 1.14 atatat } 704 1.14 atatat else 705 1.14 atatat printf(" "); 706 1.14 atatat l--; 707 1.14 atatat } 708 1.14 atatat 709 1.43 lukem dump_vm_anon(kd, am_anon, i); 710 1.14 atatat } 711 1.14 atatat 712 1.14 atatat free(am_anon); 713 1.14 atatat free(am_bckptr); 714 1.14 atatat free(am_slots); 715 1.14 atatat if (am_ppref) 716 1.14 atatat free(am_ppref); 717 1.14 atatat } 718 1.14 atatat 719 1.14 atatat static void 720 1.14 atatat dump_vm_anon(kvm_t *kd, struct vm_anon **alist, int i) 721 1.14 atatat { 722 1.14 atatat 723 1.14 atatat printf(" %10p", alist[i]); 724 1.14 atatat 725 1.14 atatat if (debug & PRINT_VM_ANON) { 726 1.14 atatat struct kbit kbit, *anon = &kbit; 727 1.14 atatat 728 1.14 atatat A(anon) = (u_long)alist[i]; 729 1.14 atatat S(anon) = sizeof(struct vm_anon); 730 1.14 atatat if (A(anon) == 0) { 731 1.14 atatat printf(" = { }\n"); 732 1.14 atatat return; 733 1.14 atatat } 734 1.14 atatat else 735 1.14 atatat KDEREF(kd, anon); 736 1.14 atatat 737 1.46 mrg printf(" = { an_ref = %"PRIuPTR", an_page = %p, an_swslot = %d }", 738 1.31 yamt D(anon, anon)->an_ref, D(anon, anon)->an_page, 739 1.31 yamt D(anon, anon)->an_swslot); 740 1.14 atatat } 741 1.14 atatat 742 1.14 atatat printf("\n"); 743 1.1 atatat } 744 1.1 atatat 745 1.10 atatat static char* 746 1.1 atatat findname(kvm_t *kd, struct kbit *vmspace, 747 1.1 atatat struct kbit *vm_map_entry, struct kbit *vp, 748 1.1 atatat struct kbit *vfs, struct kbit *uvm_obj) 749 1.1 atatat { 750 1.1 atatat static char buf[1024], *name; 751 1.1 atatat struct vm_map_entry *vme; 752 1.1 atatat size_t l; 753 1.55 ad int rv; 754 1.1 atatat 755 1.1 atatat vme = D(vm_map_entry, vm_map_entry); 756 1.1 atatat 757 1.1 atatat if (UVM_ET_ISOBJ(vme)) { 758 1.1 atatat if (A(vfs)) { 759 1.1 atatat l = (unsigned)strlen(D(vfs, mount)->mnt_stat.f_mntonname); 760 1.55 ad rv = search_cache(kd, P(vp), &name, buf, sizeof(buf)); 761 1.55 ad switch (rv) { 762 1.1 atatat case 0: /* found something */ 763 1.1 atatat name--; 764 1.1 atatat *name = '/'; 765 1.1 atatat /*FALLTHROUGH*/ 766 1.1 atatat case 2: /* found nothing */ 767 1.9 thorpej name -= 5; 768 1.9 thorpej memcpy(name, " -?- ", (size_t)5); 769 1.1 atatat name -= l; 770 1.1 atatat memcpy(name, 771 1.1 atatat D(vfs, mount)->mnt_stat.f_mntonname, l); 772 1.1 atatat break; 773 1.1 atatat case 1: /* all is well */ 774 1.1 atatat name--; 775 1.1 atatat *name = '/'; 776 1.1 atatat if (l != 1) { 777 1.1 atatat name -= l; 778 1.1 atatat memcpy(name, 779 1.1 atatat D(vfs, mount)->mnt_stat.f_mntonname, l); 780 1.1 atatat } 781 1.1 atatat break; 782 1.1 atatat } 783 1.1 atatat } 784 1.1 atatat else if (UVM_OBJ_IS_DEVICE(D(uvm_obj, uvm_object))) { 785 1.1 atatat struct kbit kdev; 786 1.1 atatat dev_t dev; 787 1.1 atatat 788 1.1 atatat P(&kdev) = P(uvm_obj); 789 1.1 atatat S(&kdev) = sizeof(struct uvm_device); 790 1.1 atatat KDEREF(kd, &kdev); 791 1.1 atatat dev = D(&kdev, uvm_device)->u_device; 792 1.1 atatat name = devname(dev, S_IFCHR); 793 1.1 atatat if (name != NULL) 794 1.1 atatat snprintf(buf, sizeof(buf), "/dev/%s", name); 795 1.1 atatat else 796 1.42 christos snprintf(buf, sizeof(buf), " [ device %llu,%llu ]", 797 1.42 christos (unsigned long long)major(dev), 798 1.42 christos (unsigned long long)minor(dev)); 799 1.1 atatat name = buf; 800 1.1 atatat } 801 1.43 lukem else if (UVM_OBJ_IS_AOBJ(D(uvm_obj, uvm_object))) { 802 1.43 lukem snprintf(buf, sizeof(buf), " [ uvm_aobj ]"); 803 1.43 lukem name = buf; 804 1.43 lukem } 805 1.43 lukem else if (UVM_OBJ_IS_UBCPAGER(D(uvm_obj, uvm_object))) { 806 1.43 lukem snprintf(buf, sizeof(buf), " [ ubc_pager ]"); 807 1.43 lukem name = buf; 808 1.43 lukem } 809 1.43 lukem else if (UVM_OBJ_IS_VNODE(D(uvm_obj, uvm_object))) { 810 1.43 lukem snprintf(buf, sizeof(buf), " [ ?VNODE? ]"); 811 1.43 lukem name = buf; 812 1.43 lukem } 813 1.1 atatat else { 814 1.1 atatat snprintf(buf, sizeof(buf), " [ ?? %p ?? ]", 815 1.1 atatat D(uvm_obj, uvm_object)->pgops); 816 1.1 atatat name = buf; 817 1.1 atatat } 818 1.1 atatat } 819 1.1 atatat 820 1.33 christos else if ((char *)D(vmspace, vmspace)->vm_maxsaddr <= 821 1.33 christos (char *)vme->start && 822 1.33 christos ((char *)D(vmspace, vmspace)->vm_maxsaddr + (size_t)maxssiz) >= 823 1.43 lukem (char *)vme->end) { 824 1.43 lukem snprintf(buf, sizeof(buf), " [ stack ]"); 825 1.43 lukem name = buf; 826 1.43 lukem } 827 1.1 atatat 828 1.13 atatat else if (!heapfound && 829 1.13 atatat (vme->protection & rwx) == rwx && 830 1.13 atatat vme->start >= (u_long)D(vmspace, vmspace)->vm_daddr) { 831 1.1 atatat heapfound = 1; 832 1.43 lukem snprintf(buf, sizeof(buf), " [ heap ]"); 833 1.43 lukem name = buf; 834 1.13 atatat } 835 1.13 atatat 836 1.13 atatat else if (UVM_ET_ISSUBMAP(vme)) { 837 1.13 atatat const char *sub = mapname(vme->object.sub_map); 838 1.13 atatat snprintf(buf, sizeof(buf), " [ %s ]", sub ? sub : "(submap)"); 839 1.13 atatat name = buf; 840 1.1 atatat } 841 1.1 atatat 842 1.43 lukem else { 843 1.43 lukem snprintf(buf, sizeof(buf), " [ anon ]"); 844 1.43 lukem name = buf; 845 1.43 lukem } 846 1.1 atatat 847 1.1 atatat return (name); 848 1.1 atatat } 849 1.1 atatat 850 1.10 atatat static int 851 1.55 ad search_cache(kvm_t *kd, struct vnode *vp, char **name, char *buf, size_t blen) 852 1.1 atatat { 853 1.1 atatat char *o, *e; 854 1.55 ad struct namecache nc; 855 1.55 ad struct vnode_impl vi; 856 1.55 ad u_long vip, ncp, ncp2; 857 1.57 mlelstv size_t nlen; 858 1.1 atatat 859 1.55 ad vip = (u_long)vp; 860 1.1 atatat e = &buf[blen - 1]; 861 1.1 atatat o = e; 862 1.55 ad ncp2 = 0; 863 1.1 atatat do { 864 1.55 ad /* Pull down vnode_impl for vnode. */ 865 1.55 ad _KDEREF(kd, vip, &vi, sizeof(vi)); 866 1.55 ad 867 1.55 ad /* From that, get first cached name for vnode. */ 868 1.55 ad ncp = (u_long)vi.vi_nc_list.tqh_first; 869 1.55 ad if (ncp != 0 && ncp != ncp2) { 870 1.55 ad /* Pull down the cache entry. */ 871 1.55 ad _KDEREF(kd, ncp, &nc, sizeof(nc)); 872 1.55 ad /* Done if own parent or at the root. */ 873 1.55 ad if ((u_long)nc.nc_dvp == vip || 874 1.55 ad (vi.vi_vnode.v_vflag & VV_ROOT) != 0) 875 1.1 atatat break; 876 1.55 ad /* Otherwise pull first NCHNAMLEN chars of name. */ 877 1.58 ad nlen = MIN(NC_NLEN(&nc), NCHNAMLEN); 878 1.57 mlelstv /* too small */ 879 1.57 mlelstv if ((size_t)(o - buf) < nlen + (o != e ? 1 : 0)) 880 1.57 mlelstv break; 881 1.1 atatat if (o != e) 882 1.1 atatat *(--o) = '/'; 883 1.57 mlelstv o -= nlen; 884 1.57 mlelstv memcpy(o, nc.nc_name, nlen); 885 1.55 ad vip = (u_long)nc.nc_dvp; 886 1.55 ad ncp2 = ncp; 887 1.55 ad } else 888 1.1 atatat break; 889 1.1 atatat } while (1/*CONSTCOND*/); 890 1.1 atatat *e = '\0'; 891 1.1 atatat *name = o; 892 1.1 atatat 893 1.1 atatat if (e == o) 894 1.1 atatat return (2); 895 1.1 atatat 896 1.55 ad return (vi.vi_vnode.v_vflag & VV_ROOT); 897 1.1 atatat } 898