xref: /titanic_52/usr/src/cmd/sgs/liblddbg/common/got.c (revision d58fda4376e4bf67072ce2e69f6f47036f9dbb68)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  *	Copyright 2003 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 
34 static int
35 comparegotsym(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(Gottable * gtp, Ofl_desc *ofl)
50 {
51 	Word	gotndx;
52 
53 	if (DBG_NOTCLASS(DBG_GOT))
54 		return;
55 
56 	if (ofl->ofl_gotcnt == M_GOT_XNumber)
57 		return;
58 
59 	dbg_print(MSG_ORIG(MSG_STR_EMPTY));
60 	dbg_print(MSG_INTL(MSG_GOT_TITLE), EC_WORD(ofl->ofl_gotcnt));
61 
62 	if (DBG_NOTDETAIL())
63 		return;
64 
65 	qsort((char *)gtp, ofl->ofl_gotcnt, sizeof (Gottable),
66 		(int(*)(const void *, const void *))comparegotsym);
67 
68 	dbg_print(MSG_ORIG(MSG_GOT_COLUMNS));
69 
70 	for (gotndx = 0; gotndx < ofl->ofl_gotcnt; gotndx++, gtp++) {
71 		Sym_desc	*sdp;
72 		const char	*refstr, *name;
73 		Gotndx		*gnp = &gtp->gt_gndx;
74 
75 		if ((sdp = gtp->gt_sym) == 0)
76 			continue;
77 
78 		if (sdp->sd_flags & FLG_SY_SMGOT)
79 			refstr = MSG_ORIG(MSG_GOT_SMALL_PIC);
80 		else
81 			refstr = MSG_ORIG(MSG_GOT_PIC);
82 
83 		if (sdp->sd_name)
84 			name = _Dbg_sym_dem(sdp->sd_name);
85 		else
86 			name = MSG_INTL(MSG_STR_UNKNOWN);
87 
88 		if ((sdp->sd_sym->st_shndx == SHN_UNDEF) ||
89 		    (sdp->sd_file == 0)) {
90 			dbg_print(MSG_ORIG(MSG_GOT_FORMAT1),
91 			    EC_SWORD(gnp->gn_gotndx), refstr,
92 			    EC_LWORD(gnp->gn_addend), name);
93 		} else {
94 			dbg_print(MSG_ORIG(MSG_GOT_FORMAT2),
95 			    EC_SWORD(gnp->gn_gotndx), refstr,
96 			    EC_LWORD(gnp->gn_addend),
97 			    sdp->sd_file->ifl_name, name);
98 		}
99 	}
100 }
101 
102 
103 #if	!defined(_ELF64)
104 void
105 Gelf_got_title(uchar_t class)
106 {
107 	if (class == ELFCLASS64)
108 		dbg_print(MSG_ORIG(MSG_GOT_ECOLUMNS_64));
109 	else
110 		dbg_print(MSG_ORIG(MSG_GOT_ECOLUMNS));
111 }
112 
113 void
114 Gelf_got_entry(GElf_Ehdr *ehdr, Sword gotndx, GElf_Addr addr, GElf_Xword value,
115 	GElf_Word rshtype, void *rel, const char *sname)
116 {
117 	GElf_Word	rtype;
118 	GElf_Sxword	addend;
119 	const char	*rstring, * fmt;
120 
121 	if (rel) {
122 		if (rshtype == SHT_RELA) {
123 			/* LINTED */
124 			rtype = (GElf_Word)GELF_R_TYPE(
125 			    ((GElf_Rela *)rel)->r_info);
126 			addend = ((GElf_Rela *)rel)->r_addend;
127 		} else {
128 			/* LINTED */
129 			rtype = (GElf_Word)GELF_R_TYPE(
130 			    ((GElf_Rel *)rel)->r_info);
131 			addend = 0;
132 		}
133 		rstring = conv_reloc_type_str(ehdr->e_machine, rtype);
134 	} else {
135 		addend = 0;
136 		rstring = MSG_ORIG(MSG_STR_EMPTY);
137 	}
138 
139 	if (sname)
140 		sname = _Dbg_sym_dem(sname);
141 	else
142 		sname = MSG_ORIG(MSG_STR_EMPTY);
143 
144 	if ((int)ehdr->e_ident[EI_CLASS] == ELFCLASS64)
145 		fmt = MSG_ORIG(MSG_GOT_EFORMAT_64);
146 	else
147 		fmt = MSG_ORIG(MSG_GOT_EFORMAT);
148 
149 	dbg_print(fmt, EC_SWORD(gotndx), EC_ADDR(addr), EC_XWORD(value),
150 	    rstring, EC_SXWORD(addend), sname);
151 }
152 #endif	/* !defined(_ELF64) */
153