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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 29 #include <sys/types.h> 30 #include <string.h> 31 #include <debug.h> 32 #include <conv.h> 33 #include "_debug.h" 34 #include "msg.h" 35 36 void 37 Dbg_bind_plt_summary(Lm_list *lml, Half mach, Word pltcnt21d, Word pltcnt24d, 38 Word pltcntu32, Word pltcntu44, Word pltcntfull, Word pltcntfar) 39 { 40 Word plttotal = pltcnt21d + pltcnt24d + pltcntu32 + 41 pltcntu44 + pltcntfull + pltcntfar; 42 43 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 44 return; 45 46 switch (mach) { 47 case EM_SPARC: 48 dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARC), EC_WORD(pltcnt21d), 49 EC_WORD(pltcnt24d), EC_WORD(pltcntfull), EC_WORD(plttotal)); 50 break; 51 case EM_SPARCV9: 52 dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARCV9), 53 EC_WORD(pltcnt21d), EC_WORD(pltcnt24d), EC_WORD(pltcntu32), 54 EC_WORD(pltcntu44), EC_WORD(pltcntfull), EC_WORD(pltcntfar), 55 EC_WORD(plttotal)); 56 break; 57 default: 58 dbg_print(lml, MSG_INTL(MSG_BND_PSUM_DEFAULT), 59 EC_WORD(plttotal)); 60 break; 61 }; 62 } 63 64 static const char *pltbindtypes[PLT_T_NUM] = { 65 MSG_ORIG(MSG_STR_EMPTY), /* PLT_T_NONE */ 66 MSG_ORIG(MSG_PLT_21D), /* PLT_T_21D */ 67 MSG_ORIG(MSG_PLT_24D), /* PLT_T_24D */ 68 MSG_ORIG(MSG_PLT_U32), /* PLT_T_U32 */ 69 MSG_ORIG(MSG_PLT_U44), /* PLT_T_U44 */ 70 MSG_ORIG(MSG_PLT_FULL), /* PLT_T_FULL */ 71 MSG_ORIG(MSG_PLT_FAR) /* PLT_T_FAR */ 72 }; 73 74 #define BINFOSZ MSG_BINFO_START_SIZE + \ 75 MSG_BINFO_DIRECT_SIZE + MSG_BINFO_SEP_SIZE + \ 76 MSG_BINFO_INTERPOSE_SIZE + MSG_BINFO_SEP_SIZE + \ 77 MSG_BINFO_COPYREF_SIZE + MSG_BINFO_SEP_SIZE + \ 78 MSG_BINFO_FILTEE_SIZE + MSG_BINFO_SEP_SIZE + \ 79 MSG_BINFO_PLTADDR_SIZE + \ 80 CONV_INV_STRSIZE + MSG_BINFO_END_SIZE 81 82 83 void 84 Dbg_bind_global(Rt_map *flmp, Addr fabs, Off foff, Xword pltndx, 85 Pltbindtype pbtype, Rt_map *tlmp, Addr tabs, Off toff, 86 const char *sym, uint_t binfo) 87 { 88 static Val_desc vda[] = { 89 { DBG_BINFO_DIRECT, MSG_ORIG(MSG_BINFO_DIRECT) }, 90 { DBG_BINFO_INTERPOSE, MSG_ORIG(MSG_BINFO_INTERPOSE) }, 91 { DBG_BINFO_COPYREF, MSG_ORIG(MSG_BINFO_COPYREF) }, 92 { DBG_BINFO_FILTEE, MSG_ORIG(MSG_BINFO_FILTEE) }, 93 { DBG_BINFO_PLTADDR, MSG_ORIG(MSG_BINFO_PLTADDR) }, 94 { 0, 0 } 95 }; 96 char binfostr[BINFOSZ]; 97 const char *ffile = NAME(flmp); 98 const char *tfile = NAME(tlmp); 99 Lm_list *lml = LIST(flmp); 100 101 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 102 return; 103 104 if (DBG_NOTDETAIL()) { 105 dbg_print(lml, MSG_INTL(MSG_BND_BASIC), ffile, tfile, 106 Dbg_demangle_name(sym)); 107 return; 108 } 109 110 /* 111 * Determine if this binding has any associated information, such as 112 * interposition, direct binding, copy-relocations, etc. 113 */ 114 binfo &= ~DBG_BINFO_FOUND; 115 binfo &= DBG_BINFO_MSK; 116 if (binfo) { 117 (void) strlcpy(binfostr, MSG_ORIG(MSG_BINFO_START), BINFOSZ); 118 119 if (conv_expn_field(binfostr, BINFOSZ, vda, binfo, binfo, 120 MSG_ORIG(MSG_BINFO_SEP), 0)) 121 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_END)); 122 } else 123 binfostr[0] = '\0'; 124 125 if (pltndx != (Xword)-1) { 126 const char *pltstring; 127 128 if (pbtype < PLT_T_NUM) 129 pltstring = pltbindtypes[pbtype]; 130 else 131 pltstring = pltbindtypes[PLT_T_NONE]; 132 133 /* 134 * Called from a plt offset. 135 */ 136 dbg_print(lml, MSG_INTL(MSG_BND_PLT), ffile, EC_ADDR(fabs), 137 EC_OFF(foff), EC_XWORD(pltndx), pltstring, tfile, 138 EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), 139 binfostr); 140 141 } else if ((fabs == 0) && (foff == 0)) { 142 /* 143 * Called from a dlsym(). We're not performing a relocation, 144 * but are handing the address of the symbol back to the user. 145 */ 146 dbg_print(lml, MSG_INTL(MSG_BND_DLSYM), ffile, tfile, 147 EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), 148 binfostr); 149 } else { 150 /* 151 * Standard relocation. 152 */ 153 dbg_print(lml, MSG_INTL(MSG_BND_DEFAULT), ffile, EC_ADDR(fabs), 154 EC_OFF(foff), tfile, EC_ADDR(tabs), EC_OFF(toff), 155 Dbg_demangle_name(sym), binfostr); 156 } 157 } 158 159 void 160 Dbg_bind_weak(Rt_map *flmp, Addr fabs, Addr frel, const char *sym) 161 { 162 Lm_list *lml = LIST(flmp); 163 const char *ffile = NAME(flmp); 164 165 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 166 return; 167 168 if (DBG_NOTDETAIL()) 169 dbg_print(lml, MSG_INTL(MSG_BND_WEAK_1), ffile, 170 Dbg_demangle_name(sym)); 171 else 172 dbg_print(lml, MSG_INTL(MSG_BND_WEAK_2), ffile, EC_ADDR(fabs), 173 EC_ADDR(frel), Dbg_demangle_name(sym)); 174 } 175 176 #if defined(_ELF64) 177 178 void 179 Dbg_bind_pltpad_to(Rt_map *lmp, Addr pltpad, const char *dfile, 180 const char *sname) 181 { 182 if (DBG_NOTCLASS(DBG_C_RELOC)) 183 return; 184 if (DBG_NOTDETAIL()) 185 return; 186 187 dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), 188 NAME(lmp), dfile, sname); 189 } 190 191 void 192 Dbg_bind_pltpad_from(Rt_map *lmp, Addr pltpad, const char *sname) 193 { 194 if (DBG_NOTCLASS(DBG_C_RELOC)) 195 return; 196 if (DBG_NOTDETAIL()) 197 return; 198 199 dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), 200 NAME(lmp), sname); 201 } 202 203 #endif 204