debug.c revision 5aefb6555731130ca4fd295960123d71f2d21fe8
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott/*
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * CDDL HEADER START
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott *
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * The contents of this file are subject to the terms of the
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * Common Development and Distribution License (the "License").
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * You may not use this file except in compliance with the License.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott *
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * or http://www.opensolaris.org/os/licensing.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * See the License for the specific language governing permissions
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * and limitations under the License.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott *
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * When distributing Covered Code, include this CDDL HEADER in each
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * If applicable, add the following below this CDDL HEADER, with the
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington * fields enclosed by brackets "[]" replaced with your own identifying
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * information: Portions Copyright [yyyy] [name of copyright owner]
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott *
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * CDDL HEADER END
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott */
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott/*
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * Use is subject to license terms.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott */
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott#pragma ident "%Z%%M% %I% %E% SMI"
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott#include <stdio.h>
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott#include <stdarg.h>
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott#include <strings.h>
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington#include <dlfcn.h>
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington#include <debug.h>
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington#include "msg.h"
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington/*
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * dbg_setup() can be called a number of times. The typical use through
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * LD_OPTIONS, results in dbg_setup() being called as the first argument to
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * ld(1). It's also possible to pass debugging tokens through the compiler,
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * for example -Wl,-Dlibs -Wl-Ddetail, in which case multiple dbg_setup()
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * calls are made.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott *
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * A distinction is also made between diagnostics being requested before any
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * other ld(1) options are read, or whether the debugging options occur
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * between other options on the command line. In the latter case, the
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * debugging options can be used to isolate diagnostics around one or more
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * input files. The "phase" argument allows us to select which phase of
c49a898cb851f8fef7d7a6a9501c66b8f03ae05cPhill Cunnington * dbg_setup() processing we should isolate ourselves to.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott *
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * dbg_print() can require the output filename for use in the diagnostics
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * created. Save the address of the output filename pointer for this use.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott */
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshottstatic const char **Name = 0;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshottstatic int Phase = 0;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshottuintptr_t
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshottdbg_setup(const char *options, Dbg_desc *dbp, const char **name, int phase)
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott{
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott if (Phase == 0)
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott Phase = phase;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott else if (Phase != phase)
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden return (0);
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden Name = name;
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden /*
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden * Call the debugging setup routine to initialize the mask and
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden * debug function array.
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden */
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden return (Dbg_setup(options, dbp));
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden}
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden/* PRINTFLIKE2 */
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Maddenvoid
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Maddendbg_print(Lm_list *lml, const char *format, ...)
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden{
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott static char *prestr = 0;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott va_list args;
20aa78f25733d8ab7d7c0f43c4930dad32db279eNeil Madden
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott#if defined(lint)
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott /*
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * The lml argument is only meaningful for diagnostics sent to ld.so.1.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * Supress the lint error by making a dummy assignment.
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott */
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott lml = 0;
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott#endif
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott /*
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * Knock off any newline indicator to signify that a diagnostic has
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott * been processed.
d739a02123d066f5b76a43c9f922d8afbcc94b97Phill Cunnington */
d739a02123d066f5b76a43c9f922d8afbcc94b97Phill Cunnington dbg_desc->d_extra &= ~DBG_E_STDNL;
d739a02123d066f5b76a43c9f922d8afbcc94b97Phill Cunnington
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott if (DBG_ISSNAME()) {
537857b204a4425e0ea257b0413a02c5c7c5e266Robert Wapshott /*
* If the debugging options have requested each diagnostic line
* be prepended by a name create a prefix string.
*/
if ((prestr == 0) && *Name) {
const char *name, *cls;
size_t len;
/*
* Select the fullname or basename of the output file
* being created.
*/
if (DBG_ISFNAME())
name = *Name;
else {
if ((name =
strrchr(*Name, '/')) == 0)
name = *Name;
else
name++;
}
len = strlen(name) +
strlen(MSG_INTL(MSG_DBG_NAME_FMT)) + 1;
/*
* Add the output file class if required.
*/
if (DBG_ISCLASS()) {
#if defined(_ELF64)
len += MSG_DBG_CLS64_FMT_SIZE;
cls = MSG_ORIG(MSG_DBG_CLS64_FMT);
#else
len += MSG_DBG_CLS32_FMT_SIZE;
cls = MSG_ORIG(MSG_DBG_CLS32_FMT);
#endif
}
/*
* Allocate a string to build the prefix.
*/
if ((prestr = malloc(len)) == 0)
prestr = (char *)MSG_INTL(MSG_DBG_DFLT_FMT);
else {
(void) snprintf(prestr, len,
MSG_INTL(MSG_DBG_NAME_FMT), name);
if (DBG_ISCLASS())
(void) strcat(prestr, cls);
}
}
if (prestr)
(void) fputs(prestr, stderr);
else
(void) fputs(MSG_INTL(MSG_DBG_AOUT_FMT), stderr);
} else
(void) fputs(MSG_INTL(MSG_DBG_DFLT_FMT), stderr);
va_start(args, format);
(void) vfprintf(stderr, format, args);
(void) fprintf(stderr, MSG_ORIG(MSG_STR_NL));
va_end(args);
}