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 "msg.h" 28 #include "_debug.h" 29 #include "libld.h" 30 31 /* 32 * If any run-time linker debugging is being carried out always indicate the 33 * fact and specify the point at which we transfer control to the main program. 34 */ 35 void 36 Dbg_util_call_main(Rt_map *lmp) 37 { 38 Lm_list *lml = LIST(lmp); 39 40 Dbg_util_nl(lml, DBG_NL_FRC); 41 dbg_print(lml, MSG_INTL(MSG_UTL_TRANS), NAME(lmp)); 42 Dbg_util_nl(lml, DBG_NL_FRC); 43 } 44 45 void 46 Dbg_util_call_init(Rt_map *lmp, int flag) 47 { 48 Lm_list *lml = LIST(lmp); 49 const char *str; 50 51 if (DBG_NOTCLASS(DBG_C_INIT)) 52 return; 53 54 if (flag == DBG_INIT_SORT) 55 str = MSG_INTL(MSG_UTL_SORT); 56 else if (flag == DBG_INIT_PEND) 57 str = MSG_INTL(MSG_UTL_PEND); 58 else if (flag == DBG_INIT_DYN) 59 str = MSG_INTL(MSG_UTL_DYN); 60 else 61 str = MSG_INTL(MSG_UTL_DONE); 62 63 Dbg_util_nl(lml, DBG_NL_STD); 64 dbg_print(lml, MSG_INTL(MSG_UTL_INIT), str, NAME(lmp)); 65 Dbg_util_nl(lml, DBG_NL_STD); 66 } 67 68 void 69 Dbg_util_no_init(Rt_map *lmp) 70 { 71 Lm_list *lml = LIST(lmp); 72 73 if (DBG_NOTCLASS(DBG_C_INIT)) 74 return; 75 76 Dbg_util_nl(lml, DBG_NL_STD); 77 dbg_print(lml, MSG_INTL(MSG_UTL_NOINIT), NAME(lmp)); 78 Dbg_util_nl(lml, DBG_NL_STD); 79 } 80 81 void 82 Dbg_util_intoolate(Rt_map *lmp) 83 { 84 Lm_list *lml = LIST(lmp); 85 86 Dbg_util_nl(lml, DBG_NL_STD); 87 dbg_print(lml, MSG_INTL(MSG_UTL_INTOOLATE), NAME(lmp)); 88 Dbg_util_nl(lml, DBG_NL_STD); 89 } 90 91 void 92 Dbg_util_dbnotify(Lm_list *lml, rd_event_e event, r_state_e state) 93 { 94 const char *estr; 95 const char *sstr; 96 97 if (DBG_NOTCLASS(DBG_C_FILES)) 98 return; 99 if (DBG_NOTDETAIL()) 100 return; 101 102 switch (event) { 103 case RD_PREINIT: 104 estr = MSG_ORIG(MSG_UTL_EVNT_PREINIT); 105 sstr = MSG_INTL(MSG_STR_NULL); 106 break; 107 case RD_POSTINIT: 108 estr = MSG_ORIG(MSG_UTL_EVNT_POSTINIT); 109 sstr = MSG_INTL(MSG_STR_NULL); 110 break; 111 case RD_DLACTIVITY: 112 estr = MSG_ORIG(MSG_UTL_EVNT_DLACT); 113 switch (state) { 114 case RT_CONSISTENT: 115 sstr = MSG_ORIG(MSG_UTL_STA_CONSIST); 116 break; 117 case RT_ADD: 118 sstr = MSG_ORIG(MSG_UTL_STA_ADD); 119 break; 120 case RT_DELETE: 121 sstr = MSG_ORIG(MSG_UTL_STA_DELETE); 122 break; 123 default: 124 sstr = MSG_INTL(MSG_STR_NULL); 125 break; 126 } 127 break; 128 default: 129 sstr = MSG_INTL(MSG_STR_NULL); 130 estr = MSG_INTL(MSG_STR_UNKNOWN); 131 break; 132 } 133 134 Dbg_util_nl(lml, DBG_NL_STD); 135 dbg_print(lml, MSG_INTL(MSG_UTL_DBNOTIFY), estr, sstr); 136 Dbg_util_nl(lml, DBG_NL_STD); 137 } 138 139 void 140 Dbg_util_call_array(Rt_map *lmp, void *addr, int ndx, Word shtype) 141 { 142 Lm_list *lml = LIST(lmp); 143 const char *str; 144 145 if (DBG_NOTCLASS(DBG_C_INIT)) 146 return; 147 148 if (shtype == SHT_INIT_ARRAY) 149 str = MSG_ORIG(MSG_SCN_INITARRAY); 150 else if (shtype == SHT_FINI_ARRAY) 151 str = MSG_ORIG(MSG_SCN_FINIARRAY); 152 else 153 str = MSG_ORIG(MSG_SCN_PREINITARRAY); 154 155 dbg_print(lml, MSG_INTL(MSG_UTL_ARRAY), str, ndx, EC_NATPTR(addr), 156 NAME(lmp)); 157 } 158 159 void 160 Dbg_util_call_fini(Rt_map *lmp) 161 { 162 Lm_list *lml = LIST(lmp); 163 164 if (DBG_NOTCLASS(DBG_C_INIT)) 165 return; 166 167 Dbg_util_nl(lml, DBG_NL_STD); 168 dbg_print(lml, MSG_INTL(MSG_UTL_FINI), NAME(lmp)); 169 Dbg_util_nl(lml, DBG_NL_STD); 170 } 171 172 void 173 Dbg_util_str(Lm_list *lml, const char *str) 174 { 175 Dbg_util_nl(lml, DBG_NL_STD); 176 Dbg_util_nl(lml, DBG_NL_FRC); 177 dbg_print(lml, MSG_ORIG(MSG_FMT_STR), str); 178 Dbg_util_nl(lml, DBG_NL_FRC); 179 Dbg_util_nl(lml, DBG_NL_STD); 180 } 181 182 void 183 Dbg_util_scc_title(Lm_list *lml, int sec) 184 { 185 const char *_sec; 186 187 if (DBG_NOTCLASS(DBG_C_INIT)) 188 return; 189 if (DBG_NOTDETAIL()) 190 return; 191 192 if (sec) 193 _sec = MSG_INTL(MSG_UTL_SCC_SUBI); 194 else 195 _sec = MSG_INTL(MSG_UTL_SCC_SUBF); 196 197 Dbg_util_nl(lml, DBG_NL_STD); 198 dbg_print(lml, MSG_INTL(MSG_UTL_SCC_TITLE), _sec); 199 } 200 201 void 202 Dbg_util_scc_entry(Rt_map *lmp, uint_t idx) 203 { 204 if (DBG_NOTCLASS(DBG_C_INIT)) 205 return; 206 if (DBG_NOTDETAIL()) 207 return; 208 209 dbg_print(LIST(lmp), MSG_ORIG(MSG_UTL_SCC_ENTRY), idx, NAME(lmp)); 210 } 211 212 static int ectoggle = 0; 213 214 void 215 Dbg_util_edge_in(Lm_list *lml, Rt_map *clmp, uint_t flags, Rt_map *dlmp, 216 int ndx, int flag) 217 { 218 Conv_bnd_type_buf_t bnd_type_buf; 219 const char *str; 220 221 if (DBG_NOTCLASS(DBG_C_INIT)) 222 return; 223 if (DBG_NOTDETAIL()) 224 return; 225 226 if (flag & RT_SORT_REV) 227 str = MSG_ORIG(MSG_SCN_INIT); 228 else 229 str = MSG_ORIG(MSG_SCN_FINI); 230 231 if ((clmp == 0) || (ectoggle == 0)) 232 Dbg_util_nl(lml, DBG_NL_STD); 233 if (clmp == 0) { 234 if (flag & RT_SORT_INTPOSE) 235 dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_I), str); 236 else 237 dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_TITLE_S), str); 238 239 dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_START), ndx, NAME(dlmp)); 240 } else 241 dbg_print(lml, MSG_INTL(MSG_UTL_EDGE_IN), ndx, NAME(dlmp), 242 NAME(clmp), conv_bnd_type(flags, &bnd_type_buf)); 243 244 ectoggle = 1; 245 } 246 247 void 248 Dbg_util_edge_out(Rt_map *clmp, Rt_map *dlmp) 249 { 250 if (DBG_NOTCLASS(DBG_C_INIT)) 251 return; 252 if (DBG_NOTDETAIL()) 253 return; 254 255 dbg_print(LIST(clmp), MSG_INTL(MSG_UTL_EDGE_OUT), SORTVAL(clmp), 256 NAME(clmp), NAME(dlmp)); 257 } 258 259 void 260 Dbg_util_collect(Rt_map *lmp, int ndx, int flag) 261 { 262 Lm_list *lml = LIST(lmp); 263 const char *str; 264 265 if (DBG_NOTCLASS(DBG_C_INIT)) 266 return; 267 if (DBG_NOTDETAIL()) 268 return; 269 270 if (flag & RT_SORT_REV) 271 str = MSG_ORIG(MSG_SCN_INIT); 272 else 273 str = MSG_ORIG(MSG_SCN_FINI); 274 275 if (ectoggle == 1) { 276 Dbg_util_nl(lml, DBG_NL_STD); 277 ectoggle = 0; 278 } 279 dbg_print(lml, MSG_INTL(MSG_UTL_COLLECT), ndx, NAME(lmp), str); 280 } 281 282 static const Msg tags[] = { 283 MSG_CI_NULL, /* MSG_ORIG(MSG_CI_NULL) */ 284 MSG_CI_VERSION, /* MSG_ORIG(MSG_CI_VERSION) */ 285 MSG_CI_ATEXIT, /* MSG_ORIG(MSG_CI_ATEXIT) */ 286 MSG_CI_LCMESSAGES, /* MSG_ORIG(MSG_CI_LCMESSAGES) */ 287 MSG_CI_BIND_GUARD, /* MSG_ORIG(MSG_CI_BIND_GUARD) */ 288 MSG_CI_BIND_CLEAR, /* MSG_ORIG(MSG_CI_BIND_CLEAR) */ 289 MSG_CI_THR_SELF, /* MSG_ORIG(MSG_CI_THR_SELF) */ 290 MSG_CI_TLS_MODADD, /* MSG_ORIG(MSG_CI_TLS_MODADD) */ 291 MSG_CI_TLS_MODREM, /* MSG_ORIG(MSG_CI_TLS_MODREM) */ 292 MSG_CI_TLS_STATMOD, /* MSG_ORIG(MSG_CI_TLS_STATMOD) */ 293 MSG_CI_THRINIT, /* MSG_ORIG(MSG_CI_THRINIT) */ 294 MSG_CI_CRITICAL /* MSG_ORIG(MSG_CI_CRITICAL) */ 295 }; 296 297 void 298 Dbg_util_lcinterface(Rt_map *lmp, int tag, char *val) 299 { 300 const char *str; 301 Conv_inv_buf_t inv_buf; 302 303 if (DBG_NOTDETAIL()) 304 return; 305 306 if (tag < CI_MAX) 307 str = MSG_ORIG(tags[tag]); 308 else 309 str = conv_invalid_val(&inv_buf, tag, 0); 310 311 dbg_print(LIST(lmp), MSG_INTL(MSG_UTL_LCINTERFACE), NAME(lmp), str, 312 EC_NATPTR(val)); 313 } 314 315 void 316 Dbg_unused_lcinterface(Rt_map *nlmp, Rt_map *olmp, int tag) 317 { 318 const char *str; 319 Conv_inv_buf_t inv_buf; 320 321 if (DBG_NOTCLASS(DBG_C_UNUSED)) 322 return; 323 324 if (tag < CI_MAX) 325 str = MSG_ORIG(tags[tag]); 326 else 327 str = conv_invalid_val(&inv_buf, tag, 0); 328 329 dbg_print(LIST(nlmp), MSG_INTL(MSG_USD_LCINTERFACE), NAME(nlmp), str, 330 NAME(olmp)); 331 } 332 333 /* 334 * Generic new line generator. To prevent multiple newlines from being 335 * generated, a flag is maintained in the global debug descriptor. This flag 336 * is cleared by the callers dbg_print() function to indicate that a newline 337 * (actually, any line) has been printed. Multiple newlines can be generated 338 * using the DBG_NL_FRC flag. 339 */ 340 void 341 Dbg_util_nl(Lm_list *lml, int flag) 342 { 343 if ((flag == DBG_NL_STD) && (dbg_desc->d_extra & DBG_E_STDNL)) 344 return; 345 346 dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY)); 347 348 if (flag == DBG_NL_STD) 349 dbg_desc->d_extra |= DBG_E_STDNL; 350 } 351 352 /* 353 * Define name demanglers. 354 */ 355 const char * 356 Dbg_demangle_name(const char *name) 357 { 358 if (DBG_NOTCLASS(DBG_C_DEMANGLE)) 359 return (name); 360 361 return (conv_demangle_name(name)); 362 } 363 364 const char * 365 Elf_demangle_name(const char *name) 366 { 367 if (DBG_ISDEMANGLE()) 368 return (conv_demangle_name(name)); 369 return (name); 370 } 371