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 2005 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 "msg.h" 32 #include "_debug.h" 33 34 void 35 Dbg_bind_plt_summary(Half mach, Word pltcnt21d, Word pltcnt24d, Word pltcntu32, 36 Word pltcntu44, Word pltcntfull, Word pltcntfar) 37 { 38 Word plttotal = pltcnt21d + pltcnt24d + pltcntu32 + 39 pltcntu44 + pltcntfull + pltcntfar; 40 41 if (DBG_NOTCLASS(DBG_BINDINGS)) 42 return; 43 44 switch (mach) { 45 case EM_SPARC: 46 dbg_print(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(MSG_INTL(MSG_BND_PSUM_SPARCV9), EC_WORD(pltcnt21d), 51 EC_WORD(pltcnt24d), EC_WORD(pltcntu32), EC_WORD(pltcntu44), 52 EC_WORD(pltcntfull), EC_WORD(pltcntfar), EC_WORD(plttotal)); 53 break; 54 default: 55 dbg_print(MSG_INTL(MSG_BND_PSUM_DEFAULT), EC_WORD(plttotal)); 56 break; 57 }; 58 } 59 60 static const char *pltbindtypes[PLT_T_NUM] = { 61 MSG_ORIG(MSG_STR_EMPTY), /* PLT_T_NONE */ 62 MSG_ORIG(MSG_PLT_21D), /* PLT_T_21D */ 63 MSG_ORIG(MSG_PLT_24D), /* PLT_T_24D */ 64 MSG_ORIG(MSG_PLT_U32), /* PLT_T_U32 */ 65 MSG_ORIG(MSG_PLT_U44), /* PLT_T_U44 */ 66 MSG_ORIG(MSG_PLT_FULL), /* PLT_T_FULL */ 67 MSG_ORIG(MSG_PLT_FAR) /* PLT_T_FAR */ 68 }; 69 70 #define BINFOSZ MSG_BINFO_START_SIZE + \ 71 MSG_BINFO_DIRECT_SIZE + \ 72 MSG_BINFO_SEP_SIZE + \ 73 MSG_BINFO_COPYREF_SIZE + \ 74 MSG_BINFO_SEP_SIZE + \ 75 MSG_BINFO_FILTEE_SIZE + \ 76 MSG_BINFO_SEP_SIZE + \ 77 MSG_BINFO_PLTADDR_SIZE + \ 78 MSG_BINFO_END_SIZE + 1 79 80 /* 81 * Normally we don't want to display any ld.so.1 bindings (i.e. the bindings 82 * to these calls themselves). So, if a Dbg_bind_global() originates from 83 * ld.so.1 don't print anything. If we really want to see the ld.so.1 bindings, 84 * simply give the run-time linker a different SONAME. 85 */ 86 void 87 Dbg_bind_global(const char *ffile, caddr_t fabs, caddr_t frel, Xword pltndx, 88 Pltbindtype pbtype, const char *tfile, caddr_t tabs, caddr_t trel, 89 const char *sym, uint_t binfo) 90 { 91 const char *rfile; 92 char binfostr[BINFOSZ]; 93 94 if (DBG_NOTCLASS(DBG_BINDINGS)) 95 return; 96 97 if ((rfile = strrchr(ffile, '/')) == NULL) 98 rfile = ffile; 99 else 100 rfile++; 101 102 if (strcmp(rfile, MSG_ORIG(MSG_FIL_RTLD)) == 0) 103 return; 104 105 if (DBG_NOTDETAIL()) { 106 dbg_print(MSG_INTL(MSG_BND_BASIC), ffile, tfile, 107 _Dbg_sym_dem(sym)); 108 return; 109 } 110 111 /* 112 * Determine if this binding has any associated information, such as 113 * and interposition, direct binding, copy-relocations, etc. 114 */ 115 binfo &= ~DBG_BINFO_FOUND; 116 binfo &= DBG_BINFO_MSK; 117 if (binfo) { 118 int _binfo = 0; 119 120 (void) strcpy(binfostr, MSG_ORIG(MSG_BINFO_START)); 121 if (binfo & DBG_BINFO_DIRECT) { 122 _binfo |= DBG_BINFO_DIRECT; 123 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_DIRECT)); 124 } 125 if (binfo & DBG_BINFO_INTERPOSE) { 126 if (_binfo) 127 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_SEP)); 128 _binfo |= DBG_BINFO_INTERPOSE; 129 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_INTERPOSE)); 130 } 131 if (binfo & DBG_BINFO_COPYREF) { 132 if (_binfo) 133 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_SEP)); 134 _binfo |= DBG_BINFO_COPYREF; 135 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_COPYREF)); 136 } 137 if (binfo & DBG_BINFO_FILTEE) { 138 if (_binfo) 139 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_SEP)); 140 _binfo |= DBG_BINFO_FILTEE; 141 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_FILTEE)); 142 } 143 if (binfo & DBG_BINFO_PLTADDR) { 144 if (_binfo) 145 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_SEP)); 146 _binfo |= DBG_BINFO_PLTADDR; 147 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_PLTADDR)); 148 } 149 if (binfo & ~_binfo) { 150 size_t len; 151 152 if (_binfo) 153 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_SEP)); 154 155 len = strlen(binfostr); 156 conv_invalid_str(&binfostr[len], (BINFOSZ - len), 157 (Lword)(binfo & ~_binfo), 0); 158 } 159 (void) strcat(binfostr, MSG_ORIG(MSG_BINFO_END)); 160 } else 161 binfostr[0] = '\0'; 162 163 164 if (pltndx != (Xword)-1) { 165 const char *pltstring; 166 167 if (pbtype < PLT_T_NUM) 168 pltstring = pltbindtypes[pbtype]; 169 else 170 pltstring = pltbindtypes[PLT_T_NONE]; 171 172 /* 173 * Called from a plt offset. 174 */ 175 dbg_print(MSG_INTL(MSG_BND_PLT), ffile, EC_ADDR(fabs), 176 EC_ADDR(frel), EC_WORD(pltndx), pltstring, tfile, 177 EC_ADDR(tabs), EC_ADDR(trel), _Dbg_sym_dem(sym), binfostr); 178 179 } else if ((fabs == 0) && (frel == 0)) { 180 /* 181 * Called from a dlsym(). We're not performing a relocation, 182 * but are handing the address of the symbol back to the user. 183 */ 184 dbg_print(MSG_INTL(MSG_BND_DLSYM), ffile, tfile, EC_ADDR(tabs), 185 EC_ADDR(trel), _Dbg_sym_dem(sym), binfostr); 186 187 } else { 188 /* 189 * Standard relocation. 190 */ 191 dbg_print(MSG_INTL(MSG_BND_DEFAULT), ffile, EC_ADDR(fabs), 192 EC_ADDR(frel), tfile, EC_ADDR(tabs), EC_ADDR(trel), 193 _Dbg_sym_dem(sym), binfostr); 194 } 195 } 196 197 void 198 Dbg_bind_weak(const char *ffile, caddr_t fabs, caddr_t frel, const char *sym) 199 { 200 if (DBG_NOTCLASS(DBG_BINDINGS)) 201 return; 202 203 if (DBG_NOTDETAIL()) 204 dbg_print(MSG_INTL(MSG_BND_WEAK_1), ffile, _Dbg_sym_dem(sym)); 205 else 206 dbg_print(MSG_INTL(MSG_BND_WEAK_2), ffile, EC_ADDR(fabs), 207 EC_ADDR(frel), _Dbg_sym_dem(sym)); 208 } 209 210 void 211 Dbg_bind_profile(uint_t ndx, uint_t count) 212 { 213 if (DBG_NOTCLASS(DBG_BINDINGS)) 214 return; 215 if (DBG_NOTDETAIL()) 216 return; 217 218 dbg_print(MSG_INTL(MSG_BND_PROFILE), EC_WORD(ndx), EC_WORD(count)); 219 } 220