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 2009 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 /* 87 * MSG_ORIG(MSG_BINFO_DIRECT) 88 * MSG_ORIG(MSG_BINFO_INTERPOSE) 89 * MSG_ORIG(MSG_BINFO_COPYREF) 90 * MSG_ORIG(MSG_BINFO_FILTEE) 91 * MSG_ORIG(MSG_BINFO_PLTADDR) 92 */ 93 static char binfostr[BINFOSZ]; 94 static Val_desc vda[] = { 95 { DBG_BINFO_DIRECT, MSG_BINFO_DIRECT }, 96 { DBG_BINFO_INTERPOSE, MSG_BINFO_INTERPOSE }, 97 { DBG_BINFO_COPYREF, MSG_BINFO_COPYREF }, 98 { DBG_BINFO_FILTEE, MSG_BINFO_FILTEE }, 99 { DBG_BINFO_PLTADDR, MSG_BINFO_PLTADDR }, 100 { 0, 0 } 101 }; 102 static CONV_EXPN_FIELD_ARG conv_arg = { binfostr, sizeof (binfostr), 103 NULL, 0, 0, MSG_ORIG(MSG_BINFO_START), 104 MSG_ORIG(MSG_BINFO_SEP), MSG_ORIG(MSG_BINFO_END) }; 105 106 const char *ffile = NAME(flmp); 107 const char *tfile = NAME(tlmp); 108 Lm_list *lml = LIST(flmp); 109 110 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 111 return; 112 113 if (DBG_NOTDETAIL()) { 114 dbg_print(lml, MSG_INTL(MSG_BND_BASIC), ffile, tfile, 115 Dbg_demangle_name(sym)); 116 return; 117 } 118 119 /* 120 * Determine if this binding has any associated information, such as 121 * interposition, direct binding, copy-relocations, etc. 122 */ 123 binfo &= ~DBG_BINFO_FOUND; 124 binfo &= DBG_BINFO_MSK; 125 if (binfo) { 126 conv_arg.oflags = conv_arg.rflags = binfo; 127 (void) conv_expn_field(&conv_arg, vda, 0); 128 } else { 129 binfostr[0] = '\0'; 130 } 131 132 if (pltndx != (Xword)-1) { 133 const char *pltstring; 134 135 if (pbtype < PLT_T_NUM) 136 pltstring = pltbindtypes[pbtype]; 137 else 138 pltstring = pltbindtypes[PLT_T_NONE]; 139 140 /* 141 * Called from a plt offset. 142 */ 143 dbg_print(lml, MSG_INTL(MSG_BND_PLT), ffile, EC_ADDR(fabs), 144 EC_OFF(foff), EC_XWORD(pltndx), pltstring, tfile, 145 EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), 146 binfostr); 147 148 } else if ((fabs == 0) && (foff == 0)) { 149 /* 150 * Called from a dlsym(). We're not performing a relocation, 151 * but are handing the address of the symbol back to the user. 152 */ 153 dbg_print(lml, MSG_INTL(MSG_BND_DLSYM), ffile, tfile, 154 EC_ADDR(tabs), EC_OFF(toff), Dbg_demangle_name(sym), 155 binfostr); 156 } else { 157 /* 158 * Standard relocation. 159 */ 160 dbg_print(lml, MSG_INTL(MSG_BND_DEFAULT), ffile, EC_ADDR(fabs), 161 EC_OFF(foff), tfile, EC_ADDR(tabs), EC_OFF(toff), 162 Dbg_demangle_name(sym), binfostr); 163 } 164 } 165 166 void 167 Dbg_bind_reject(Rt_map *flmp, Rt_map *tlmp, const char *sym, int why) 168 { 169 static Msg reason[DBG_BNDREJ_NUM + 1] = { 170 MSG_BNDREJ_DIRECT, /* MSG_INTL(MSG_BNDREJ_DIRECT) */ 171 MSG_BNDREJ_GROUP, /* MSG_INTL(MSG_BNDREJ_GROUP) */ 172 MSG_BNDREJ_SINGLE /* MSG_INTL(MSG_BNDREJ_SINGLE) */ 173 }; 174 175 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 176 return; 177 178 dbg_print(LIST(flmp), MSG_INTL(MSG_BND_REJECT), NAME(flmp), NAME(tlmp), 179 sym, MSG_INTL(reason[why])); 180 } 181 182 void 183 Dbg_bind_weak(Rt_map *flmp, Addr fabs, Addr frel, const char *sym) 184 { 185 Lm_list *lml = LIST(flmp); 186 const char *ffile = NAME(flmp); 187 188 if (DBG_NOTCLASS(DBG_C_BINDINGS)) 189 return; 190 191 if (DBG_NOTDETAIL()) 192 dbg_print(lml, MSG_INTL(MSG_BND_WEAK_1), ffile, 193 Dbg_demangle_name(sym)); 194 else 195 dbg_print(lml, MSG_INTL(MSG_BND_WEAK_2), ffile, EC_ADDR(fabs), 196 EC_ADDR(frel), Dbg_demangle_name(sym)); 197 } 198 199 #if defined(_ELF64) 200 201 void 202 Dbg_bind_pltpad_to(Rt_map *lmp, Addr pltpad, const char *dfile, 203 const char *sname) 204 { 205 if (DBG_NOTCLASS(DBG_C_RELOC)) 206 return; 207 if (DBG_NOTDETAIL()) 208 return; 209 210 dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_TO), EC_ADDR(pltpad), 211 NAME(lmp), dfile, sname); 212 } 213 214 void 215 Dbg_bind_pltpad_from(Rt_map *lmp, Addr pltpad, const char *sname) 216 { 217 if (DBG_NOTCLASS(DBG_C_RELOC)) 218 return; 219 if (DBG_NOTDETAIL()) 220 return; 221 222 dbg_print(LIST(lmp), MSG_INTL(MSG_BND_PLTPAD_FROM), EC_ADDR(pltpad), 223 NAME(lmp), sname); 224 } 225 226 #endif 227