xref: /onnv-gate/usr/src/cmd/ptools/pmap/pmap_common.c (revision 7675:df8814607da7)
1*7675SEdward.Pilatowicz@Sun.COM /*
2*7675SEdward.Pilatowicz@Sun.COM  * CDDL HEADER START
3*7675SEdward.Pilatowicz@Sun.COM  *
4*7675SEdward.Pilatowicz@Sun.COM  * The contents of this file are subject to the terms of the
5*7675SEdward.Pilatowicz@Sun.COM  * Common Development and Distribution License (the "License").
6*7675SEdward.Pilatowicz@Sun.COM  * You may not use this file except in compliance with the License.
7*7675SEdward.Pilatowicz@Sun.COM  *
8*7675SEdward.Pilatowicz@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7675SEdward.Pilatowicz@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7675SEdward.Pilatowicz@Sun.COM  * See the License for the specific language governing permissions
11*7675SEdward.Pilatowicz@Sun.COM  * and limitations under the License.
12*7675SEdward.Pilatowicz@Sun.COM  *
13*7675SEdward.Pilatowicz@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7675SEdward.Pilatowicz@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7675SEdward.Pilatowicz@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7675SEdward.Pilatowicz@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7675SEdward.Pilatowicz@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7675SEdward.Pilatowicz@Sun.COM  *
19*7675SEdward.Pilatowicz@Sun.COM  * CDDL HEADER END
20*7675SEdward.Pilatowicz@Sun.COM  */
21*7675SEdward.Pilatowicz@Sun.COM 
22*7675SEdward.Pilatowicz@Sun.COM /*
23*7675SEdward.Pilatowicz@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*7675SEdward.Pilatowicz@Sun.COM  * Use is subject to license terms.
25*7675SEdward.Pilatowicz@Sun.COM  */
26*7675SEdward.Pilatowicz@Sun.COM 
27*7675SEdward.Pilatowicz@Sun.COM #include <fcntl.h>
28*7675SEdward.Pilatowicz@Sun.COM #include <libproc.h>
29*7675SEdward.Pilatowicz@Sun.COM #include <limits.h>
30*7675SEdward.Pilatowicz@Sun.COM #include <stdio.h>
31*7675SEdward.Pilatowicz@Sun.COM #include <strings.h>
32*7675SEdward.Pilatowicz@Sun.COM #include <sys/mkdev.h>
33*7675SEdward.Pilatowicz@Sun.COM #include <sys/stat.h>
34*7675SEdward.Pilatowicz@Sun.COM #include <sys/types.h>
35*7675SEdward.Pilatowicz@Sun.COM 
36*7675SEdward.Pilatowicz@Sun.COM #include "pmap_common.h"
37*7675SEdward.Pilatowicz@Sun.COM 
38*7675SEdward.Pilatowicz@Sun.COM /*
39*7675SEdward.Pilatowicz@Sun.COM  * We compare the high memory addresses since stacks are faulted in from
40*7675SEdward.Pilatowicz@Sun.COM  * high memory addresses to low memory addresses, and our prmap_t
41*7675SEdward.Pilatowicz@Sun.COM  * structures identify only the range of addresses that have been faulted
42*7675SEdward.Pilatowicz@Sun.COM  * in so far.
43*7675SEdward.Pilatowicz@Sun.COM  */
44*7675SEdward.Pilatowicz@Sun.COM int
cmpstacks(const void * ap,const void * bp)45*7675SEdward.Pilatowicz@Sun.COM cmpstacks(const void *ap, const void *bp)
46*7675SEdward.Pilatowicz@Sun.COM {
47*7675SEdward.Pilatowicz@Sun.COM 	const lwpstack_t *as = ap;
48*7675SEdward.Pilatowicz@Sun.COM 	const lwpstack_t *bs = bp;
49*7675SEdward.Pilatowicz@Sun.COM 	uintptr_t a = (uintptr_t)as->lwps_stack.ss_sp + as->lwps_stack.ss_size;
50*7675SEdward.Pilatowicz@Sun.COM 	uintptr_t b = (uintptr_t)bs->lwps_stack.ss_sp + bs->lwps_stack.ss_size;
51*7675SEdward.Pilatowicz@Sun.COM 
52*7675SEdward.Pilatowicz@Sun.COM 	if (a < b)
53*7675SEdward.Pilatowicz@Sun.COM 		return (1);
54*7675SEdward.Pilatowicz@Sun.COM 	if (a > b)
55*7675SEdward.Pilatowicz@Sun.COM 		return (-1);
56*7675SEdward.Pilatowicz@Sun.COM 	return (0);
57*7675SEdward.Pilatowicz@Sun.COM }
58*7675SEdward.Pilatowicz@Sun.COM 
59*7675SEdward.Pilatowicz@Sun.COM /*
60*7675SEdward.Pilatowicz@Sun.COM  * Create labels for non-anon, non-heap mappings
61*7675SEdward.Pilatowicz@Sun.COM  */
62*7675SEdward.Pilatowicz@Sun.COM char *
make_name(struct ps_prochandle * Pr,int lflag,uintptr_t addr,const char * mapname,char * buf,size_t bufsz)63*7675SEdward.Pilatowicz@Sun.COM make_name(struct ps_prochandle *Pr, int lflag, uintptr_t addr,
64*7675SEdward.Pilatowicz@Sun.COM     const char *mapname, char *buf, size_t bufsz)
65*7675SEdward.Pilatowicz@Sun.COM {
66*7675SEdward.Pilatowicz@Sun.COM 	const pstatus_t		*Psp = Pstatus(Pr);
67*7675SEdward.Pilatowicz@Sun.COM 	struct stat		statb;
68*7675SEdward.Pilatowicz@Sun.COM 	char			path[PATH_MAX];
69*7675SEdward.Pilatowicz@Sun.COM 	int			len;
70*7675SEdward.Pilatowicz@Sun.COM 
71*7675SEdward.Pilatowicz@Sun.COM 	if (lflag) {
72*7675SEdward.Pilatowicz@Sun.COM 		if (Pobjname(Pr, addr, buf, bufsz) != NULL)
73*7675SEdward.Pilatowicz@Sun.COM 			return (buf);
74*7675SEdward.Pilatowicz@Sun.COM 	} else {
75*7675SEdward.Pilatowicz@Sun.COM 		if (Pobjname_resolved(Pr, addr, buf, bufsz) != NULL) {
76*7675SEdward.Pilatowicz@Sun.COM 			/* Verify that the path exists */
77*7675SEdward.Pilatowicz@Sun.COM 			if ((len = resolvepath(buf, buf, bufsz)) > 0) {
78*7675SEdward.Pilatowicz@Sun.COM 				buf[len] = '\0';
79*7675SEdward.Pilatowicz@Sun.COM 				return (buf);
80*7675SEdward.Pilatowicz@Sun.COM 			}
81*7675SEdward.Pilatowicz@Sun.COM 		}
82*7675SEdward.Pilatowicz@Sun.COM 	}
83*7675SEdward.Pilatowicz@Sun.COM 
84*7675SEdward.Pilatowicz@Sun.COM 	if (Pstate(Pr) == PS_DEAD || *mapname == '\0')
85*7675SEdward.Pilatowicz@Sun.COM 		return (NULL);
86*7675SEdward.Pilatowicz@Sun.COM 
87*7675SEdward.Pilatowicz@Sun.COM 	/* first see if we can find a path via /proc */
88*7675SEdward.Pilatowicz@Sun.COM 	(void) snprintf(path, sizeof (path), "/proc/%d/path/%s",
89*7675SEdward.Pilatowicz@Sun.COM 	    (int)Psp->pr_pid, mapname);
90*7675SEdward.Pilatowicz@Sun.COM 	len = readlink(path, buf, bufsz - 1);
91*7675SEdward.Pilatowicz@Sun.COM 	if (len >= 0) {
92*7675SEdward.Pilatowicz@Sun.COM 		buf[len] = '\0';
93*7675SEdward.Pilatowicz@Sun.COM 		return (buf);
94*7675SEdward.Pilatowicz@Sun.COM 	}
95*7675SEdward.Pilatowicz@Sun.COM 
96*7675SEdward.Pilatowicz@Sun.COM 	/* fall back to object information reported by /proc */
97*7675SEdward.Pilatowicz@Sun.COM 	(void) snprintf(path, sizeof (path),
98*7675SEdward.Pilatowicz@Sun.COM 	    "/proc/%d/object/%s", (int)Psp->pr_pid, mapname);
99*7675SEdward.Pilatowicz@Sun.COM 	if (stat(path, &statb) == 0) {
100*7675SEdward.Pilatowicz@Sun.COM 		dev_t dev = statb.st_dev;
101*7675SEdward.Pilatowicz@Sun.COM 		ino_t ino = statb.st_ino;
102*7675SEdward.Pilatowicz@Sun.COM 		(void) snprintf(buf, bufsz, "dev:%lu,%lu ino:%lu",
103*7675SEdward.Pilatowicz@Sun.COM 		    (ulong_t)major(dev), (ulong_t)minor(dev), ino);
104*7675SEdward.Pilatowicz@Sun.COM 		return (buf);
105*7675SEdward.Pilatowicz@Sun.COM 	}
106*7675SEdward.Pilatowicz@Sun.COM 
107*7675SEdward.Pilatowicz@Sun.COM 	return (NULL);
108*7675SEdward.Pilatowicz@Sun.COM }
109*7675SEdward.Pilatowicz@Sun.COM 
110*7675SEdward.Pilatowicz@Sun.COM /*
111*7675SEdward.Pilatowicz@Sun.COM  * Create label for anon mappings
112*7675SEdward.Pilatowicz@Sun.COM  */
113*7675SEdward.Pilatowicz@Sun.COM char *
anon_name(char * name,const pstatus_t * Psp,lwpstack_t * stacks,uint_t nstacks,uintptr_t vaddr,size_t size,int mflags,int shmid,int * mtypesp)114*7675SEdward.Pilatowicz@Sun.COM anon_name(char *name, const pstatus_t *Psp, lwpstack_t *stacks, uint_t nstacks,
115*7675SEdward.Pilatowicz@Sun.COM     uintptr_t vaddr, size_t size, int mflags, int shmid, int *mtypesp)
116*7675SEdward.Pilatowicz@Sun.COM {
117*7675SEdward.Pilatowicz@Sun.COM 	int mtypes = 0;
118*7675SEdward.Pilatowicz@Sun.COM 
119*7675SEdward.Pilatowicz@Sun.COM 	if (mflags & MA_ISM) {
120*7675SEdward.Pilatowicz@Sun.COM 		if (shmid == -1)
121*7675SEdward.Pilatowicz@Sun.COM 			(void) snprintf(name, PATH_MAX, "  [ %s shmid=null ]",
122*7675SEdward.Pilatowicz@Sun.COM 			    (mflags & MA_NORESERVE) ? "ism" : "dism");
123*7675SEdward.Pilatowicz@Sun.COM 		else
124*7675SEdward.Pilatowicz@Sun.COM 			(void) snprintf(name, PATH_MAX, "  [ %s shmid=0x%x ]",
125*7675SEdward.Pilatowicz@Sun.COM 			    (mflags & MA_NORESERVE) ? "ism" : "dism", shmid);
126*7675SEdward.Pilatowicz@Sun.COM 		mtypes |= (1 << AT_SHARED);
127*7675SEdward.Pilatowicz@Sun.COM 	} else if (mflags & MA_SHM) {
128*7675SEdward.Pilatowicz@Sun.COM 		if (shmid == -1)
129*7675SEdward.Pilatowicz@Sun.COM 			(void) sprintf(name, "  [ shmid=null ]");
130*7675SEdward.Pilatowicz@Sun.COM 		else
131*7675SEdward.Pilatowicz@Sun.COM 			(void) sprintf(name, "  [ shmid=0x%x ]", shmid);
132*7675SEdward.Pilatowicz@Sun.COM 		mtypes |= (1 << AT_SHARED);
133*7675SEdward.Pilatowicz@Sun.COM 	} else if (vaddr + size > Psp->pr_stkbase &&
134*7675SEdward.Pilatowicz@Sun.COM 	    vaddr < Psp->pr_stkbase + Psp->pr_stksize) {
135*7675SEdward.Pilatowicz@Sun.COM 		(void) strcpy(name, "  [ stack ]");
136*7675SEdward.Pilatowicz@Sun.COM 		mtypes |= (1 << AT_STACK);
137*7675SEdward.Pilatowicz@Sun.COM 	} else if ((mflags & MA_ANON) &&
138*7675SEdward.Pilatowicz@Sun.COM 	    vaddr + size > Psp->pr_brkbase &&
139*7675SEdward.Pilatowicz@Sun.COM 	    vaddr < Psp->pr_brkbase + Psp->pr_brksize) {
140*7675SEdward.Pilatowicz@Sun.COM 		(void) strcpy(name, "  [ heap ]");
141*7675SEdward.Pilatowicz@Sun.COM 		mtypes |= (1 << AT_HEAP);
142*7675SEdward.Pilatowicz@Sun.COM 	} else {
143*7675SEdward.Pilatowicz@Sun.COM 		lwpstack_t key, *stk;
144*7675SEdward.Pilatowicz@Sun.COM 
145*7675SEdward.Pilatowicz@Sun.COM 		key.lwps_stack.ss_sp = (void *)vaddr;
146*7675SEdward.Pilatowicz@Sun.COM 		key.lwps_stack.ss_size = size;
147*7675SEdward.Pilatowicz@Sun.COM 		if (nstacks > 0 &&
148*7675SEdward.Pilatowicz@Sun.COM 		    (stk = bsearch(&key, stacks, nstacks, sizeof (stacks[0]),
149*7675SEdward.Pilatowicz@Sun.COM 		    cmpstacks)) != NULL) {
150*7675SEdward.Pilatowicz@Sun.COM 			(void) snprintf(name, PATH_MAX, "  [ %s tid=%d ]",
151*7675SEdward.Pilatowicz@Sun.COM 			    (stk->lwps_stack.ss_flags & SS_ONSTACK) ?
152*7675SEdward.Pilatowicz@Sun.COM 			    "altstack" : "stack",
153*7675SEdward.Pilatowicz@Sun.COM 			    stk->lwps_lwpid);
154*7675SEdward.Pilatowicz@Sun.COM 			mtypes |= (1 << AT_STACK);
155*7675SEdward.Pilatowicz@Sun.COM 		} else {
156*7675SEdward.Pilatowicz@Sun.COM 			(void) strcpy(name, "  [ anon ]");
157*7675SEdward.Pilatowicz@Sun.COM 			mtypes |= (1 << AT_PRIVM);
158*7675SEdward.Pilatowicz@Sun.COM 		}
159*7675SEdward.Pilatowicz@Sun.COM 	}
160*7675SEdward.Pilatowicz@Sun.COM 
161*7675SEdward.Pilatowicz@Sun.COM 	if (mtypesp)
162*7675SEdward.Pilatowicz@Sun.COM 		*mtypesp = mtypes;
163*7675SEdward.Pilatowicz@Sun.COM 	return (name);
164*7675SEdward.Pilatowicz@Sun.COM }
165