17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 55aefb655Srie * Common Development and Distribution License (the "License"). 65aefb655Srie * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 215aefb655Srie 227c478bd9Sstevel@tonic-gate /* 2356deab07SRod Evans * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277257d1b4Sraf #include <libintl.h> 287257d1b4Sraf #include <sys/varargs.h> 297257d1b4Sraf #include <stdio.h> 307257d1b4Sraf #include <string.h> 317257d1b4Sraf #include <stdlib.h> 327257d1b4Sraf #include <alist.h> 337257d1b4Sraf #include <debug.h> 347257d1b4Sraf #include <_debug.h> 357257d1b4Sraf #include <msg.h> 367c478bd9Sstevel@tonic-gate 375aefb655Srie /* 385aefb655Srie * Define a debug descriptor. Note, although this provides the default 395aefb655Srie * definition to which most users bind, ld.so.1 must provide its own definition, 405aefb655Srie * and thus interposition is expected. This item should be defined NODIRECT. 415aefb655Srie */ 422017c965SRod Evans static Dbg_desc _dbg_desc = { 0, 0, NULL, { 0, 0 }, { 0, 0 } }; 435aefb655Srie Dbg_desc *dbg_desc = &_dbg_desc; 447c478bd9Sstevel@tonic-gate 455aefb655Srie int _Dbg_cnt = 0; 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate /* 485aefb655Srie * Debugging initialization and processing. The dbg_options[] array defines 497c478bd9Sstevel@tonic-gate * a set of option strings that can be specified using the -D flag or from an 505aefb655Srie * environment variable. For each option, a class is enabled in the d_class 515aefb655Srie * bit mask, or an extra flag is enabled in the d_extra bit mask. 527c478bd9Sstevel@tonic-gate */ 53e23c41c9SAli Bahrami static DBG_options _Dbg_options[] = { /* Options accepted by both linkers */ 545aefb655Srie {MSG_ORIG(MSG_TOK_DETAIL), 0, DBG_E_DETAIL}, 555aefb655Srie {MSG_ORIG(MSG_TOK_LONG), 0, DBG_E_LONG}, 56e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_HELP), 0, DBG_E_HELP}, 572017c965SRod Evans {MSG_ORIG(MSG_TOK_TTIME), 0, DBG_E_TTIME}, 582017c965SRod Evans {MSG_ORIG(MSG_TOK_DTIME), 0, DBG_E_DTIME}, 595aefb655Srie 605aefb655Srie {MSG_ORIG(MSG_TOK_ALL), DBG_C_ALL, 0}, 615aefb655Srie {MSG_ORIG(MSG_TOK_BASIC), DBG_C_BASIC, 0}, 62e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_CAP), DBG_C_CAP, 0}, 63e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_DEMANGLE), DBG_C_DEMANGLE, 0}, 645aefb655Srie {MSG_ORIG(MSG_TOK_FILES), DBG_C_FILES, 0}, 655aefb655Srie {MSG_ORIG(MSG_TOK_LIBS), DBG_C_LIBS, 0}, 66e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_MOVE), DBG_C_MOVE, 0}, 675aefb655Srie {MSG_ORIG(MSG_TOK_RELOC), DBG_C_RELOC, 0}, 685aefb655Srie {MSG_ORIG(MSG_TOK_SYMBOLS), DBG_C_SYMBOLS, 0}, 695aefb655Srie {MSG_ORIG(MSG_TOK_TLS), DBG_C_TLS, 0}, 70e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0}, 715aefb655Srie {MSG_ORIG(MSG_TOK_VERSIONS), DBG_C_VERSIONS, 0}, 72e23c41c9SAli Bahrami {NULL, NULL}, 73e23c41c9SAli Bahrami }; 74e23c41c9SAli Bahrami 75e23c41c9SAli Bahrami static DBG_options _Dbg_options_ld[] = { /* ld only options */ 76e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_CLASS), 0, DBG_E_SNAME | DBG_E_CLASS}, 77e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_FULLNAME), 0, DBG_E_SNAME | DBG_E_FNAME}, 78e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_NAME), 0, DBG_E_SNAME}, 79e23c41c9SAli Bahrami 80e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_ARGS), DBG_C_ARGS, 0}, 81e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_ENTRY), DBG_C_ENTRY, 0}, 825aefb655Srie {MSG_ORIG(MSG_TOK_GOT), DBG_C_GOT, 0}, 83e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_MAP), DBG_C_MAP, 0}, 84e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_SECTIONS), DBG_C_SECTIONS, 0}, 85e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_SEGMENTS), DBG_C_SEGMENTS, 0}, 865aefb655Srie {MSG_ORIG(MSG_TOK_STATS), DBG_C_STATS, 0}, 87e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_STRTAB), DBG_C_STRTAB, 0}, 88e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_SUPPORT), DBG_C_SUPPORT, 0}, 89e23c41c9SAli Bahrami {NULL, NULL}, 90e23c41c9SAli Bahrami }; 91e23c41c9SAli Bahrami 92e23c41c9SAli Bahrami static DBG_options _Dbg_options_rtld[] = { /* ld.so.1 only options */ 93e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_AUDIT), DBG_C_AUDITING, 0}, 94e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_BINDINGS), DBG_C_BINDINGS, 0}, 955aefb655Srie {MSG_ORIG(MSG_TOK_INIT), DBG_C_INIT, 0}, 967c478bd9Sstevel@tonic-gate {NULL, NULL}, 977c478bd9Sstevel@tonic-gate }; 987c478bd9Sstevel@tonic-gate 995aefb655Srie /* 100e23c41c9SAli Bahrami * Compare name to the options found in optarr. If one matches, 101e23c41c9SAli Bahrami * update *dbp and return TRUE. Otherwise, FALSE. 1025aefb655Srie */ 103e23c41c9SAli Bahrami static Boolean 104e23c41c9SAli Bahrami process_options(const char *name, Boolean set, Dbg_desc *dbp, 105e23c41c9SAli Bahrami DBG_options *optarr) 106e23c41c9SAli Bahrami { 107e23c41c9SAli Bahrami DBG_options *opt; 108e23c41c9SAli Bahrami 109e23c41c9SAli Bahrami for (opt = optarr; opt->o_name != NULL; opt++) { 110e23c41c9SAli Bahrami if (strcmp(name, opt->o_name) != 0) 111e23c41c9SAli Bahrami continue; 112e23c41c9SAli Bahrami 113e23c41c9SAli Bahrami if (set == TRUE) { 114e23c41c9SAli Bahrami if (opt->o_class) 115e23c41c9SAli Bahrami dbp->d_class |= opt->o_class; 116e23c41c9SAli Bahrami if (opt->o_extra) 117e23c41c9SAli Bahrami dbp->d_extra |= opt->o_extra; 118e23c41c9SAli Bahrami } else { 119e23c41c9SAli Bahrami if (opt->o_class) 120e23c41c9SAli Bahrami dbp->d_class &= ~(opt->o_class); 121e23c41c9SAli Bahrami if (opt->o_extra) 122e23c41c9SAli Bahrami dbp->d_extra &= ~(opt->o_extra); 123e23c41c9SAli Bahrami } 124e23c41c9SAli Bahrami return (TRUE); 125e23c41c9SAli Bahrami } 126e23c41c9SAli Bahrami 127e23c41c9SAli Bahrami return (FALSE); 128e23c41c9SAli Bahrami } 1295aefb655Srie 1307c478bd9Sstevel@tonic-gate /* 1317c478bd9Sstevel@tonic-gate * Provide a debugging usage message 1327c478bd9Sstevel@tonic-gate */ 1335aefb655Srie void 134e23c41c9SAli Bahrami Dbg_help(void) 1357c478bd9Sstevel@tonic-gate { 1365aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 137e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_A)); 138e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_B)); 139e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_C)); 140e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_D)); 141e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_E)); 142e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_F)); 143e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_G)); 144e23c41c9SAli Bahrami 1455aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 146e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_A)); 147e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_B)); 148e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_C)); 149e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_D)); 150e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_E)); 151e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_F)); 152e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_G)); 153e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_H)); 154e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_I)); 155e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_J)); 156e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_K)); 157e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_L)); 158e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_M)); 159e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_N)); 160e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_O)); 161e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_P)); 162e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_Q)); 163*1dd9d86fSAli Bahrami 164*1dd9d86fSAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 165e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_R)); 166e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_S)); 167*1dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_T)); 168*1dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_U)); 169*1dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_V)); 170*1dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_W)); 171e23c41c9SAli Bahrami 172e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 173e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_A)); 174e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_B)); 175e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_C)); 176e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_D)); 177e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_E)); 178e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_F)); 179e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_G)); 180e23c41c9SAli Bahrami 1815aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 182e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_H)); 183e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_F)); 184e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_I)); 185e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_J)); 186e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_K)); 187e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_L)); 188e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_M)); 1895aefb655Srie 1905aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 191e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_N)); 192e23c41c9SAli Bahrami 1935aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 194e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_DCT)); 195e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); 196e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_A)); 197e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_B)); 198e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_B2)); 199e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_C)); 2002017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_C2)); 2012017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_C3)); 202e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_D)); 2032017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_E)); 2042017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_E2)); 2052017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_E3)); 2062017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F)); 2072017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F2)); 2082017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F3)); 2092017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F4)); 2102017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F5)); 2112017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F6)); 212e23c41c9SAli Bahrami 2135aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 214e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); 215e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A)); 216e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A2)); 217e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A3)); 218e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A4)); 219e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A5)); 220e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A6)); 221e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A7)); 222e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A8)); 223e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A9)); 224e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A0)); 225e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_B)); 226e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_C)); 227e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_D)); 228e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_E)); 229e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_F)); 230e23c41c9SAli Bahrami 2315aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 232e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); 233e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_A)); 234e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_B)); 235e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_C)); 236e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_C2)); 237e23c41c9SAli Bahrami 2385aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 239e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_CST)); 240e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); 241e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_A)); 242e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_B)); 243e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_C)); 244e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_D)); 245e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_E)); 246e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_F)); 247e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_F2)); 248e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_G)); 249e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_H)); 250e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_I)); 251e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_I2)); 252e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_J)); 253e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_K)); 254e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_K2)); 255e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_L)); 2565aefb655Srie 2575aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 258e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); 259e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_A)); 260e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_B)); 261e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_B2)); 262e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_C)); 263e23c41c9SAli Bahrami 2645aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 265e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); 266e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_A)); 267e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_B)); 268e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_C)); 269e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_D)); 270e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_E)); 271e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_F)); 272e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_F2)); 273e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_G)); 274e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_H)); 275e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_H2)); 276e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_I)); 277e23c41c9SAli Bahrami 2785aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 2795aefb655Srie } 2805aefb655Srie 2815aefb655Srie /* 2825aefb655Srie * Messaging support - funnel everything through dgettext() as this provides 2835aefb655Srie * the real binding to libc. 2845aefb655Srie */ 2855aefb655Srie const char * 2865aefb655Srie _liblddbg_msg(Msg mid) 2875aefb655Srie { 2885aefb655Srie return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid))); 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 291e23c41c9SAli Bahrami /* 292e23c41c9SAli Bahrami * Given a name starting with "lmid", finish processing it. Return TRUE 293e23c41c9SAli Bahrami * if a valid lmid token was seen, and FALSE for any error. 294e23c41c9SAli Bahrami * 295e23c41c9SAli Bahrami * exit: 296e23c41c9SAli Bahrami * On failure, returns FALSE, indicating a syntax error 297e23c41c9SAli Bahrami * 298e23c41c9SAli Bahrami * On success: 299e23c41c9SAli Bahrami * - Appropriate flags in dbg->d_extra have been set 300e23c41c9SAli Bahrami * - Any link-map list names specified have been added to 301e23c41c9SAli Bahrami * d_list, for the rtld dbg_print() to compare against 302e23c41c9SAli Bahrami * link-map list names. 303e23c41c9SAli Bahrami * - TRUE is returned. 304e23c41c9SAli Bahrami */ 305e23c41c9SAli Bahrami static Boolean 306e23c41c9SAli Bahrami process_lmid(char *name, Dbg_desc *dbp) 307e23c41c9SAli Bahrami { 308e23c41c9SAli Bahrami /* 309e23c41c9SAli Bahrami * "lmid" can have an optional argument. Allowed values are "all", 310e23c41c9SAli Bahrami * "alt[0-9]+", "base", or "ldso". Alt has a variable ending, but 311e23c41c9SAli Bahrami * we can use process_options() to handle the other three. 312e23c41c9SAli Bahrami */ 313e23c41c9SAli Bahrami static DBG_options options_lmid[] = { 314e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_ALL), 0, DBG_E_LMID_ALL}, 315e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_BASE), 0, DBG_E_LMID_BASE}, 316e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_LDSO), 0, DBG_E_LMID_LDSO}, 317e23c41c9SAli Bahrami {NULL, NULL}, 318e23c41c9SAli Bahrami }; 319e23c41c9SAli Bahrami 320e23c41c9SAli Bahrami Dbg_desc tmp_db; 321e23c41c9SAli Bahrami const char *lmid_opt; 322e23c41c9SAli Bahrami 323e23c41c9SAli Bahrami /* If it's a plain "lmid", we can set the flag and return now */ 324e23c41c9SAli Bahrami if (name[MSG_TOK_LMID_SIZE] == '\0') { 325e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID; 326e23c41c9SAli Bahrami return (TRUE); 327e23c41c9SAli Bahrami } 328e23c41c9SAli Bahrami 329e23c41c9SAli Bahrami /* If there's no value, its an error */ 330e23c41c9SAli Bahrami if (conv_strproc_extract_value(name, MSG_TOK_LMID_SIZE, 331e23c41c9SAli Bahrami CONV_SPEXV_F_UCASE, &lmid_opt) == 0) 332e23c41c9SAli Bahrami return (FALSE); 333e23c41c9SAli Bahrami 334e23c41c9SAli Bahrami /* 335e23c41c9SAli Bahrami * ALL, BASE, or LDSO? 336e23c41c9SAli Bahrami */ 337e23c41c9SAli Bahrami tmp_db.d_extra = 0; 338e23c41c9SAli Bahrami if (process_options(lmid_opt, TRUE, &tmp_db, options_lmid)) { 339e23c41c9SAli Bahrami /* 340e23c41c9SAli Bahrami * If BASE, and we haven't already seen it, add it to the 341e23c41c9SAli Bahrami * rtld name matching list. For the others, setting the 342e23c41c9SAli Bahrami * e_extra bit suffices. 343e23c41c9SAli Bahrami */ 344e23c41c9SAli Bahrami if (((tmp_db.d_extra & DBG_E_LMID_BASE) != 0) && 345e23c41c9SAli Bahrami ((dbp->d_extra & DBG_E_LMID_BASE) == 0) && 346e23c41c9SAli Bahrami (aplist_append(&dbp->d_list, MSG_ORIG(MSG_TOK_LMID_BASE), 347e23c41c9SAli Bahrami AL_CNT_DEBUG) == NULL)) 348e23c41c9SAli Bahrami return (FALSE); 349e23c41c9SAli Bahrami 350e23c41c9SAli Bahrami /* Add the resulting flags into the callers descriptor */ 351e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID | tmp_db.d_extra; 352e23c41c9SAli Bahrami return (TRUE); 353e23c41c9SAli Bahrami } 354e23c41c9SAli Bahrami 355e23c41c9SAli Bahrami /* 356e23c41c9SAli Bahrami * ALT? 357e23c41c9SAli Bahrami */ 358e23c41c9SAli Bahrami if (strncmp(lmid_opt, MSG_ORIG(MSG_TOK_LMID_ALT), 359e23c41c9SAli Bahrami MSG_TOK_LMID_ALT_SIZE) == 0) { 360e23c41c9SAli Bahrami const char *tail = lmid_opt + MSG_TOK_LMID_ALT_SIZE; 361e23c41c9SAli Bahrami 362e23c41c9SAli Bahrami /* 'ALT' without a # means "all alternative link-map lists" */ 363e23c41c9SAli Bahrami if (*tail == '\0') { 364e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID | DBG_E_LMID_ALT; 365e23c41c9SAli Bahrami return (TRUE); 366e23c41c9SAli Bahrami } 367e23c41c9SAli Bahrami 368e23c41c9SAli Bahrami /* 369e23c41c9SAli Bahrami * It is ALT[0-9]+. Make sure the characters following 'ALT' 370e23c41c9SAli Bahrami * are numbers, and then add it to the rtld name matching list. 371e23c41c9SAli Bahrami */ 372e23c41c9SAli Bahrami for (; *tail; tail++) 373e23c41c9SAli Bahrami if ((*tail < '0') || (*tail > '9')) 374e23c41c9SAli Bahrami return (FALSE); 375e23c41c9SAli Bahrami 376e23c41c9SAli Bahrami if (aplist_append(&dbp->d_list, lmid_opt, AL_CNT_DEBUG) == NULL) 377e23c41c9SAli Bahrami return (FALSE); 378e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID; 379e23c41c9SAli Bahrami return (TRUE); 380e23c41c9SAli Bahrami } 381e23c41c9SAli Bahrami 382e23c41c9SAli Bahrami /* It's nothing we recognize */ 383e23c41c9SAli Bahrami return (FALSE); 384e23c41c9SAli Bahrami } 385e23c41c9SAli Bahrami 3867c478bd9Sstevel@tonic-gate /* 3877c478bd9Sstevel@tonic-gate * Validate and enable the appropriate debugging classes. 388e23c41c9SAli Bahrami * 389e23c41c9SAli Bahrami * entry: 390e23c41c9SAli Bahrami * string - String to be analyzed for debugging options 391e23c41c9SAli Bahrami * dbp - Pointer to debug descriptor to be initialized 392e23c41c9SAli Bahrami * outfile_ret - NULL, or pointer to receive result of 'output=' 393e23c41c9SAli Bahrami * token. A NULL value means that the 'output=' token 394e23c41c9SAli Bahrami * is not accepted. A non-NULL value means that it is. 395e23c41c9SAli Bahrami * 396e23c41c9SAli Bahrami * exit: 397e23c41c9SAli Bahrami * On failure, False (0) is returned. 398e23c41c9SAli Bahrami * 399e23c41c9SAli Bahrami * On success, string has been parsed, and the descriptor referenced 400e23c41c9SAli Bahrami * by dbp has been initialized. If outfile is non-NULL, *outfile will 401e23c41c9SAli Bahrami * be set to NULL if the 'output=' token is not present, and to the 402e23c41c9SAli Bahrami * user supplied string otherwise. True (1) is returned. 4037c478bd9Sstevel@tonic-gate */ 404e23c41c9SAli Bahrami int 405e23c41c9SAli Bahrami Dbg_setup(dbg_setup_caller_t caller, const char *string, Dbg_desc *dbp, 406e23c41c9SAli Bahrami const char **outfile) 4077c478bd9Sstevel@tonic-gate { 4085aefb655Srie char *name, *_name; /* buffer in which to perform */ 4095aefb655Srie /* strtok_r() operations. */ 4107c478bd9Sstevel@tonic-gate char *lasts; 4117c478bd9Sstevel@tonic-gate const char *delimit = MSG_ORIG(MSG_STR_DELIMIT); 4127c478bd9Sstevel@tonic-gate 413e23c41c9SAli Bahrami /* 414e23c41c9SAli Bahrami * Clear the help flags --- these items only apply for a single 415e23c41c9SAli Bahrami * call to Dbg_setup(). 416e23c41c9SAli Bahrami */ 417e23c41c9SAli Bahrami dbp->d_extra &= ~(DBG_E_HELP | DBG_E_HELP_EXIT); 418e23c41c9SAli Bahrami 419e23c41c9SAli Bahrami if ((_name = (char *)malloc(strlen(string) + 1)) == NULL) 420e23c41c9SAli Bahrami return (0); 4217c478bd9Sstevel@tonic-gate (void) strcpy(_name, string); 4227c478bd9Sstevel@tonic-gate 423e23c41c9SAli Bahrami if (outfile) 424e23c41c9SAli Bahrami *outfile = NULL; /* No output file yet */ 425e23c41c9SAli Bahrami 4267c478bd9Sstevel@tonic-gate /* 4277c478bd9Sstevel@tonic-gate * The token should be of the form "-Dtok,tok,tok,...". Separate the 4287c478bd9Sstevel@tonic-gate * pieces and build up the appropriate mask, unrecognized options are 4297c478bd9Sstevel@tonic-gate * flagged. 4307c478bd9Sstevel@tonic-gate */ 4317c478bd9Sstevel@tonic-gate if ((name = strtok_r(_name, delimit, &lasts)) != NULL) { 4327c478bd9Sstevel@tonic-gate do { 433e23c41c9SAli Bahrami Boolean set; 434e23c41c9SAli Bahrami 435e23c41c9SAli Bahrami /* Remove leading and trailing whitespace */ 436e23c41c9SAli Bahrami name = conv_strproc_trim(name); 4375aefb655Srie 4387c478bd9Sstevel@tonic-gate if (name[0] == '!') { 4397c478bd9Sstevel@tonic-gate set = FALSE; 4407c478bd9Sstevel@tonic-gate name++; 4415aefb655Srie } else 4425aefb655Srie set = TRUE; 4435aefb655Srie 444e23c41c9SAli Bahrami if (*name == '\0') 445e23c41c9SAli Bahrami continue; /* Skip null token */ 446e23c41c9SAli Bahrami 4475aefb655Srie /* 4485aefb655Srie * First, determine if the token represents a class or 4495aefb655Srie * extra. 4505aefb655Srie */ 451e23c41c9SAli Bahrami if (process_options(name, set, dbp, _Dbg_options)) 452e23c41c9SAli Bahrami continue; 453e23c41c9SAli Bahrami switch (caller) { 454e23c41c9SAli Bahrami case DBG_CALLER_LD: /* ld only tokens */ 455e23c41c9SAli Bahrami if (process_options(name, set, dbp, 456e23c41c9SAli Bahrami _Dbg_options_ld)) 457e23c41c9SAli Bahrami continue; 458e23c41c9SAli Bahrami break; 459e23c41c9SAli Bahrami case DBG_CALLER_RTLD: /* rtld only tokens */ 460e23c41c9SAli Bahrami if (process_options(name, set, dbp, 461e23c41c9SAli Bahrami _Dbg_options_rtld)) 4625aefb655Srie continue; 4635aefb655Srie break; 4647c478bd9Sstevel@tonic-gate } 465e23c41c9SAli Bahrami 466e23c41c9SAli Bahrami /* The remaining options do not accept negation */ 467e23c41c9SAli Bahrami if (!set) { 468e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name); 4695aefb655Srie continue; 470e23c41c9SAli Bahrami } 4715aefb655Srie 4725aefb655Srie /* 473e23c41c9SAli Bahrami * Is it an 'output=' token? This item is a special 474e23c41c9SAli Bahrami * case because it depends on the presence of 475e23c41c9SAli Bahrami * a non-NULL outfile argument, and because the 476e23c41c9SAli Bahrami * part following the '=' is variable. 4775aefb655Srie */ 478e23c41c9SAli Bahrami if ((outfile != NULL) && 479e23c41c9SAli Bahrami strncmp(name, MSG_ORIG(MSG_TOK_OUTFILE), 480e23c41c9SAli Bahrami MSG_TOK_OUTFILE_SIZE) == 0) { 481e23c41c9SAli Bahrami if (conv_strproc_extract_value(name, 482e23c41c9SAli Bahrami MSG_TOK_OUTFILE_SIZE, 0, outfile)) 4835aefb655Srie continue; 4847c478bd9Sstevel@tonic-gate } 4855aefb655Srie 486e23c41c9SAli Bahrami /* 487e23c41c9SAli Bahrami * Only the rtld "lmid" token is left. 488e23c41c9SAli Bahrami */ 489e23c41c9SAli Bahrami if ((caller == DBG_CALLER_RTLD) && (strncmp(name, 490e23c41c9SAli Bahrami MSG_ORIG(MSG_TOK_LMID), MSG_TOK_LMID_SIZE) == 0) && 491e23c41c9SAli Bahrami process_lmid(name, dbp)) 492e23c41c9SAli Bahrami continue; 493e23c41c9SAli Bahrami 494e23c41c9SAli Bahrami /* If we make it here, the token is not understood */ 495e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name); 4965aefb655Srie 4977c478bd9Sstevel@tonic-gate } while ((name = strtok_r(NULL, delimit, &lasts)) != NULL); 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate /* 501e23c41c9SAli Bahrami * If the debug help option was specified and this is the only debug 502e23c41c9SAli Bahrami * class, return an indication that the user should exit. 5037c478bd9Sstevel@tonic-gate */ 504e23c41c9SAli Bahrami if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) && 505e23c41c9SAli Bahrami (dbp->d_class == 0)) 506e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_HELP_EXIT; 507e23c41c9SAli Bahrami 5085aefb655Srie return (1); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate /* 5125aefb655Srie * Define our own printing routine. This provides a basic fallback, as ld(1) 5135aefb655Srie * and ld.so.1(1) provide their own routines that augment their diagnostic 5145aefb655Srie * output, and direct the output to stderr. This item should be defined 5155aefb655Srie * NODIRECT. 5167c478bd9Sstevel@tonic-gate */ 5175aefb655Srie /* PRINTFLIKE2 */ 5187c478bd9Sstevel@tonic-gate void 5195aefb655Srie dbg_print(Lm_list *lml, const char *format, ...) 5207c478bd9Sstevel@tonic-gate { 5215aefb655Srie va_list ap; 5227c478bd9Sstevel@tonic-gate 5235aefb655Srie #if defined(lint) 5245aefb655Srie /* 5255aefb655Srie * The lml argument is only meaningful for diagnostics sent to ld.so.1. 5265aefb655Srie * Supress the lint error by making a dummy assignment. 5275aefb655Srie */ 5285aefb655Srie lml = 0; 5295aefb655Srie #endif 5305aefb655Srie va_start(ap, format); 5315aefb655Srie (void) vprintf(format, ap); 5325aefb655Srie (void) printf(MSG_ORIG(MSG_STR_NL)); 5335aefb655Srie va_end(ap); 5347c478bd9Sstevel@tonic-gate } 535