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