Home | History | Annotate | Download | only in common
      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 2009 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #include	<sys/types.h>
     28 #include	<string.h>
     29 #include	<debug.h>
     30 #include	<conv.h>
     31 #include	"_debug.h"
     32 #include	"msg.h"
     33 
     34 void
     35 Dbg_bind_plt_summary(Lm_list *lml, Half mach, Word pltcnt21d, Word pltcnt24d,
     36     Word pltcntu32, Word pltcntu44, Word pltcntfull, Word pltcntfar)
     37 {
     38 	Word plttotal = pltcnt21d + pltcnt24d + pltcntu32 +
     39 	    pltcntu44 + pltcntfull + pltcntfar;
     40 
     41 	if (DBG_NOTCLASS(DBG_C_BINDINGS))
     42 		return;
     43 
     44 	switch (mach) {
     45 	case EM_SPARC:
     46 		dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARC), EC_WORD(pltcnt21d),
     47 		    EC_WORD(pltcnt24d), EC_WORD(pltcntfull), EC_WORD(plttotal));
     48 		break;
     49 	case EM_SPARCV9:
     50 		dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARCV9),
     51 		    EC_WORD(pltcnt21d), EC_WORD(pltcnt24d), EC_WORD(pltcntu32),
     52 		    EC_WORD(pltcntu44), EC_WORD(pltcntfull), EC_WORD(pltcntfar),
     53 		    EC_WORD(plttotal));
     54 		break;
     55 	default:
     56 		dbg_print(lml, MSG_INTL(MSG_BND_PSUM_DEFAULT),
     57 		    EC_WORD(plttotal));
     58 		break;
     59 	};
     60 }
     61 
     62 static const char	*pltbindtypes[PLT_T_NUM] = {
     63 	MSG_ORIG(MSG_STR_EMPTY),	/* PLT_T_NONE */
     64 	MSG_ORIG(MSG_PLT_21D),		/* PLT_T_21D */
     65 	MSG_ORIG(MSG_PLT_24D),		/* PLT_T_24D */
     66 	MSG_ORIG(MSG_PLT_U32),		/* PLT_T_U32 */
     67 	MSG_ORIG(MSG_PLT_U44),		/* PLT_T_U44 */
     68 	MSG_ORIG(MSG_PLT_FULL),		/* PLT_T_FULL */
     69 	MSG_ORIG(MSG_PLT_FAR)		/* PLT_T_FAR */
     70 };
     71 
     72 #define	BINFOSZ	MSG_BINFO_START_SIZE + \
     73 		MSG_BINFO_DIRECT_SIZE +		MSG_BINFO_SEP_SIZE + \
     74 		MSG_BINFO_INTERPOSE_SIZE +	MSG_BINFO_SEP_SIZE + \
     75 		MSG_BINFO_COPYREF_SIZE +	MSG_BINFO_SEP_SIZE + \
     76 		MSG_BINFO_FILTEE_SIZE +		MSG_BINFO_SEP_SIZE + \
     77 		MSG_BINFO_PLTADDR_SIZE + \
     78 		CONV_INV_BUFSIZE + MSG_BINFO_END_SIZE
     79 
     80 
     81 void
     82 Dbg_bind_global(Rt_map *flmp, Addr fabs, Off foff, Xword pltndx,
     83     Pltbindtype pbtype, Rt_map *tlmp, Addr tabs, Off toff,
     84     const char *sym, uint_t binfo)
     85 {
     86 	/*
     87 	 * MSG_ORIG(MSG_BINFO_DIRECT)
     88 	 * MSG_ORIG(MSG_BINFO_INTERPOSE)
     89 	 * MSG_ORIG(MSG_BINFO_COPYREF)
     90 	 * MSG_ORIG(MSG_BINFO_FILTEE)
     91 	 * MSG_ORIG(MSG_BINFO_PLTADDR)
     92 	 */
     93 	static char binfostr[BINFOSZ];
     94 	static Val_desc vda[] = {
     95 		{ DBG_BINFO_DIRECT,	MSG_BINFO_DIRECT },
     96 		{ DBG_BINFO_INTERPOSE,	MSG_BINFO_INTERPOSE },
     97 		{ DBG_BINFO_COPYREF,	MSG_BINFO_COPYREF },
     98 		{ DBG_BINFO_FILTEE,	MSG_BINFO_FILTEE },
     99 		{ DBG_BINFO_PLTADDR,	MSG_BINFO_PLTADDR },
    100 		{ 0,			0 }
    101 	};
    102 	static CONV_EXPN_FIELD_ARG conv_arg = { binfostr, sizeof (binfostr),
    103 		NULL, 0, 0, MSG_ORIG(MSG_BINFO_START),
    104 		MSG_ORIG(MSG_BINFO_SEP), MSG_ORIG(MSG_BINFO_END) };
    105 
    106 	const char	*ffile = NAME(flmp);
    107 	const char	*tfile = NAME(tlmp);
    108 	Lm_list		*lml = LIST(flmp);
    109 
    110 	if (DBG_NOTCLASS(DBG_C_BINDINGS))
    111 		return;
    112 
    113 	if (DBG_NOTDETAIL()) {
    114 		dbg_print(lml, MSG_INTL(MSG_BND_BASIC), ffile, tfile,
    115 		    Dbg_demangle_name(sym));
    116 		return;
    117 	}
    118 
    119 	/*
    120 	 * Determine if this binding has any associated information, such as
    121 	 * interposition, direct binding, copy-relocations, etc.
    122 	 */
    123 	binfo &= ~DBG_BINFO_FOUND;
    124 	binfo &= DBG_BINFO_MSK;
    125 	if (binfo) {
    126 		conv_arg.oflags = conv_arg.rflags = binfo;
    127 		(void) conv_expn_field(&conv_arg, vda, 0);
    128 	} else {
    129 		binfostr[0] = '\0';
    130 	}
    131 
    132 	if (pltndx != (Xword)-1) {
    133 		const char	*pltstring;
    134 
    135 		if (pbtype < PLT_T_NUM)
    136 			pltstring = pltbindtypes[pbtype];
    137 		else
    138 			pltstring = pltbindtypes[PLT_T_NONE];
    139 
    140 		/*
    141 		 * Called from a plt offset.
    142 		 */
    143 		dbg_print(lml, MSG_INTL(MSG_BND_PLT), ffile, EC_ADDR(fabs),
    144 		    EC_OFF(foff), EC_XWORD(pltndx), pltstring, tfile,
    145 		    EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym),
    146 		    binfostr);
    147 
    148 	} else if ((fabs == 0) && (foff == 0)) {
    149 		/*
    150 		 * Called from a dlsym().  We're not performing a relocation,
    151 		 * but are handing the address of the symbol back to the user.
    152 		 */
    153 		dbg_print(lml, MSG_INTL(MSG_BND_DLSYM), ffile, tfile,
    154 		    EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym),
    155 		    binfostr);
    156 	} else {
    157 		/*
    158 		 * Standard relocation.
    159 		 */
    160 		dbg_print(lml, MSG_INTL(MSG_BND_DEFAULT), ffile, EC_ADDR(fabs),
    161 		    EC_OFF(foff), tfile, EC_ADDR(tabs), EC_OFF(toff),
    162 		    Dbg_demangle_name(sym), binfostr);
    163 	}
    164 }
    165 
    166 void
    167 Dbg_bind_reject(Rt_map *flmp, Rt_map *tlmp, const char *sym, int why)
    168 {
    169 	static Msg reason[DBG_BNDREJ_NUM + 1] = {
    170 		MSG_BNDREJ_DIRECT,	/* MSG_INTL(MSG_BNDREJ_DIRECT) */
    171 		MSG_BNDREJ_GROUP,	/* MSG_INTL(MSG_BNDREJ_GROUP) */
    172 		MSG_BNDREJ_SINGLE	/* MSG_INTL(MSG_BNDREJ_SINGLE) */
    173 	};
    174 
    175 	if (DBG_NOTCLASS(DBG_C_BINDINGS))
    176 		return;
    177 
    178 	dbg_print(LIST(flmp), MSG_INTL(MSG_BND_REJECT), NAME(flmp), NAME(tlmp),
    179 	    sym, MSG_INTL(reason[why]));
    180 }
    181 
    182 void
    183 Dbg_bind_weak(Rt_map *flmp, Addr fabs, Addr frel, const char *sym)
    184 {
    185 	Lm_list		*lml = LIST(flmp);
    186 	const char	*ffile = NAME(flmp);
    187 
    188 	if (DBG_NOTCLASS(DBG_C_BINDINGS))
    189 		return;
    190 
    191 	if (DBG_NOTDETAIL())
    192 		dbg_print(lml, MSG_INTL(MSG_BND_WEAK_1), ffile,
    193 		    Dbg_demangle_name(sym));
    194 	else
    195 		dbg_print(lml, MSG_INTL(MSG_BND_WEAK_2), ffile, EC_ADDR(fabs),
    196 		    EC_ADDR(frel), Dbg_demangle_name(sym));
    197 }
    198 
    199 #if	defined(_ELF64)
    200 
    201 void
    202 Dbg_bind_pltpad_to(Rt_map *lmp, Addr pltpad, const char *dfile,
    203     const char *sname)
    204 {
    205 	if (DBG_NOTCLASS(DBG_C_RELOC))
    206 		return;
    207 	if (DBG_NOTDETAIL())
    208 		return;
    209 
    210 	dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad),
    211 	    NAME(lmp), dfile, sname);
    212 }
    213 
    214 void
    215 Dbg_bind_pltpad_from(Rt_map *lmp, Addr pltpad, const char *sname)
    216 {
    217 	if (DBG_NOTCLASS(DBG_C_RELOC))
    218 		return;
    219 	if (DBG_NOTDETAIL())
    220 		return;
    221 
    222 	dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad),
    223 	    NAME(lmp), sname);
    224 }
    225 
    226 #endif
    227