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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <stdarg.h> 30 #include <strings.h> 31 #include <dlfcn.h> 32 #include <debug.h> 33 #include "msg.h" 34 35 /* 36 * dbg_setup() can be called a number of times. The typical use through 37 * LD_OPTIONS, results in dbg_setup() being called as the first argument to 38 * ld(1). It's also possible to pass debugging tokens through the compiler, 39 * for example -Wl,-Dlibs -Wl-Ddetail, in which case multiple dbg_setup() 40 * calls are made. 41 * 42 * A distinction is also made between diagnostics being requested before any 43 * other ld(1) options are read, or whether the debugging options occur 44 * between other options on the command line. In the latter case, the 45 * debugging options can be used to isolate diagnostics around one or more 46 * input files. The "phase" argument allows us to select which phase of 47 * dbg_setup() processing we should isolate ourselves to. 48 * 49 * dbg_print() can require the output filename for use in the diagnostics 50 * created. Save the address of the output filename pointer for this use. 51 */ 52 static const char **Name = 0; 53 static int Phase = 0; 54 55 uintptr_t 56 dbg_setup(const char *options, Dbg_desc *dbp, const char **name, int phase) 57 { 58 if (Phase == 0) 59 Phase = phase; 60 else if (Phase != phase) 61 return (0); 62 63 Name = name; 64 65 /* 66 * Call the debugging setup routine to initialize the mask and 67 * debug function array. 68 */ 69 return (Dbg_setup(options, dbp)); 70 } 71 72 /* PRINTFLIKE2 */ 73 void 74 dbg_print(Lm_list *lml, const char *format, ...) 75 { 76 static char *prestr = 0; 77 va_list args; 78 79 #if defined(lint) 80 /* 81 * The lml argument is only meaningful for diagnostics sent to ld.so.1. 82 * Supress the lint error by making a dummy assignment. 83 */ 84 lml = 0; 85 #endif 86 /* 87 * Knock off any newline indicator to signify that a diagnostic has 88 * been processed. 89 */ 90 dbg_desc->d_extra &= ~DBG_E_STDNL; 91 92 if (DBG_ISSNAME()) { 93 /* 94 * If the debugging options have requested each diagnostic line 95 * be prepended by a name create a prefix string. 96 */ 97 if ((prestr == 0) && *Name) { 98 const char *name, *cls; 99 size_t len; 100 101 /* 102 * Select the fullname or basename of the output file 103 * being created. 104 */ 105 if (DBG_ISFNAME()) 106 name = *Name; 107 else { 108 if ((name = 109 strrchr(*Name, '/')) == 0) 110 name = *Name; 111 else 112 name++; 113 } 114 len = strlen(name) + 115 strlen(MSG_INTL(MSG_DBG_NAME_FMT)) + 1; 116 117 /* 118 * Add the output file class if required. 119 */ 120 if (DBG_ISCLASS()) { 121 #if defined(_ELF64) 122 len += MSG_DBG_CLS64_FMT_SIZE; 123 cls = MSG_ORIG(MSG_DBG_CLS64_FMT); 124 #else 125 len += MSG_DBG_CLS32_FMT_SIZE; 126 cls = MSG_ORIG(MSG_DBG_CLS32_FMT); 127 #endif 128 } 129 130 /* 131 * Allocate a string to build the prefix. 132 */ 133 if ((prestr = malloc(len)) == 0) 134 prestr = (char *)MSG_INTL(MSG_DBG_DFLT_FMT); 135 else { 136 (void) snprintf(prestr, len, 137 MSG_INTL(MSG_DBG_NAME_FMT), name); 138 if (DBG_ISCLASS()) 139 (void) strcat(prestr, cls); 140 } 141 } 142 if (prestr) 143 (void) fputs(prestr, stderr); 144 else 145 (void) fputs(MSG_INTL(MSG_DBG_AOUT_FMT), stderr); 146 } else 147 (void) fputs(MSG_INTL(MSG_DBG_DFLT_FMT), stderr); 148 149 va_start(args, format); 150 (void) vfprintf(stderr, format, args); 151 (void) fprintf(stderr, MSG_ORIG(MSG_STR_NL)); 152 va_end(args); 153 } 154