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.
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.
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]
23 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
37 * dbg_setup() can be called a number of times. The typical use through
38 * LD_OPTIONS, results in dbg_setup() being called as the first argument to
39 * ld(1). It's also possible to pass debugging tokens through the compiler,
40 * for example -Wl,-Dlibs -Wl-Ddetail, in which case multiple dbg_setup()
43 * A distinction is also made between diagnostics being requested before any
44 * other ld(1) options are read, or whether the debugging options occur
45 * between other options on the command line. In the latter case, the
46 * debugging options can be used to isolate diagnostics around one or more
47 * input files. The "phase" argument allows us to select which phase of
48 * dbg_setup() processing we should isolate ourselves to.
50 * dbg_print() can require the output filename for use in the diagnostics
51 * created. Save the address of the output filename pointer for this use.
53 static const char **Name
= NULL
;
56 /* Debug file output state */
58 FILE *fptr
; /* File to send debug output */
59 int close_needed
; /* True if explicitly opened stream */
67 * If there is an explicitly opened debug file, close it and reset the state.
72 if (dbg_ofile
.close_needed
) {
73 (void) fclose(dbg_ofile
.fptr
);
74 dbg_ofile
.close_needed
= 0;
75 dbg_ofile
.fptr
= stderr
;
80 * Process debug tokens. Returns True (1) on success, and False (0)
84 dbg_setup(Ofl_desc
*ofl
, const char *options
, int phase
)
90 else if (Phase
!= phase
)
93 Name
= &ofl
->ofl_name
;
96 * Call the debugging setup routine to initialize the mask and
97 * debug function array.
99 if (Dbg_setup(DBG_CALLER_LD
, options
, dbg_desc
, &ofile
) == 0)
103 * If output= token was used, close the old file if necessary
104 * and open a new one if the file name is not NULL.
108 if (*ofile
!= '\0') {
109 FILE *fptr
= fopen(ofile
, MSG_ORIG(MSG_DBG_FOPEN_MODE
));
113 ld_eprintf(ofl
, ERR_FATAL
,
114 MSG_INTL(MSG_SYS_OPEN
), ofile
,
118 dbg_ofile
.fptr
= fptr
;
119 dbg_ofile
.close_needed
= 1;
125 * Now that the output file is established, identify the linker
126 * package, and generate help output if the user specified the
130 if (dbg_desc
->d_extra
& DBG_E_HELP
)
138 dbg_print(Lm_list
*lml
, const char *format
, ...)
140 static char *prestr
= NULL
;
145 * The lml argument is only meaningful for diagnostics sent to ld.so.1.
146 * Supress the lint error by making a dummy assignment.
151 * Knock off any newline indicator to signify that a diagnostic has
154 dbg_desc
->d_extra
&= ~DBG_E_STDNL
;
158 * If the debugging options have requested each diagnostic line
159 * be prepended by a name create a prefix string.
161 if ((prestr
== NULL
) && *Name
) {
162 const char *name
, *cls
;
166 * Select the fullname or basename of the output file
173 strrchr(*Name
, '/')) == NULL
)
179 strlen(MSG_INTL(MSG_DBG_NAME_FMT
)) + 1;
182 * Add the output file class if required.
186 len
+= MSG_DBG_CLS64_FMT_SIZE
;
187 cls
= MSG_ORIG(MSG_DBG_CLS64_FMT
);
189 len
+= MSG_DBG_CLS32_FMT_SIZE
;
190 cls
= MSG_ORIG(MSG_DBG_CLS32_FMT
);
195 * Allocate a string to build the prefix.
197 if ((prestr
= libld_malloc(len
)) == NULL
)
198 prestr
= (char *)MSG_INTL(MSG_DBG_DFLT_FMT
);
200 (void) snprintf(prestr
, len
,
201 MSG_INTL(MSG_DBG_NAME_FMT
), name
);
203 (void) strcat(prestr
, cls
);
206 (void) fputs(prestr
? prestr
: MSG_INTL(MSG_DBG_AOUT_FMT
),
209 (void) fputs(MSG_INTL(MSG_DBG_DFLT_FMT
), dbg_ofile
.fptr
);
215 if (gettimeofday(&new, NULL
) == 0) {
217 (void) fputs(conv_time(&DBG_TOTALTIME
, &new,
220 (void) fputs(conv_time(&DBG_DELTATIME
, &new,
227 va_start(args
, format
);
228 (void) vfprintf(dbg_ofile
.fptr
, format
, args
);
229 (void) fprintf(dbg_ofile
.fptr
, MSG_ORIG(MSG_STR_NL
));