got.c revision 4734:a4708faa3e85
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 2007 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	<stdlib.h>
29#include	"_debug.h"
30#include	"msg.h"
31#include	"libld.h"
32
33
34static int
35Dbg_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
48void
49Dbg_got_display(Ofl_desc *ofl, Off goff, int stage)
50{
51	Lm_list		*lml = ofl->ofl_lml;
52	Gottable	*gtp = ofl->ofl_gottable;
53	Word		gotndx;
54	Xword		*gptr;
55
56	if (DBG_NOTCLASS(DBG_C_GOT))
57		return;
58
59	if (ofl->ofl_gotcnt == M_GOT_XNumber)
60		return;
61
62	Dbg_util_nl(lml, DBG_NL_STD);
63	dbg_print(lml, MSG_INTL(MSG_GOT_INFO), EC_WORD(ofl->ofl_gotcnt));
64
65	if (DBG_NOTDETAIL())
66		return;
67
68	qsort((char *)gtp, ofl->ofl_gotcnt, sizeof (Gottable),
69	    (int(*)(const void *, const void *))Dbg_got_compare);
70
71	if (stage == 0)
72		dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS1));
73	else
74		dbg_print(lml, MSG_INTL(MSG_GOT_COLUMNS2));
75
76	gptr = (Xword *)ofl->ofl_osgot->os_outdata->d_buf;
77
78	for (gotndx = 0; gotndx < ofl->ofl_gotcnt; gotndx++, gtp++, gptr++) {
79		Sym_desc	*sdp = gtp->gt_sym;
80		const char	*refstr, *name;
81		Gotndx		*gnp = &gtp->gt_gndx;
82		Lword		gotaddval;
83		Off		off = goff + (gotndx * M_GOT_ENTSIZE);
84		char		index[INDEX_STR_SIZE];
85
86		(void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX),
87		    EC_SWORD(gnp->gn_gotndx));
88
89		if (sdp == 0)
90			refstr = MSG_ORIG(MSG_STR_EMPTY);
91		else if (sdp->sd_flags & FLG_SY_SMGOT)
92			refstr = MSG_ORIG(MSG_GOT_SMALL_PIC);
93		else
94			refstr = MSG_ORIG(MSG_GOT_BIG_PIC);
95
96		if (sdp == 0)
97			name = MSG_ORIG(MSG_STR_EMPTY);
98		else if (sdp->sd_name)
99			name = Dbg_demangle_name(sdp->sd_name);
100		else
101			name = MSG_INTL(MSG_STR_UNKNOWN);
102
103		if (stage == 0)
104			gotaddval = gnp->gn_addend;
105		else
106			gotaddval = *gptr;
107
108		if ((sdp == 0) || (sdp->sd_sym->st_shndx == SHN_UNDEF) ||
109		    (sdp->sd_file == 0)) {
110			dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT1), index,
111			    refstr, EC_OFF(off), EC_XWORD(gotaddval), name);
112		} else {
113			dbg_print(lml, MSG_INTL(MSG_GOT_FORMAT2), index,
114			    refstr, EC_OFF(off), EC_XWORD(gotaddval),
115			    sdp->sd_file->ifl_name, name);
116		}
117	}
118}
119
120void
121Elf_got_title(Lm_list *lml)
122{
123	dbg_print(lml, MSG_INTL(MSG_GOT_TITLE));
124}
125
126void
127Elf_got_entry(Lm_list *lml, Sword ndx, Addr addr, Xword value, Half mach,
128    Word type, void *reloc, const char *name)
129{
130	Rela		*rela;
131	Rel		*rel;
132	const char	*str;
133	Conv_inv_buf_t	inv_buf;
134	char		index[INDEX_STR_SIZE];
135
136	(void) snprintf(index, INDEX_STR_SIZE, MSG_ORIG(MSG_GOT_INDEX),
137	    EC_SWORD(ndx));
138
139	if (reloc) {
140		if (type == SHT_RELA) {
141			rela = (Rela *)reloc;
142			str = conv_reloc_type(mach, ELF_R_TYPE(rela->r_info),
143			    0, &inv_buf);
144		} else {
145			rel = (Rel *)reloc;
146			str = conv_reloc_type(mach, ELF_R_TYPE(rel->r_info),
147			    0, &inv_buf);
148		}
149
150		if (name)
151			name = Elf_demangle_name(name);
152		else
153			name = MSG_ORIG(MSG_STR_EMPTY);
154
155		dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_RE), index, EC_ADDR(addr),
156		    EC_XWORD(value), str, name);
157	} else
158		dbg_print(lml, MSG_INTL(MSG_GOT_ENTRY_NR), index, EC_ADDR(addr),
159		    EC_XWORD(value));
160}
161