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