1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <mdb/mdb_modapi.h> 30 #include <sys/machelf.h> 31 32 #include <libproc.h> 33 #include <stdio.h> 34 35 #include "proc_kludges.h" 36 37 typedef struct prockuldge_mappings { 38 struct ps_prochandle *pkm_Pr; 39 40 uint_t pkm_idx; 41 42 uint_t pkm_count; 43 uint_t pkm_max; 44 45 prmap_t *pkm_mappings; 46 47 uint_t pkm_old_max; 48 prmap_t *pkm_old_mappings; 49 } prockludge_mappings_t; 50 51 /* ARGSUSED */ 52 static int 53 prockludge_mappings_iter(prockludge_mappings_t *pkm, const prmap_t *pmp, 54 const char *object_name) 55 { 56 if (pkm->pkm_count >= pkm->pkm_max) { 57 int s = pkm->pkm_max ? pkm->pkm_max * 2 : 16; 58 59 pkm->pkm_old_max = pkm->pkm_max; 60 pkm->pkm_old_mappings = pkm->pkm_mappings; 61 pkm->pkm_max = s; 62 pkm->pkm_mappings = mdb_alloc(sizeof (prmap_t) * s, UM_SLEEP); 63 64 bcopy(pkm->pkm_old_mappings, pkm->pkm_mappings, 65 sizeof (prmap_t) * pkm->pkm_old_max); 66 67 mdb_free(pkm->pkm_old_mappings, 68 sizeof (prmap_t) * pkm->pkm_old_max); 69 70 pkm->pkm_old_mappings = NULL; 71 pkm->pkm_old_max = 0; 72 } 73 bcopy(pmp, &pkm->pkm_mappings[pkm->pkm_count++], sizeof (prmap_t)); 74 75 return (0); 76 } 77 78 int 79 prockludge_mappings_walk_init(mdb_walk_state_t *mws) 80 { 81 struct ps_prochandle *Pr; 82 int rc; 83 84 prockludge_mappings_t *pkm; 85 86 if (mdb_get_xdata("pshandle", &Pr, sizeof (Pr)) == -1) { 87 mdb_warn("couldn't read pshandle xdata"); 88 return (WALK_ERR); 89 } 90 91 pkm = mdb_zalloc(sizeof (prockludge_mappings_t), UM_SLEEP); 92 pkm->pkm_Pr = Pr; 93 mws->walk_data = pkm; 94 95 rc = Pmapping_iter(Pr, (proc_map_f *)prockludge_mappings_iter, pkm); 96 if (rc != 0) { 97 mdb_warn("Pmapping_iter failed"); 98 /* clean up */ 99 prockludge_mappings_walk_fini(mws); 100 return (WALK_ERR); 101 } 102 return (WALK_NEXT); 103 } 104 105 int 106 prockludge_mappings_walk_step(mdb_walk_state_t *wsp) 107 { 108 prockludge_mappings_t *pkm = wsp->walk_data; 109 int status; 110 111 if (pkm->pkm_idx >= pkm->pkm_count) 112 return (WALK_DONE); 113 114 status = wsp->walk_callback(0, &pkm->pkm_mappings[pkm->pkm_idx++], 115 wsp->walk_cbdata); 116 117 return (status); 118 } 119 120 void 121 prockludge_mappings_walk_fini(mdb_walk_state_t *wsp) 122 { 123 prockludge_mappings_t *pkm = wsp->walk_data; 124 if (pkm != NULL) { 125 if (pkm->pkm_old_mappings != NULL) { 126 mdb_free(pkm->pkm_old_mappings, 127 sizeof (prmap_t) * pkm->pkm_old_max); 128 } 129 if (pkm->pkm_mappings && 130 pkm->pkm_mappings != pkm->pkm_old_mappings) { 131 mdb_free(pkm->pkm_mappings, 132 sizeof (prmap_t) * pkm->pkm_max); 133 } 134 mdb_free(pkm, sizeof (prockludge_mappings_t)); 135 } 136 } 137 138 static int add_count = 0; 139 140 void 141 prockludge_add_walkers(void) 142 { 143 mdb_walker_t w; 144 145 if (add_count++ == 0) { 146 w.walk_name = KLUDGE_MAPWALK_NAME; 147 w.walk_descr = "kludge: walk the process' prmap_ts"; 148 w.walk_init = prockludge_mappings_walk_init; 149 w.walk_step = prockludge_mappings_walk_step; 150 w.walk_fini = prockludge_mappings_walk_fini; 151 w.walk_init_arg = NULL; 152 153 if (mdb_add_walker(&w) == -1) { 154 mdb_warn("unable to add walker "KLUDGE_MAPWALK_NAME); 155 } 156 } 157 } 158 159 void 160 prockludge_remove_walkers(void) 161 { 162 if (--add_count == 0) { 163 mdb_remove_walker(KLUDGE_MAPWALK_NAME); 164 } 165 } 166