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