6aa0591be7d6908040512cb8f9ff414e54263964
2 * Copyright (c) 2000 Dag-Erling Coïdan Smørgrav
3 * Copyright (c) 1999 Pierre Beyssac
4 * Copyright (c) 1993 Jan-Simon Pendry
6 * The Regents of the University of California. All rights reserved.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
41 * $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_misc.c,v 1.3.2.8 2001/06/25 19:46:47 pirzyk Exp $
42 * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_misc.c,v 1.19 2008/05/10 17:24:05 dillon Exp $
45 #include <sys/param.h>
46 #include <sys/blist.h>
47 #include <sys/kernel.h>
48 #include <sys/kinfo.h>
51 #include <sys/resourcevar.h>
52 #include <sys/systm.h>
54 #include <sys/vnode.h>
60 #include <vm/vm_map.h>
61 #include <vm/vm_param.h>
62 #include <vm/vm_object.h>
63 #include <vm/swap_pager.h>
64 #include <sys/vmmeter.h>
67 #include <machine/clock.h>
68 #include <machine/cputypes.h>
69 #include <machine/inttypes.h>
70 #include <machine/md_var.h>
71 #include <machine/vmparam.h>
73 #include "linprocfs.h"
75 #include "../../linux_ioctl.h"
76 #include "../../linux_mib.h"
79 * Various conversion macros
81 #define T2J(x) (((x) * 100) / (stathz ? stathz : hz)) /* ticks to jiffies */
82 #define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */
83 #define B2K(x) ((unsigned long)((x) >> 10)) /* bytes to kbytes */
84 #define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */
85 #define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */
88 linprocfs_domeminfo(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
92 char psbuf
[512]; /* XXX - conservative */
93 unsigned long memtotal
; /* total memory in bytes */
94 unsigned long memused
; /* used memory in bytes */
95 unsigned long memfree
; /* free memory in bytes */
96 unsigned long memshared
; /* shared memory ??? */
97 unsigned long buffers
, cached
; /* buffer / cache memory ??? */
98 unsigned long long swaptotal
; /* total swap space in bytes */
99 unsigned long long swapused
; /* used swap space in bytes */
100 unsigned long long swapfree
; /* free swap space in bytes */
103 if (uio
->uio_rw
!= UIO_READ
)
106 memtotal
= Maxmem
* PAGE_SIZE
;
108 * The correct thing here would be:
110 memfree = vmstats.v_free_count * PAGE_SIZE;
111 memused = memtotal - memfree;
113 * but it might mislead linux binaries into thinking there
114 * is very little memory left, so we cheat and tell them that
115 * all memory that isn't wired down is free.
117 memused
= vmstats
.v_wire_count
* PAGE_SIZE
;
118 memfree
= memtotal
- memused
;
119 if (swapblist
== NULL
) {
123 swaptotal
= swapblist
->bl_blocks
* 1024LL; /* XXX why 1024? */
124 swapfree
= (unsigned long long)swapblist
->bl_root
->u
.bmu_avail
* PAGE_SIZE
;
126 swapused
= swaptotal
- swapfree
;
128 for (object
= TAILQ_FIRST(&vm_object_list
); object
!= NULL
;
129 object
= TAILQ_NEXT(object
, object_list
)) {
130 if (object
->type
== OBJT_MARKER
)
132 if (object
->shadow_count
> 1)
133 memshared
+= object
->resident_page_count
;
135 memshared
*= PAGE_SIZE
;
137 * We'd love to be able to write:
141 * but bufspace is internal to vfs_bio.c and we don't feel
142 * like unstaticizing it just for linprocfs's sake.
145 cached
= vmstats
.v_cache_count
* PAGE_SIZE
;
149 " total: used: free: shared: buffers: cached:\n"
150 "Mem: %lu %lu %lu %lu %lu %lu\n"
151 "Swap: %llu %llu %llu\n"
152 "MemTotal: %9lu kB\n"
154 "MemShared:%9lu kB\n"
157 "SwapTotal:%9lu kB\n"
158 "SwapFree: %9lu kB\n",
159 memtotal
, memused
, memfree
, memshared
, buffers
, cached
,
160 swaptotal
, swapused
, swapfree
,
161 B2K(memtotal
), B2K(memfree
),
162 B2K(memshared
), B2K(buffers
), B2K(cached
),
163 B2K(swaptotal
), B2K(swapfree
));
165 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
169 linprocfs_docpuinfo(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
173 char psbuf
[512]; /* XXX - conservative */
177 extern char *cpu_model
; /* Yuck */
179 /* We default the flags to include all non-conflicting flags,
180 and the Intel versions of conflicting flags. Note the space
181 before each name; that is significant, and should be
184 static char *flags
[] = {
185 "fpu", "vme", "de", "pse", "tsc",
186 "msr", "pae", "mce", "cx8", "apic",
187 "sep", "sep", "mtrr", "pge", "mca",
188 "cmov", "pat", "pse36", "pn", "b19",
189 "b20", "b21", "mmxext", "mmx", "fxsr",
190 "xmm", "b26", "b27", "b28", "b29",
194 if (uio
->uio_rw
!= UIO_READ
)
221 "vendor_id\t: %.20s\n"
225 0, cpu_vendor
, class, cpu
, cpu_id
& 0xf);
230 if (!strcmp(cpu_vendor
, "AuthenticAMD") && (class < 6)) {
232 } else if (!strcmp(cpu_vendor
, "CyrixInstead")) {
236 for (i
= 0; i
< 32; i
++)
237 if (cpu_feature
& (1 << i
))
238 ps
+= ksprintf(ps
, " %s", flags
[i
]);
239 ps
+= ksprintf(ps
, "\n");
242 "cpu MHz\t\t: %d.%02d\n"
243 "bogomips\t: %d.%02d\n",
244 (int)((tsc_frequency
+ 4999) / 1000000),
245 (int)((tsc_frequency
+ 4999) / 10000) % 100,
246 (int)((tsc_frequency
+ 4999) / 1000000),
247 (int)((tsc_frequency
+ 4999) / 10000) % 100);
250 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
259 for (i
= 0; i
< ncpus
; ++i
) {
260 struct globaldata
*gd
= globaldata_find(i
);
261 count
+= *(unsigned int *)((char *)&gd
->gd_cnt
+ offset
);
267 linprocfs_dostat(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
275 "cpu %"PRIu64
" %"PRIu64
" %"PRIu64
" %"PRIu64
"\n"
282 T2J(cpu_time
.cp_user
),
283 T2J(cpu_time
.cp_nice
),
284 T2J(cpu_time
.cp_sys
/*+ cpu_time[CP_INTR]*/),
285 T2J(cpu_time
.cp_idle
),
286 cpucnt(offsetof(struct vmmeter
, v_vnodepgsin
)),
287 cpucnt(offsetof(struct vmmeter
, v_vnodepgsout
)),
288 cpucnt(offsetof(struct vmmeter
, v_swappgsin
)),
289 cpucnt(offsetof(struct vmmeter
, v_swappgsout
)),
290 cpucnt(offsetof(struct vmmeter
, v_intr
)),
291 cpucnt(offsetof(struct vmmeter
, v_swtch
)),
293 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
297 linprocfs_douptime(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
306 ps
+= ksprintf(ps
, "%ld.%02ld %"PRIu64
".%02"PRIu64
"\n",
307 tv
.tv_sec
, tv
.tv_usec
/ 10000,
308 T2S(cpu_time
.cp_idle
), T2J(cpu_time
.cp_idle
) % 100);
309 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
313 linprocfs_doversion(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
319 ps
= version
; /* XXX not entirely correct */
320 for (xlen
= 0; ps
[xlen
] != '\n'; ++xlen
)
323 return (uiomove_frombuf(ps
, xlen
, uio
));
326 #define B2P(x) ((x) >> PAGE_SHIFT) /* bytes to pages */
328 linprocfs_dostatm(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
331 char *ps
, psbuf
[1024];
332 struct kinfo_proc kp
;
334 fill_kinfo_proc(p
, &kp
);
337 ps
+= ksprintf(ps
, "%d", p
->p_pid
);
338 #define PS_ADD(name, fmt, arg) ps += ksprintf(ps, " " fmt, arg)
339 PS_ADD("", "%ju", B2P((uintmax_t)(kp
.kp_vm_tsize
+ kp
.kp_vm_dsize
+ kp
.kp_vm_ssize
)));
340 PS_ADD("", "%ju", (uintmax_t)kp
.kp_vm_rssize
);
341 PS_ADD("", "%ju", (uintmax_t)0); /* XXX */
342 PS_ADD("", "%ju", (uintmax_t)kp
.kp_vm_tsize
);
343 PS_ADD("", "%ju", (uintmax_t)kp
.kp_vm_dsize
);
344 PS_ADD("", "%ju", (uintmax_t)kp
.kp_vm_ssize
);
345 PS_ADD("", "%ju", (uintmax_t)0); /* XXX */
347 ps
+= ksprintf(ps
, "\n");
349 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
352 #define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */
354 linprocfs_doprocstat(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
357 vm_map_t map
= &p
->p_vmspace
->vm_map
;
358 vm_map_entry_t entry
;
359 vm_offset_t start
, end
;
360 char *ps
, psbuf
[1024];
361 struct kinfo_proc kp
;
363 fill_kinfo_proc(p
, &kp
);
367 vm_map_lock_read(map
);
368 for (entry
= map
->header
.next
; entry
!= &map
->header
;
369 entry
= entry
->next
) {
370 if (entry
->maptype
!= VM_MAPTYPE_NORMAL
&&
371 entry
->maptype
!= VM_MAPTYPE_VPAGETABLE
) {
374 /* Assuming that text is the first entry */
375 start
= entry
->start
;
378 vm_map_unlock_read(map
);
381 ps
+= ksprintf(ps
, "%d", p
->p_pid
);
382 #define PS_ADD(name, fmt, arg) ps += ksprintf(ps, " " fmt, arg)
383 PS_ADD("comm", "(%s)", p
->p_comm
);
384 PS_ADD("statr", "%c", '0'); /* XXX */
385 PS_ADD("ppid", "%d", p
->p_pptr
? p
->p_pptr
->p_pid
: 0);
386 PS_ADD("pgrp", "%d", p
->p_pgid
);
387 PS_ADD("session", "%d", p
->p_session
->s_sid
);
388 PS_ADD("tty", "%d", 0); /* XXX */
389 PS_ADD("tpgid", "%d", kp
.kp_tpgid
); /* XXX */
390 PS_ADD("flags", "%u", 0); /* XXX */
391 PS_ADD("minflt", "%lu", kp
.kp_ru
.ru_minflt
); /* XXX */
392 PS_ADD("cminflt", "%lu", kp
.kp_cru
.ru_minflt
); /* XXX */
393 PS_ADD("majflt", "%lu", kp
.kp_ru
.ru_majflt
); /* XXX */
394 PS_ADD("cmajflt", "%lu", kp
.kp_cru
.ru_majflt
); /* XXX */
395 PS_ADD("utime", "%d", T2J(tvtohz_high(&kp
.kp_ru
.ru_utime
))); /* XXX */
396 PS_ADD("stime", "%d", T2J(tvtohz_high(&kp
.kp_ru
.ru_stime
))); /* XXX */
397 PS_ADD("cutime", "%d", T2J(tvtohz_high(&kp
.kp_cru
.ru_utime
))); /* XXX */
398 PS_ADD("cstime", "%d", T2J(tvtohz_high(&kp
.kp_cru
.ru_stime
))); /* XXX */
399 PS_ADD("priority", "%d", 0); /* XXX */
400 PS_ADD("nice", "%d", kp
.kp_nice
);
401 PS_ADD("timeout", "%u", 0); /* XXX */
402 PS_ADD("itrealvalue", "%u", 0); /* XXX */
403 PS_ADD("starttime", "%d", T2J(tvtohz_high(&kp
.kp_start
))); /* XXX */
404 PS_ADD("vsize", "%ju", P2K((uintmax_t)(kp
.kp_vm_tsize
+ kp
.kp_vm_dsize
+ kp
.kp_vm_ssize
))); /* XXX: not sure */
405 PS_ADD("rss", "%ju", (uintmax_t)kp
.kp_vm_rssize
); /* XXX */
406 PS_ADD("rlim", "%lu", kp
.kp_ru
.ru_maxrss
); /* XXX */
407 PS_ADD("startcode", "%lu", start
); /* XXX */
408 PS_ADD("endcode", "%lu", end
); /* XXX */
409 PS_ADD("startstack", "%lu", (u_long
)p
->p_vmspace
->vm_minsaddr
); /* XXX */
410 PS_ADD("kstkesp", "%u", 0); /* XXX */
411 PS_ADD("kstkeip", "%u", 0); /* XXX */
412 PS_ADD("signal", "%d", 0); /* XXX */
413 PS_ADD("blocked", "%d", 0); /* XXX */
414 PS_ADD("sigignore", "%d", 0); /* XXX */
415 PS_ADD("sigcatch", "%d", 0); /* XXX */
416 PS_ADD("wchan", "%u", 0); /* XXX */
417 PS_ADD("nswap", "%lu", kp
.kp_ru
.ru_nswap
); /* XXX */
418 PS_ADD("cnswap", "%lu", kp
.kp_cru
.ru_nswap
); /* XXX */
419 PS_ADD("exitsignal", "%d", 0); /* XXX */
420 PS_ADD("processor", "%u", kp
.kp_lwp
.kl_cpuid
); /* XXX */
421 PS_ADD("rt_priority", "%u", 0); /* XXX */ /* >= 2.5.19 */
422 PS_ADD("policy", "%u", kp
.kp_nice
); /* XXX */ /* >= 2.5.19 */
424 ps
+= ksprintf(ps
, "\n");
426 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
430 * Map process state to descriptive letter. Note that this does not
431 * quite correspond to what Linux outputs, but it's close enough.
433 static char *state_str
[] = {
445 linprocfs_doprocstatus(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
448 char *ps
, psbuf
[1024];
454 if (p
->p_stat
> sizeof state_str
/ sizeof *state_str
)
455 state
= state_str
[0];
457 state
= state_str
[(int)p
->p_stat
];
459 #define PS_ADD ps += ksprintf
460 PS_ADD(ps
, "Name:\t%s\n", p
->p_comm
); /* XXX escape */
461 PS_ADD(ps
, "State:\t%s\n", state
);
466 PS_ADD(ps
, "Pid:\t%d\n", p
->p_pid
);
467 PS_ADD(ps
, "PPid:\t%d\n", p
->p_pptr
? p
->p_pptr
->p_pid
: 0);
468 PS_ADD(ps
, "Uid:\t%d %d %d %d\n", p
->p_ucred
->cr_ruid
,
470 p
->p_ucred
->cr_svuid
,
471 /* FreeBSD doesn't have fsuid */
473 PS_ADD(ps
, "Gid:\t%d %d %d %d\n", p
->p_ucred
->cr_rgid
,
475 p
->p_ucred
->cr_svgid
,
476 /* FreeBSD doesn't have fsgid */
478 PS_ADD(ps
, "Groups:\t");
479 for (i
= 0; i
< p
->p_ucred
->cr_ngroups
; i
++)
480 PS_ADD(ps
, "%d ", p
->p_ucred
->cr_groups
[i
]);
486 PS_ADD(ps
, "VmSize:\t%8lu kB\n", B2K(p
->p_vmspace
->vm_map
.size
));
487 PS_ADD(ps
, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */
488 /* XXX vm_rssize seems to always be zero, how can this be? */
489 PS_ADD(ps
, "VmRss:\t%8u kB\n", P2K(p
->p_vmspace
->vm_rssize
));
490 PS_ADD(ps
, "VmData:\t%8u kB\n", P2K(p
->p_vmspace
->vm_dsize
));
491 PS_ADD(ps
, "VmStk:\t%8u kB\n", P2K(p
->p_vmspace
->vm_ssize
));
492 PS_ADD(ps
, "VmExe:\t%8u kB\n", P2K(p
->p_vmspace
->vm_tsize
));
493 PS_ADD(ps
, "VmLib:\t%8u kB\n", P2K(0)); /* XXX */
498 * We support up to 128 signals, while Linux supports 32,
499 * but we only define 32 (the same 32 as Linux, to boot), so
500 * just show the lower 32 bits of each mask. XXX hack.
502 * NB: on certain platforms (Sparc at least) Linux actually
503 * supports 64 signals, but this code is a long way from
504 * running on anything but i386, so ignore that for now.
506 PS_ADD(ps
, "SigPnd:\t%08x\n", p
->p_siglist
.__bits
[0]);
507 PS_ADD(ps
, "SigBlk:\t%08x\n", 0); /* XXX */
508 PS_ADD(ps
, "SigIgn:\t%08x\n", p
->p_sigignore
.__bits
[0]);
509 PS_ADD(ps
, "SigCgt:\t%08x\n", p
->p_sigcatch
.__bits
[0]);
512 * Linux also prints the capability masks, but we don't have
513 * capabilities yet, and when we do get them they're likely to
514 * be meaningless to Linux programs, so we lie. XXX
516 PS_ADD(ps
, "CapInh:\t%016x\n", 0);
517 PS_ADD(ps
, "CapPrm:\t%016x\n", 0);
518 PS_ADD(ps
, "CapEff:\t%016x\n", 0);
521 return (uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
525 linprocfs_doloadavg(struct proc
*curp
, struct proc
*p
,
526 struct pfsnode
*pfs
, struct uio
*uio
)
528 char *ps
, psbuf
[512];
531 ps
+= ksprintf(ps
, "%d.%02d %d.%02d %d.%02d %d/%d %d\n",
532 (int)(averunnable
.ldavg
[0] / averunnable
.fscale
),
533 (int)(averunnable
.ldavg
[0] * 100 / averunnable
.fscale
% 100),
534 (int)(averunnable
.ldavg
[1] / averunnable
.fscale
),
535 (int)(averunnable
.ldavg
[1] * 100 / averunnable
.fscale
% 100),
536 (int)(averunnable
.ldavg
[2] / averunnable
.fscale
),
537 (int)(averunnable
.ldavg
[2] * 100 / averunnable
.fscale
% 100),
538 1, /* number of running tasks */
539 -1, /* number of tasks */
540 1 /* The last pid, just kidding */
542 return(uiomove_frombuf(psbuf
, ps
- psbuf
, uio
));
546 linprocfs_donetdev(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
550 char ifname
[16]; /* XXX LINUX_IFNAMSIZ */
554 sb
= sbuf_new_auto();
556 sbuf_printf(sb
, "%6s|%58s|%s\n%6s|%58s|%58s\n",
557 "Inter-", " Receive", " Transmit", " face",
558 "bytes packets errs drop fifo frame compressed",
559 "bytes packets errs drop fifo frame compressed");
562 TAILQ_FOREACH(ifp
, &ifnet
, if_link
) {
563 linux_ifname(ifp
, ifname
, sizeof ifname
);
564 sbuf_printf(sb
, "%6.6s:", ifname
);
565 sbuf_printf(sb
, "%8lu %7lu %4lu %4lu %4lu %5lu %10lu %9lu ",
566 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
567 sbuf_printf(sb
, "%8lu %7lu %4lu %4lu %4lu %5lu %7lu %10lu\n",
568 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
572 error
= uiomove_frombuf(sbuf_data(sb
), sbuf_len(sb
), uio
);
578 linprocfs_dodevices(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
585 linprocfs_doosrelease(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
590 osrelease
= linux_get_osrelease(curthread
);
591 return(uiomove_frombuf(osrelease
, strlen(osrelease
)+1, uio
));
595 linprocfs_doostype(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
600 osname
= linux_get_osname(curthread
);
601 return(uiomove_frombuf(osname
, strlen(osname
)+1, uio
));
605 linprocfs_dopidmax(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
610 ksnprintf(buf
, sizeof(buf
), "%d", PID_MAX
);
611 return(uiomove_frombuf(buf
, strlen(buf
)+1, uio
));
616 linprocfs_domaps(struct proc
*curp
, struct proc
*p
, struct pfsnode
*pfs
,
621 vm_map_t map
= &p
->p_vmspace
->vm_map
;
622 vm_map_entry_t entry
;
623 vm_ooffset_t off
= 0;
625 char *name
= "", *freename
= NULL
;
631 if (uio
->uio_rw
!= UIO_READ
)
634 if (uio
->uio_offset
!= 0)
638 vm_map_lock_read(map
);
639 for (entry
= map
->header
.next
;
640 ((uio
->uio_resid
> 0) && (entry
!= &map
->header
));
641 entry
= entry
->next
) {
642 vm_object_t obj
, tobj
, lobj
;
647 if (entry
->maptype
!= VM_MAPTYPE_NORMAL
&&
648 entry
->maptype
!= VM_MAPTYPE_VPAGETABLE
) {
652 * Use map->hint as a poor man's ripout detector.
655 ostart
= entry
->start
;
656 obj
= entry
->object
.vm_object
;
658 for( lobj
= tobj
= obj
; tobj
; tobj
= tobj
->backing_object
)
662 off
= IDX_TO_OFF(lobj
->size
);
663 if (lobj
->type
== OBJT_VNODE
) {
672 vn_fullpath(curproc
, vp
, &name
, &freename
);
673 vn_lock(vp
, LK_SHARED
| LK_RETRY
);
674 VOP_GETATTR(vp
, &vat
);
676 major
= vat
.va_rmajor
;
677 minor
= vat
.va_rminor
;
681 if (freename
== NULL
) {
682 if (entry
->eflags
& MAP_ENTRY_STACK
)
688 * start-end access offset major:minor inode [.text file]
690 ksnprintf(mebuffer
, sizeof(mebuffer
),
691 "%08lx-%08lx %s%s%s%s %08llx %02x:%02x %llu%s%s\n",
692 (u_long
)entry
->start
, (u_long
)entry
->end
,
693 (entry
->protection
& VM_PROT_READ
)?"r":"-",
694 (entry
->protection
& VM_PROT_WRITE
)?"w":"-",
695 (entry
->protection
& VM_PROT_EXECUTE
)?"x":"-",
705 kfree(freename
, M_TEMP
);
707 len
= strlen(mebuffer
);
708 if (len
> uio
->uio_resid
) {
714 * We cannot safely hold the map locked while accessing
715 * userspace as a VM fault might recurse the locked map.
717 vm_map_unlock_read(map
);
718 error
= uiomove(mebuffer
, len
, uio
);
719 vm_map_lock_read(map
);
724 * We use map->hint as a poor man's ripout detector. If
725 * it does not match the entry we set it to prior to
726 * unlocking the map the entry MIGHT now be stale. In
727 * this case we do an expensive lookup to find our place
728 * in the iteration again.
730 if (map
->hint
!= entry
) {
731 vm_map_entry_t reentry
;
733 vm_map_lookup_entry(map
, ostart
, &reentry
);
737 vm_map_unlock_read(map
);