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 #include "msg.h" 29 #include "_debug.h" 30 #include "libld.h" 31 #include <sys/elf_SPARC.h> 32 33 34 void _gelf_reloc_entry(const char *prestr, GElf_Half mach, 35 GElf_Word type, void *reloc, 36 const char *sec, const char *name, const char *com); 37 38 void 39 Dbg_reloc_generate(Os_desc * osp, Word relshtype) 40 { 41 if (DBG_NOTCLASS(DBG_RELOC)) 42 return; 43 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 44 dbg_print(MSG_INTL(MSG_REL_GENERATE), osp->os_name); 45 if (DBG_NOTDETAIL()) 46 return; 47 if (relshtype == SHT_RELA) 48 dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_2)); 49 else 50 dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_2)); 51 } 52 53 void 54 Dbg_reloc_proc(Os_desc *osp, Is_desc *isp, Is_desc *risp) 55 { 56 const char *str1, *str2; 57 58 if (DBG_NOTCLASS(DBG_RELOC)) 59 return; 60 61 if (osp && osp->os_name) 62 str1 = osp->os_name; 63 else 64 str1 = MSG_INTL(MSG_STR_NULL); 65 66 if (isp && isp->is_file) 67 str2 = isp->is_file->ifl_name; 68 else if (risp && risp->is_file) 69 str2 = risp->is_file->ifl_name; 70 else 71 str2 = MSG_INTL(MSG_STR_NULL); 72 73 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 74 dbg_print(MSG_INTL(MSG_REL_COLLECT), str1, str2); 75 if (DBG_NOTDETAIL()) 76 return; 77 78 /* 79 * Determine the relocation titles from the sections type. 80 */ 81 if (risp->is_shdr->sh_type == SHT_RELA) 82 dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_2)); 83 else 84 dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_2)); 85 } 86 87 #if !defined(_ELF64) 88 void 89 Dbg_reloc_doactiverel() 90 { 91 if (DBG_NOTCLASS(DBG_RELOC)) 92 return; 93 if (DBG_NOTDETAIL()) 94 return; 95 96 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 97 dbg_print(MSG_INTL(MSG_REL_ACTIVE)); 98 dbg_print(MSG_ORIG(MSG_REL_TITLE_1)); 99 } 100 #endif /* !defined(_ELF64) */ 101 102 void 103 Dbg_reloc_doact(Half mach, Word rtype, Xword off, Xword value, const char *sym, 104 Os_desc *osp) 105 { 106 const char *sec; 107 const char *msg; 108 109 if (DBG_NOTCLASS(DBG_RELOC)) 110 return; 111 if (DBG_NOTDETAIL()) 112 return; 113 if (DBG_NOTLONG()) 114 msg = MSG_ORIG(MSG_REL_ARGS_6); 115 else 116 msg = MSG_ORIG(MSG_REL_L_ARGS_6); 117 118 if (osp) { 119 sec = osp->os_name; 120 off += osp->os_shdr->sh_offset; 121 } else 122 sec = MSG_ORIG(MSG_STR_EMPTY); 123 124 dbg_print(msg, MSG_ORIG(MSG_STR_EMPTY), 125 conv_reloc_type_str(mach, rtype), EC_OFF(off), EC_XWORD(value), 126 sec, _Dbg_sym_dem(sym), MSG_ORIG(MSG_STR_EMPTY)); 127 } 128 129 void 130 Dbg_reloc_dooutrel(GElf_Word type) 131 { 132 if (DBG_NOTCLASS(DBG_RELOC)) 133 return; 134 if (DBG_NOTDETAIL()) 135 return; 136 137 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 138 dbg_print(MSG_INTL(MSG_REL_CREATING)); 139 140 if (type == SHT_RELA) 141 dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_2)); 142 else 143 dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_2)); 144 } 145 146 void 147 Dbg_reloc_discard(Half mach, Rel_desc *rsp) 148 { 149 if (DBG_NOTCLASS(DBG_RELOC)) 150 return; 151 if (DBG_NOTDETAIL()) 152 return; 153 154 dbg_print(MSG_INTL(MSG_REL_DISCARDED), rsp->rel_isdesc->is_basename, 155 rsp->rel_isdesc->is_file->ifl_name, 156 conv_reloc_type_str(mach, rsp->rel_rtype), 157 EC_OFF(rsp->rel_roffset)); 158 } 159 160 void 161 Dbg_reloc_transition(Half mach, Word oldrtype, Word newrtype, Xword off, 162 const char *sym) 163 { 164 if (DBG_NOTCLASS(DBG_RELOC)) 165 return; 166 dbg_print(MSG_INTL(MSG_REL_TRANS), EC_OFF(off), 167 conv_reloc_type_str(mach, oldrtype) + M_R_STR_LEN, 168 conv_reloc_type_str(mach, newrtype) + M_R_STR_LEN, 169 sym); 170 } 171 172 void 173 Dbg_reloc_reg_apply(unsigned long long off, unsigned long long value) 174 { 175 if (DBG_NOTCLASS(DBG_RELOC)) 176 return; 177 if (DBG_NOTDETAIL()) 178 return; 179 dbg_print(MSG_ORIG(MSG_REL_REGSYM), 180 #if defined(_ELF64) 181 conv_sym_value_str(EM_SPARCV9, STT_SPARC_REGISTER, off), 182 #else 183 conv_sym_value_str(EM_SPARC, STT_SPARC_REGISTER, off), 184 #endif 185 value); 186 } 187 188 #if !defined(_ELF64) 189 void 190 Dbg_reloc_apply(unsigned long long off, unsigned long long value) 191 { 192 if (DBG_NOTCLASS(DBG_RELOC)) 193 return; 194 if (DBG_NOTDETAIL()) 195 return; 196 197 /* 198 * Print the actual relocation being applied to the specified output 199 * section, the offset represents the actual relocation address, and the 200 * value is the new data being written to that address). 201 */ 202 dbg_print(MSG_ORIG(MSG_REL_ARGS_2), off, value); 203 } 204 #endif /* !defined(_ELF64) */ 205 206 void 207 Dbg_reloc_out(Half mach, Word type, void *rel, const char *name, 208 const char *relsectname) 209 { 210 if (DBG_NOTCLASS(DBG_RELOC)) 211 return; 212 if (DBG_NOTDETAIL()) 213 return; 214 215 _gelf_reloc_entry(MSG_ORIG(MSG_STR_EMPTY), mach, type, rel, 216 relsectname, _Dbg_sym_dem(name), MSG_ORIG(MSG_STR_EMPTY)); 217 } 218 219 void 220 Dbg_reloc_in(Half mach, Word type, void *rel, const char *name, 221 const char *iname) 222 { 223 if (DBG_NOTCLASS(DBG_RELOC)) 224 return; 225 if (DBG_NOTDETAIL()) 226 return; 227 228 _gelf_reloc_entry(MSG_INTL(MSG_STR_IN), mach, type, rel, 229 (iname ? iname : MSG_ORIG(MSG_STR_EMPTY)), 230 (name ? _Dbg_sym_dem(name) : MSG_ORIG(MSG_STR_EMPTY)), 231 MSG_ORIG(MSG_STR_EMPTY)); 232 } 233 234 void 235 Dbg_reloc_error(Half mach, Word type, void *rel, const char *name, 236 const char *com) 237 { 238 if (DBG_NOTCLASS(DBG_RELOC)) 239 return; 240 if (DBG_NOTDETAIL()) 241 return; 242 243 _gelf_reloc_entry(MSG_INTL(MSG_STR_ERROR), mach, type, rel, 244 MSG_ORIG(MSG_STR_EMPTY), 245 (name ? _Dbg_sym_dem(name) : MSG_ORIG(MSG_STR_EMPTY)), 246 (com ? com : MSG_ORIG(MSG_STR_EMPTY))); 247 } 248 249 /* 250 * Print a output relocation structure(Rel_desc). 251 */ 252 void 253 Dbg_reloc_ors_entry(Half mach, Rel_desc *orsp) 254 { 255 const char *os_name; 256 const char *sym_name; 257 const char *msg; 258 259 if (DBG_NOTCLASS(DBG_RELOC)) 260 return; 261 if (DBG_NOTDETAIL()) 262 return; 263 if (DBG_NOTLONG()) 264 msg = MSG_ORIG(MSG_REL_ARGS_5); 265 else 266 msg = MSG_ORIG(MSG_REL_L_ARGS_5); 267 268 if (orsp->rel_flags & (FLG_REL_GOT | FLG_REL_RFPTR1 | FLG_REL_RFPTR2)) 269 os_name = MSG_ORIG(MSG_SCN_GOT); 270 else if (orsp->rel_flags & FLG_REL_PLT) 271 os_name = MSG_ORIG(MSG_SCN_PLT); 272 else if (orsp->rel_flags & FLG_REL_BSS) 273 os_name = MSG_ORIG(MSG_SCN_BSS); 274 else if (orsp->rel_osdesc) 275 os_name = orsp->rel_osdesc->os_name; 276 else 277 os_name = MSG_INTL(MSG_STR_NULL); 278 279 /* 280 * Register symbols can be relocated/initialized 281 * to a constant, which is a special case where 282 * the symbol index is 0. 283 */ 284 if (orsp->rel_sym != NULL) 285 sym_name = orsp->rel_sym->sd_name; 286 else 287 sym_name = MSG_ORIG(MSG_STR_EMPTY); 288 289 dbg_print(msg, MSG_INTL(MSG_STR_OUT), 290 conv_reloc_type_str(mach, orsp->rel_rtype), 291 EC_OFF(orsp->rel_roffset), os_name, 292 _Dbg_sym_dem(sym_name), MSG_ORIG(MSG_STR_EMPTY)); 293 } 294 295 /* 296 * Print a Active relocation structure (Rel_desc). 297 */ 298 void 299 Dbg_reloc_ars_entry(Half mach, Rel_desc *arsp) 300 { 301 const char *os_name; 302 const char *msg; 303 304 if (DBG_NOTCLASS(DBG_RELOC)) 305 return; 306 if (DBG_NOTDETAIL()) 307 return; 308 if (DBG_NOTLONG()) 309 msg = MSG_ORIG(MSG_REL_ARGS_5); 310 else 311 msg = MSG_ORIG(MSG_REL_L_ARGS_5); 312 313 if (arsp->rel_flags & (FLG_REL_GOT | FLG_REL_FPTR)) 314 os_name = MSG_ORIG(MSG_SCN_GOT); 315 else 316 os_name = arsp->rel_osdesc->os_name; 317 318 dbg_print(msg, MSG_INTL(MSG_STR_ACT), 319 conv_reloc_type_str(mach, arsp->rel_rtype), 320 EC_OFF(arsp->rel_roffset), os_name, 321 _Dbg_sym_dem(arsp->rel_sym->sd_name), MSG_ORIG(MSG_STR_EMPTY)); 322 } 323 324 #if !defined(_ELF64) 325 void 326 Dbg_reloc_run(const char *file, uint_t rel, int info, int type) 327 { 328 const char *str; 329 330 if (DBG_NOTCLASS(DBG_RELOC)) 331 return; 332 333 if (type == DBG_REL_FINISH) { 334 if (info) 335 str = MSG_ORIG(MSG_STR_EMPTY); 336 else 337 str = MSG_INTL(MSG_REL_RELOC_FAIL); 338 } else { 339 if (info) 340 str = MSG_INTL(MSG_REL_RELOC_PLT); 341 else 342 str = MSG_ORIG(MSG_STR_EMPTY); 343 } 344 345 if (type == DBG_REL_START) { 346 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 347 dbg_print(MSG_INTL(MSG_REL_RELOC_START), file, str); 348 349 if (DBG_NOTDETAIL()) 350 return; 351 352 if (rel == SHT_RELA) { 353 dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_3)); 354 dbg_print(MSG_ORIG(MSG_REL_RELA_TITLE_4)); 355 } else 356 dbg_print(MSG_ORIG(MSG_REL_REL_TITLE_3)); 357 } else { 358 if (type == DBG_REL_NONE) { 359 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 360 dbg_print(MSG_INTL(MSG_REL_RELOC_NONE), file, str); 361 } else 362 dbg_print(MSG_INTL(MSG_REL_RELOC_FINISH), file, str); 363 364 dbg_print(MSG_ORIG(MSG_STR_EMPTY)); 365 } 366 } 367 368 void 369 Dbg_reloc_copy(const char *dname, const char *rname, const char *sname, 370 int zero) 371 { 372 const char *str; 373 374 if (DBG_NOTCLASS(DBG_RELOC)) 375 return; 376 if (DBG_NOTDETAIL()) 377 return; 378 379 if (zero) 380 str = MSG_INTL(MSG_STR_COPYZERO); 381 else 382 str = MSG_ORIG(MSG_STR_EMPTY); 383 384 dbg_print(MSG_INTL(MSG_REL_COPY), dname, rname, sname, str); 385 } 386 387 /* 388 * Print a relocation entry. This can either be an input or output 389 * relocation record, and specifies the relocation section for which is 390 * associated. 391 */ 392 void 393 Gelf_reloc_entry(const char *prestr, GElf_Half mach, GElf_Word type, 394 GElf_Rela *rel, const char *sec, const char *name) 395 { 396 const char *msg; 397 398 if (type == SHT_RELA) { 399 if (DBG_NOTLONG()) 400 msg = MSG_ORIG(MSG_REL_ARGS_6); 401 else 402 msg = MSG_ORIG(MSG_REL_L_ARGS_6); 403 } else { 404 if (DBG_NOTLONG()) 405 msg = MSG_ORIG(MSG_REL_ARGS_5); 406 else 407 msg = MSG_ORIG(MSG_REL_L_ARGS_5); 408 } 409 410 if (type == SHT_RELA) 411 dbg_print(msg, prestr, 412 conv_reloc_type_str(mach, (uint_t)GELF_R_TYPE(rel->r_info)), 413 EC_ADDR(rel->r_offset), EC_XWORD(rel->r_addend), 414 sec, _Dbg_sym_dem(name), MSG_ORIG(MSG_STR_EMPTY)); 415 else 416 dbg_print(msg, prestr, 417 conv_reloc_type_str(mach, (uint_t)GELF_R_TYPE(rel->r_info)), 418 EC_ADDR(rel->r_offset), sec, _Dbg_sym_dem(name), 419 MSG_ORIG(MSG_STR_EMPTY)); 420 } 421 422 void 423 _gelf_reloc_entry(const char *prestr, GElf_Half mach, GElf_Word type, 424 void *reloc, const char *sec, const char *name, const char *com) 425 { 426 const char *msg; 427 428 /* 429 * Register relocations can use a constant initialzer, 430 * in which case the associated symbol is 0. 431 */ 432 if (name == NULL) 433 name = MSG_ORIG(MSG_STR_EMPTY); 434 435 if (type == SHT_RELA) { 436 if (DBG_NOTLONG()) 437 msg = MSG_ORIG(MSG_REL_ARGS_6); 438 else 439 msg = MSG_ORIG(MSG_REL_L_ARGS_6); 440 } else { 441 if (DBG_NOTLONG()) 442 msg = MSG_ORIG(MSG_REL_ARGS_5); 443 else 444 msg = MSG_ORIG(MSG_REL_L_ARGS_5); 445 } 446 447 if ((mach == EM_SPARCV9) || (mach == EM_AMD64)) { 448 Elf64_Rela * rel = (Elf64_Rela *)reloc; 449 450 if (type == SHT_RELA) { 451 dbg_print(msg, prestr, 452 conv_reloc_type_str(mach, 453 (uint_t)ELF64_R_TYPE(rel->r_info)), 454 EC_ADDR(rel->r_offset), 455 EC_XWORD(rel->r_addend), 456 sec, name, com); 457 } else { 458 dbg_print(msg, prestr, 459 conv_reloc_type_str(mach, 460 (uint_t)ELF64_R_TYPE(rel->r_info)), 461 EC_ADDR(rel->r_offset), sec, name, com); 462 } 463 } else { 464 Elf32_Rela * rel = (Elf32_Rela *)reloc; 465 466 if (type == SHT_RELA) { 467 dbg_print(msg, prestr, 468 conv_reloc_type_str(mach, 469 ELF32_R_TYPE(rel->r_info)), 470 EC_ADDR(rel->r_offset), EC_XWORD(rel->r_addend), 471 sec, name, com); 472 } else { 473 dbg_print(msg, prestr, 474 conv_reloc_type_str(mach, 475 ELF32_R_TYPE(rel->r_info)), 476 EC_ADDR(rel->r_offset), sec, name, com); 477 } 478 } 479 } 480 #endif /* !defined(_ELF64) */ 481 482 #if defined(_ELF64) 483 void 484 Dbg_pltpad_boundto64(const char *file, Addr pltpad, const char *dfile, 485 const char *symname) 486 { 487 if (DBG_NOTCLASS(DBG_RELOC)) 488 return; 489 if (DBG_NOTDETAIL()) 490 return; 491 dbg_print(MSG_INTL(MSG_REL_PADBOUNDTO), file, EC_ADDR(pltpad), 492 dfile, symname); 493 } 494 495 void 496 Dbg_pltpad_bindto64(const char *file, const char *sname, Addr pltpad) 497 { 498 if (DBG_NOTCLASS(DBG_RELOC)) 499 return; 500 if (DBG_NOTDETAIL()) 501 return; 502 dbg_print(MSG_INTL(MSG_REL_PADBINDTO), file, _Dbg_sym_dem(sname), 503 EC_ADDR(pltpad)); 504 } 505 #endif 506