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 = >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 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 = >p->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