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 27 #include <sys/types.h> 28 #include <string.h> 29 #include <debug.h> 30 #include <conv.h> 31 #include "_debug.h" 32 #include "msg.h" 33 34 void 35 Dbg_bind_plt_summary(Lm_list *lml, Half mach, Word pltcnt21d, Word pltcnt24d, 36 Word pltcntu32, Word pltcntu44, Word pltcntfull, Word pltcntfar) 37 { 38 Word plttotal = pltcnt21d + pltcnt24d + pltcntu32 + 39 pltcntu44 + pltcntfull + pltcntfar; 40 41 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 42 return; 43 44 switch (mach) { 45 case EM_SPARC: 46 dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARC), EC_WORD(pltcnt21d), 47 EC_WORD(pltcnt24d), EC_WORD(pltcntfull), EC_WORD(plttotal)); 48 break; 49 case EM_SPARCV9: 50 dbg_print(lml, MSG_INTL(MSG_BND_PSUM_SPARCV9), 51 EC_WORD(pltcnt21d), EC_WORD(pltcnt24d), EC_WORD(pltcntu32), 52 EC_WORD(pltcntu44), EC_WORD(pltcntfull), EC_WORD(pltcntfar), 53 EC_WORD(plttotal)); 54 break; 55 default: 56 dbg_print(lml, MSG_INTL(MSG_BND_PSUM_DEFAULT), 57 EC_WORD(plttotal)); 58 break; 59 }; 60 } 61 62 static const char *pltbindtypes[PLT_T_NUM] = { 63 MSG_ORIG(MSG_STR_EMPTY), /* PLT_T_NONE */ 64 MSG_ORIG(MSG_PLT_21D), /* PLT_T_21D */ 65 MSG_ORIG(MSG_PLT_24D), /* PLT_T_24D */ 66 MSG_ORIG(MSG_PLT_U32), /* PLT_T_U32 */ 67 MSG_ORIG(MSG_PLT_U44), /* PLT_T_U44 */ 68 MSG_ORIG(MSG_PLT_FULL), /* PLT_T_FULL */ 69 MSG_ORIG(MSG_PLT_FAR) /* PLT_T_FAR */ 70 }; 71 72 #define BINFOSZ MSG_BINFO_START_SIZE + \ 73 MSG_BINFO_DIRECT_SIZE + MSG_BINFO_SEP_SIZE + \ 74 MSG_BINFO_INTERPOSE_SIZE + MSG_BINFO_SEP_SIZE + \ 75 MSG_BINFO_COPYREF_SIZE + MSG_BINFO_SEP_SIZE + \ 76 MSG_BINFO_FILTEE_SIZE + MSG_BINFO_SEP_SIZE + \ 77 MSG_BINFO_PLTADDR_SIZE + \ 78 CONV_INV_BUFSIZE + MSG_BINFO_END_SIZE 79 80 81 void 82 Dbg_bind_global(Rt_map *flmp, Addr fabs, Off foff, Xword pltndx, 83 Pltbindtype pbtype, Rt_map *tlmp, Addr tabs, Off toff, 84 const char *sym, uint_t binfo) 85 { 86 static char binfostr[BINFOSZ]; 87 static Val_desc vda[] = { 88 { DBG_BINFO_DIRECT, MSG_ORIG(MSG_BINFO_DIRECT) }, 89 { DBG_BINFO_INTERPOSE, MSG_ORIG(MSG_BINFO_INTERPOSE) }, 90 { DBG_BINFO_COPYREF, MSG_ORIG(MSG_BINFO_COPYREF) }, 91 { DBG_BINFO_FILTEE, MSG_ORIG(MSG_BINFO_FILTEE) }, 92 { DBG_BINFO_PLTADDR, MSG_ORIG(MSG_BINFO_PLTADDR) }, 93 { 0, 0 } 94 }; 95 static CONV_EXPN_FIELD_ARG conv_arg = { binfostr, sizeof (binfostr), 96 vda, NULL, 0, 0, MSG_ORIG(MSG_BINFO_START), 97 MSG_ORIG(MSG_BINFO_SEP), MSG_ORIG(MSG_BINFO_END) }; 98 99 const char *ffile = NAME(flmp); 100 const char *tfile = NAME(tlmp); 101 Lm_list *lml = LIST(flmp); 102 103 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 104 return; 105 106 if (DBG_NOTDETAIL()) { 107 dbg_print(lml, MSG_INTL(MSG_BND_BASIC), ffile, tfile, 108 Dbg_demangle_name(sym)); 109 return; 110 } 111 112 /* 113 * Determine if this binding has any associated information, such as 114 * interposition, direct binding, copy-relocations, etc. 115 */ 116 binfo &= ~DBG_BINFO_FOUND; 117 binfo &= DBG_BINFO_MSK; 118 if (binfo) { 119 conv_arg.oflags = conv_arg.rflags = binfo; 120 (void) conv_expn_field(&conv_arg, 0); 121 } else { 122 binfostr[0] = '\0'; 123 } 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_reject(Rt_map *flmp, Rt_map *tlmp, const char *sym, int why) 161 { 162 static Msg reason[DBG_BNDREJ_NUM + 1] = { 163 MSG_BNDREJ_DIRECT, /* MSG_INTL(MSG_BNDREJ_DIRECT) */ 164 MSG_BNDREJ_GROUP, /* MSG_INTL(MSG_BNDREJ_GROUP) */ 165 MSG_BNDREJ_SINGLE /* MSG_INTL(MSG_BNDREJ_SINGLE) */ 166 }; 167 168 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 169 return; 170 171 dbg_print(LIST(flmp), MSG_INTL(MSG_BND_REJECT), NAME(flmp), NAME(tlmp), 172 sym, MSG_INTL(reason[why])); 173 } 174 175 void 176 Dbg_bind_weak(Rt_map *flmp, Addr fabs, Addr frel, const char *sym) 177 { 178 Lm_list *lml = LIST(flmp); 179 const char *ffile = NAME(flmp); 180 181 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 182 return; 183 184 if (DBG_NOTDETAIL()) 185 dbg_print(lml, MSG_INTL(MSG_BND_WEAK_1), ffile, 186 Dbg_demangle_name(sym)); 187 else 188 dbg_print(lml, MSG_INTL(MSG_BND_WEAK_2), ffile, EC_ADDR(fabs), 189 EC_ADDR(frel), Dbg_demangle_name(sym)); 190 } 191 192 #if defined(_ELF64) 193 194 void 195 Dbg_bind_pltpad_to(Rt_map *lmp, Addr pltpad, const char *dfile, 196 const char *sname) 197 { 198 if (DBG_NOTCLASS(DBG_C_RELOC)) 199 return; 200 if (DBG_NOTDETAIL()) 201 return; 202 203 dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), 204 NAME(lmp), dfile, sname); 205 } 206 207 void 208 Dbg_bind_pltpad_from(Rt_map *lmp, Addr pltpad, const char *sname) 209 { 210 if (DBG_NOTCLASS(DBG_C_RELOC)) 211 return; 212 if (DBG_NOTDETAIL()) 213 return; 214 215 dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), 216 NAME(lmp), sname); 217 } 218 219 #endif 220