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
Dbg_got_compare(Gottable * gtp1,Gottable * gtp2)35 Dbg_got_compare(Gottable *gtp1, Gottable *gtp2)
36 {
37 Gotndx *gnp1 = >p1->gt_gndx;
38 Gotndx *gnp2 = >p2->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
Dbg_got_display(Ofl_desc * ofl,Off goff,int stage,Word m_got_xnumber,size_t m_got_entsize)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 = >p->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
Elf_got_title(Lm_list * lml)122 Elf_got_title(Lm_list *lml)
123 {
124 dbg_print(lml, MSG_INTL(MSG_GOT_TITLE));
125 }
126
127 void
Elf_got_entry(Lm_list * lml,Sword ndx,Addr addr,Xword value,Half mach,uchar_t ei_target_data,uchar_t ei_host_data,Word type,void * reloc,const char * name)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