4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
35 #include <sys/mkdev.h>
37 #include <sys/types.h>
39 #include "pmap_common.h"
42 * We compare the high memory addresses since stacks are faulted in from
43 * high memory addresses to low memory addresses, and our prmap_t
44 * structures identify only the range of addresses that have been faulted
48 cmpstacks(const void *ap
, const void *bp
)
50 const lwpstack_t
*as
= ap
;
51 const lwpstack_t
*bs
= bp
;
52 uintptr_t a
= (uintptr_t)as
->lwps_stack
.ss_sp
+ as
->lwps_stack
.ss_size
;
53 uintptr_t b
= (uintptr_t)bs
->lwps_stack
.ss_sp
+ bs
->lwps_stack
.ss_size
;
63 * Create labels for non-anon, non-heap mappings
66 make_name(struct ps_prochandle
*Pr
, int lflag
, uintptr_t addr
,
67 const char *mapname
, char *buf
, size_t bufsz
)
69 const pstatus_t
*Psp
= Pstatus(Pr
);
74 if (lflag
|| Pstate(Pr
) == PS_DEAD
) {
75 if (Pobjname(Pr
, addr
, buf
, bufsz
) != NULL
)
78 if (Pobjname_resolved(Pr
, addr
, buf
, bufsz
) != NULL
) {
79 /* Verify that the path exists */
80 if ((len
= resolvepath(buf
, buf
, bufsz
)) > 0) {
87 if (Pstate(Pr
) == PS_DEAD
|| *mapname
== '\0')
90 /* first see if we can find a path via /proc */
91 (void) snprintf(path
, sizeof (path
), "/proc/%d/path/%s",
92 (int)Psp
->pr_pid
, mapname
);
93 len
= readlink(path
, buf
, bufsz
- 1);
99 /* fall back to object information reported by /proc */
100 (void) snprintf(path
, sizeof (path
),
101 "/proc/%d/object/%s", (int)Psp
->pr_pid
, mapname
);
102 if (stat(path
, &statb
) == 0) {
103 dev_t dev
= statb
.st_dev
;
104 ino_t ino
= statb
.st_ino
;
105 (void) snprintf(buf
, bufsz
, "dev:%lu,%lu ino:%lu",
106 (ulong_t
)major(dev
), (ulong_t
)minor(dev
), ino
);
114 * Create label for anon mappings
117 anon_name(char *name
, const pstatus_t
*Psp
, lwpstack_t
*stacks
, uint_t nstacks
,
118 uintptr_t vaddr
, size_t size
, int mflags
, int shmid
, int *mtypesp
)
122 if (mflags
& MA_ISM
) {
124 (void) snprintf(name
, PATH_MAX
, " [ %s shmid=null ]",
125 (mflags
& MA_NORESERVE
) ? "ism" : "dism");
127 (void) snprintf(name
, PATH_MAX
, " [ %s shmid=0x%x ]",
128 (mflags
& MA_NORESERVE
) ? "ism" : "dism", shmid
);
129 mtypes
|= (1 << AT_SHARED
);
130 } else if (mflags
& MA_SHM
) {
132 (void) sprintf(name
, " [ shmid=null ]");
134 (void) sprintf(name
, " [ shmid=0x%x ]", shmid
);
135 mtypes
|= (1 << AT_SHARED
);
136 } else if (vaddr
+ size
> Psp
->pr_stkbase
&&
137 vaddr
< Psp
->pr_stkbase
+ Psp
->pr_stksize
) {
138 (void) strcpy(name
, " [ stack ]");
139 mtypes
|= (1 << AT_STACK
);
140 } else if ((mflags
& MA_ANON
) &&
141 vaddr
+ size
> Psp
->pr_brkbase
&&
142 vaddr
< Psp
->pr_brkbase
+ Psp
->pr_brksize
) {
143 (void) strcpy(name
, " [ heap ]");
144 mtypes
|= (1 << AT_HEAP
);
146 lwpstack_t key
, *stk
;
148 key
.lwps_stack
.ss_sp
= (void *)vaddr
;
149 key
.lwps_stack
.ss_size
= size
;
151 (stk
= bsearch(&key
, stacks
, nstacks
, sizeof (stacks
[0]),
152 cmpstacks
)) != NULL
) {
153 (void) snprintf(name
, PATH_MAX
, " [ %s tid=%d ]",
154 (stk
->lwps_stack
.ss_flags
& SS_ONSTACK
) ?
155 "altstack" : "stack",
157 mtypes
|= (1 << AT_STACK
);
159 (void) strcpy(name
, " [ anon ]");
160 mtypes
|= (1 << AT_PRIVM
);