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 #include <mdb/mdb_modapi.h> 28 #include <sys/machelf.h> 29 30 #include <libproc.h> 31 #include <stdio.h> 32 33 #include "proc_kludges.h" 34 35 typedef struct prockuldge_mappings { 36 struct ps_prochandle *pkm_Pr; 37 38 uint_t pkm_idx; 39 40 uint_t pkm_count; 41 uint_t pkm_max; 42 43 prmap_t *pkm_mappings; 44 45 uint_t pkm_old_max; 46 prmap_t *pkm_old_mappings; 47 } prockludge_mappings_t; 48 49 /* ARGSUSED */ 50 static int 51 prockludge_mappings_iter(prockludge_mappings_t *pkm, const prmap_t *pmp, 52 const char *object_name) 53 { 54 if (pkm->pkm_count >= pkm->pkm_max) { 55 int s = pkm->pkm_max ? pkm->pkm_max * 2 : 16; 56 57 pkm->pkm_old_max = pkm->pkm_max; 58 pkm->pkm_old_mappings = pkm->pkm_mappings; 59 pkm->pkm_max = s; 60 pkm->pkm_mappings = mdb_alloc(sizeof (prmap_t) * s, UM_SLEEP); 61 62 bcopy(pkm->pkm_old_mappings, pkm->pkm_mappings, 63 sizeof (prmap_t) * pkm->pkm_old_max); 64 65 mdb_free(pkm->pkm_old_mappings, 66 sizeof (prmap_t) * pkm->pkm_old_max); 67 68 pkm->pkm_old_mappings = NULL; 69 pkm->pkm_old_max = 0; 70 } 71 bcopy(pmp, &pkm->pkm_mappings[pkm->pkm_count++], sizeof (prmap_t)); 72 73 return (0); 74 } 75 76 int 77 prockludge_mappings_walk_init(mdb_walk_state_t *mws) 78 { 79 struct ps_prochandle *Pr; 80 int rc; 81 82 prockludge_mappings_t *pkm; 83 84 if (mdb_get_xdata("pshandle", &Pr, sizeof (Pr)) == -1) { 85 mdb_warn("couldn't read pshandle xdata"); 86 return (WALK_ERR); 87 } 88 89 pkm = mdb_zalloc(sizeof (prockludge_mappings_t), UM_SLEEP); 90 pkm->pkm_Pr = Pr; 91 mws->walk_data = pkm; 92 93 rc = Pmapping_iter(Pr, (proc_map_f *)prockludge_mappings_iter, pkm); 94 if (rc != 0) { 95 mdb_warn("Pmapping_iter failed"); 96 /* clean up */ 97 prockludge_mappings_walk_fini(mws); 98 return (WALK_ERR); 99 } 100 return (WALK_NEXT); 101 } 102 103 int 104 prockludge_mappings_walk_step(mdb_walk_state_t *wsp) 105 { 106 prockludge_mappings_t *pkm = wsp->walk_data; 107 int status; 108 109 if (pkm->pkm_idx >= pkm->pkm_count) 110 return (WALK_DONE); 111 112 status = wsp->walk_callback(0, &pkm->pkm_mappings[pkm->pkm_idx++], 113 wsp->walk_cbdata); 114 115 return (status); 116 } 117 118 void 119 prockludge_mappings_walk_fini(mdb_walk_state_t *wsp) 120 { 121 prockludge_mappings_t *pkm = wsp->walk_data; 122 if (pkm != NULL) { 123 if (pkm->pkm_old_mappings != NULL) { 124 mdb_free(pkm->pkm_old_mappings, 125 sizeof (prmap_t) * pkm->pkm_old_max); 126 } 127 if (pkm->pkm_mappings && 128 pkm->pkm_mappings != pkm->pkm_old_mappings) { 129 mdb_free(pkm->pkm_mappings, 130 sizeof (prmap_t) * pkm->pkm_max); 131 } 132 mdb_free(pkm, sizeof (prockludge_mappings_t)); 133 } 134 } 135 136 static int add_count = 0; 137 138 void 139 prockludge_add_walkers(void) 140 { 141 mdb_walker_t w; 142 143 if (add_count++ == 0) { 144 w.walk_name = KLUDGE_MAPWALK_NAME; 145 w.walk_descr = "kludge: walk the process' prmap_ts"; 146 w.walk_init = prockludge_mappings_walk_init; 147 w.walk_step = prockludge_mappings_walk_step; 148 w.walk_fini = prockludge_mappings_walk_fini; 149 w.walk_init_arg = NULL; 150 151 if (mdb_add_walker(&w) == -1) { 152 mdb_warn("unable to add walker "KLUDGE_MAPWALK_NAME); 153 } 154 } 155 } 156 157 void 158 prockludge_remove_walkers(void) 159 { 160 if (--add_count == 0) { 161 mdb_remove_walker(KLUDGE_MAPWALK_NAME); 162 } 163 } 164