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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 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 <msg.h> 30 #include <_rtld.h> 31 #include <conv.h> 32 #include <sys/mdb_modapi.h> 33 #include <sys/param.h> 34 #include <stdlib.h> 35 36 /* 37 * Data structure for walkers. 38 */ 39 typedef struct { 40 uint_t w_flags; 41 } W_desc; 42 43 44 /* 45 * Flags values for dcmds 46 */ 47 48 #define RTLD_FLG_VERBOSE 0x0001 /* verbose output */ 49 50 static const mdb_bitmask_t rtflags_bits[] = { 51 { MSG_ORIG(MSG_FLG_ISMAIN), FLG_RT_ISMAIN, FLG_RT_ISMAIN}, 52 { MSG_ORIG(MSG_FLG_IMGALLOC), FLG_RT_IMGALLOC, FLG_RT_IMGALLOC}, 53 { MSG_ORIG(MSG_FLG_RELOCED), FLG_RT_RELOCED, FLG_RT_RELOCED}, 54 { MSG_ORIG(MSG_FLG_SETGROUP), FLG_RT_SETGROUP, FLG_RT_SETGROUP}, 55 { MSG_ORIG(MSG_FLG_HWCAP), FLG_RT_HWCAP, FLG_RT_HWCAP}, 56 { MSG_ORIG(MSG_FLG_OBJECT), FLG_RT_OBJECT, FLG_RT_OBJECT}, 57 { MSG_ORIG(MSG_FLG_NODUMP), FLG_RT_NODUMP, FLG_RT_NODUMP}, 58 { MSG_ORIG(MSG_FLG_DELETE), FLG_RT_DELETE, FLG_RT_DELETE}, 59 { MSG_ORIG(MSG_FLG_ANALYZED), FLG_RT_ANALYZED, FLG_RT_ANALYZED}, 60 { MSG_ORIG(MSG_FLG_INITDONE), FLG_RT_INITDONE, FLG_RT_INITDONE}, 61 { MSG_ORIG(MSG_FLG_TRANS), FLG_RT_TRANS, FLG_RT_TRANS}, 62 { MSG_ORIG(MSG_FLG_FIXED), FLG_RT_FIXED, FLG_RT_FIXED}, 63 { MSG_ORIG(MSG_FLG_PRELOAD), FLG_RT_PRELOAD, FLG_RT_PRELOAD}, 64 { MSG_ORIG(MSG_FLG_ALTER), FLG_RT_ALTER, FLG_RT_ALTER}, 65 { MSG_ORIG(MSG_FLG_LOADFLTR), FLG_RT_LOADFLTR, FLG_RT_LOADFLTR}, 66 { MSG_ORIG(MSG_FLG_AUDIT), FLG_RT_AUDIT, FLG_RT_AUDIT}, 67 { MSG_ORIG(MSG_FLG_MODESET), FLG_RT_MODESET, FLG_RT_MODESET}, 68 { MSG_ORIG(MSG_FLG_ANALZING), FLG_RT_ANALZING, FLG_RT_ANALZING}, 69 { MSG_ORIG(MSG_FLG_INITFRST), FLG_RT_INITFRST, FLG_RT_INITFRST}, 70 { MSG_ORIG(MSG_FLG_NOOPEN), FLG_RT_NOOPEN, FLG_RT_NOOPEN}, 71 { MSG_ORIG(MSG_FLG_FINICLCT), FLG_RT_FINICLCT, FLG_RT_FINICLCT}, 72 { MSG_ORIG(MSG_FLG_INITCALL), FLG_RT_INITCALL, FLG_RT_INITCALL}, 73 { MSG_ORIG(MSG_FLG_SUNWBSS), FLG_RT_SUNWBSS, FLG_RT_SUNWBSS}, 74 { MSG_ORIG(MSG_FLG_OBJINTPO), FLG_RT_OBJINTPO, FLG_RT_OBJINTPO}, 75 { MSG_ORIG(MSG_FLG_SYMINTPO), FLG_RT_SYMINTPO, FLG_RT_SYMINTPO}, 76 { MSG_ORIG(MSG_FLG_MOVE), FLG_RT_MOVE, FLG_RT_MOVE}, 77 { MSG_ORIG(MSG_FLG_DLSYM), FLG_RT_DLSYM, FLG_RT_DLSYM}, 78 { MSG_ORIG(MSG_FLG_REGSYMS), FLG_RT_REGSYMS, FLG_RT_REGSYMS}, 79 { MSG_ORIG(MSG_FLG_INITCLCT), FLG_RT_INITCLCT, FLG_RT_INITCLCT}, 80 { MSG_ORIG(MSG_FLG_HANDLE), FLG_RT_HANDLE, FLG_RT_HANDLE}, 81 { MSG_ORIG(MSG_FLG_RELOCING), FLG_RT_RELOCING, FLG_RT_RELOCING}, 82 { NULL, 0, 0} 83 }; 84 85 static const mdb_bitmask_t rtflags1_bits[] = { 86 { MSG_ORIG(MSG_FL1_COPYTOOK), FL1_RT_COPYTOOK, FL1_RT_COPYTOOK}, 87 { MSG_ORIG(MSG_FL1_RELATIVE), FL1_RT_RELATIVE, FL1_RT_RELATIVE }, 88 { MSG_ORIG(MSG_FL1_CONFSET), FL1_RT_CONFSET, FL1_RT_CONFSET }, 89 { MSG_ORIG(MSG_FL1_NODEFLIB), FL1_RT_NODEFLIB, FL1_RT_NODEFLIB }, 90 { MSG_ORIG(MSG_FL1_ENDFILTE), FL1_RT_ENDFILTE, FL1_RT_ENDFILTE }, 91 { MSG_ORIG(MSG_FL1_DISPREL), FL1_RT_DISPREL, FL1_RT_DISPREL }, 92 { MSG_ORIG(MSG_FL1_TEXTREL), FL1_RT_TEXTREL, FL1_RT_TEXTREL }, 93 { MSG_ORIG(MSG_FL1_INITWAIT), FL1_RT_INITWAIT, FL1_RT_INITWAIT }, 94 { MSG_ORIG(MSG_FL1_LDDSTUB), FL1_RT_LDDSTUB, FL1_RT_LDDSTUB}, 95 { MSG_ORIG(MSG_FL1_NOINIFIN), FL1_RT_NOINIFIN, FL1_RT_NOINIFIN }, 96 { MSG_ORIG(MSG_FL1_USED), FL1_RT_USED, FL1_RT_USED }, 97 { MSG_ORIG(MSG_FL1_SYMBOLIC), FL1_RT_SYMBOLIC, FL1_RT_SYMBOLIC }, 98 { MSG_ORIG(MSG_FL1_OBJSFLTR), FL1_RT_OBJSFLTR, FL1_RT_OBJSFLTR }, 99 { MSG_ORIG(MSG_FL1_OBJAFLTR), FL1_RT_OBJAFLTR, FL1_RT_OBJAFLTR }, 100 { MSG_ORIG(MSG_FL1_SYMSFLTR), FL1_RT_SYMSFLTR, FL1_RT_SYMSFLTR }, 101 { MSG_ORIG(MSG_FL1_SYMAFLTR), FL1_RT_SYMAFLTR, FL1_RT_SYMAFLTR }, 102 { MSG_ORIG(MSG_FL1_TLSADD), FL1_RT_TLSADD, FL1_RT_TLSADD }, 103 { MSG_ORIG(MSG_FL1_TLSSTAT), FL1_RT_TLSSTAT, FL1_RT_TLSSTAT }, 104 { MSG_ORIG(MSG_FL1_DIRECT), FL1_RT_DIRECT, FL1_RT_DIRECT}, 105 { MSG_ORIG(MSG_FL1_GLOBAUD), FL1_RT_GLOBAUD, FL1_RT_GLOBAUD}, 106 107 { MSG_ORIG(MSG_LTFL_AUD_PREINIT), LML_TFLG_AUD_PREINIT, 108 LML_TFLG_AUD_PREINIT }, 109 { MSG_ORIG(MSG_LTFL_AUD_OBJSEARCH), LML_TFLG_AUD_OBJSEARCH, 110 LML_TFLG_AUD_OBJSEARCH }, 111 { MSG_ORIG(MSG_LTFL_AUD_OBJOPEN), LML_TFLG_AUD_OBJOPEN, 112 LML_TFLG_AUD_OBJOPEN }, 113 { MSG_ORIG(MSG_LTFL_AUD_OBJFILTER), LML_TFLG_AUD_OBJFILTER, 114 LML_TFLG_AUD_OBJFILTER }, 115 { MSG_ORIG(MSG_LTFL_AUD_OBJCLOSE), LML_TFLG_AUD_OBJCLOSE, 116 LML_TFLG_AUD_OBJCLOSE }, 117 { MSG_ORIG(MSG_LTFL_AUD_SYMBIND), LML_TFLG_AUD_SYMBIND, 118 LML_TFLG_AUD_SYMBIND }, 119 { MSG_ORIG(MSG_LTFL_AUD_PLTENTER), LML_TFLG_AUD_PLTENTER, 120 LML_TFLG_AUD_PLTENTER }, 121 { MSG_ORIG(MSG_LTFL_AUD_PLTEXIT), LML_TFLG_AUD_PLTEXIT, 122 LML_TFLG_AUD_PLTEXIT }, 123 { MSG_ORIG(MSG_LTFL_AUD_ACTIVITY), LML_TFLG_AUD_ACTIVITY, 124 LML_TFLG_AUD_ACTIVITY }, 125 { NULL, 0, 0} 126 }; 127 128 static const mdb_bitmask_t rtmode_bits[] = { 129 { MSG_ORIG(MSG_MODE_LAZY), RTLD_LAZY, RTLD_LAZY }, 130 { MSG_ORIG(MSG_MODE_NOW), RTLD_NOW, RTLD_NOW }, 131 { MSG_ORIG(MSG_MODE_NOLOAD), RTLD_NOLOAD, RTLD_NOLOAD }, 132 { MSG_ORIG(MSG_MODE_GLOBAL), RTLD_GLOBAL, RTLD_GLOBAL }, 133 { MSG_ORIG(MSG_MODE_PARENT), RTLD_PARENT, RTLD_PARENT }, 134 { MSG_ORIG(MSG_MODE_GROUP), RTLD_GROUP, RTLD_GROUP }, 135 { MSG_ORIG(MSG_MODE_WORLD), RTLD_WORLD, RTLD_WORLD }, 136 { MSG_ORIG(MSG_MODE_NODELETE), RTLD_NODELETE, RTLD_NODELETE }, 137 { MSG_ORIG(MSG_MODE_FIRST), RTLD_FIRST, RTLD_FIRST }, 138 { MSG_ORIG(MSG_MODE_CONFGEN), RTLD_CONFGEN, RTLD_CONFGEN }, 139 { NULL, 0, 0} 140 }; 141 142 static const mdb_bitmask_t bndflags_bits[] = { 143 { MSG_ORIG(MSG_BFL_NEEDED), BND_NEEDED, BND_NEEDED }, 144 { MSG_ORIG(MSG_BFL_REFER), BND_REFER, BND_REFER }, 145 { MSG_ORIG(MSG_BFL_FILTER), BND_FILTER, BND_FILTER }, 146 { NULL, 0, 0} 147 }; 148 149 static const mdb_bitmask_t grhflags_bits[] = { 150 { MSG_ORIG(MSG_GPH_ZERO), GPH_ZERO, GPH_ZERO }, 151 { MSG_ORIG(MSG_GPH_LDSO), GPH_LDSO, GPH_LDSO }, 152 { MSG_ORIG(MSG_GPH_FIRST), GPH_FIRST, GPH_FIRST }, 153 { MSG_ORIG(MSG_GPH_PARENT), GPH_PARENT, GPH_PARENT }, 154 { MSG_ORIG(MSG_GPH_FILTEE), GPH_FILTEE, GPH_FILTEE }, 155 { MSG_ORIG(MSG_GPH_INITIAL), GPH_INITIAL, GPH_INITIAL }, 156 { MSG_ORIG(MSG_GPH_NOPENDLAZY), GPH_NOPENDLAZY, GPH_NOPENDLAZY }, 157 { NULL, 0, 0} 158 }; 159 160 static const mdb_bitmask_t grdflags_bits[] = { 161 { MSG_ORIG(MSG_GPD_DLSYM), GPD_DLSYM, GPD_DLSYM }, 162 { MSG_ORIG(MSG_GPD_RELOC), GPD_RELOC, GPD_RELOC }, 163 { MSG_ORIG(MSG_GPD_ADDEPS), GPD_ADDEPS, GPD_ADDEPS }, 164 { MSG_ORIG(MSG_GPD_PARENT), GPD_PARENT, GPD_PARENT }, 165 { MSG_ORIG(MSG_GPD_FILTER), GPD_FILTER, GPD_FILTER }, 166 { MSG_ORIG(MSG_GPD_REMOVE), GPD_REMOVE, GPD_REMOVE }, 167 { NULL, 0, 0} 168 }; 169 170 static const mdb_bitmask_t lmc_bits[] = { 171 { MSG_ORIG(MSG_LMC_ANALYZING), LMC_FLG_ANALYZING, LMC_FLG_ANALYZING}, 172 { MSG_ORIG(MSG_LMC_RELOCATING), LMC_FLG_RELOCATING, LMC_FLG_RELOCATING}, 173 { MSG_ORIG(MSG_LMC_REANALYZE), LMC_FLG_REANALYZE, LMC_FLG_REANALYZE}, 174 { NULL, 0, 0} 175 }; 176 177 /* 178 * Obtain a string - typically a link-map name. 179 */ 180 static char * 181 String(uintptr_t addr, const char *name) 182 { 183 static char str[MAXPATHLEN]; 184 185 if (addr) { 186 if (mdb_readstr(str, MAXPATHLEN, addr) == -1) { 187 mdb_warn(MSG_ORIG(MSG_ERR_READ), name, addr); 188 return (0); 189 } 190 return (str); 191 } 192 return ((char *)MSG_ORIG(MSG_STR_EMPTY)); 193 } 194 195 /* 196 * Obtain a link-map name. 197 */ 198 static char * 199 Rtmap_Name(uintptr_t addr) 200 { 201 Rt_map rtmap; 202 203 if (addr) { 204 if (mdb_vread(&rtmap, sizeof (Rt_map), addr) == -1) { 205 mdb_warn(MSG_ORIG(MSG_ERR_READ), 206 MSG_ORIG(MSG_RTMAP_STR), addr); 207 return (0); 208 } 209 return (String((uintptr_t)NAME(&rtmap), 210 MSG_ORIG(MSG_STR_NAME))); 211 } 212 return ((char *)MSG_ORIG(MSG_STR_EMPTY)); 213 } 214 215 void 216 dcmd_Bind_help(void) 217 { 218 mdb_printf(MSG_ORIG(MSG_BND_HELP)); 219 } 220 221 static int 222 /* ARGSUSED2 */ 223 dcmd_Bind(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 224 { 225 Bnd_desc bnd; 226 char *str; 227 228 /* 229 * Insure we have a valid address. 230 */ 231 if ((flags & DCMD_ADDRSPEC) == 0) { 232 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_BND_STR)); 233 return (DCMD_USAGE); 234 } 235 236 /* 237 * Obtain the binding descriptor. 238 */ 239 if (mdb_vread(&bnd, sizeof (Bnd_desc), addr) == -1) { 240 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_BND_STR), addr); 241 return (DCMD_ERR); 242 } 243 mdb_printf(MSG_ORIG(MSG_BND_TITLE), addr); 244 245 /* 246 * Establish the identity of the caller. 247 */ 248 if ((str = Rtmap_Name((uintptr_t)bnd.b_caller)) == 0) 249 return (DCMD_ERR); 250 mdb_printf(MSG_ORIG(MSG_BND_LINE1), bnd.b_caller, str); 251 252 /* 253 * Establish the identity of the dependency. 254 */ 255 if ((str = Rtmap_Name((uintptr_t)bnd.b_depend)) == 0) 256 return (DCMD_ERR); 257 mdb_printf(MSG_ORIG(MSG_BND_LINE2), bnd.b_depend, str); 258 259 /* 260 * Display any flags. 261 */ 262 mdb_printf(MSG_ORIG(MSG_BND_LINE3), bnd.b_flags, bnd.b_flags, 263 bndflags_bits); 264 265 return (DCMD_OK); 266 } 267 268 static void 269 dcmd_Depends_help(void) 270 { 271 mdb_printf(MSG_ORIG(MSG_DEPENDS_HELP)); 272 } 273 274 static int 275 Depends(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv, 276 uint_t flg, const char *msg) 277 { 278 Alist al; 279 uintptr_t listcalc, listnext; 280 size_t ucnt, tcnt; 281 Bnd_desc * bdp; 282 283 /* 284 * Obtain the Alist and determine its number of elements and those 285 * that are in use. 286 */ 287 if (mdb_vread(&al, sizeof (Alist), addr) == -1) { 288 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); 289 return (DCMD_ERR); 290 } 291 292 ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; 293 tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; 294 mdb_printf(msg, addr, ucnt, tcnt); 295 296 if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) 297 return (DCMD_OK); 298 299 /* 300 * Under verbose mode print the name of each dependency. An Alist can 301 * have a variable number of data items, so read each individual entry. 302 */ 303 listcalc = (uintptr_t)(&(al.al_data[0])); 304 listcalc -= (uintptr_t)(&al); 305 listcalc += addr; 306 if (mdb_vread(&bdp, sizeof (Bnd_desc *), listcalc) == -1) { 307 mdb_warn(MSG_ORIG(MSG_ERR_READ), 308 MSG_ORIG(MSG_BNDDESC_STR), listcalc); 309 return (DCMD_ERR); 310 } 311 312 mdb_inc_indent(4); 313 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 314 315 if (dcmd_Bind((uintptr_t)bdp, flags, argc, argv) == DCMD_ERR) { 316 mdb_dec_indent(4); 317 return (DCMD_ERR); 318 } 319 320 listnext = (uintptr_t)(al.al_next + addr); 321 for (listcalc += al.al_size; listcalc < listnext; 322 listcalc += al.al_size) { 323 if (mdb_vread(&bdp, sizeof (Bnd_desc *), listcalc) == -1) { 324 mdb_warn(MSG_ORIG(MSG_ERR_READ), 325 MSG_ORIG(MSG_BNDDESC_STR), listcalc); 326 return (DCMD_ERR); 327 } 328 329 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 330 if (dcmd_Bind((uintptr_t)bdp, flags, argc, argv) == DCMD_ERR) { 331 mdb_dec_indent(4); 332 return (DCMD_ERR); 333 } 334 } 335 mdb_dec_indent(4); 336 return (DCMD_OK); 337 } 338 339 static int 340 dcmd_Depends(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 341 { 342 Rt_map rtmap; 343 char *str; 344 uint_t flg = 0; 345 346 /* 347 * Insure we have a valid address, and provide for a -v option. 348 */ 349 if ((flags & DCMD_ADDRSPEC) == 0) { 350 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_DEPENDS_STR)); 351 return (DCMD_USAGE); 352 } 353 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 354 &flg, NULL) != argc) 355 return (DCMD_USAGE); 356 357 /* 358 * Read the Rt_map contents. 359 */ 360 if (mdb_vread(&rtmap, sizeof (Rt_map), addr) == -1) { 361 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_RTMAP_STR), addr); 362 return (DCMD_ERR); 363 } 364 if ((str = String((uintptr_t)NAME(&rtmap), 365 MSG_ORIG(MSG_STR_NAME))) == 0) 366 return (DCMD_ERR); 367 368 mdb_printf(MSG_ORIG(MSG_DEPENDS_LINE1), str); 369 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 370 371 if (DEPENDS(&rtmap) == 0) 372 return (DCMD_OK); 373 374 return (Depends((uintptr_t)DEPENDS(&rtmap), flags, argc, argv, flg, 375 MSG_ORIG(MSG_DEPENDS_LINE2))); 376 } 377 378 static void 379 dcmd_Callers_help(void) 380 { 381 mdb_printf(MSG_ORIG(MSG_CALLERS_HELP)); 382 } 383 384 static int 385 dcmd_Callers(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 386 { 387 Rt_map rtmap; 388 char *str; 389 uint_t flg = 0; 390 391 /* 392 * Insure we have a valid address, and provide for a -v option. 393 */ 394 if ((flags & DCMD_ADDRSPEC) == 0) { 395 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_DEPENDS_STR)); 396 return (DCMD_USAGE); 397 } 398 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 399 &flg, NULL) != argc) 400 return (DCMD_USAGE); 401 402 /* 403 * Read the Rt_map contents. 404 */ 405 if (mdb_vread(&rtmap, sizeof (Rt_map), addr) == -1) { 406 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_RTMAP_STR), addr); 407 return (DCMD_ERR); 408 } 409 if ((str = String((uintptr_t)NAME(&rtmap), 410 MSG_ORIG(MSG_STR_NAME))) == 0) 411 return (DCMD_ERR); 412 413 mdb_printf(MSG_ORIG(MSG_CALLERS_LINE1), str); 414 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 415 416 if (CALLERS(&rtmap) == 0) 417 return (DCMD_OK); 418 419 return (Depends((uintptr_t)CALLERS(&rtmap), flags, argc, argv, flg, 420 MSG_ORIG(MSG_CALLERS_LINE2))); 421 } 422 423 void 424 dcmd_rtmap_help(void) 425 { 426 mdb_printf(MSG_ORIG(MSG_RTMAP_HELP)); 427 } 428 429 static int 430 /* ARGSUSED2 */ 431 dcmd_rtmap(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 432 { 433 Rt_map rtmap; 434 char *str; 435 436 if ((flags & DCMD_ADDRSPEC) == 0) { 437 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_RTMAP_STR)); 438 return (DCMD_USAGE); 439 } 440 441 if (mdb_vread(&rtmap, sizeof (Rt_map), addr) == -1) { 442 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_RTMAP_STR), addr); 443 return (DCMD_ERR); 444 } 445 446 mdb_printf(MSG_ORIG(MSG_RTMAP_TITLE), addr); 447 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 448 449 /* 450 * Determine the objects name. NAME() is the name by which the object 451 * has been opened, typically from adding a search path to a file name. 452 * PATHNAME() is the fully resolve name, which is displayed by the proc 453 * tools and debuggers. If the two names differ, print the PATHNAME(). 454 */ 455 if ((str = String((uintptr_t)NAME(&rtmap), 456 MSG_ORIG(MSG_STR_NAME))) == 0) 457 return (DCMD_ERR); 458 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE1), str); 459 if (NAME(&rtmap) != PATHNAME(&rtmap)) { 460 if ((str = String((uintptr_t)PATHNAME(&rtmap), 461 MSG_ORIG(MSG_STR_PATHNAME))) == 0) 462 return (DCMD_ERR); 463 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE2), str); 464 } 465 466 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE3), ADDR(&rtmap), DYN(&rtmap)); 467 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE4), NEXT(&rtmap), PREV(&rtmap)); 468 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE5), rtmap.rt_fct, TLSMODID(&rtmap)); 469 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE6), INIT(&rtmap), FINI(&rtmap)); 470 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE7), GROUPS(&rtmap), HANDLES(&rtmap)); 471 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE8), DEPENDS(&rtmap), CALLERS(&rtmap)); 472 473 if ((str = String((uintptr_t)REFNAME(&rtmap), 474 MSG_ORIG(MSG_STR_REFNAME))) == 0) 475 return (DCMD_ERR); 476 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE9), DYNINFO(&rtmap), str); 477 478 if ((str = String((uintptr_t)RPATH(&rtmap), 479 MSG_ORIG(MSG_STR_RPATH))) == 0) 480 return (DCMD_ERR); 481 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE10), RLIST(&rtmap), str); 482 483 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE11), LIST(&rtmap), LIST(&rtmap)); 484 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE12), FLAGS(&rtmap)); 485 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), FLAGS(&rtmap), rtflags_bits); 486 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE13), FLAGS1(&rtmap)); 487 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), FLAGS1(&rtmap), rtflags1_bits); 488 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE14), MODE(&rtmap)); 489 mdb_printf(MSG_ORIG(MSG_RTMAP_LINE20), MODE(&rtmap), rtmode_bits); 490 491 return (DCMD_OK); 492 } 493 494 495 static int 496 rtmap_format(uintptr_t addr, const void * data, void * private) 497 { 498 const Rt_map *lmp = (const Rt_map *)data; 499 W_desc *wdp = (W_desc *)private; 500 char *str; 501 502 if (wdp && (wdp->w_flags & RTLD_FLG_VERBOSE)) { 503 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 504 mdb_call_dcmd(MSG_ORIG(MSG_RTMAP_STR), addr, DCMD_ADDRSPEC, 505 NULL, NULL); 506 return (0); 507 } 508 509 if ((str = String((uintptr_t)NAME(lmp), 510 MSG_ORIG(MSG_STR_NAME))) == 0) 511 return (DCMD_ERR); 512 513 mdb_printf(MSG_ORIG(MSG_FMT_RT), CNTL(lmp), addr, ADDR(lmp), str); 514 return (0); 515 } 516 517 void 518 dcmd_Rtmaps_help(void) 519 { 520 mdb_printf(MSG_ORIG(MSG_RTMAPS_HELP)); 521 } 522 523 static int 524 dcmd_Rtmaps(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 525 { 526 uint_t flg = 0; 527 GElf_Sym gsym; 528 List l; 529 Listnode ln; 530 uintptr_t naddr; 531 const char *str; 532 W_desc wdesc; 533 534 /* 535 * '-v' - Verbose output of rtmap 536 */ 537 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 538 &flg, NULL) != argc) 539 return (DCMD_USAGE); 540 541 /* 542 * If an address was provided use it. 543 */ 544 if (flags & DCMD_ADDRSPEC) { 545 if (((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) && 546 !(flg & RTLD_FLG_VERBOSE)) { 547 mdb_printf(MSG_ORIG(MSG_RTMAPS_TITLE0)); 548 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 549 } 550 551 wdesc.w_flags = flg; 552 if (mdb_pwalk(MSG_ORIG(MSG_RTMAPS_STR), rtmap_format, 553 (void *)&wdesc, addr) == -1) 554 return (DCMD_ERR); 555 return (DCMD_OK); 556 } 557 558 /* 559 * Otherwise traverse the dynlm_list and display each link-map. 560 */ 561 if (mdb_lookup_by_obj(MSG_ORIG(MSG_STR_LDSO1), 562 MSG_ORIG(MSG_STR_DYNLMLIST), &gsym) == -1) { 563 mdb_warn(MSG_ORIG(MSG_ERR_SYMFAILED), MSG_ORIG(MSG_STR_LDSO1), 564 MSG_ORIG(MSG_STR_DYNLMLIST)); 565 return (DCMD_ERR); 566 } 567 if (mdb_vread((void *)&l, sizeof (l), (uintptr_t)gsym.st_value) == -1) { 568 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_LIST_STR), 569 gsym.st_value); 570 return (DCMD_ERR); 571 } 572 573 mdb_printf(MSG_ORIG(MSG_LMLIST_TITLE1), MSG_ORIG(MSG_STR_DYNLMLIST), 574 gsym.st_value); 575 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 576 577 flags |= (DCMD_LOOP | DCMD_LOOPFIRST); 578 for (naddr = (uintptr_t)l.head; naddr; naddr = (uintptr_t)ln.next) { 579 Lm_list lml; 580 581 if (mdb_vread(&ln, sizeof (ln), naddr) == -1) { 582 mdb_warn(MSG_ORIG(MSG_ERR_READ), 583 MSG_ORIG(MSG_STR_LISTNODE), naddr); 584 return (DCMD_ERR); 585 } 586 if (mdb_vread(&lml, sizeof (lml), (uintptr_t)ln.data) == -1) { 587 mdb_warn(MSG_ORIG(MSG_ERR_READ), 588 MSG_ORIG(MSG_LMLIST_STR), ln.data); 589 return (DCMD_ERR); 590 } 591 592 mdb_inc_indent(2); 593 if (lml.lm_flags & LML_FLG_BASELM) 594 str = MSG_ORIG(MSG_LMLIST_BASE); 595 else if (lml.lm_flags & LML_FLG_RTLDLM) 596 str = MSG_ORIG(MSG_LMLIST_LDSO); 597 else 598 str = MSG_ORIG(MSG_LMLIST_NEWLM); 599 600 if ((flags & DCMD_LOOP) && ((flags & DCMD_LOOPFIRST) == 0)) 601 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 602 603 mdb_printf(MSG_ORIG(MSG_LMLIST_TITLE2), ln.data, str); 604 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 605 606 mdb_inc_indent(2); 607 608 if (((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) && 609 !(flg & RTLD_FLG_VERBOSE)) { 610 mdb_printf(MSG_ORIG(MSG_RTMAPS_TITLE0)); 611 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 612 } 613 614 wdesc.w_flags = flg; 615 if (mdb_pwalk(MSG_ORIG(MSG_RTMAPS_STR), rtmap_format, 616 (void *)&wdesc, (uintptr_t)lml.lm_head) == -1) { 617 mdb_dec_indent(4); 618 return (DCMD_ERR); 619 } 620 mdb_dec_indent(4); 621 flags &= ~DCMD_LOOPFIRST; 622 } 623 return (DCMD_OK); 624 } 625 626 static int 627 /* ARGSUSED2 */ 628 format_listnode(uintptr_t addr, const void * data, void * private) 629 { 630 Listnode * lnp = (Listnode *)data; 631 632 mdb_printf(MSG_ORIG(MSG_FMT_LN), addr, lnp->data, lnp->next); 633 return (0); 634 } 635 636 void 637 dcmd_List_help(void) 638 { 639 mdb_printf(MSG_ORIG(MSG_LIST_HELP)); 640 } 641 642 static int 643 /* ARGSUSED2 */ 644 dcmd_List(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 645 { 646 if ((flags & DCMD_ADDRSPEC) == 0) 647 return (DCMD_USAGE); 648 if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { 649 mdb_printf(MSG_ORIG(MSG_LIST_TITLE)); 650 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 651 } 652 if (mdb_pwalk(MSG_ORIG(MSG_LIST_STR), format_listnode, 653 (void *)0, addr) == -1) 654 return (DCMD_ERR); 655 return (DCMD_OK); 656 } 657 658 void 659 dcmd_Setenv_help(void) 660 { 661 mdb_printf(MSG_ORIG(MSG_SETENV_HELP)); 662 } 663 664 /* 665 * As of s10, mdb provides its own setenv command. This command allows the 666 * environment of the process being controlled to be changed at any time. 667 * Prior to this, ld.so.1 provided it's own, more primitive implementation. 668 * This allowed for changing mdb's environment only, which if it was changed 669 * before the application ws executed, would be copied to the applications 670 * environment. Thus, we could start mdb, set an LD_ variable within its 671 * environment (which it's own ld.so.1 had already finished processing), and 672 * have this setting be inherited by the application. 673 */ 674 static int 675 /* ARGSUSED */ 676 dcmd_Setenv(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 677 { 678 char *str; 679 680 if (mdb_call_dcmd(MSG_ORIG(MSG_STR_SETENV), addr, flags, argc, 681 argv) == 0) 682 return (DCMD_OK); 683 684 if (((flags & DCMD_ADDRSPEC) != 0) || (argc == 0) || (argc > 1) || 685 (argv->a_type != MDB_TYPE_STRING)) 686 return (DCMD_USAGE); 687 688 str = mdb_alloc((strlen(argv->a_un.a_str) + 1), UM_NOSLEEP); 689 if (str == NULL) 690 return (DCMD_ERR); 691 692 (void) strcpy(str, argv->a_un.a_str); 693 (void) putenv(str); 694 return (DCMD_OK); 695 } 696 697 int 698 walk_List_init(mdb_walk_state_t *wsp) 699 { 700 List lst; 701 702 if (wsp->walk_addr == NULL) { 703 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_LIST_STR)); 704 return (WALK_ERR); 705 } 706 707 if (mdb_vread(&lst, sizeof (List), wsp->walk_addr) == -1) { 708 mdb_warn(MSG_ORIG(MSG_ERR_READ), 709 MSG_ORIG(MSG_LIST_STR), wsp->walk_addr); 710 return (WALK_DONE); 711 } 712 713 wsp->walk_addr = (uintptr_t)lst.head; 714 return (WALK_NEXT); 715 } 716 717 718 static int 719 walk_List_step(mdb_walk_state_t *wsp) 720 { 721 Listnode lnp; 722 int status; 723 724 if (wsp->walk_addr == NULL) 725 return (WALK_DONE); 726 727 if (mdb_vread(&lnp, sizeof (Listnode), wsp->walk_addr) == -1) { 728 mdb_warn(MSG_ORIG(MSG_ERR_READ), 729 MSG_ORIG(MSG_STR_LISTNODE), wsp->walk_addr); 730 return (WALK_DONE); 731 } 732 733 status = wsp->walk_callback(wsp->walk_addr, &lnp, wsp->walk_cbdata); 734 wsp->walk_addr = (uintptr_t)lnp.next; 735 return (status); 736 } 737 738 /* 739 * Walk Rt_map lists 740 */ 741 static int 742 walk_rtmap_init(mdb_walk_state_t *wsp) 743 { 744 if (wsp->walk_addr == NULL) { 745 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_RTMAP_STR)); 746 return (WALK_ERR); 747 } 748 return (WALK_NEXT); 749 } 750 751 static int 752 walk_rtmap_step(mdb_walk_state_t *wsp) 753 { 754 int status; 755 Rt_map lmp; 756 757 if (wsp->walk_addr == NULL) 758 return (WALK_DONE); 759 if (mdb_vread(&lmp, sizeof (Rt_map), wsp->walk_addr) == -1) { 760 mdb_warn(MSG_ORIG(MSG_ERR_READ), 761 MSG_ORIG(MSG_RTMAP_STR), wsp->walk_addr); 762 return (WALK_DONE); 763 } 764 765 status = wsp->walk_callback(wsp->walk_addr, &lmp, wsp->walk_cbdata); 766 wsp->walk_addr = (uintptr_t)(NEXT(&lmp)); 767 return (status); 768 } 769 770 static const mdb_bitmask_t lml_flags_bit[] = { 771 { MSG_ORIG(MSG_LFL_BASELM), LML_FLG_BASELM, LML_FLG_BASELM }, 772 { MSG_ORIG(MSG_LFL_RTLDLM), LML_FLG_RTLDLM, LML_FLG_RTLDLM }, 773 { MSG_ORIG(MSG_LFL_NOAUDIT), LML_FLG_NOAUDIT, LML_FLG_NOAUDIT }, 774 { MSG_ORIG(MSG_LFL_PLTREL), LML_FLG_PLTREL, LML_FLG_PLTREL }, 775 { MSG_ORIG(MSG_LFL_HOLDLOCK), LML_FLG_HOLDLOCK, LML_FLG_HOLDLOCK }, 776 { MSG_ORIG(MSG_LFL_ENVIRON), LML_FLG_ENVIRON, LML_FLG_ENVIRON }, 777 { MSG_ORIG(MSG_LFL_INTRPOSE), LML_FLG_INTRPOSE, LML_FLG_INTRPOSE }, 778 { MSG_ORIG(MSG_LFL_LOCAUDIT), LML_FLG_LOCAUDIT, LML_FLG_LOCAUDIT }, 779 { MSG_ORIG(MSG_LFL_LOADAVAIL), LML_FLG_LOADAVAIL, LML_FLG_LOADAVAIL }, 780 { MSG_ORIG(MSG_LFL_IGNRELERR), LML_FLG_IGNRELERR, LML_FLG_IGNRELERR }, 781 { MSG_ORIG(MSG_LFL_DBNOTIF), LML_FLG_DBNOTIF, LML_FLG_DBNOTIF }, 782 { MSG_ORIG(MSG_LFL_STARTREL), LML_FLG_STARTREL, LML_FLG_STARTREL }, 783 { MSG_ORIG(MSG_LFL_ATEXIT), LML_FLG_ATEXIT, LML_FLG_ATEXIT }, 784 { MSG_ORIG(MSG_LFL_OBJADDED), LML_FLG_OBJADDED, LML_FLG_OBJADDED }, 785 { MSG_ORIG(MSG_LFL_OBJDELETED), LML_FLG_OBJDELETED, 786 LML_FLG_OBJDELETED }, 787 { MSG_ORIG(MSG_LFL_OBJREEVAL), LML_FLG_OBJREEVAL, LML_FLG_OBJREEVAL }, 788 { MSG_ORIG(MSG_LFL_NOPENDGLBLAZY), LML_FLG_NOPENDGLBLAZY, 789 LML_FLG_NOPENDGLBLAZY }, 790 791 { MSG_ORIG(MSG_LFL_TRC_LDDSTUB), LML_FLG_TRC_LDDSTUB, 792 LML_FLG_TRC_LDDSTUB }, 793 { MSG_ORIG(MSG_LFL_TRC_ENABLE), LML_FLG_TRC_ENABLE, 794 LML_FLG_TRC_ENABLE }, 795 { MSG_ORIG(MSG_LFL_TRC_WARN), LML_FLG_TRC_WARN, LML_FLG_TRC_WARN }, 796 { MSG_ORIG(MSG_LFL_TRC_VERBOSE), LML_FLG_TRC_VERBOSE, 797 LML_FLG_TRC_VERBOSE }, 798 { MSG_ORIG(MSG_LFL_TRC_SEARCH), LML_FLG_TRC_SEARCH, 799 LML_FLG_TRC_SEARCH }, 800 { MSG_ORIG(MSG_LFL_TRC_UNREF), LML_FLG_TRC_UNREF, LML_FLG_TRC_UNREF }, 801 { MSG_ORIG(MSG_LFL_TRC_UNUSED), LML_FLG_TRC_UNUSED, 802 LML_FLG_TRC_UNUSED }, 803 { MSG_ORIG(MSG_LFL_TRC_INIT), LML_FLG_TRC_INIT, LML_FLG_TRC_INIT }, 804 { NULL, 0, 0} 805 }; 806 807 static const mdb_bitmask_t lml_tflags_bit[] = { 808 { MSG_ORIG(MSG_LTFL_NOLAZYLD), LML_TFLG_NOLAZYLD, LML_TFLG_NOLAZYLD }, 809 { MSG_ORIG(MSG_LTFL_NODIRECT), LML_TFLG_NODIRECT, LML_TFLG_NODIRECT }, 810 { MSG_ORIG(MSG_LTFL_LOADFLTR), LML_TFLG_LOADFLTR, LML_TFLG_LOADFLTR }, 811 812 { MSG_ORIG(MSG_LTFL_AUD_PREINIT), LML_TFLG_AUD_PREINIT, 813 LML_TFLG_AUD_PREINIT }, 814 { MSG_ORIG(MSG_LTFL_AUD_OBJSEARCH), LML_TFLG_AUD_OBJSEARCH, 815 LML_TFLG_AUD_OBJSEARCH }, 816 { MSG_ORIG(MSG_LTFL_AUD_OBJOPEN), LML_TFLG_AUD_OBJOPEN, 817 LML_TFLG_AUD_OBJOPEN }, 818 { MSG_ORIG(MSG_LTFL_AUD_OBJFILTER), LML_TFLG_AUD_OBJFILTER, 819 LML_TFLG_AUD_OBJFILTER }, 820 { MSG_ORIG(MSG_LTFL_AUD_OBJCLOSE), LML_TFLG_AUD_OBJCLOSE, 821 LML_TFLG_AUD_OBJCLOSE }, 822 { MSG_ORIG(MSG_LTFL_AUD_SYMBIND), LML_TFLG_AUD_SYMBIND, 823 LML_TFLG_AUD_SYMBIND }, 824 { MSG_ORIG(MSG_LTFL_AUD_PLTENTER), LML_TFLG_AUD_PLTENTER, 825 LML_TFLG_AUD_PLTENTER }, 826 { MSG_ORIG(MSG_LTFL_AUD_PLTEXIT), LML_TFLG_AUD_PLTEXIT, 827 LML_TFLG_AUD_PLTEXIT }, 828 { MSG_ORIG(MSG_LTFL_AUD_ACTIVITY), LML_TFLG_AUD_ACTIVITY, 829 LML_TFLG_AUD_ACTIVITY }, 830 { NULL, 0, 0} 831 }; 832 833 void 834 dcmd_Lm_list_help(void) 835 { 836 mdb_printf(MSG_ORIG(MSG_LMLIST_HELP)); 837 } 838 839 static int 840 /* ARGSUSED1 */ 841 _dcmd_Lm_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 842 { 843 Lm_list lml; 844 const char *str; 845 uint_t flg = 0; 846 847 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 848 &flg, NULL) != argc) 849 return (DCMD_USAGE); 850 851 if (mdb_vread(&lml, sizeof (lml), addr) == -1) { 852 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_LMLIST_STR), 853 addr); 854 return (DCMD_ERR); 855 } 856 857 if (lml.lm_flags & LML_FLG_BASELM) 858 str = MSG_ORIG(MSG_LMLIST_BASE); 859 else if (lml.lm_flags & LML_FLG_RTLDLM) 860 str = MSG_ORIG(MSG_LMLIST_LDSO); 861 else 862 str = MSG_ORIG(MSG_LMLIST_NEWLM); 863 864 if ((flags & DCMD_LOOP) && ((flags & DCMD_LOOPFIRST) == 0)) 865 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 866 867 mdb_printf(MSG_ORIG(MSG_LMLIST_TITLE2), addr, str); 868 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 869 870 if (lml.lm_lists) { 871 Alist al; 872 size_t ucnt, tcnt; 873 Lm_cntl lmc; 874 uintptr_t listcalc; 875 876 addr = (uintptr_t)lml.lm_lists; 877 if (mdb_vread(&al, sizeof (Alist), addr) == -1) { 878 mdb_warn(MSG_ORIG(MSG_ERR_READ), 879 MSG_ORIG(MSG_STR_ALIST), addr); 880 return (DCMD_ERR); 881 } 882 883 /* 884 * Determine whether the Alist has been populated. Note, the 885 * implementation first reserves an alist entry, and initializes 886 * this element when the first link-map is processed. Thus, 887 * there's a window when ucnt is updated, but before the next 888 * element has been initialized. 889 */ 890 ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / 891 al.al_size; 892 tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / 893 al.al_size; 894 895 if (ucnt && (flg & RTLD_FLG_VERBOSE)) { 896 listcalc = (uintptr_t)(&(al.al_data[0])); 897 listcalc -= (uintptr_t)(&al); 898 listcalc += addr; 899 900 if (mdb_vread(&lmc, sizeof (Lm_cntl), 901 listcalc) == -1) { 902 mdb_warn(MSG_ORIG(MSG_ERR_READ), 903 MSG_ORIG(MSG_LMLIST_STR), listcalc); 904 return (DCMD_ERR); 905 } 906 } 907 908 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE0), addr, ucnt, tcnt); 909 mdb_inc_indent(2); 910 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 911 912 if (ucnt && (flg & RTLD_FLG_VERBOSE)) { 913 uintptr_t listnext; 914 915 mdb_inc_indent(2); 916 mdb_printf(MSG_ORIG(MSG_LMC_LINE1), listcalc); 917 mdb_printf(MSG_ORIG(MSG_LMC_LINE2), lmc.lc_head, 918 lmc.lc_tail); 919 mdb_printf(MSG_ORIG(MSG_LMC_LINE3), lmc.lc_flags, 920 lmc.lc_now); 921 mdb_printf(MSG_ORIG(MSG_LMC_LINE4), lmc.lc_flags, 922 lmc_bits); 923 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 924 mdb_printf(MSG_ORIG(MSG_RTMAPS_TITLE0)); 925 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 926 927 if (lmc.lc_head) { 928 if (mdb_pwalk(MSG_ORIG(MSG_RTMAPS_STR), 929 rtmap_format, (void *)0, 930 (uintptr_t)lmc.lc_head) == -1) { 931 mdb_dec_indent(4); 932 return (DCMD_ERR); 933 } 934 } else 935 mdb_printf(MSG_ORIG(MSG_FMT_RT), 0, 0, 0, 936 MSG_ORIG(MSG_STR_EMPTY)); 937 938 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 939 940 listnext = (uintptr_t)(al.al_next + addr); 941 for (listcalc += al.al_size; listcalc < listnext; 942 listcalc += al.al_size) { 943 if (mdb_vread(&lmc, sizeof (Lm_cntl), 944 listcalc) == -1) { 945 mdb_warn(MSG_ORIG(MSG_ERR_READ), 946 MSG_ORIG(MSG_LMLIST_STR), listcalc); 947 mdb_dec_indent(4); 948 return (DCMD_ERR); 949 } 950 951 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 952 mdb_printf(MSG_ORIG(MSG_LMC_LINE1), listcalc); 953 mdb_printf(MSG_ORIG(MSG_LMC_LINE2), 954 lmc.lc_head, lmc.lc_tail); 955 mdb_printf(MSG_ORIG(MSG_LMC_LINE3), 956 lmc.lc_flags, lmc.lc_now); 957 mdb_printf(MSG_ORIG(MSG_LMC_LINE4), 958 lmc.lc_flags, lmc_bits); 959 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 960 mdb_printf(MSG_ORIG(MSG_RTMAPS_TITLE0)); 961 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 962 963 if (lmc.lc_head) { 964 if (mdb_pwalk(MSG_ORIG(MSG_RTMAPS_STR), 965 rtmap_format, (void *)0, 966 (uintptr_t)lmc.lc_head) == -1) { 967 mdb_dec_indent(4); 968 return (DCMD_ERR); 969 } 970 } else 971 mdb_printf(MSG_ORIG(MSG_FMT_RT), 0, 0, 972 0, MSG_ORIG(MSG_STR_EMPTY)); 973 974 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 975 } 976 mdb_dec_indent(2); 977 } 978 mdb_dec_indent(2); 979 } 980 981 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE1), lml.lm_head, lml.lm_tail); 982 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE2), lml.lm_alp, lml.lm_rti); 983 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE3), lml.lm_handle, lml.lm_obj, 984 lml.lm_init, lml.lm_lazy); 985 986 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE4), lml.lm_flags); 987 if (lml.lm_flags) 988 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE6), lml.lm_flags, 989 lml_flags_bit); 990 991 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE5), lml.lm_tflags); 992 if (lml.lm_tflags) 993 mdb_printf(MSG_ORIG(MSG_LMLIST_LINE6), lml.lm_tflags, 994 lml_tflags_bit); 995 996 return (DCMD_OK); 997 } 998 999 static int 1000 /* ARGSUSED2 */ 1001 dcmd_Lm_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1002 { 1003 GElf_Sym gsym; 1004 List l; 1005 Listnode ln; 1006 uintptr_t naddr; 1007 1008 /* 1009 * If an address was provided us it. 1010 */ 1011 if (flags & DCMD_ADDRSPEC) 1012 return (_dcmd_Lm_list(addr, flags, argc, argv)); 1013 1014 /* 1015 * Otherwise traverse the dynlm_list and display each link-map list. 1016 */ 1017 if (mdb_lookup_by_obj(MSG_ORIG(MSG_STR_LDSO1), 1018 MSG_ORIG(MSG_STR_DYNLMLIST), &gsym) == -1) { 1019 mdb_warn(MSG_ORIG(MSG_ERR_SYMFAILED), MSG_ORIG(MSG_STR_LDSO1), 1020 MSG_ORIG(MSG_STR_DYNLMLIST)); 1021 return (DCMD_ERR); 1022 } 1023 if (mdb_vread((void *)&l, sizeof (l), (uintptr_t)gsym.st_value) == -1) { 1024 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_LIST_STR), 1025 gsym.st_value); 1026 return (DCMD_ERR); 1027 } 1028 1029 mdb_printf(MSG_ORIG(MSG_LMLIST_TITLE1), MSG_ORIG(MSG_STR_DYNLMLIST), 1030 gsym.st_value); 1031 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1032 1033 flags |= (DCMD_LOOP | DCMD_LOOPFIRST); 1034 for (naddr = (uintptr_t)l.head; naddr; naddr = (uintptr_t)ln.next) { 1035 if (mdb_vread(&ln, sizeof (ln), naddr) == -1) { 1036 mdb_warn(MSG_ORIG(MSG_ERR_READ), 1037 MSG_ORIG(MSG_STR_LISTNODE), naddr); 1038 return (DCMD_ERR); 1039 } 1040 1041 mdb_inc_indent(2); 1042 if (_dcmd_Lm_list((uintptr_t)ln.data, flags, 1043 argc, argv) == DCMD_ERR) { 1044 mdb_dec_indent(2); 1045 return (DCMD_ERR); 1046 } 1047 mdb_dec_indent(2); 1048 flags &= ~DCMD_LOOPFIRST; 1049 } 1050 return (DCMD_OK); 1051 } 1052 1053 void 1054 dcmd_GrpDesc_help(void) 1055 { 1056 mdb_printf(MSG_ORIG(MSG_GRPDESC_HELP)); 1057 } 1058 1059 static int 1060 /* ARGSUSED2 */ 1061 dcmd_GrpDesc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1062 { 1063 Grp_desc gd; 1064 char *str; 1065 1066 /* 1067 * Insure we have a valid address. 1068 */ 1069 if ((flags & DCMD_ADDRSPEC) == 0) { 1070 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_GRPDESC_STR)); 1071 return (DCMD_USAGE); 1072 } 1073 1074 mdb_printf(MSG_ORIG(MSG_GRPDESC_LINE1), addr); 1075 if (mdb_vread(&gd, sizeof (Grp_desc), addr) == -1) { 1076 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_GRPDESC_STR), 1077 addr); 1078 return (DCMD_ERR); 1079 } 1080 1081 if ((str = Rtmap_Name((uintptr_t)gd.gd_depend)) == 0) 1082 return (DCMD_ERR); 1083 1084 mdb_printf(MSG_ORIG(MSG_GRPDESC_LINE2), gd.gd_depend, str); 1085 mdb_printf(MSG_ORIG(MSG_GRPDESC_LINE3), gd.gd_flags, gd.gd_flags, 1086 grdflags_bits); 1087 1088 return (DCMD_OK); 1089 } 1090 1091 void 1092 dcmd_GrpHdl_help(void) 1093 { 1094 mdb_printf(MSG_ORIG(MSG_GRPHDL_HELP)); 1095 } 1096 1097 static int 1098 /* ARGSUSED2 */ 1099 dcmd_GrpHdl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1100 { 1101 Grp_hdl gh; 1102 Alist al; 1103 uintptr_t listcalc, listnext; 1104 char *str; 1105 uint_t flg = 0; 1106 size_t ucnt, tcnt; 1107 1108 /* 1109 * Insure we have a valid address, and provide for a -v option. 1110 */ 1111 if ((flags & DCMD_ADDRSPEC) == 0) { 1112 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_GRPHDL_STR)); 1113 return (DCMD_USAGE); 1114 } 1115 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 1116 &flg, NULL) != argc) 1117 return (DCMD_USAGE); 1118 1119 mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE1), addr); 1120 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1121 1122 if (mdb_vread(&gh, sizeof (Grp_hdl), addr) == -1) { 1123 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_GRPHDL_STR), 1124 addr); 1125 return (DCMD_ERR); 1126 } 1127 1128 /* 1129 * Determine the handles owner. Note that an orphaned handle may no 1130 * longer contain its originating owner. 1131 */ 1132 if (gh.gh_ownlmp) { 1133 if ((str = Rtmap_Name((uintptr_t)gh.gh_ownlmp)) == 0) 1134 return (DCMD_ERR); 1135 } else 1136 str = (char *)MSG_ORIG(MSG_STR_ORPHANED); 1137 1138 mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE2), str); 1139 mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE3), gh.gh_flags, gh.gh_flags, 1140 grhflags_bits); 1141 1142 if (gh.gh_depends == 0) { 1143 mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE4), gh.gh_refcnt); 1144 return (DCMD_OK); 1145 } 1146 1147 addr = (uintptr_t)gh.gh_depends; 1148 if (mdb_vread(&al, sizeof (Alist), addr) == -1) { 1149 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); 1150 return (DCMD_ERR); 1151 } 1152 1153 ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; 1154 tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; 1155 mdb_printf(MSG_ORIG(MSG_GRPHDL_LINE5), gh.gh_refcnt, addr, ucnt, tcnt); 1156 1157 if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) 1158 return (DCMD_OK); 1159 1160 mdb_inc_indent(4); 1161 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1162 1163 /* 1164 * Under verbose mode print the name of each dependency. An Alist can 1165 * have a variable number of data items, so read each individual entry. 1166 */ 1167 listcalc = (uintptr_t)(&(al.al_data[0])); 1168 listcalc -= (uintptr_t)(&al); 1169 listcalc += addr; 1170 if (dcmd_GrpDesc(listcalc, flags, argc, argv) == DCMD_ERR) { 1171 mdb_dec_indent(4); 1172 return (DCMD_ERR); 1173 } 1174 1175 listnext = (uintptr_t)(al.al_next + addr); 1176 for (listcalc += al.al_size; listcalc < listnext; 1177 listcalc += al.al_size) { 1178 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1179 if (dcmd_GrpDesc(listcalc, flags, argc, argv) == DCMD_ERR) { 1180 mdb_dec_indent(4); 1181 return (DCMD_ERR); 1182 } 1183 } 1184 1185 mdb_dec_indent(4); 1186 return (DCMD_OK); 1187 } 1188 1189 static void 1190 dcmd_Handles_help(void) 1191 { 1192 mdb_printf(MSG_ORIG(MSG_HANDLES_HELP)); 1193 } 1194 1195 static int 1196 dcmd_Handles(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1197 { 1198 Rt_map rtmap; 1199 char *str; 1200 uint_t flg = 0; 1201 Alist al; 1202 uintptr_t listcalc, listnext; 1203 size_t ucnt, tcnt; 1204 Grp_hdl * ghp; 1205 1206 /* 1207 * Insure we have a valid address, and provide for a -v option. 1208 */ 1209 if ((flags & DCMD_ADDRSPEC) == 0) { 1210 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_HANDLES_STR)); 1211 return (DCMD_USAGE); 1212 } 1213 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 1214 &flg, NULL) != argc) 1215 return (DCMD_USAGE); 1216 1217 /* 1218 * Read the Rt_map contents. 1219 */ 1220 if (mdb_vread(&rtmap, sizeof (Rt_map), addr) == -1) { 1221 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_RTMAP_STR), addr); 1222 return (DCMD_ERR); 1223 } 1224 if ((str = String((uintptr_t)NAME(&rtmap), 1225 MSG_ORIG(MSG_STR_NAME))) == 0) 1226 return (DCMD_ERR); 1227 1228 mdb_printf(MSG_ORIG(MSG_HANDLES_LINE1), str); 1229 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1230 1231 if (HANDLES(&rtmap) == 0) 1232 return (DCMD_OK); 1233 1234 addr = (uintptr_t)HANDLES(&rtmap); 1235 if (mdb_vread(&al, sizeof (Alist), addr) == -1) { 1236 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); 1237 return (DCMD_ERR); 1238 } 1239 1240 ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; 1241 tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; 1242 mdb_printf(MSG_ORIG(MSG_HANDLES_LINE2), addr, ucnt, tcnt); 1243 1244 if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) 1245 return (DCMD_OK); 1246 1247 /* 1248 * Under verbose mode print the name of each dependency. An Alist can 1249 * have a variable number of data items, so read each individual entry. 1250 */ 1251 listcalc = (uintptr_t)(&(al.al_data[0])); 1252 listcalc -= (uintptr_t)(&al); 1253 listcalc += addr; 1254 if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) { 1255 mdb_warn(MSG_ORIG(MSG_ERR_READ), 1256 MSG_ORIG(MSG_GRPHDL_STR), listcalc); 1257 return (DCMD_ERR); 1258 } 1259 1260 mdb_inc_indent(4); 1261 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1262 1263 if (dcmd_GrpHdl((uintptr_t)ghp, flags, argc, argv) == DCMD_ERR) { 1264 mdb_dec_indent(4); 1265 return (DCMD_ERR); 1266 } 1267 1268 listnext = (uintptr_t)(al.al_next + addr); 1269 for (listcalc += al.al_size; listcalc < listnext; 1270 listcalc += al.al_size) { 1271 if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) { 1272 mdb_warn(MSG_ORIG(MSG_ERR_READ), 1273 MSG_ORIG(MSG_GRPHDL_STR), listcalc); 1274 return (DCMD_ERR); 1275 } 1276 1277 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1278 if (dcmd_GrpHdl((uintptr_t)ghp, flags, argc, 1279 argv) == DCMD_ERR) { 1280 mdb_dec_indent(4); 1281 return (DCMD_ERR); 1282 } 1283 } 1284 mdb_dec_indent(4); 1285 return (DCMD_OK); 1286 } 1287 1288 static void 1289 dcmd_Groups_help(void) 1290 { 1291 mdb_printf(MSG_ORIG(MSG_GROUPS_HELP)); 1292 } 1293 1294 1295 static int 1296 dcmd_Groups(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1297 { 1298 Rt_map rtmap; 1299 char *str; 1300 Alist al; 1301 uint_t flg = 0; 1302 uintptr_t listcalc, listnext; 1303 size_t ucnt, tcnt; 1304 Grp_hdl * ghp; 1305 1306 /* 1307 * Insure we have a valid address, and provide for a -v option. 1308 */ 1309 if ((flags & DCMD_ADDRSPEC) == 0) { 1310 mdb_warn(MSG_ORIG(MSG_ERR_NAS), MSG_ORIG(MSG_GROUPS_STR)); 1311 return (DCMD_USAGE); 1312 } 1313 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, RTLD_FLG_VERBOSE, 1314 &flg, NULL) != argc) 1315 return (DCMD_USAGE); 1316 1317 /* 1318 * Read the Rt_map contents. 1319 */ 1320 if (mdb_vread(&rtmap, sizeof (Rt_map), addr) == -1) { 1321 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_RTMAP_STR), addr); 1322 return (DCMD_ERR); 1323 } 1324 if ((str = String((uintptr_t)NAME(&rtmap), 1325 MSG_ORIG(MSG_STR_NAME))) == 0) 1326 return (DCMD_ERR); 1327 1328 mdb_printf(MSG_ORIG(MSG_GROUPS_LINE1), str); 1329 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1330 1331 if (GROUPS(&rtmap) == 0) 1332 return (DCMD_OK); 1333 1334 addr = (uintptr_t)GROUPS(&rtmap); 1335 if (mdb_vread(&al, sizeof (Alist), addr) == -1) { 1336 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_STR_ALIST), addr); 1337 return (DCMD_ERR); 1338 } 1339 1340 ucnt = (al.al_next - sizeof (Alist) + sizeof (void *)) / al.al_size; 1341 tcnt = (al.al_end - sizeof (Alist) + sizeof (void *)) / al.al_size; 1342 mdb_printf(MSG_ORIG(MSG_GROUPS_LINE2), addr, ucnt, tcnt); 1343 1344 if (((flg & RTLD_FLG_VERBOSE) == 0) || (ucnt == 0)) 1345 return (DCMD_OK); 1346 1347 /* 1348 * Under verbose mode print the name of each dependency. An Alist can 1349 * have a variable number of data items, so read each individual entry. 1350 */ 1351 listcalc = (uintptr_t)(&(al.al_data[0])); 1352 listcalc -= (uintptr_t)(&al); 1353 listcalc += addr; 1354 if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) { 1355 mdb_warn(MSG_ORIG(MSG_ERR_READ), 1356 MSG_ORIG(MSG_GRPHDL_STR), listcalc); 1357 return (DCMD_ERR); 1358 } 1359 1360 mdb_inc_indent(4); 1361 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1362 1363 if (dcmd_GrpHdl((uintptr_t)ghp, flags, argc, argv) == DCMD_ERR) { 1364 mdb_dec_indent(4); 1365 return (DCMD_ERR); 1366 } 1367 1368 listnext = (uintptr_t)(al.al_next + addr); 1369 for (listcalc += al.al_size; listcalc < listnext; 1370 listcalc += al.al_size) { 1371 if (mdb_vread(&ghp, sizeof (Grp_hdl *), listcalc) == -1) { 1372 mdb_warn(MSG_ORIG(MSG_ERR_READ), 1373 MSG_ORIG(MSG_GRPHDL_STR), listcalc); 1374 return (DCMD_ERR); 1375 } 1376 1377 mdb_printf(MSG_ORIG(MSG_STR_DASHES)); 1378 if (dcmd_GrpHdl((uintptr_t)ghp, flags, argc, 1379 argv) == DCMD_ERR) { 1380 mdb_dec_indent(4); 1381 return (DCMD_ERR); 1382 } 1383 } 1384 mdb_dec_indent(4); 1385 return (DCMD_OK); 1386 } 1387 static void 1388 dcmd_ElfDyn_help(void) 1389 { 1390 mdb_printf(MSG_ORIG(MSG_ELFDYN_HELP)); 1391 } 1392 1393 static int 1394 /* ARGSUSED2 */ 1395 dcmd_ElfDyn(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1396 { 1397 Dyn dyn; 1398 const char *dynstr; 1399 Conv_inv_buf_t inv_buf; 1400 1401 if ((flags & DCMD_ADDRSPEC) == 0) 1402 return (DCMD_USAGE); 1403 if (mdb_vread(&dyn, sizeof (dyn), addr) == -1) { 1404 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_ELFDYN_STR), 1405 addr); 1406 return (DCMD_ERR); 1407 } 1408 1409 mdb_printf(MSG_ORIG(MSG_ELFDYN_TITLE), addr); 1410 dynstr = conv_dyn_tag(dyn.d_tag, M_MACH, 0, &inv_buf); 1411 mdb_printf(MSG_ORIG(MSG_ELFDYN_LINE1), addr, dynstr, dyn.d_un.d_ptr); 1412 1413 mdb_set_dot(addr + sizeof (Dyn)); 1414 1415 return (DCMD_OK); 1416 } 1417 1418 static void 1419 dcmd_ElfEhdr_help(void) 1420 { 1421 mdb_printf(MSG_ORIG(MSG_EHDR_HELP)); 1422 } 1423 1424 static int 1425 /* ARGSUSED2 */ 1426 dcmd_ElfEhdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1427 { 1428 Ehdr ehdr; 1429 Byte *byte; 1430 const char *flgs; 1431 Conv_inv_buf_t inv_buf1, inv_buf2; 1432 Conv_ehdr_flags_buf_t ehdr_flags_buf; 1433 1434 1435 if ((flags & DCMD_ADDRSPEC) == 0) 1436 return (DCMD_USAGE); 1437 1438 if (mdb_vread(&ehdr, sizeof (ehdr), addr) == -1) { 1439 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_EHDR_STR), 1440 addr); 1441 return (DCMD_ERR); 1442 } 1443 1444 mdb_printf(MSG_ORIG(MSG_EHDR_TITLE), addr); 1445 byte = &ehdr.e_ident[0]; 1446 mdb_printf(MSG_ORIG(MSG_EHDR_LINE1), byte[EI_MAG0], 1447 (byte[EI_MAG1] ? byte[EI_MAG1] : '0'), 1448 (byte[EI_MAG2] ? byte[EI_MAG2] : '0'), 1449 (byte[EI_MAG3] ? byte[EI_MAG3] : '0')); 1450 mdb_printf(MSG_ORIG(MSG_EHDR_LINE2), 1451 conv_ehdr_class(ehdr.e_ident[EI_CLASS], 0, &inv_buf1), 1452 conv_ehdr_data(ehdr.e_ident[EI_DATA], 0, &inv_buf2)); 1453 1454 mdb_printf(MSG_ORIG(MSG_EHDR_LINE3), 1455 conv_ehdr_mach(ehdr.e_machine, 0, &inv_buf1), 1456 conv_ehdr_vers(ehdr.e_version, 0, &inv_buf2)); 1457 mdb_printf(MSG_ORIG(MSG_EHDR_LINE4), 1458 conv_ehdr_type(ehdr.e_type, 0, &inv_buf1)); 1459 1460 /* 1461 * Line up the flags differently depending on whether we 1462 * received a numeric (e.g. "0x200") or text representation 1463 * (e.g. "[ EF_SPARC_SUN_US1 ]"). 1464 */ 1465 flgs = conv_ehdr_flags(ehdr.e_machine, ehdr.e_flags, &ehdr_flags_buf); 1466 if (flgs[0] == '[') 1467 mdb_printf(MSG_ORIG(MSG_EHDR_LINE5), flgs); 1468 else 1469 mdb_printf(MSG_ORIG(MSG_EHDR_LINE6), flgs); 1470 1471 mdb_printf(MSG_ORIG(MSG_EHDR_LINE7), ehdr.e_entry, ehdr.e_ehsize, 1472 ehdr.e_shstrndx); 1473 mdb_printf(MSG_ORIG(MSG_EHDR_LINE8), ehdr.e_shoff, ehdr.e_shentsize, 1474 ehdr.e_shnum); 1475 mdb_printf(MSG_ORIG(MSG_EHDR_LINE9), ehdr.e_phoff, ehdr.e_phentsize, 1476 ehdr.e_phnum); 1477 1478 mdb_set_dot(addr + sizeof (Ehdr)); 1479 1480 return (DCMD_OK); 1481 } 1482 1483 static void 1484 dcmd_ElfPhdr_help(void) 1485 { 1486 mdb_printf(MSG_ORIG(MSG_EPHDR_HELP)); 1487 } 1488 1489 static int 1490 /* ARGSUSED2 */ 1491 dcmd_ElfPhdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1492 { 1493 Phdr phdr; 1494 Conv_inv_buf_t inv_buf; 1495 Conv_phdr_flags_buf_t phdr_flags_buf; 1496 1497 if ((flags & DCMD_ADDRSPEC) == 0) 1498 return (DCMD_USAGE); 1499 1500 if (mdb_vread(&phdr, sizeof (phdr), addr) == -1) { 1501 mdb_warn(MSG_ORIG(MSG_ERR_READ), MSG_ORIG(MSG_EPHDR_STR), 1502 addr); 1503 return (DCMD_ERR); 1504 } 1505 1506 mdb_printf(MSG_ORIG(MSG_EPHDR_TITLE), addr); 1507 mdb_printf(MSG_ORIG(MSG_EPHDR_LINE1), phdr.p_vaddr, 1508 conv_phdr_flags(phdr.p_flags, &phdr_flags_buf)); 1509 mdb_printf(MSG_ORIG(MSG_EPHDR_LINE2), phdr.p_paddr, 1510 conv_phdr_type(M_MACH, phdr.p_type, 0, &inv_buf)); 1511 mdb_printf(MSG_ORIG(MSG_EPHDR_LINE3), phdr.p_filesz, phdr.p_memsz); 1512 mdb_printf(MSG_ORIG(MSG_EPHDR_LINE4), phdr.p_offset, phdr.p_align); 1513 1514 mdb_set_dot(addr + sizeof (Phdr)); 1515 1516 return (DCMD_OK); 1517 } 1518 1519 1520 static const mdb_dcmd_t dcmds[] = { 1521 { MSG_ORIG(MSG_BND_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1522 MSG_ORIG(MSG_BND_DCD), 1523 dcmd_Bind, dcmd_Bind_help}, 1524 { MSG_ORIG(MSG_DEPENDS_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1525 MSG_ORIG(MSG_DEPENDS_DCD), 1526 dcmd_Depends, dcmd_Depends_help}, 1527 { MSG_ORIG(MSG_CALLERS_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1528 MSG_ORIG(MSG_CALLERS_DCD), 1529 dcmd_Callers, dcmd_Callers_help}, 1530 { MSG_ORIG(MSG_GRPHDL_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1531 MSG_ORIG(MSG_GRPHDL_DCD), 1532 dcmd_GrpHdl, dcmd_GrpHdl_help}, 1533 { MSG_ORIG(MSG_GRPDESC_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1534 MSG_ORIG(MSG_GRPDESC_DCD), 1535 dcmd_GrpDesc, dcmd_GrpDesc_help}, 1536 { MSG_ORIG(MSG_HANDLES_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1537 MSG_ORIG(MSG_HANDLES_DCD), 1538 dcmd_Handles, dcmd_Handles_help}, 1539 { MSG_ORIG(MSG_GROUPS_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1540 MSG_ORIG(MSG_GROUPS_DCD), 1541 dcmd_Groups, dcmd_Groups_help}, 1542 { MSG_ORIG(MSG_ELFDYN_STR), MSG_ORIG(MSG_USG_ADDREQ), 1543 MSG_ORIG(MSG_ELFDYN_DCD), 1544 dcmd_ElfDyn, dcmd_ElfDyn_help}, 1545 { MSG_ORIG(MSG_EHDR_STR), MSG_ORIG(MSG_USG_ADDREQ), 1546 MSG_ORIG(MSG_EHDR_DCD), 1547 dcmd_ElfEhdr, dcmd_ElfEhdr_help}, 1548 { MSG_ORIG(MSG_EPHDR_STR), MSG_ORIG(MSG_USG_ADDREQ), 1549 MSG_ORIG(MSG_EPHDR_DCD), 1550 dcmd_ElfPhdr, dcmd_ElfPhdr_help}, 1551 { MSG_ORIG(MSG_LIST_STR), MSG_ORIG(MSG_USG_ADDREQ), 1552 MSG_ORIG(MSG_LIST_DCD), 1553 dcmd_List, dcmd_List_help}, 1554 { MSG_ORIG(MSG_LMLIST_STR), MSG_ORIG(MSG_USG_ADDREQ_V), 1555 MSG_ORIG(MSG_LMLIST_DCD), 1556 dcmd_Lm_list, dcmd_Lm_list_help}, 1557 { MSG_ORIG(MSG_RTMAPS_STR), MSG_ORIG(MSG_USG_ADDOPT_V), 1558 MSG_ORIG(MSG_RTMAPS_DCD), 1559 dcmd_Rtmaps, dcmd_Rtmaps_help}, 1560 { MSG_ORIG(MSG_RTMAP_STR), MSG_ORIG(MSG_USG_ADDREQ), 1561 MSG_ORIG(MSG_RTMAP_DCD), 1562 dcmd_rtmap, dcmd_rtmap_help}, 1563 { MSG_ORIG(MSG_SETENV_STR), MSG_ORIG(MSG_USG_SETENV), 1564 MSG_ORIG(MSG_SETENV_DCD), 1565 dcmd_Setenv, dcmd_Setenv_help}, 1566 { NULL } 1567 }; 1568 1569 static const mdb_walker_t walkers[] = { 1570 { MSG_ORIG(MSG_RTMAPS_STR), MSG_ORIG(MSG_WWD_RTMAP), 1571 walk_rtmap_init, walk_rtmap_step, NULL, NULL }, 1572 { MSG_ORIG(MSG_LIST_STR), MSG_ORIG(MSG_WWD_LIST), 1573 walk_List_init, walk_List_step, NULL, NULL }, 1574 { NULL } 1575 }; 1576 1577 static const mdb_modinfo_t modinfo = { 1578 MDB_API_VERSION, dcmds, walkers 1579 }; 1580 1581 const mdb_modinfo_t * 1582 _mdb_init(void) 1583 { 1584 return (&modinfo); 1585 } 1586