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 /* 2320272c2eSAli Bahrami * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 275aefb655Srie #include <libintl.h> 285aefb655Srie #include <sys/varargs.h> 297c478bd9Sstevel@tonic-gate #include <stdio.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <stdlib.h> 325aefb655Srie #include <alist.h> 335aefb655Srie #include <debug.h> 345aefb655Srie #include <_debug.h> 355aefb655Srie #include <msg.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* 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. 417c478bd9Sstevel@tonic-gate */ 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; 465aefb655Srie 475aefb655Srie /* 485aefb655Srie * Debugging initialization and processing. The dbg_options[] array defines 495aefb655Srie * 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. 525aefb655Srie */ 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 60e64d0ff9SAli Bahrami {MSG_ORIG(MSG_TOK_ALL), DBG_C_ALL & ~DBG_C_DEMANGLE, 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}, 705aefb655Srie {MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0}, 71e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_VERSIONS), DBG_C_VERSIONS, 0}, 72e64d0ff9SAli Bahrami {NULL, 0, 0}, 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}, 82e23c41c9SAli Bahrami {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}, 86e23c41c9SAli Bahrami {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}, 89e64d0ff9SAli Bahrami {NULL, 0, 0}, 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}, 95*98c080d5SRod Evans {MSG_ORIG(MSG_TOK_DL), DBG_C_DL, 0}, 965aefb655Srie {MSG_ORIG(MSG_TOK_INIT), DBG_C_INIT, 0}, 97e64d0ff9SAli Bahrami {NULL, 0, 0}, 987c478bd9Sstevel@tonic-gate }; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate /* 101e23c41c9SAli Bahrami * Compare name to the options found in optarr. If one matches, 102e23c41c9SAli Bahrami * update *dbp and return TRUE. Otherwise, FALSE. 1035aefb655Srie */ 104e23c41c9SAli Bahrami static Boolean 105e23c41c9SAli Bahrami process_options(const char *name, Boolean set, Dbg_desc *dbp, 106e23c41c9SAli Bahrami DBG_options *optarr) 1077c478bd9Sstevel@tonic-gate { 1085aefb655Srie DBG_options *opt; 1095aefb655Srie 110e23c41c9SAli Bahrami for (opt = optarr; opt->o_name != NULL; opt++) { 1115aefb655Srie if (strcmp(name, opt->o_name) != 0) 1125aefb655Srie continue; 1135aefb655Srie 1145aefb655Srie if (set == TRUE) { 1155aefb655Srie if (opt->o_class) 1165aefb655Srie dbp->d_class |= opt->o_class; 1175aefb655Srie if (opt->o_extra) 1185aefb655Srie dbp->d_extra |= opt->o_extra; 1195aefb655Srie } else { 1205aefb655Srie if (opt->o_class) 1215aefb655Srie dbp->d_class &= ~(opt->o_class); 1225aefb655Srie if (opt->o_extra) 1235aefb655Srie dbp->d_extra &= ~(opt->o_extra); 1247c478bd9Sstevel@tonic-gate } 125e23c41c9SAli Bahrami return (TRUE); 126e23c41c9SAli Bahrami } 127e23c41c9SAli Bahrami 128e23c41c9SAli Bahrami return (FALSE); 129e23c41c9SAli Bahrami } 130e23c41c9SAli Bahrami 131e23c41c9SAli Bahrami /* 132e23c41c9SAli Bahrami * Provide a debugging usage message 133e23c41c9SAli Bahrami */ 134e23c41c9SAli Bahrami void 135e23c41c9SAli Bahrami Dbg_help(void) 136e23c41c9SAli Bahrami { 13769112eddSAli Bahrami Dbg_util_nl(0, DBG_NL_STD); 138e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_A)); 139e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_B)); 140e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_C)); 141e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_D)); 142e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_E)); 143e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_F)); 144e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_G)); 145e23c41c9SAli Bahrami 146e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 147e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_A)); 148e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_B)); 149e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_C)); 150e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_D)); 151e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_E)); 152e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_F)); 153e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_G)); 154e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_H)); 155e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_I)); 156e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_J)); 157e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_K)); 158e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_L)); 159e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_M)); 160e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_N)); 161e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_O)); 162e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_P)); 163e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_Q)); 1641dd9d86fSAli Bahrami 1651dd9d86fSAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 166e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_R)); 167e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_S)); 1681dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_T)); 1691dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_U)); 1701dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_V)); 1711dd9d86fSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_W)); 172e23c41c9SAli Bahrami 173e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 174e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_A)); 175e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_B)); 176e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_C)); 177e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_D)); 178e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_E)); 179e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_F)); 180e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_G)); 181e23c41c9SAli Bahrami 182e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 183e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_H)); 184e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_F)); 185e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_I)); 186e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_J)); 187e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_K)); 188e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_L)); 189e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_M)); 190e23c41c9SAli Bahrami 191e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 192e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_N)); 193e23c41c9SAli Bahrami 194e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 195e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_DCT)); 196e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); 197e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_A)); 198e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_B)); 199e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_B2)); 200e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_C)); 2012017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_C2)); 2022017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_C3)); 203e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_D)); 2042017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_E)); 2052017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_E2)); 2062017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_E3)); 2072017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F)); 2082017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F2)); 2092017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F3)); 2102017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F4)); 2112017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F5)); 2122017c965SRod Evans dbg_print(0, MSG_INTL(MSG_USE_R4_F6)); 213e23c41c9SAli Bahrami 214e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 215e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); 216e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A)); 217e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A2)); 218e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A3)); 219e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A4)); 220e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A5)); 221e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A6)); 222e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A7)); 223e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A8)); 224e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A9)); 225e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A0)); 226e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_B)); 227e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_C)); 228e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_D)); 229e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_E)); 230e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_F)); 231e23c41c9SAli Bahrami 232e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 233e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); 234e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_A)); 235e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_B)); 236e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_C)); 237e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_C2)); 238e23c41c9SAli Bahrami 239e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 240e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_CST)); 241e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); 242e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_A)); 243e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_B)); 244e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_C)); 245e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_D)); 246e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_E)); 247e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_F)); 248e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_F2)); 249e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_G)); 250e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_H)); 251e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_I)); 252e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_I2)); 253e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_J)); 254e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_K)); 255e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_K2)); 256e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_L)); 257e23c41c9SAli Bahrami 258e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 259e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); 260e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_A)); 261e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_B)); 262e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_B2)); 263e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_C)); 26420272c2eSAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_D)); 265e23c41c9SAli Bahrami 266e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 267e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); 268e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_A)); 269e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_B)); 270e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_C)); 271e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_D)); 272e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_E)); 273e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_F)); 274e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_F2)); 275e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_G)); 276e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_H)); 277e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_H2)); 278e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_I)); 279e23c41c9SAli Bahrami 280e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 281e23c41c9SAli Bahrami } 282e23c41c9SAli Bahrami 283e23c41c9SAli Bahrami /* 28469112eddSAli Bahrami * Provide a debugging message showing the version of the linker package 28569112eddSAli Bahrami */ 28669112eddSAli Bahrami void 28769112eddSAli Bahrami Dbg_version(void) 28869112eddSAli Bahrami { 28969112eddSAli Bahrami Dbg_util_nl(0, DBG_NL_STD); 29069112eddSAli Bahrami dbg_print(0, MSG_ORIG(MSG_STR_LDVER), link_ver_string); 29169112eddSAli Bahrami Dbg_util_nl(0, DBG_NL_STD); 29269112eddSAli Bahrami } 29369112eddSAli Bahrami 29469112eddSAli Bahrami /* 295e23c41c9SAli Bahrami * Messaging support - funnel everything through dgettext() as this provides 296e23c41c9SAli Bahrami * the real binding to libc. 297e23c41c9SAli Bahrami */ 298e23c41c9SAli Bahrami const char * 299e23c41c9SAli Bahrami _liblddbg_msg(Msg mid) 300e23c41c9SAli Bahrami { 301e23c41c9SAli Bahrami return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid))); 302e23c41c9SAli Bahrami } 303e23c41c9SAli Bahrami 304e23c41c9SAli Bahrami /* 305e23c41c9SAli Bahrami * Given a name starting with "lmid", finish processing it. Return TRUE 306e23c41c9SAli Bahrami * if a valid lmid token was seen, and FALSE for any error. 307e23c41c9SAli Bahrami * 308e23c41c9SAli Bahrami * exit: 309e23c41c9SAli Bahrami * On failure, returns FALSE, indicating a syntax error 310e23c41c9SAli Bahrami * 311e23c41c9SAli Bahrami * On success: 312e23c41c9SAli Bahrami * - Appropriate flags in dbg->d_extra have been set 313e23c41c9SAli Bahrami * - Any link-map list names specified have been added to 314e23c41c9SAli Bahrami * d_list, for the rtld dbg_print() to compare against 315e23c41c9SAli Bahrami * link-map list names. 316e23c41c9SAli Bahrami * - TRUE is returned. 317e23c41c9SAli Bahrami */ 318e23c41c9SAli Bahrami static Boolean 319e23c41c9SAli Bahrami process_lmid(char *name, Dbg_desc *dbp) 320e23c41c9SAli Bahrami { 321e23c41c9SAli Bahrami /* 322e23c41c9SAli Bahrami * "lmid" can have an optional argument. Allowed values are "all", 323e23c41c9SAli Bahrami * "alt[0-9]+", "base", or "ldso". Alt has a variable ending, but 324e23c41c9SAli Bahrami * we can use process_options() to handle the other three. 325e23c41c9SAli Bahrami */ 326e23c41c9SAli Bahrami static DBG_options options_lmid[] = { 327e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_ALL), 0, DBG_E_LMID_ALL}, 328e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_BASE), 0, DBG_E_LMID_BASE}, 329e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_LDSO), 0, DBG_E_LMID_LDSO}, 330e23c41c9SAli Bahrami {NULL, NULL}, 331e23c41c9SAli Bahrami }; 332e23c41c9SAli Bahrami 333e23c41c9SAli Bahrami Dbg_desc tmp_db; 334e23c41c9SAli Bahrami const char *lmid_opt; 335e23c41c9SAli Bahrami 336e23c41c9SAli Bahrami /* If it's a plain "lmid", we can set the flag and return now */ 337e23c41c9SAli Bahrami if (name[MSG_TOK_LMID_SIZE] == '\0') { 338e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID; 339e23c41c9SAli Bahrami return (TRUE); 340e23c41c9SAli Bahrami } 341e23c41c9SAli Bahrami 342e23c41c9SAli Bahrami /* If there's no value, its an error */ 343e23c41c9SAli Bahrami if (conv_strproc_extract_value(name, MSG_TOK_LMID_SIZE, 344e23c41c9SAli Bahrami CONV_SPEXV_F_UCASE, &lmid_opt) == 0) 345e23c41c9SAli Bahrami return (FALSE); 346e23c41c9SAli Bahrami 347e23c41c9SAli Bahrami /* 348e23c41c9SAli Bahrami * ALL, BASE, or LDSO? 349e23c41c9SAli Bahrami */ 350e23c41c9SAli Bahrami tmp_db.d_extra = 0; 351e23c41c9SAli Bahrami if (process_options(lmid_opt, TRUE, &tmp_db, options_lmid)) { 352e23c41c9SAli Bahrami /* 353e23c41c9SAli Bahrami * If BASE, and we haven't already seen it, add it to the 354e23c41c9SAli Bahrami * rtld name matching list. For the others, setting the 355e23c41c9SAli Bahrami * e_extra bit suffices. 356e23c41c9SAli Bahrami */ 357e23c41c9SAli Bahrami if (((tmp_db.d_extra & DBG_E_LMID_BASE) != 0) && 358e23c41c9SAli Bahrami ((dbp->d_extra & DBG_E_LMID_BASE) == 0) && 359e23c41c9SAli Bahrami (aplist_append(&dbp->d_list, MSG_ORIG(MSG_TOK_LMID_BASE), 360e23c41c9SAli Bahrami AL_CNT_DEBUG) == NULL)) 361e23c41c9SAli Bahrami return (FALSE); 362e23c41c9SAli Bahrami 363e23c41c9SAli Bahrami /* Add the resulting flags into the callers descriptor */ 364e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID | tmp_db.d_extra; 365e23c41c9SAli Bahrami return (TRUE); 366e23c41c9SAli Bahrami } 367e23c41c9SAli Bahrami 368e23c41c9SAli Bahrami /* 369e23c41c9SAli Bahrami * ALT? 370e23c41c9SAli Bahrami */ 371e23c41c9SAli Bahrami if (strncmp(lmid_opt, MSG_ORIG(MSG_TOK_LMID_ALT), 372e23c41c9SAli Bahrami MSG_TOK_LMID_ALT_SIZE) == 0) { 373e23c41c9SAli Bahrami const char *tail = lmid_opt + MSG_TOK_LMID_ALT_SIZE; 374e23c41c9SAli Bahrami 375e23c41c9SAli Bahrami /* 'ALT' without a # means "all alternative link-map lists" */ 376e23c41c9SAli Bahrami if (*tail == '\0') { 377e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID | DBG_E_LMID_ALT; 378e23c41c9SAli Bahrami return (TRUE); 379e23c41c9SAli Bahrami } 380e23c41c9SAli Bahrami 381e23c41c9SAli Bahrami /* 382e23c41c9SAli Bahrami * It is ALT[0-9]+. Make sure the characters following 'ALT' 383e23c41c9SAli Bahrami * are numbers, and then add it to the rtld name matching list. 384e23c41c9SAli Bahrami */ 385e23c41c9SAli Bahrami for (; *tail; tail++) 386e23c41c9SAli Bahrami if ((*tail < '0') || (*tail > '9')) 387e23c41c9SAli Bahrami return (FALSE); 388e23c41c9SAli Bahrami 389e23c41c9SAli Bahrami if (aplist_append(&dbp->d_list, lmid_opt, AL_CNT_DEBUG) == NULL) 390e23c41c9SAli Bahrami return (FALSE); 391e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID; 392e23c41c9SAli Bahrami return (TRUE); 393e23c41c9SAli Bahrami } 394e23c41c9SAli Bahrami 395e23c41c9SAli Bahrami /* It's nothing we recognize */ 396e23c41c9SAli Bahrami return (FALSE); 397e23c41c9SAli Bahrami } 398e23c41c9SAli Bahrami 399e23c41c9SAli Bahrami /* 400e23c41c9SAli Bahrami * Validate and enable the appropriate debugging classes. 401e23c41c9SAli Bahrami * 402e23c41c9SAli Bahrami * entry: 403e23c41c9SAli Bahrami * string - String to be analyzed for debugging options 404e23c41c9SAli Bahrami * dbp - Pointer to debug descriptor to be initialized 405e23c41c9SAli Bahrami * outfile_ret - NULL, or pointer to receive result of 'output=' 406e23c41c9SAli Bahrami * token. A NULL value means that the 'output=' token 407e23c41c9SAli Bahrami * is not accepted. A non-NULL value means that it is. 408e23c41c9SAli Bahrami * 409e23c41c9SAli Bahrami * exit: 410e23c41c9SAli Bahrami * On failure, False (0) is returned. 411e23c41c9SAli Bahrami * 412e23c41c9SAli Bahrami * On success, string has been parsed, and the descriptor referenced 413e23c41c9SAli Bahrami * by dbp has been initialized. If outfile is non-NULL, *outfile will 414e23c41c9SAli Bahrami * be set to NULL if the 'output=' token is not present, and to the 415e23c41c9SAli Bahrami * user supplied string otherwise. True (1) is returned. 416e23c41c9SAli Bahrami */ 417e23c41c9SAli Bahrami int 418e23c41c9SAli Bahrami Dbg_setup(dbg_setup_caller_t caller, const char *string, Dbg_desc *dbp, 419e23c41c9SAli Bahrami const char **outfile) 420e23c41c9SAli Bahrami { 421e23c41c9SAli Bahrami char *name, *_name; /* buffer in which to perform */ 422e23c41c9SAli Bahrami /* strtok_r() operations. */ 423e23c41c9SAli Bahrami char *lasts; 424e23c41c9SAli Bahrami const char *delimit = MSG_ORIG(MSG_STR_DELIMIT); 425e23c41c9SAli Bahrami 426e23c41c9SAli Bahrami /* 427e23c41c9SAli Bahrami * Clear the help flags --- these items only apply for a single 428e23c41c9SAli Bahrami * call to Dbg_setup(). 429e23c41c9SAli Bahrami */ 430e23c41c9SAli Bahrami dbp->d_extra &= ~(DBG_E_HELP | DBG_E_HELP_EXIT); 431e23c41c9SAli Bahrami 432e23c41c9SAli Bahrami if ((_name = (char *)malloc(strlen(string) + 1)) == NULL) 433e23c41c9SAli Bahrami return (0); 434e23c41c9SAli Bahrami (void) strcpy(_name, string); 435e23c41c9SAli Bahrami 436e23c41c9SAli Bahrami if (outfile) 437e23c41c9SAli Bahrami *outfile = NULL; /* No output file yet */ 438e23c41c9SAli Bahrami 439e23c41c9SAli Bahrami /* 440e23c41c9SAli Bahrami * The token should be of the form "-Dtok,tok,tok,...". Separate the 441e23c41c9SAli Bahrami * pieces and build up the appropriate mask, unrecognized options are 442e23c41c9SAli Bahrami * flagged. 443e23c41c9SAli Bahrami */ 444e23c41c9SAli Bahrami if ((name = strtok_r(_name, delimit, &lasts)) != NULL) { 445e23c41c9SAli Bahrami do { 446e23c41c9SAli Bahrami Boolean set; 447e23c41c9SAli Bahrami 448e23c41c9SAli Bahrami /* Remove leading and trailing whitespace */ 449e23c41c9SAli Bahrami name = conv_strproc_trim(name); 450e23c41c9SAli Bahrami 451e23c41c9SAli Bahrami if (name[0] == '!') { 452e23c41c9SAli Bahrami set = FALSE; 453e23c41c9SAli Bahrami name++; 454e23c41c9SAli Bahrami } else 455e23c41c9SAli Bahrami set = TRUE; 456e23c41c9SAli Bahrami 457e23c41c9SAli Bahrami if (*name == '\0') 458e23c41c9SAli Bahrami continue; /* Skip null token */ 459e23c41c9SAli Bahrami 460e23c41c9SAli Bahrami /* 461e23c41c9SAli Bahrami * First, determine if the token represents a class or 462e23c41c9SAli Bahrami * extra. 463e23c41c9SAli Bahrami */ 464e23c41c9SAli Bahrami if (process_options(name, set, dbp, _Dbg_options)) 465e23c41c9SAli Bahrami continue; 466e23c41c9SAli Bahrami switch (caller) { 467e23c41c9SAli Bahrami case DBG_CALLER_LD: /* ld only tokens */ 468e23c41c9SAli Bahrami if (process_options(name, set, dbp, 469e23c41c9SAli Bahrami _Dbg_options_ld)) 470e23c41c9SAli Bahrami continue; 4717c478bd9Sstevel@tonic-gate break; 472e23c41c9SAli Bahrami case DBG_CALLER_RTLD: /* rtld only tokens */ 473e23c41c9SAli Bahrami if (process_options(name, set, dbp, 474e23c41c9SAli Bahrami _Dbg_options_rtld)) 4755aefb655Srie continue; 4765aefb655Srie break; 4775aefb655Srie } 4785aefb655Srie 479e23c41c9SAli Bahrami /* The remaining options do not accept negation */ 480e23c41c9SAli Bahrami if (!set) { 481e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name); 482e23c41c9SAli Bahrami continue; 483e23c41c9SAli Bahrami } 484e23c41c9SAli Bahrami 485e23c41c9SAli Bahrami /* 486e23c41c9SAli Bahrami * Is it an 'output=' token? This item is a special 487e23c41c9SAli Bahrami * case because it depends on the presence of 488e23c41c9SAli Bahrami * a non-NULL outfile argument, and because the 489e23c41c9SAli Bahrami * part following the '=' is variable. 490e23c41c9SAli Bahrami */ 491e23c41c9SAli Bahrami if ((outfile != NULL) && 492e23c41c9SAli Bahrami strncmp(name, MSG_ORIG(MSG_TOK_OUTFILE), 493e23c41c9SAli Bahrami MSG_TOK_OUTFILE_SIZE) == 0) { 494e23c41c9SAli Bahrami if (conv_strproc_extract_value(name, 495e23c41c9SAli Bahrami MSG_TOK_OUTFILE_SIZE, 0, outfile)) 496e23c41c9SAli Bahrami continue; 497e23c41c9SAli Bahrami } 498e23c41c9SAli Bahrami 499e23c41c9SAli Bahrami /* 500e23c41c9SAli Bahrami * Only the rtld "lmid" token is left. 501e23c41c9SAli Bahrami */ 502e23c41c9SAli Bahrami if ((caller == DBG_CALLER_RTLD) && (strncmp(name, 503e23c41c9SAli Bahrami MSG_ORIG(MSG_TOK_LMID), MSG_TOK_LMID_SIZE) == 0) && 504e23c41c9SAli Bahrami process_lmid(name, dbp)) 505e23c41c9SAli Bahrami continue; 506e23c41c9SAli Bahrami 507e23c41c9SAli Bahrami /* If we make it here, the token is not understood */ 5085aefb655Srie dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name); 5095aefb655Srie 5107c478bd9Sstevel@tonic-gate } while ((name = strtok_r(NULL, delimit, &lasts)) != NULL); 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate /* 514e23c41c9SAli Bahrami * If the debug help option was specified and this is the only debug 515e23c41c9SAli Bahrami * class, return an indication that the user should exit. 5167c478bd9Sstevel@tonic-gate */ 517e23c41c9SAli Bahrami if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) && 518e23c41c9SAli Bahrami (dbp->d_class == 0)) 519e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_HELP_EXIT; 520e23c41c9SAli Bahrami 5215aefb655Srie return (1); 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate /* 5255aefb655Srie * Define our own printing routine. This provides a basic fallback, as ld(1) 5265aefb655Srie * and ld.so.1(1) provide their own routines that augment their diagnostic 5275aefb655Srie * output, and direct the output to stderr. This item should be defined 5285aefb655Srie * NODIRECT. 5297c478bd9Sstevel@tonic-gate */ 5305aefb655Srie /* PRINTFLIKE2 */ 5317c478bd9Sstevel@tonic-gate void 5325aefb655Srie dbg_print(Lm_list *lml, const char *format, ...) 5337c478bd9Sstevel@tonic-gate { 5345aefb655Srie va_list ap; 5357c478bd9Sstevel@tonic-gate 5365aefb655Srie #if defined(lint) 5377c478bd9Sstevel@tonic-gate /* 5385aefb655Srie * The lml argument is only meaningful for diagnostics sent to ld.so.1. 5395aefb655Srie * Supress the lint error by making a dummy assignment. 5407c478bd9Sstevel@tonic-gate */ 5415aefb655Srie lml = 0; 5425aefb655Srie #endif 5435aefb655Srie va_start(ap, format); 5445aefb655Srie (void) vprintf(format, ap); 5455aefb655Srie (void) printf(MSG_ORIG(MSG_STR_NL)); 5465aefb655Srie va_end(ap); 5477c478bd9Sstevel@tonic-gate } 54869112eddSAli Bahrami 54969112eddSAli Bahrami /* 55069112eddSAli Bahrami * Return an internationalized state transition string. These are used by 55169112eddSAli Bahrami * various debugging output. 55269112eddSAli Bahrami */ 55369112eddSAli Bahrami const char * 55469112eddSAli Bahrami Dbg_state_str(dbg_state_t type) 55569112eddSAli Bahrami { 55669112eddSAli Bahrami static const Msg state[DBG_STATE_NUM] = { 55769112eddSAli Bahrami MSG_STR_ADD, /* MSG_INTL(MSG_STR_ADD) */ 55869112eddSAli Bahrami MSG_STR_CURRENT, /* MSG_INTL(MSG_STR_CURRENT) */ 55969112eddSAli Bahrami MSG_STR_EXCLUDE, /* MSG_INTL(MSG_STR_EXCLUDE) */ 56069112eddSAli Bahrami MSG_STR_IGNORE, /* MSG_INTL(MSG_STR_IGNORE) */ 56169112eddSAli Bahrami MSG_STR_MOD_BEFORE, /* MSG_INTL(MSG_STR_MOD_BEFORE) */ 56269112eddSAli Bahrami MSG_STR_MOD_AFTER, /* MSG_INTL(MSG_STR_MOD_AFTER) */ 56369112eddSAli Bahrami MSG_STR_NEW, /* MSG_INTL(MSG_STR_NEW) */ 56469112eddSAli Bahrami MSG_STR_NEW_IMPLICIT, /* MSG_INTL(MSG_STR_NEW_IMPLICIT) */ 56569112eddSAli Bahrami MSG_STR_RESET, /* MSG_INTL(MSG_STR_RESET) */ 56608278a5eSRod Evans MSG_STR_ORIGINAL, /* MSG_INTL(MSG_STR_ORIGINAL) */ 56769112eddSAli Bahrami MSG_STR_RESOLVED, /* MSG_INTL(MSG_STR_RESOLVED) */ 56869112eddSAli Bahrami }; 56969112eddSAli Bahrami #if DBG_STATE_NUM != (DBG_STATE_RESOLVED + 1) 57069112eddSAli Bahrami #error DBG_SEG_NUM has changed. Update segtype[] 57169112eddSAli Bahrami #endif 57269112eddSAli Bahrami 57369112eddSAli Bahrami assert(type < DBG_STATE_NUM); 57469112eddSAli Bahrami return (MSG_INTL(state[type])); 57569112eddSAli Bahrami } 576