1186f7fbfSEdward Pilatowicz /* 2186f7fbfSEdward Pilatowicz * CDDL HEADER START 3186f7fbfSEdward Pilatowicz * 4186f7fbfSEdward Pilatowicz * The contents of this file are subject to the terms of the 5186f7fbfSEdward Pilatowicz * Common Development and Distribution License (the "License"). 6186f7fbfSEdward Pilatowicz * You may not use this file except in compliance with the License. 7186f7fbfSEdward Pilatowicz * 8186f7fbfSEdward Pilatowicz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9186f7fbfSEdward Pilatowicz * or http://www.opensolaris.org/os/licensing. 10186f7fbfSEdward Pilatowicz * See the License for the specific language governing permissions 11186f7fbfSEdward Pilatowicz * and limitations under the License. 12186f7fbfSEdward Pilatowicz * 13186f7fbfSEdward Pilatowicz * When distributing Covered Code, include this CDDL HEADER in each 14186f7fbfSEdward Pilatowicz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15186f7fbfSEdward Pilatowicz * If applicable, add the following below this CDDL HEADER, with the 16186f7fbfSEdward Pilatowicz * fields enclosed by brackets "[]" replaced with your own identifying 17186f7fbfSEdward Pilatowicz * information: Portions Copyright [yyyy] [name of copyright owner] 18186f7fbfSEdward Pilatowicz * 19186f7fbfSEdward Pilatowicz * CDDL HEADER END 20186f7fbfSEdward Pilatowicz */ 21186f7fbfSEdward Pilatowicz 22186f7fbfSEdward Pilatowicz /* 23186f7fbfSEdward Pilatowicz * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24186f7fbfSEdward Pilatowicz * Use is subject to license terms. 25186f7fbfSEdward Pilatowicz */ 26*8f68126cSBryan Cantrill /* 27*8f68126cSBryan Cantrill * Copyright (c) 2013, Joyent, Inc. All rights reserved. 28*8f68126cSBryan Cantrill */ 29186f7fbfSEdward Pilatowicz 30186f7fbfSEdward Pilatowicz #include <fcntl.h> 31186f7fbfSEdward Pilatowicz #include <libproc.h> 32186f7fbfSEdward Pilatowicz #include <limits.h> 33186f7fbfSEdward Pilatowicz #include <stdio.h> 34186f7fbfSEdward Pilatowicz #include <strings.h> 35186f7fbfSEdward Pilatowicz #include <sys/mkdev.h> 36186f7fbfSEdward Pilatowicz #include <sys/stat.h> 37186f7fbfSEdward Pilatowicz #include <sys/types.h> 38186f7fbfSEdward Pilatowicz 39186f7fbfSEdward Pilatowicz #include "pmap_common.h" 40186f7fbfSEdward Pilatowicz 41186f7fbfSEdward Pilatowicz /* 42186f7fbfSEdward Pilatowicz * We compare the high memory addresses since stacks are faulted in from 43186f7fbfSEdward Pilatowicz * high memory addresses to low memory addresses, and our prmap_t 44186f7fbfSEdward Pilatowicz * structures identify only the range of addresses that have been faulted 45186f7fbfSEdward Pilatowicz * in so far. 46186f7fbfSEdward Pilatowicz */ 47186f7fbfSEdward Pilatowicz int 48186f7fbfSEdward Pilatowicz cmpstacks(const void *ap, const void *bp) 49186f7fbfSEdward Pilatowicz { 50186f7fbfSEdward Pilatowicz const lwpstack_t *as = ap; 51186f7fbfSEdward Pilatowicz const lwpstack_t *bs = bp; 52186f7fbfSEdward Pilatowicz uintptr_t a = (uintptr_t)as->lwps_stack.ss_sp + as->lwps_stack.ss_size; 53186f7fbfSEdward Pilatowicz uintptr_t b = (uintptr_t)bs->lwps_stack.ss_sp + bs->lwps_stack.ss_size; 54186f7fbfSEdward Pilatowicz 55186f7fbfSEdward Pilatowicz if (a < b) 56186f7fbfSEdward Pilatowicz return (1); 57186f7fbfSEdward Pilatowicz if (a > b) 58186f7fbfSEdward Pilatowicz return (-1); 59186f7fbfSEdward Pilatowicz return (0); 60186f7fbfSEdward Pilatowicz } 61186f7fbfSEdward Pilatowicz 62186f7fbfSEdward Pilatowicz /* 63186f7fbfSEdward Pilatowicz * Create labels for non-anon, non-heap mappings 64186f7fbfSEdward Pilatowicz */ 65186f7fbfSEdward Pilatowicz char * 66186f7fbfSEdward Pilatowicz make_name(struct ps_prochandle *Pr, int lflag, uintptr_t addr, 67186f7fbfSEdward Pilatowicz const char *mapname, char *buf, size_t bufsz) 68186f7fbfSEdward Pilatowicz { 69186f7fbfSEdward Pilatowicz const pstatus_t *Psp = Pstatus(Pr); 70186f7fbfSEdward Pilatowicz struct stat statb; 71186f7fbfSEdward Pilatowicz char path[PATH_MAX]; 72186f7fbfSEdward Pilatowicz int len; 73186f7fbfSEdward Pilatowicz 74*8f68126cSBryan Cantrill if (lflag || Pstate(Pr) == PS_DEAD) { 75186f7fbfSEdward Pilatowicz if (Pobjname(Pr, addr, buf, bufsz) != NULL) 76186f7fbfSEdward Pilatowicz return (buf); 77186f7fbfSEdward Pilatowicz } else { 78186f7fbfSEdward Pilatowicz if (Pobjname_resolved(Pr, addr, buf, bufsz) != NULL) { 79186f7fbfSEdward Pilatowicz /* Verify that the path exists */ 80186f7fbfSEdward Pilatowicz if ((len = resolvepath(buf, buf, bufsz)) > 0) { 81186f7fbfSEdward Pilatowicz buf[len] = '\0'; 82186f7fbfSEdward Pilatowicz return (buf); 83186f7fbfSEdward Pilatowicz } 84186f7fbfSEdward Pilatowicz } 85186f7fbfSEdward Pilatowicz } 86186f7fbfSEdward Pilatowicz 87186f7fbfSEdward Pilatowicz if (Pstate(Pr) == PS_DEAD || *mapname == '\0') 88186f7fbfSEdward Pilatowicz return (NULL); 89186f7fbfSEdward Pilatowicz 90186f7fbfSEdward Pilatowicz /* first see if we can find a path via /proc */ 91186f7fbfSEdward Pilatowicz (void) snprintf(path, sizeof (path), "/proc/%d/path/%s", 92186f7fbfSEdward Pilatowicz (int)Psp->pr_pid, mapname); 93186f7fbfSEdward Pilatowicz len = readlink(path, buf, bufsz - 1); 94186f7fbfSEdward Pilatowicz if (len >= 0) { 95186f7fbfSEdward Pilatowicz buf[len] = '\0'; 96186f7fbfSEdward Pilatowicz return (buf); 97186f7fbfSEdward Pilatowicz } 98186f7fbfSEdward Pilatowicz 99186f7fbfSEdward Pilatowicz /* fall back to object information reported by /proc */ 100186f7fbfSEdward Pilatowicz (void) snprintf(path, sizeof (path), 101186f7fbfSEdward Pilatowicz "/proc/%d/object/%s", (int)Psp->pr_pid, mapname); 102186f7fbfSEdward Pilatowicz if (stat(path, &statb) == 0) { 103186f7fbfSEdward Pilatowicz dev_t dev = statb.st_dev; 104186f7fbfSEdward Pilatowicz ino_t ino = statb.st_ino; 105186f7fbfSEdward Pilatowicz (void) snprintf(buf, bufsz, "dev:%lu,%lu ino:%lu", 106186f7fbfSEdward Pilatowicz (ulong_t)major(dev), (ulong_t)minor(dev), ino); 107186f7fbfSEdward Pilatowicz return (buf); 108186f7fbfSEdward Pilatowicz } 109186f7fbfSEdward Pilatowicz 110186f7fbfSEdward Pilatowicz return (NULL); 111186f7fbfSEdward Pilatowicz } 112186f7fbfSEdward Pilatowicz 113186f7fbfSEdward Pilatowicz /* 114186f7fbfSEdward Pilatowicz * Create label for anon mappings 115186f7fbfSEdward Pilatowicz */ 116186f7fbfSEdward Pilatowicz char * 117186f7fbfSEdward Pilatowicz anon_name(char *name, const pstatus_t *Psp, lwpstack_t *stacks, uint_t nstacks, 118186f7fbfSEdward Pilatowicz uintptr_t vaddr, size_t size, int mflags, int shmid, int *mtypesp) 119186f7fbfSEdward Pilatowicz { 120186f7fbfSEdward Pilatowicz int mtypes = 0; 121186f7fbfSEdward Pilatowicz 122186f7fbfSEdward Pilatowicz if (mflags & MA_ISM) { 123186f7fbfSEdward Pilatowicz if (shmid == -1) 124186f7fbfSEdward Pilatowicz (void) snprintf(name, PATH_MAX, " [ %s shmid=null ]", 125186f7fbfSEdward Pilatowicz (mflags & MA_NORESERVE) ? "ism" : "dism"); 126186f7fbfSEdward Pilatowicz else 127186f7fbfSEdward Pilatowicz (void) snprintf(name, PATH_MAX, " [ %s shmid=0x%x ]", 128186f7fbfSEdward Pilatowicz (mflags & MA_NORESERVE) ? "ism" : "dism", shmid); 129186f7fbfSEdward Pilatowicz mtypes |= (1 << AT_SHARED); 130186f7fbfSEdward Pilatowicz } else if (mflags & MA_SHM) { 131186f7fbfSEdward Pilatowicz if (shmid == -1) 132186f7fbfSEdward Pilatowicz (void) sprintf(name, " [ shmid=null ]"); 133186f7fbfSEdward Pilatowicz else 134186f7fbfSEdward Pilatowicz (void) sprintf(name, " [ shmid=0x%x ]", shmid); 135186f7fbfSEdward Pilatowicz mtypes |= (1 << AT_SHARED); 136186f7fbfSEdward Pilatowicz } else if (vaddr + size > Psp->pr_stkbase && 137186f7fbfSEdward Pilatowicz vaddr < Psp->pr_stkbase + Psp->pr_stksize) { 138186f7fbfSEdward Pilatowicz (void) strcpy(name, " [ stack ]"); 139186f7fbfSEdward Pilatowicz mtypes |= (1 << AT_STACK); 140186f7fbfSEdward Pilatowicz } else if ((mflags & MA_ANON) && 141186f7fbfSEdward Pilatowicz vaddr + size > Psp->pr_brkbase && 142186f7fbfSEdward Pilatowicz vaddr < Psp->pr_brkbase + Psp->pr_brksize) { 143186f7fbfSEdward Pilatowicz (void) strcpy(name, " [ heap ]"); 144186f7fbfSEdward Pilatowicz mtypes |= (1 << AT_HEAP); 145186f7fbfSEdward Pilatowicz } else { 146186f7fbfSEdward Pilatowicz lwpstack_t key, *stk; 147186f7fbfSEdward Pilatowicz 148186f7fbfSEdward Pilatowicz key.lwps_stack.ss_sp = (void *)vaddr; 149186f7fbfSEdward Pilatowicz key.lwps_stack.ss_size = size; 150186f7fbfSEdward Pilatowicz if (nstacks > 0 && 151186f7fbfSEdward Pilatowicz (stk = bsearch(&key, stacks, nstacks, sizeof (stacks[0]), 152186f7fbfSEdward Pilatowicz cmpstacks)) != NULL) { 153186f7fbfSEdward Pilatowicz (void) snprintf(name, PATH_MAX, " [ %s tid=%d ]", 154186f7fbfSEdward Pilatowicz (stk->lwps_stack.ss_flags & SS_ONSTACK) ? 155186f7fbfSEdward Pilatowicz "altstack" : "stack", 156186f7fbfSEdward Pilatowicz stk->lwps_lwpid); 157186f7fbfSEdward Pilatowicz mtypes |= (1 << AT_STACK); 158186f7fbfSEdward Pilatowicz } else { 159186f7fbfSEdward Pilatowicz (void) strcpy(name, " [ anon ]"); 160186f7fbfSEdward Pilatowicz mtypes |= (1 << AT_PRIVM); 161186f7fbfSEdward Pilatowicz } 162186f7fbfSEdward Pilatowicz } 163186f7fbfSEdward Pilatowicz 164186f7fbfSEdward Pilatowicz if (mtypesp) 165186f7fbfSEdward Pilatowicz *mtypesp = mtypes; 166186f7fbfSEdward Pilatowicz return (name); 167186f7fbfSEdward Pilatowicz } 168