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 */ 425aefb655Srie static Dbg_desc _dbg_desc = { 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 */ 53*e23c41c9SAli 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}, 56*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_HELP), 0, DBG_E_HELP}, 575aefb655Srie 585aefb655Srie {MSG_ORIG(MSG_TOK_ALL), DBG_C_ALL, 0}, 595aefb655Srie {MSG_ORIG(MSG_TOK_BASIC), DBG_C_BASIC, 0}, 60*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_CAP), DBG_C_CAP, 0}, 61*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_DEMANGLE), DBG_C_DEMANGLE, 0}, 625aefb655Srie {MSG_ORIG(MSG_TOK_FILES), DBG_C_FILES, 0}, 635aefb655Srie {MSG_ORIG(MSG_TOK_LIBS), DBG_C_LIBS, 0}, 64*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_MOVE), DBG_C_MOVE, 0}, 655aefb655Srie {MSG_ORIG(MSG_TOK_RELOC), DBG_C_RELOC, 0}, 665aefb655Srie {MSG_ORIG(MSG_TOK_SYMBOLS), DBG_C_SYMBOLS, 0}, 675aefb655Srie {MSG_ORIG(MSG_TOK_TLS), DBG_C_TLS, 0}, 68*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_UNUSED), DBG_C_UNUSED, 0}, 695aefb655Srie {MSG_ORIG(MSG_TOK_VERSIONS), DBG_C_VERSIONS, 0}, 70*e23c41c9SAli Bahrami {NULL, NULL}, 71*e23c41c9SAli Bahrami }; 72*e23c41c9SAli Bahrami 73*e23c41c9SAli Bahrami static DBG_options _Dbg_options_ld[] = { /* ld only options */ 74*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_CLASS), 0, DBG_E_SNAME | DBG_E_CLASS}, 75*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_FULLNAME), 0, DBG_E_SNAME | DBG_E_FNAME}, 76*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_NAME), 0, DBG_E_SNAME}, 77*e23c41c9SAli Bahrami 78*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_ARGS), DBG_C_ARGS, 0}, 79*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_ENTRY), DBG_C_ENTRY, 0}, 805aefb655Srie {MSG_ORIG(MSG_TOK_GOT), DBG_C_GOT, 0}, 81*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_MAP), DBG_C_MAP, 0}, 82*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_SECTIONS), DBG_C_SECTIONS, 0}, 83*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_SEGMENTS), DBG_C_SEGMENTS, 0}, 845aefb655Srie {MSG_ORIG(MSG_TOK_STATS), DBG_C_STATS, 0}, 85*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_STRTAB), DBG_C_STRTAB, 0}, 86*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_SUPPORT), DBG_C_SUPPORT, 0}, 87*e23c41c9SAli Bahrami {NULL, NULL}, 88*e23c41c9SAli Bahrami }; 89*e23c41c9SAli Bahrami 90*e23c41c9SAli Bahrami static DBG_options _Dbg_options_rtld[] = { /* ld.so.1 only options */ 91*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_AUDIT), DBG_C_AUDITING, 0}, 92*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_BINDINGS), DBG_C_BINDINGS, 0}, 935aefb655Srie {MSG_ORIG(MSG_TOK_INIT), DBG_C_INIT, 0}, 947c478bd9Sstevel@tonic-gate {NULL, NULL}, 957c478bd9Sstevel@tonic-gate }; 967c478bd9Sstevel@tonic-gate 975aefb655Srie /* 98*e23c41c9SAli Bahrami * Compare name to the options found in optarr. If one matches, 99*e23c41c9SAli Bahrami * update *dbp and return TRUE. Otherwise, FALSE. 1005aefb655Srie */ 101*e23c41c9SAli Bahrami static Boolean 102*e23c41c9SAli Bahrami process_options(const char *name, Boolean set, Dbg_desc *dbp, 103*e23c41c9SAli Bahrami DBG_options *optarr) 104*e23c41c9SAli Bahrami { 105*e23c41c9SAli Bahrami DBG_options *opt; 106*e23c41c9SAli Bahrami 107*e23c41c9SAli Bahrami for (opt = optarr; opt->o_name != NULL; opt++) { 108*e23c41c9SAli Bahrami if (strcmp(name, opt->o_name) != 0) 109*e23c41c9SAli Bahrami continue; 110*e23c41c9SAli Bahrami 111*e23c41c9SAli Bahrami if (set == TRUE) { 112*e23c41c9SAli Bahrami if (opt->o_class) 113*e23c41c9SAli Bahrami dbp->d_class |= opt->o_class; 114*e23c41c9SAli Bahrami if (opt->o_extra) 115*e23c41c9SAli Bahrami dbp->d_extra |= opt->o_extra; 116*e23c41c9SAli Bahrami } else { 117*e23c41c9SAli Bahrami if (opt->o_class) 118*e23c41c9SAli Bahrami dbp->d_class &= ~(opt->o_class); 119*e23c41c9SAli Bahrami if (opt->o_extra) 120*e23c41c9SAli Bahrami dbp->d_extra &= ~(opt->o_extra); 121*e23c41c9SAli Bahrami } 122*e23c41c9SAli Bahrami return (TRUE); 123*e23c41c9SAli Bahrami } 124*e23c41c9SAli Bahrami 125*e23c41c9SAli Bahrami return (FALSE); 126*e23c41c9SAli Bahrami } 1275aefb655Srie 1287c478bd9Sstevel@tonic-gate /* 1297c478bd9Sstevel@tonic-gate * Provide a debugging usage message 1307c478bd9Sstevel@tonic-gate */ 1315aefb655Srie void 132*e23c41c9SAli Bahrami Dbg_help(void) 1337c478bd9Sstevel@tonic-gate { 1345aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 135*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_A)); 136*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_B)); 137*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_C)); 138*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_D)); 139*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_E)); 140*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_F)); 141*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R1_G)); 142*e23c41c9SAli Bahrami 1435aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 144*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_A)); 145*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_B)); 146*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_C)); 147*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_D)); 148*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_E)); 149*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_F)); 150*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_G)); 151*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_H)); 152*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_I)); 153*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_J)); 154*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_K)); 155*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_L)); 156*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_M)); 157*e23c41c9SAli Bahrami 1585aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 159*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_L)); 160*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_M)); 161*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_N)); 162*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_O)); 163*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_P)); 164*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_Q)); 165*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_R)); 166*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R2_S)); 167*e23c41c9SAli Bahrami 168*e23c41c9SAli Bahrami Dbg_util_nl(0, DBG_NL_FRC); 169*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_A)); 170*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_B)); 171*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_C)); 172*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_D)); 173*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_E)); 174*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_F)); 175*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_G)); 176*e23c41c9SAli Bahrami 1775aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 178*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_H)); 179*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_F)); 180*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_I)); 181*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_J)); 182*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_K)); 183*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_L)); 184*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_M)); 1855aefb655Srie 1865aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 187*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R3_N)); 188*e23c41c9SAli Bahrami 1895aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 190*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_DCT)); 191*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); 192*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_A)); 193*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_B)); 194*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_B2)); 195*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_C)); 196*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_D)); 197*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_D2)); 198*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R4_D3)); 199*e23c41c9SAli Bahrami 2005aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 201*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); 202*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A)); 203*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A2)); 204*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A3)); 205*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A4)); 206*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A5)); 207*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A6)); 208*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A7)); 209*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A8)); 210*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A9)); 211*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_A0)); 212*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_B)); 213*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_C)); 214*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_D)); 215*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_E)); 216*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R5_F)); 217*e23c41c9SAli Bahrami 2185aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 219*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); 220*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_A)); 221*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_B)); 222*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_C)); 223*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R6_C2)); 224*e23c41c9SAli Bahrami 2255aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 226*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_CST)); 227*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_BOTH)); 228*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_A)); 229*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_B)); 230*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_C)); 231*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_D)); 232*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_E)); 233*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_F)); 234*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_F2)); 235*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_G)); 236*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_H)); 237*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_I)); 238*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_I2)); 239*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_J)); 240*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_K)); 241*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_K2)); 242*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R7_L)); 2435aefb655Srie 2445aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 245*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_RTLD)); 246*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_A)); 247*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_B)); 248*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_B2)); 249*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R8_C)); 250*e23c41c9SAli Bahrami 2515aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 252*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_HDR_LD)); 253*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_A)); 254*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_B)); 255*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_C)); 256*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_D)); 257*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_E)); 258*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_F)); 259*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_F2)); 260*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_G)); 261*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_H)); 262*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_H2)); 263*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_R9_I)); 264*e23c41c9SAli Bahrami 2655aefb655Srie Dbg_util_nl(0, DBG_NL_FRC); 2665aefb655Srie } 2675aefb655Srie 2685aefb655Srie /* 2695aefb655Srie * Messaging support - funnel everything through dgettext() as this provides 2705aefb655Srie * the real binding to libc. 2715aefb655Srie */ 2725aefb655Srie const char * 2735aefb655Srie _liblddbg_msg(Msg mid) 2745aefb655Srie { 2755aefb655Srie return (dgettext(MSG_ORIG(MSG_SUNW_OST_SGS), MSG_ORIG(mid))); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate 278*e23c41c9SAli Bahrami /* 279*e23c41c9SAli Bahrami * Given a name starting with "lmid", finish processing it. Return TRUE 280*e23c41c9SAli Bahrami * if a valid lmid token was seen, and FALSE for any error. 281*e23c41c9SAli Bahrami * 282*e23c41c9SAli Bahrami * exit: 283*e23c41c9SAli Bahrami * On failure, returns FALSE, indicating a syntax error 284*e23c41c9SAli Bahrami * 285*e23c41c9SAli Bahrami * On success: 286*e23c41c9SAli Bahrami * - Appropriate flags in dbg->d_extra have been set 287*e23c41c9SAli Bahrami * - Any link-map list names specified have been added to 288*e23c41c9SAli Bahrami * d_list, for the rtld dbg_print() to compare against 289*e23c41c9SAli Bahrami * link-map list names. 290*e23c41c9SAli Bahrami * - TRUE is returned. 291*e23c41c9SAli Bahrami */ 292*e23c41c9SAli Bahrami static Boolean 293*e23c41c9SAli Bahrami process_lmid(char *name, Dbg_desc *dbp) 294*e23c41c9SAli Bahrami { 295*e23c41c9SAli Bahrami /* 296*e23c41c9SAli Bahrami * "lmid" can have an optional argument. Allowed values are "all", 297*e23c41c9SAli Bahrami * "alt[0-9]+", "base", or "ldso". Alt has a variable ending, but 298*e23c41c9SAli Bahrami * we can use process_options() to handle the other three. 299*e23c41c9SAli Bahrami */ 300*e23c41c9SAli Bahrami static DBG_options options_lmid[] = { 301*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_ALL), 0, DBG_E_LMID_ALL}, 302*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_BASE), 0, DBG_E_LMID_BASE}, 303*e23c41c9SAli Bahrami {MSG_ORIG(MSG_TOK_LMID_LDSO), 0, DBG_E_LMID_LDSO}, 304*e23c41c9SAli Bahrami {NULL, NULL}, 305*e23c41c9SAli Bahrami }; 306*e23c41c9SAli Bahrami 307*e23c41c9SAli Bahrami Dbg_desc tmp_db; 308*e23c41c9SAli Bahrami const char *lmid_opt; 309*e23c41c9SAli Bahrami 310*e23c41c9SAli Bahrami /* If it's a plain "lmid", we can set the flag and return now */ 311*e23c41c9SAli Bahrami if (name[MSG_TOK_LMID_SIZE] == '\0') { 312*e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID; 313*e23c41c9SAli Bahrami return (TRUE); 314*e23c41c9SAli Bahrami } 315*e23c41c9SAli Bahrami 316*e23c41c9SAli Bahrami /* If there's no value, its an error */ 317*e23c41c9SAli Bahrami if (conv_strproc_extract_value(name, MSG_TOK_LMID_SIZE, 318*e23c41c9SAli Bahrami CONV_SPEXV_F_UCASE, &lmid_opt) == 0) 319*e23c41c9SAli Bahrami return (FALSE); 320*e23c41c9SAli Bahrami 321*e23c41c9SAli Bahrami /* 322*e23c41c9SAli Bahrami * ALL, BASE, or LDSO? 323*e23c41c9SAli Bahrami */ 324*e23c41c9SAli Bahrami tmp_db.d_extra = 0; 325*e23c41c9SAli Bahrami if (process_options(lmid_opt, TRUE, &tmp_db, options_lmid)) { 326*e23c41c9SAli Bahrami /* 327*e23c41c9SAli Bahrami * If BASE, and we haven't already seen it, add it to the 328*e23c41c9SAli Bahrami * rtld name matching list. For the others, setting the 329*e23c41c9SAli Bahrami * e_extra bit suffices. 330*e23c41c9SAli Bahrami */ 331*e23c41c9SAli Bahrami if (((tmp_db.d_extra & DBG_E_LMID_BASE) != 0) && 332*e23c41c9SAli Bahrami ((dbp->d_extra & DBG_E_LMID_BASE) == 0) && 333*e23c41c9SAli Bahrami (aplist_append(&dbp->d_list, MSG_ORIG(MSG_TOK_LMID_BASE), 334*e23c41c9SAli Bahrami AL_CNT_DEBUG) == NULL)) 335*e23c41c9SAli Bahrami return (FALSE); 336*e23c41c9SAli Bahrami 337*e23c41c9SAli Bahrami /* Add the resulting flags into the callers descriptor */ 338*e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID | tmp_db.d_extra; 339*e23c41c9SAli Bahrami return (TRUE); 340*e23c41c9SAli Bahrami } 341*e23c41c9SAli Bahrami 342*e23c41c9SAli Bahrami /* 343*e23c41c9SAli Bahrami * ALT? 344*e23c41c9SAli Bahrami */ 345*e23c41c9SAli Bahrami if (strncmp(lmid_opt, MSG_ORIG(MSG_TOK_LMID_ALT), 346*e23c41c9SAli Bahrami MSG_TOK_LMID_ALT_SIZE) == 0) { 347*e23c41c9SAli Bahrami const char *tail = lmid_opt + MSG_TOK_LMID_ALT_SIZE; 348*e23c41c9SAli Bahrami 349*e23c41c9SAli Bahrami /* 'ALT' without a # means "all alternative link-map lists" */ 350*e23c41c9SAli Bahrami if (*tail == '\0') { 351*e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID | DBG_E_LMID_ALT; 352*e23c41c9SAli Bahrami return (TRUE); 353*e23c41c9SAli Bahrami } 354*e23c41c9SAli Bahrami 355*e23c41c9SAli Bahrami /* 356*e23c41c9SAli Bahrami * It is ALT[0-9]+. Make sure the characters following 'ALT' 357*e23c41c9SAli Bahrami * are numbers, and then add it to the rtld name matching list. 358*e23c41c9SAli Bahrami */ 359*e23c41c9SAli Bahrami for (; *tail; tail++) 360*e23c41c9SAli Bahrami if ((*tail < '0') || (*tail > '9')) 361*e23c41c9SAli Bahrami return (FALSE); 362*e23c41c9SAli Bahrami 363*e23c41c9SAli Bahrami if (aplist_append(&dbp->d_list, lmid_opt, AL_CNT_DEBUG) == NULL) 364*e23c41c9SAli Bahrami return (FALSE); 365*e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_LMID; 366*e23c41c9SAli Bahrami return (TRUE); 367*e23c41c9SAli Bahrami } 368*e23c41c9SAli Bahrami 369*e23c41c9SAli Bahrami /* It's nothing we recognize */ 370*e23c41c9SAli Bahrami return (FALSE); 371*e23c41c9SAli Bahrami } 372*e23c41c9SAli Bahrami 3737c478bd9Sstevel@tonic-gate /* 3747c478bd9Sstevel@tonic-gate * Validate and enable the appropriate debugging classes. 375*e23c41c9SAli Bahrami * 376*e23c41c9SAli Bahrami * entry: 377*e23c41c9SAli Bahrami * string - String to be analyzed for debugging options 378*e23c41c9SAli Bahrami * dbp - Pointer to debug descriptor to be initialized 379*e23c41c9SAli Bahrami * outfile_ret - NULL, or pointer to receive result of 'output=' 380*e23c41c9SAli Bahrami * token. A NULL value means that the 'output=' token 381*e23c41c9SAli Bahrami * is not accepted. A non-NULL value means that it is. 382*e23c41c9SAli Bahrami * 383*e23c41c9SAli Bahrami * exit: 384*e23c41c9SAli Bahrami * On failure, False (0) is returned. 385*e23c41c9SAli Bahrami * 386*e23c41c9SAli Bahrami * On success, string has been parsed, and the descriptor referenced 387*e23c41c9SAli Bahrami * by dbp has been initialized. If outfile is non-NULL, *outfile will 388*e23c41c9SAli Bahrami * be set to NULL if the 'output=' token is not present, and to the 389*e23c41c9SAli Bahrami * user supplied string otherwise. True (1) is returned. 3907c478bd9Sstevel@tonic-gate */ 391*e23c41c9SAli Bahrami int 392*e23c41c9SAli Bahrami Dbg_setup(dbg_setup_caller_t caller, const char *string, Dbg_desc *dbp, 393*e23c41c9SAli Bahrami const char **outfile) 3947c478bd9Sstevel@tonic-gate { 3955aefb655Srie char *name, *_name; /* buffer in which to perform */ 3965aefb655Srie /* strtok_r() operations. */ 3977c478bd9Sstevel@tonic-gate char *lasts; 3987c478bd9Sstevel@tonic-gate const char *delimit = MSG_ORIG(MSG_STR_DELIMIT); 3997c478bd9Sstevel@tonic-gate 400*e23c41c9SAli Bahrami /* 401*e23c41c9SAli Bahrami * Clear the help flags --- these items only apply for a single 402*e23c41c9SAli Bahrami * call to Dbg_setup(). 403*e23c41c9SAli Bahrami */ 404*e23c41c9SAli Bahrami dbp->d_extra &= ~(DBG_E_HELP | DBG_E_HELP_EXIT); 405*e23c41c9SAli Bahrami 406*e23c41c9SAli Bahrami if ((_name = (char *)malloc(strlen(string) + 1)) == NULL) 407*e23c41c9SAli Bahrami return (0); 4087c478bd9Sstevel@tonic-gate (void) strcpy(_name, string); 4097c478bd9Sstevel@tonic-gate 410*e23c41c9SAli Bahrami if (outfile) 411*e23c41c9SAli Bahrami *outfile = NULL; /* No output file yet */ 412*e23c41c9SAli Bahrami 4137c478bd9Sstevel@tonic-gate /* 4147c478bd9Sstevel@tonic-gate * The token should be of the form "-Dtok,tok,tok,...". Separate the 4157c478bd9Sstevel@tonic-gate * pieces and build up the appropriate mask, unrecognized options are 4167c478bd9Sstevel@tonic-gate * flagged. 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate if ((name = strtok_r(_name, delimit, &lasts)) != NULL) { 4197c478bd9Sstevel@tonic-gate do { 420*e23c41c9SAli Bahrami Boolean set; 421*e23c41c9SAli Bahrami 422*e23c41c9SAli Bahrami /* Remove leading and trailing whitespace */ 423*e23c41c9SAli Bahrami name = conv_strproc_trim(name); 4245aefb655Srie 4257c478bd9Sstevel@tonic-gate if (name[0] == '!') { 4267c478bd9Sstevel@tonic-gate set = FALSE; 4277c478bd9Sstevel@tonic-gate name++; 4285aefb655Srie } else 4295aefb655Srie set = TRUE; 4305aefb655Srie 431*e23c41c9SAli Bahrami if (*name == '\0') 432*e23c41c9SAli Bahrami continue; /* Skip null token */ 433*e23c41c9SAli Bahrami 4345aefb655Srie /* 4355aefb655Srie * First, determine if the token represents a class or 4365aefb655Srie * extra. 4375aefb655Srie */ 438*e23c41c9SAli Bahrami if (process_options(name, set, dbp, _Dbg_options)) 439*e23c41c9SAli Bahrami continue; 440*e23c41c9SAli Bahrami switch (caller) { 441*e23c41c9SAli Bahrami case DBG_CALLER_LD: /* ld only tokens */ 442*e23c41c9SAli Bahrami if (process_options(name, set, dbp, 443*e23c41c9SAli Bahrami _Dbg_options_ld)) 444*e23c41c9SAli Bahrami continue; 445*e23c41c9SAli Bahrami break; 446*e23c41c9SAli Bahrami case DBG_CALLER_RTLD: /* rtld only tokens */ 447*e23c41c9SAli Bahrami if (process_options(name, set, dbp, 448*e23c41c9SAli Bahrami _Dbg_options_rtld)) 4495aefb655Srie continue; 4505aefb655Srie break; 4517c478bd9Sstevel@tonic-gate } 452*e23c41c9SAli Bahrami 453*e23c41c9SAli Bahrami /* The remaining options do not accept negation */ 454*e23c41c9SAli Bahrami if (!set) { 455*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_CNTNEGOPT), name); 4565aefb655Srie continue; 457*e23c41c9SAli Bahrami } 4585aefb655Srie 4595aefb655Srie /* 460*e23c41c9SAli Bahrami * Is it an 'output=' token? This item is a special 461*e23c41c9SAli Bahrami * case because it depends on the presence of 462*e23c41c9SAli Bahrami * a non-NULL outfile argument, and because the 463*e23c41c9SAli Bahrami * part following the '=' is variable. 4645aefb655Srie */ 465*e23c41c9SAli Bahrami if ((outfile != NULL) && 466*e23c41c9SAli Bahrami strncmp(name, MSG_ORIG(MSG_TOK_OUTFILE), 467*e23c41c9SAli Bahrami MSG_TOK_OUTFILE_SIZE) == 0) { 468*e23c41c9SAli Bahrami if (conv_strproc_extract_value(name, 469*e23c41c9SAli Bahrami MSG_TOK_OUTFILE_SIZE, 0, outfile)) 4705aefb655Srie continue; 4717c478bd9Sstevel@tonic-gate } 4725aefb655Srie 473*e23c41c9SAli Bahrami /* 474*e23c41c9SAli Bahrami * Only the rtld "lmid" token is left. 475*e23c41c9SAli Bahrami */ 476*e23c41c9SAli Bahrami if ((caller == DBG_CALLER_RTLD) && (strncmp(name, 477*e23c41c9SAli Bahrami MSG_ORIG(MSG_TOK_LMID), MSG_TOK_LMID_SIZE) == 0) && 478*e23c41c9SAli Bahrami process_lmid(name, dbp)) 479*e23c41c9SAli Bahrami continue; 480*e23c41c9SAli Bahrami 481*e23c41c9SAli Bahrami /* If we make it here, the token is not understood */ 482*e23c41c9SAli Bahrami dbg_print(0, MSG_INTL(MSG_USE_UNRECOG), name); 4835aefb655Srie 4847c478bd9Sstevel@tonic-gate } while ((name = strtok_r(NULL, delimit, &lasts)) != NULL); 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate /* 488*e23c41c9SAli Bahrami * If the debug help option was specified and this is the only debug 489*e23c41c9SAli Bahrami * class, return an indication that the user should exit. 4907c478bd9Sstevel@tonic-gate */ 491*e23c41c9SAli Bahrami if ((_Dbg_cnt++ == 0) && (dbp->d_extra & DBG_E_HELP) && 492*e23c41c9SAli Bahrami (dbp->d_class == 0)) 493*e23c41c9SAli Bahrami dbp->d_extra |= DBG_E_HELP_EXIT; 494*e23c41c9SAli Bahrami 4955aefb655Srie return (1); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate /* 4995aefb655Srie * Define our own printing routine. This provides a basic fallback, as ld(1) 5005aefb655Srie * and ld.so.1(1) provide their own routines that augment their diagnostic 5015aefb655Srie * output, and direct the output to stderr. This item should be defined 5025aefb655Srie * NODIRECT. 5037c478bd9Sstevel@tonic-gate */ 5045aefb655Srie /* PRINTFLIKE2 */ 5057c478bd9Sstevel@tonic-gate void 5065aefb655Srie dbg_print(Lm_list *lml, const char *format, ...) 5077c478bd9Sstevel@tonic-gate { 5085aefb655Srie va_list ap; 5097c478bd9Sstevel@tonic-gate 5105aefb655Srie #if defined(lint) 5115aefb655Srie /* 5125aefb655Srie * The lml argument is only meaningful for diagnostics sent to ld.so.1. 5135aefb655Srie * Supress the lint error by making a dummy assignment. 5145aefb655Srie */ 5155aefb655Srie lml = 0; 5165aefb655Srie #endif 5175aefb655Srie va_start(ap, format); 5185aefb655Srie (void) vprintf(format, ap); 5195aefb655Srie (void) printf(MSG_ORIG(MSG_STR_NL)); 5205aefb655Srie va_end(ap); 5217c478bd9Sstevel@tonic-gate } 522