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