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 2008 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	"_debug.h"
     30 #include	"msg.h"
     31 #include	"libld.h"
     32 
     33 
     34 static int
     35 Dbg_got_compare(Gottable *gtp1, Gottable *gtp2)
     36 {
     37 	Gotndx	*gnp1 = &gtp1->gt_gndx;
     38 	Gotndx	*gnp2 = &gtp2->gt_gndx;
     39 
     40 	if (gnp1->gn_gotndx > gnp2->gn_gotndx)
     41 		return (1);
     42 	if (gnp1->gn_gotndx < gnp2->gn_gotndx)
     43 		return (-1);
     44 
     45 	return (0);
     46 }
     47 
     48 void
     49 Dbg_got_display(Ofl_desc *ofl, Off goff, int stage,
     50     Word m_got_xnumber, size_t m_got_entsize)
     51 {
     52 	Lm_list		*lml = ofl->ofl_lml;
     53 	Gottable	*gtp = ofl->ofl_gottable;
     54 	Word		gotndx;
     55 	Xword		*gptr;
     56 
     57 	if (DBG_NOTCLASS(DBG_C_GOT))
     58 		return;
     59 
     60 	if (ofl->ofl_gotcnt == m_got_xnumber)
     61 		return;
     62 
     63 	Dbg_util_nl(lml, DBG_NL_STD);
     64 	dbg_print(lml, MSG_INTL(MSG_GOT_INFO), EC_WORD(ofl->ofl_gotcnt));
     65 
     66 	if (DBG_NOTDETAIL())
     67 		return;
     68 
     69 	qsort((char *)gtp, ofl->ofl_gotcnt, sizeof (Gottable),
     70 	    (int(*)(const void *, const void *))Dbg_got_compare);
     71 
     72 	if (stage == 0)
     73 		dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS1));
     74 	else
     75 		dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS2));
     76 
     77 	gptr = (Xword *)ofl->ofl_osgot->os_outdata->d_buf;
     78 
     79 	for (gotndx = 0; gotndx < ofl->ofl_gotcnt; gotndx++, gtp++, gptr++) {
     80 		Sym_desc	*sdp = gtp->gt_sym;
     81 		const char	*refstr, *name;
     82 		Gotndx		*gnp = &gtp->gt_gndx;
     83 		Lword		gotaddval;
     84 		Off		off = goff + (gotndx * m_got_entsize);
     85 		char		index[INDEX_STR_SIZE];
     86 
     87 		(void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX),
     88 		    EC_SWORD(gnp->gn_gotndx));
     89 
     90 		if (sdp == 0)
     91 			refstr = MSG_ORIG(MSG_STR_EMPTY);
     92 		else if (sdp->sd_flags & FLG_SY_SMGOT)
     93 			refstr = MSG_ORIG(MSG_GOT_SMALL_PIC);
     94 		else
     95 			refstr = MSG_ORIG(MSG_GOT_BIG_PIC);
     96 
     97 		if (sdp == 0)
     98 			name = MSG_ORIG(MSG_STR_EMPTY);
     99 		else if (sdp->sd_name)
    100 			name = Dbg_demangle_name(sdp->sd_name);
    101 		else
    102 			name = MSG_INTL(MSG_STR_UNKNOWN);
    103 
    104 		if (stage == 0)
    105 			gotaddval = gnp->gn_addend;
    106 		else
    107 			gotaddval = *gptr;
    108 
    109 		if ((sdp == 0) || (sdp->sd_sym->st_shndx == SHN_UNDEF) ||
    110 		    (sdp->sd_file == 0)) {
    111 			dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT1), index,
    112 			    refstr, EC_OFF(off), EC_XWORD(gotaddval), name);
    113 		} else {
    114 			dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT2), index,
    115 			    refstr, EC_OFF(off), EC_XWORD(gotaddval),
    116 			    sdp->sd_file->ifl_name, name);
    117 		}
    118 	}
    119 }
    120 
    121 void
    122 Elf_got_title(Lm_list *lml)
    123 {
    124 	dbg_print(lml, MSG_INTL(MSG_GOT_TITLE));
    125 }
    126 
    127 void
    128 Elf_got_entry(Lm_list *lml, Sword ndx, Addr addr, Xword value, Half mach,
    129     uchar_t ei_target_data, uchar_t ei_host_data, Word type, void *reloc,
    130     const char *name)
    131 {
    132 	Rela		*rela;
    133 	Rel		*rel;
    134 	const char	*str;
    135 	Conv_inv_buf_t	inv_buf;
    136 	char		index[INDEX_STR_SIZE];
    137 
    138 	(void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX),
    139 	    EC_SWORD(ndx));
    140 
    141 	/*
    142 	 * Got sections are SHT_PROGBITS, and are therefore not xlated by
    143 	 * libelf. If the target system has a different byte order than
    144 	 * the system displaying the data, swap the bytes so they are
    145 	 * presented properly.
    146 	 */
    147 	if (ei_target_data != ei_host_data)
    148 		value = BSWAP_XWORD(value);
    149 
    150 	if (reloc) {
    151 		if (type == SHT_RELA) {
    152 			rela = (Rela *)reloc;
    153 			str = conv_reloc_type(mach,
    154 			    ELF_R_TYPE(rela->r_info, mach), 0, &inv_buf);
    155 		} else {
    156 			rel = (Rel *)reloc;
    157 			str = conv_reloc_type(mach,
    158 			    ELF_R_TYPE(rel->r_info, mach), 0, &inv_buf);
    159 		}
    160 
    161 		if (name)
    162 			name = Elf_demangle_name(name);
    163 		else
    164 			name = MSG_ORIG(MSG_STR_EMPTY);
    165 
    166 		dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_RE), index, EC_ADDR(addr),
    167 		    EC_XWORD(value), str, name);
    168 	} else
    169 		dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_NR), index, EC_ADDR(addr),
    170 		    EC_XWORD(value));
    171 }
    172