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 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 * 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 * 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