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 /* 28 * Dump an elf file. 29 */ 30 #include <sys/elf_386.h> 31 #include <sys/elf_amd64.h> 32 #include <sys/elf_SPARC.h> 33 #include <_libelf.h> 34 #include <dwarf.h> 35 #include <stdio.h> 36 #include <unistd.h> 37 #include <errno.h> 38 #include <strings.h> 39 #include <debug.h> 40 #include <conv.h> 41 #include <msg.h> 42 #include <_elfdump.h> 43 44 45 /* 46 * VERSYM_STATE is used to maintain information about the VERSYM section 47 * in the object being analyzed. It is filled in by versions(), and used 48 * by init_symtbl_state() when displaying symbol information. 49 * 50 * There are three forms of symbol versioning known to us: 51 * 52 * 1) The original form, introduced with Solaris 2.5, in which 53 * the Versym contains indexes to Verdef records, and the 54 * Versym values for UNDEF symbols resolved by other objects 55 * are all set to 0. 56 * 2) The GNU form, which is backward compatible with the original 57 * Solaris form, but which adds several extensions: 58 * - The Versym also contains indexes to Verneed records, recording 59 * which object/version contributed the external symbol at 60 * link time. These indexes start with the next value following 61 * the final Verdef index. The index is written to the previously 62 * reserved vna_other field of the ELF Vernaux structure. 63 * - The top bit of the Versym value is no longer part of the index, 64 * but is used as a "hidden bit" to prevent binding to the symbol. 65 * - Multiple implementations of a given symbol, contained in varying 66 * versions are allowed, using special assembler pseudo ops, 67 * and encoded in the symbol name using '@' characters. 68 * 3) Modified Solaris form, in which we adopt the first GNU extension 69 * (Versym indexes to Verneed records), but not the others. 70 * 71 * elfdump can handle any of these cases. The presence of a DT_VERSYM 72 * dynamic element indicates a full GNU object. An object that lacks 73 * a DT_VERSYM entry, but which has non-zero vna_other fields in the Vernaux 74 * structures is a modified Solaris object. An object that has neither of 75 * these uses the original form. 76 * 77 * max_verndx contains the largest version index that can appear 78 * in a Versym entry. This can never be less than 1: In the case where 79 * there is no verdef/verneed sections, the [0] index is reserved 80 * for local symbols, and the [1] index for globals. If the original 81 * Solaris versioning rules are in effect and there is a verdef section, 82 * then max_verndex is the number of defined versions. If one of the 83 * other versioning forms is in effect, then: 84 * 1) If there is no verneed section, it is the same as for 85 * original Solaris versioning. 86 * 2) If there is a verneed section, the vna_other field of the 87 * Vernaux structs contain versions, and max_verndx is the 88 * largest such index. 89 * 90 * If gnu_full is True, the object uses the full GNU form of versioning. 91 * The value of the gnu_full field is based on the presence of 92 * a DT_VERSYM entry in the dynamic section: GNU ld produces these, and 93 * Solaris ld does not. 94 * 95 * The gnu_needed field is True if the Versym contains indexes to 96 * Verneed records, as indicated by non-zero vna_other fields in the Verneed 97 * section. If gnu_full is True, then gnu_needed will always be true. 98 * However, gnu_needed can be true without gnu_full. This is the modified 99 * Solaris form. 100 */ 101 typedef struct { 102 Cache *cache; /* Pointer to cache entry for VERSYM */ 103 Versym *data; /* Pointer to versym array */ 104 int gnu_full; /* True if object uses GNU versioning rules */ 105 int gnu_needed; /* True if object uses VERSYM indexes for */ 106 /* VERNEED (subset of gnu_full) */ 107 int max_verndx; /* largest versym index value */ 108 } VERSYM_STATE; 109 110 /* 111 * SYMTBL_STATE is used to maintain information about a single symbol 112 * table section, for use by the routines that display symbol information. 113 */ 114 typedef struct { 115 const char *file; /* Name of file */ 116 Ehdr *ehdr; /* ELF header for file */ 117 Cache *cache; /* Cache of all section headers */ 118 Word shnum; /* # of sections in cache */ 119 Cache *seccache; /* Cache of symbol table section hdr */ 120 Word secndx; /* Index of symbol table section hdr */ 121 const char *secname; /* Name of section */ 122 uint_t flags; /* Command line option flags */ 123 struct { /* Extended section index data */ 124 int checked; /* TRUE if already checked for shxndx */ 125 Word *data; /* NULL, or extended section index */ 126 /* used for symbol table entries */ 127 uint_t n; /* # items in shxndx.data */ 128 } shxndx; 129 VERSYM_STATE *versym; /* NULL, or associated VERSYM section */ 130 Sym *sym; /* Array of symbols */ 131 Word symn; /* # of symbols */ 132 } SYMTBL_STATE; 133 134 135 136 /* 137 * Focal point for verifying symbol names. 138 */ 139 static const char * 140 string(Cache *refsec, Word ndx, Cache *strsec, const char *file, Word name) 141 { 142 /* 143 * If an error in this routine is due to a property of the string 144 * section, as opposed to a bad offset into the section (a property of 145 * the referencing section), then we will detect the same error on 146 * every call involving those sections. We use these static variables 147 * to retain the information needed to only issue each such error once. 148 */ 149 static Cache *last_refsec; /* Last referencing section seen */ 150 static int strsec_err; /* True if error issued */ 151 152 const char *strs; 153 Word strn; 154 155 if (strsec->c_data == NULL) 156 return (NULL); 157 158 strs = (char *)strsec->c_data->d_buf; 159 strn = strsec->c_data->d_size; 160 161 /* 162 * We only print a diagnostic regarding a bad string table once per 163 * input section being processed. If the refsec has changed, reset 164 * our retained error state. 165 */ 166 if (last_refsec != refsec) { 167 last_refsec = refsec; 168 strsec_err = 0; 169 } 170 171 /* Verify that strsec really is a string table */ 172 if (strsec->c_shdr->sh_type != SHT_STRTAB) { 173 if (!strsec_err) { 174 (void) fprintf(stderr, MSG_INTL(MSG_ERR_NOTSTRTAB), 175 file, strsec->c_ndx, refsec->c_ndx); 176 strsec_err = 1; 177 } 178 return (MSG_INTL(MSG_STR_UNKNOWN)); 179 } 180 181 /* 182 * Is the string table offset within range of the available strings? 183 */ 184 if (name >= strn) { 185 /* 186 * Do we have a empty string table? 187 */ 188 if (strs == NULL) { 189 if (!strsec_err) { 190 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 191 file, strsec->c_name); 192 strsec_err = 1; 193 } 194 } else { 195 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSTOFF), 196 file, refsec->c_name, EC_WORD(ndx), strsec->c_name, 197 EC_WORD(name), EC_WORD(strn - 1)); 198 } 199 200 /* 201 * Return the empty string so that the calling function can 202 * continue it's output diagnostics. 203 */ 204 return (MSG_INTL(MSG_STR_UNKNOWN)); 205 } 206 return (strs + name); 207 } 208 209 /* 210 * Relocations can reference section symbols and standard symbols. If the 211 * former, establish the section name. 212 */ 213 static const char * 214 relsymname(Cache *cache, Cache *csec, Cache *strsec, Word symndx, Word symnum, 215 Word relndx, Sym *syms, char *secstr, size_t secsz, const char *file) 216 { 217 Sym *sym; 218 const char *name; 219 220 if (symndx >= symnum) { 221 (void) fprintf(stderr, MSG_INTL(MSG_ERR_RELBADSYMNDX), 222 file, EC_WORD(symndx), EC_WORD(relndx)); 223 return (MSG_INTL(MSG_STR_UNKNOWN)); 224 } 225 226 sym = (Sym *)(syms + symndx); 227 name = string(csec, symndx, strsec, file, sym->st_name); 228 229 /* 230 * If the symbol represents a section offset construct an appropriate 231 * string. Note, although section symbol table entries typically have 232 * a NULL name pointer, entries do exist that point into the string 233 * table to their own NULL strings. 234 */ 235 if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) && 236 ((sym->st_name == 0) || (*name == '\0'))) { 237 (void) snprintf(secstr, secsz, MSG_INTL(MSG_STR_SECTION), 238 cache[sym->st_shndx].c_name); 239 return ((const char *)secstr); 240 } 241 242 return (name); 243 } 244 245 /* 246 * Focal point for establishing a string table section. Data such as the 247 * dynamic information simply points to a string table. Data such as 248 * relocations, reference a symbol table, which in turn is associated with a 249 * string table. 250 */ 251 static int 252 stringtbl(Cache *cache, int symtab, Word ndx, Word shnum, const char *file, 253 Word *symnum, Cache **symsec, Cache **strsec) 254 { 255 Shdr *shdr = cache[ndx].c_shdr; 256 257 if (symtab) { 258 /* 259 * Validate the symbol table section. 260 */ 261 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) { 262 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 263 file, cache[ndx].c_name, EC_WORD(shdr->sh_link)); 264 return (0); 265 } 266 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) { 267 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 268 file, cache[ndx].c_name); 269 return (0); 270 } 271 272 /* 273 * Obtain, and verify the symbol table data. 274 */ 275 if ((cache[ndx].c_data == NULL) || 276 (cache[ndx].c_data->d_buf == NULL)) { 277 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 278 file, cache[ndx].c_name); 279 return (0); 280 } 281 282 /* 283 * Establish the string table index. 284 */ 285 ndx = shdr->sh_link; 286 shdr = cache[ndx].c_shdr; 287 288 /* 289 * Return symbol table information. 290 */ 291 if (symnum) 292 *symnum = (shdr->sh_size / shdr->sh_entsize); 293 if (symsec) 294 *symsec = &cache[ndx]; 295 } 296 297 /* 298 * Validate the associated string table section. 299 */ 300 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) { 301 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 302 file, cache[ndx].c_name, EC_WORD(shdr->sh_link)); 303 return (0); 304 } 305 306 if (strsec) 307 *strsec = &cache[shdr->sh_link]; 308 309 return (1); 310 } 311 312 /* 313 * Lookup a symbol and set Sym accordingly. 314 */ 315 static int 316 symlookup(const char *name, Cache *cache, Word shnum, Sym **sym, 317 Cache *symtab, const char *file) 318 { 319 Shdr *shdr; 320 Word symn, cnt; 321 Sym *syms; 322 323 if (symtab == 0) 324 return (0); 325 326 shdr = symtab->c_shdr; 327 328 /* 329 * Determine the symbol data and number. 330 */ 331 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) { 332 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 333 file, symtab->c_name); 334 return (0); 335 } 336 if (symtab->c_data == NULL) 337 return (0); 338 339 /* LINTED */ 340 symn = (Word)(shdr->sh_size / shdr->sh_entsize); 341 syms = (Sym *)symtab->c_data->d_buf; 342 343 /* 344 * Get the associated string table section. 345 */ 346 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) { 347 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 348 file, symtab->c_name, EC_WORD(shdr->sh_link)); 349 return (0); 350 } 351 352 /* 353 * Loop through the symbol table to find a match. 354 */ 355 for (cnt = 0; cnt < symn; syms++, cnt++) { 356 const char *symname; 357 358 symname = string(symtab, cnt, &cache[shdr->sh_link], file, 359 syms->st_name); 360 361 if (symname && (strcmp(name, symname) == 0)) { 362 *sym = syms; 363 return (1); 364 } 365 } 366 return (0); 367 } 368 369 /* 370 * Print section headers. 371 */ 372 static void 373 sections(const char *file, Cache *cache, Word shnum, Ehdr *ehdr) 374 { 375 size_t seccnt; 376 377 for (seccnt = 1; seccnt < shnum; seccnt++) { 378 Cache *_cache = &cache[seccnt]; 379 Shdr *shdr = _cache->c_shdr; 380 const char *secname = _cache->c_name; 381 382 /* 383 * Although numerous section header entries can be zero, it's 384 * usually a sign of trouble if the type is zero. 385 */ 386 if (shdr->sh_type == 0) { 387 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHTYPE), 388 file, secname, EC_WORD(shdr->sh_type)); 389 } 390 391 if (!match(MATCH_F_ALL, secname, seccnt, shdr->sh_type)) 392 continue; 393 394 /* 395 * Identify any sections that are suspicious. A .got section 396 * shouldn't exist in a relocatable object. 397 */ 398 if (ehdr->e_type == ET_REL) { 399 if (strncmp(secname, MSG_ORIG(MSG_ELF_GOT), 400 MSG_ELF_GOT_SIZE) == 0) { 401 (void) fprintf(stderr, 402 MSG_INTL(MSG_GOT_UNEXPECTED), file, 403 secname); 404 } 405 } 406 407 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 408 dbg_print(0, MSG_INTL(MSG_ELF_SHDR), EC_WORD(seccnt), secname); 409 Elf_shdr(0, ehdr->e_machine, shdr); 410 } 411 } 412 413 /* 414 * Obtain a specified Phdr entry. 415 */ 416 static Phdr * 417 getphdr(Word phnum, Word *type_arr, Word type_cnt, const char *file, Elf *elf) 418 { 419 Word cnt, tcnt; 420 Phdr *phdr; 421 422 if ((phdr = elf_getphdr(elf)) == NULL) { 423 failure(file, MSG_ORIG(MSG_ELF_GETPHDR)); 424 return (NULL); 425 } 426 427 for (cnt = 0; cnt < phnum; phdr++, cnt++) { 428 for (tcnt = 0; tcnt < type_cnt; tcnt++) { 429 if (phdr->p_type == type_arr[tcnt]) 430 return (phdr); 431 } 432 } 433 return (NULL); 434 } 435 436 static void 437 unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file, 438 Elf *elf) 439 { 440 #if defined(_ELF64) 441 #define MSG_UNW_BINSRTAB2 MSG_UNW_BINSRTAB2_64 442 #define MSG_UNW_BINSRTABENT MSG_UNW_BINSRTABENT_64 443 #else 444 #define MSG_UNW_BINSRTAB2 MSG_UNW_BINSRTAB2_32 445 #define MSG_UNW_BINSRTABENT MSG_UNW_BINSRTABENT_32 446 #endif 447 448 static Word phdr_types[] = { PT_SUNW_UNWIND, PT_SUNW_EH_FRAME }; 449 450 int frame_cnt = 0, hdr_cnt = 0, frame_ndx, hdr_ndx; 451 uint64_t save_frame_ptr, save_frame_base; 452 Conv_dwarf_ehe_buf_t dwarf_ehe_buf; 453 Word cnt; 454 Phdr *uphdr = NULL; 455 456 /* 457 * Historical background: .eh_frame and .eh_frame_hdr sections 458 * come from the GNU compilers (particularly C++), and are used 459 * under all architectures. Their format is based on DWARF. When 460 * the amd64 ABI was defined, these sections were adopted wholesale 461 * from the existing practice. 462 * 463 * When amd64 support was added to Solaris, support for these 464 * sections was added, using the SHT_AMD64_UNWIND section type 465 * to identify them. At first, we ignored them in objects for 466 * non-amd64 targets, but later broadened our support to include 467 * other architectures in order to better support gcc-generated 468 * objects. 469 * 470 * We match these sections by name, rather than section type, 471 * because they can come in as either SHT_AMD64_UNWIND, or as 472 * SHT_PROGBITS, and because we need to distinquish between 473 * the two types (.eh_frame and .eh_frame_hdr). 474 */ 475 476 if (phnum) 477 uphdr = getphdr(phnum, phdr_types, 478 sizeof (phdr_types) / sizeof (*phdr_types), file, elf); 479 480 for (cnt = 1; cnt < shnum; cnt++) { 481 Cache *_cache = &cache[cnt]; 482 Shdr *shdr = _cache->c_shdr; 483 uchar_t *data; 484 size_t datasize; 485 uint64_t ndx, frame_ptr, fde_cnt, tabndx; 486 uint_t vers, frame_ptr_enc, fde_cnt_enc, table_enc; 487 488 /* 489 * Skip sections of the wrong type. On amd64, Solaris tags 490 * these as SHT_AMD64_UNWIND, while gcc started out issuing 491 * them as SHT_PROGBITS and switched over when the amd64 ABI 492 * was finalized. On non-amd64, they're all SHT_PROGBITS. 493 */ 494 switch (shdr->sh_type) { 495 case SHT_PROGBITS: 496 if (ehdr->e_machine == EM_AMD64) 497 continue; 498 break; 499 case SHT_AMD64_UNWIND: 500 if (ehdr->e_machine != EM_AMD64) 501 continue; 502 break; 503 default: 504 continue; 505 } 506 507 /* 508 * Only sections with names starting with .eh_frame or 509 * .eh_frame_hdr are of interest. We do a prefix comparison, 510 * allowing for naming conventions like .eh_frame.foo, hence 511 * the use of strncmp() rather than strcmp(). This means that 512 * we only really need to test for .eh_frame, as it's a 513 * prefix of .eh_frame_hdr. 514 */ 515 if (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRM), 516 MSG_SCN_FRM_SIZE) != 0) 517 continue; 518 519 if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type)) 520 continue; 521 522 if (_cache->c_data == NULL) 523 continue; 524 525 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 526 dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name); 527 528 data = (uchar_t *)(_cache->c_data->d_buf); 529 datasize = _cache->c_data->d_size; 530 531 /* 532 * Is this a .eh_frame_hdr 533 */ 534 if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) || 535 (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR), 536 MSG_SCN_FRMHDR_SIZE) == 0)) { 537 /* 538 * There can only be a single .eh_frame_hdr. 539 * Flag duplicates. 540 */ 541 if (++hdr_cnt > 1) 542 (void) fprintf(stderr, 543 MSG_INTL(MSG_ERR_MULTEHFRMHDR), file, 544 EC_WORD(cnt), _cache->c_name); 545 546 dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR)); 547 ndx = 0; 548 549 vers = data[ndx++]; 550 frame_ptr_enc = data[ndx++]; 551 fde_cnt_enc = data[ndx++]; 552 table_enc = data[ndx++]; 553 554 dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers); 555 556 frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc, 557 ehdr->e_ident, shdr->sh_addr, ndx); 558 if (hdr_cnt == 1) { 559 hdr_ndx = cnt; 560 save_frame_ptr = frame_ptr; 561 } 562 563 dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC), 564 conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf), 565 EC_XWORD(frame_ptr)); 566 567 fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc, 568 ehdr->e_ident, shdr->sh_addr, ndx); 569 570 dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC), 571 conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf), 572 EC_XWORD(fde_cnt)); 573 dbg_print(0, MSG_ORIG(MSG_UNW_TABENC), 574 conv_dwarf_ehe(table_enc, &dwarf_ehe_buf)); 575 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1)); 576 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2)); 577 578 for (tabndx = 0; tabndx < fde_cnt; tabndx++) { 579 dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT), 580 EC_XWORD(dwarf_ehe_extract(data, &ndx, 581 table_enc, ehdr->e_ident, shdr->sh_addr, 582 ndx)), 583 EC_XWORD(dwarf_ehe_extract(data, &ndx, 584 table_enc, ehdr->e_ident, shdr->sh_addr, 585 ndx))); 586 } 587 } else { /* Display the .eh_frame section */ 588 frame_cnt++; 589 if (frame_cnt == 1) { 590 frame_ndx = cnt; 591 save_frame_base = shdr->sh_addr; 592 } else if ((frame_cnt > 1) && 593 (ehdr->e_type != ET_REL)) { 594 Conv_inv_buf_t inv_buf; 595 596 (void) fprintf(stderr, 597 MSG_INTL(MSG_WARN_MULTEHFRM), file, 598 EC_WORD(cnt), _cache->c_name, 599 conv_ehdr_type(ehdr->e_type, 0, &inv_buf)); 600 } 601 dump_eh_frame(data, datasize, shdr->sh_addr, 602 ehdr->e_machine, ehdr->e_ident); 603 } 604 605 /* 606 * If we've seen the .eh_frame_hdr and the first 607 * .eh_frame section, compare the header frame_ptr 608 * to the address of the actual frame section to ensure 609 * the link-editor got this right. 610 */ 611 if ((hdr_cnt > 0) && (frame_cnt > 0) && 612 (save_frame_ptr != save_frame_base)) 613 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR), 614 file, EC_WORD(hdr_ndx), cache[hdr_ndx].c_name, 615 EC_XWORD(save_frame_ptr), EC_WORD(frame_ndx), 616 cache[frame_ndx].c_name, EC_XWORD(save_frame_base)); 617 } 618 619 #undef MSG_UNW_BINSRTAB2 620 #undef MSG_UNW_BINSRTABENT 621 } 622 623 /* 624 * Print the hardware/software capabilities. For executables and shared objects 625 * this should be accompanied with a program header. 626 */ 627 static void 628 cap(const char *file, Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, 629 Elf *elf) 630 { 631 Word cnt; 632 Shdr *cshdr = NULL; 633 Cache *ccache; 634 Off cphdr_off = 0; 635 Xword cphdr_sz; 636 637 /* 638 * Determine if a hardware/software capabilities header exists. 639 */ 640 if (phnum) { 641 Phdr *phdr; 642 643 if ((phdr = elf_getphdr(elf)) == NULL) { 644 failure(file, MSG_ORIG(MSG_ELF_GETPHDR)); 645 return; 646 } 647 648 for (cnt = 0; cnt < phnum; phdr++, cnt++) { 649 if (phdr->p_type == PT_SUNWCAP) { 650 cphdr_off = phdr->p_offset; 651 cphdr_sz = phdr->p_filesz; 652 break; 653 } 654 } 655 } 656 657 /* 658 * Determine if a hardware/software capabilities section exists. 659 */ 660 for (cnt = 1; cnt < shnum; cnt++) { 661 Cache *_cache = &cache[cnt]; 662 Shdr *shdr = _cache->c_shdr; 663 664 if (shdr->sh_type != SHT_SUNW_cap) 665 continue; 666 667 if (cphdr_off && ((cphdr_off < shdr->sh_offset) || 668 (cphdr_off + cphdr_sz) > (shdr->sh_offset + shdr->sh_size))) 669 continue; 670 671 if (_cache->c_data == NULL) 672 continue; 673 674 ccache = _cache; 675 cshdr = shdr; 676 break; 677 } 678 679 if ((cshdr == NULL) && (cphdr_off == 0)) 680 return; 681 682 /* 683 * Print the hardware/software capabilities section. 684 */ 685 if (cshdr) { 686 Word ndx, capn; 687 Cap *cap = (Cap *)ccache->c_data->d_buf; 688 689 if ((cshdr->sh_entsize == 0) || (cshdr->sh_size == 0)) { 690 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 691 file, ccache->c_name); 692 return; 693 } 694 695 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 696 dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAP), ccache->c_name); 697 698 Elf_cap_title(0); 699 700 capn = (Word)(cshdr->sh_size / cshdr->sh_entsize); 701 702 for (ndx = 0; ndx < capn; cap++, ndx++) { 703 if (cap->c_tag == CA_SUNW_NULL) 704 continue; 705 706 Elf_cap_entry(0, cap, ndx, ehdr->e_machine); 707 708 /* 709 * An SF1_SUNW_ADDR32 software capability in a 32-bit 710 * object is suspicious as it has no effect. 711 */ 712 if ((cap->c_tag == CA_SUNW_SF_1) && 713 (ehdr->e_ident[EI_CLASS] == ELFCLASS32) && 714 (cap->c_un.c_val & SF1_SUNW_ADDR32)) { 715 (void) fprintf(stderr, 716 MSG_INTL(MSG_WARN_INADDR32SF1), 717 file, ccache->c_name); 718 } 719 } 720 } else 721 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP1), file); 722 723 /* 724 * If this object is an executable or shared object, then the 725 * hardware/software capabilities section should have an accompanying 726 * program header. 727 */ 728 if (cshdr && ((ehdr->e_type == ET_EXEC) || (ehdr->e_type == ET_DYN))) { 729 if (cphdr_off == 0) 730 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP2), 731 file, ccache->c_name); 732 else if ((cphdr_off != cshdr->sh_offset) || 733 (cphdr_sz != cshdr->sh_size)) 734 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP3), 735 file, ccache->c_name); 736 } 737 } 738 739 /* 740 * Print the interpretor. 741 */ 742 static void 743 interp(const char *file, Cache *cache, Word shnum, Word phnum, Elf *elf) 744 { 745 static Word phdr_types[] = { PT_INTERP }; 746 747 748 Word cnt; 749 Shdr *ishdr = NULL; 750 Cache *icache; 751 Off iphdr_off = 0; 752 Xword iphdr_fsz; 753 754 /* 755 * Determine if an interp header exists. 756 */ 757 if (phnum) { 758 Phdr *phdr; 759 760 phdr = getphdr(phnum, phdr_types, 761 sizeof (phdr_types) / sizeof (*phdr_types), file, elf); 762 if (phdr != NULL) { 763 iphdr_off = phdr->p_offset; 764 iphdr_fsz = phdr->p_filesz; 765 } 766 } 767 768 if (iphdr_off == 0) 769 return; 770 771 /* 772 * Determine if an interp section exists. 773 */ 774 for (cnt = 1; cnt < shnum; cnt++) { 775 Cache *_cache = &cache[cnt]; 776 Shdr *shdr = _cache->c_shdr; 777 778 /* 779 * Scan sections to find a section which contains the PT_INTERP 780 * string. The target section can't be in a NOBITS section. 781 */ 782 if ((shdr->sh_type == SHT_NOBITS) || 783 (iphdr_off < shdr->sh_offset) || 784 (iphdr_off + iphdr_fsz) > (shdr->sh_offset + shdr->sh_size)) 785 continue; 786 787 icache = _cache; 788 ishdr = shdr; 789 break; 790 } 791 792 /* 793 * Print the interpreter string based on the offset defined in the 794 * program header, as this is the offset used by the kernel. 795 */ 796 if (ishdr && icache->c_data) { 797 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 798 dbg_print(0, MSG_INTL(MSG_ELF_SCN_INTERP), icache->c_name); 799 dbg_print(0, MSG_ORIG(MSG_FMT_INDENT), 800 (char *)icache->c_data->d_buf + 801 (iphdr_off - ishdr->sh_offset)); 802 } else 803 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP1), file); 804 805 /* 806 * If there are any inconsistences between the program header and 807 * section information, flag them. 808 */ 809 if (ishdr && ((iphdr_off != ishdr->sh_offset) || 810 (iphdr_fsz != ishdr->sh_size))) { 811 (void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP2), file, 812 icache->c_name); 813 } 814 } 815 816 /* 817 * Print the syminfo section. 818 */ 819 static void 820 syminfo(Cache *cache, Word shnum, const char *file) 821 { 822 Shdr *infoshdr; 823 Syminfo *info; 824 Sym *syms; 825 Dyn *dyns; 826 Word infonum, cnt, ndx, symnum; 827 Cache *infocache = NULL, *symsec, *strsec; 828 829 for (cnt = 1; cnt < shnum; cnt++) { 830 if (cache[cnt].c_shdr->sh_type == SHT_SUNW_syminfo) { 831 infocache = &cache[cnt]; 832 break; 833 } 834 } 835 if (infocache == NULL) 836 return; 837 838 infoshdr = infocache->c_shdr; 839 if ((infoshdr->sh_entsize == 0) || (infoshdr->sh_size == 0)) { 840 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 841 file, infocache->c_name); 842 return; 843 } 844 if (infocache->c_data == NULL) 845 return; 846 847 infonum = (Word)(infoshdr->sh_size / infoshdr->sh_entsize); 848 info = (Syminfo *)infocache->c_data->d_buf; 849 850 /* 851 * Get the data buffer of the associated dynamic section. 852 */ 853 if ((infoshdr->sh_info == 0) || (infoshdr->sh_info >= shnum)) { 854 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO), 855 file, infocache->c_name, EC_WORD(infoshdr->sh_info)); 856 return; 857 } 858 if (cache[infoshdr->sh_info].c_data == NULL) 859 return; 860 861 dyns = cache[infoshdr->sh_info].c_data->d_buf; 862 if (dyns == NULL) { 863 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 864 file, cache[infoshdr->sh_info].c_name); 865 return; 866 } 867 868 /* 869 * Get the data buffer for the associated symbol table and string table. 870 */ 871 if (stringtbl(cache, 1, cnt, shnum, file, 872 &symnum, &symsec, &strsec) == 0) 873 return; 874 875 syms = symsec->c_data->d_buf; 876 877 /* 878 * Loop through the syminfo entries. 879 */ 880 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 881 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMINFO), infocache->c_name); 882 Elf_syminfo_title(0); 883 884 for (ndx = 1, info++; ndx < infonum; ndx++, info++) { 885 Sym *sym; 886 const char *needed = NULL, *name; 887 888 if ((info->si_flags == 0) && (info->si_boundto == 0)) 889 continue; 890 891 sym = &syms[ndx]; 892 name = string(infocache, ndx, strsec, file, sym->st_name); 893 894 if (info->si_boundto < SYMINFO_BT_LOWRESERVE) { 895 Dyn *dyn = &dyns[info->si_boundto]; 896 897 needed = string(infocache, info->si_boundto, 898 strsec, file, dyn->d_un.d_val); 899 } 900 Elf_syminfo_entry(0, ndx, info, name, needed); 901 } 902 } 903 904 /* 905 * Print version definition section entries. 906 */ 907 static void 908 version_def(Verdef *vdf, Word vdf_num, Cache *vcache, Cache *scache, 909 const char *file) 910 { 911 Word cnt; 912 char index[MAXNDXSIZE]; 913 914 Elf_ver_def_title(0); 915 916 for (cnt = 1; cnt <= vdf_num; cnt++, 917 vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) { 918 Conv_ver_flags_buf_t ver_flags_buf; 919 const char *name, *dep; 920 Half vcnt = vdf->vd_cnt - 1; 921 Half ndx = vdf->vd_ndx; 922 Verdaux *vdap = (Verdaux *)((uintptr_t)vdf + vdf->vd_aux); 923 924 /* 925 * Obtain the name and first dependency (if any). 926 */ 927 name = string(vcache, cnt, scache, file, vdap->vda_name); 928 vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next); 929 if (vcnt) 930 dep = string(vcache, cnt, scache, file, vdap->vda_name); 931 else 932 dep = MSG_ORIG(MSG_STR_EMPTY); 933 934 (void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX), 935 EC_XWORD(ndx)); 936 Elf_ver_line_1(0, index, name, dep, 937 conv_ver_flags(vdf->vd_flags, 0, &ver_flags_buf)); 938 939 /* 940 * Print any additional dependencies. 941 */ 942 if (vcnt) { 943 vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next); 944 for (vcnt--; vcnt; vcnt--, 945 vdap = (Verdaux *)((uintptr_t)vdap + 946 vdap->vda_next)) { 947 dep = string(vcache, cnt, scache, file, 948 vdap->vda_name); 949 Elf_ver_line_2(0, MSG_ORIG(MSG_STR_EMPTY), dep); 950 } 951 } 952 } 953 } 954 955 /* 956 * Print version needed section entries. 957 * 958 * entry: 959 * vnd - Address of verneed data 960 * vnd_num - # of Verneed entries 961 * vcache - Cache of verneed section being processed 962 * scache - Cache of associated string table section 963 * file - Name of object being processed. 964 * versym - Information about versym section 965 * 966 * exit: 967 * The versions have been printed. If GNU style versioning 968 * is in effect, versym->max_verndx has been updated to 969 * contain the largest version index seen. 970 * 971 * note: 972 * The versym section of an object that follows the original 973 * Solaris versioning rules only contains indexes into the verdef 974 * section. Symbols defined in other objects (UNDEF) are given 975 * a version of 0, indicating that they are not defined by 976 * this file, and the Verneed entries do not have associated version 977 * indexes. For these reasons, we do not display a version index 978 * for original-style Verneed sections. 979 * 980 * The GNU versioning extensions alter this: Symbols defined in other 981 * objects receive a version index in the range above those defined 982 * by the Verdef section, and the vna_other field of the Vernaux 983 * structs inside the Verneed section contain the version index for 984 * that item. We therefore display the index when showing the 985 * contents of a GNU style Verneed section. You should not 986 * necessarily expect these indexes to appear in sorted 987 * order --- it seems that the GNU ld assigns the versions as 988 * symbols are encountered during linking, and then the results 989 * are assembled into the Verneed section afterwards. 990 */ 991 static void 992 version_need(Verneed *vnd, Word vnd_num, Cache *vcache, Cache *scache, 993 const char *file, VERSYM_STATE *versym) 994 { 995 Word cnt; 996 char index[MAXNDXSIZE]; 997 const char *index_str; 998 999 Elf_ver_need_title(0, versym->gnu_needed); 1000 1001 for (cnt = 1; cnt <= vnd_num; cnt++, 1002 vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) { 1003 Conv_ver_flags_buf_t ver_flags_buf; 1004 const char *name, *dep; 1005 Half vcnt = vnd->vn_cnt; 1006 Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux); 1007 1008 /* 1009 * Obtain the name of the needed file and the version name 1010 * within it that we're dependent on. Note that the count 1011 * should be at least one, otherwise this is a pretty bogus 1012 * entry. 1013 */ 1014 name = string(vcache, cnt, scache, file, vnd->vn_file); 1015 if (vcnt) 1016 dep = string(vcache, cnt, scache, file, vnap->vna_name); 1017 else 1018 dep = MSG_INTL(MSG_STR_NULL); 1019 1020 if (vnap->vna_other == 0) { /* Traditional form */ 1021 index_str = MSG_ORIG(MSG_STR_EMPTY); 1022 } else { /* GNU form */ 1023 index_str = index; 1024 /* Format the version index value */ 1025 (void) snprintf(index, MAXNDXSIZE, 1026 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(vnap->vna_other)); 1027 if (vnap->vna_other > versym->max_verndx) 1028 versym->max_verndx = vnap->vna_other; 1029 } 1030 Elf_ver_line_1(0, index_str, name, dep, 1031 conv_ver_flags(vnap->vna_flags, 0, &ver_flags_buf)); 1032 1033 /* 1034 * Print any additional version dependencies. 1035 */ 1036 if (vcnt) { 1037 vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next); 1038 for (vcnt--; vcnt; vcnt--, 1039 vnap = (Vernaux *)((uintptr_t)vnap + 1040 vnap->vna_next)) { 1041 dep = string(vcache, cnt, scache, file, 1042 vnap->vna_name); 1043 if (vnap->vna_other > 0) { 1044 /* Format the next index value */ 1045 (void) snprintf(index, MAXNDXSIZE, 1046 MSG_ORIG(MSG_FMT_INDEX), 1047 EC_XWORD(vnap->vna_other)); 1048 Elf_ver_line_1(0, index, 1049 MSG_ORIG(MSG_STR_EMPTY), dep, 1050 conv_ver_flags(vnap->vna_flags, 1051 0, &ver_flags_buf)); 1052 if (vnap->vna_other > 1053 versym->max_verndx) 1054 versym->max_verndx = 1055 vnap->vna_other; 1056 } else { 1057 Elf_ver_line_3(0, 1058 MSG_ORIG(MSG_STR_EMPTY), dep, 1059 conv_ver_flags(vnap->vna_flags, 1060 0, &ver_flags_buf)); 1061 } 1062 } 1063 } 1064 } 1065 } 1066 1067 /* 1068 * Examine the Verneed section for information related to GNU 1069 * style Versym indexing: 1070 * - A non-zero vna_other field indicates that Versym indexes can 1071 * reference Verneed records. 1072 * - If the object uses GNU style Versym indexing, the 1073 * maximum index value is needed to detect bad Versym entries. 1074 * 1075 * entry: 1076 * vnd - Address of verneed data 1077 * vnd_num - # of Verneed entries 1078 * versym - Information about versym section 1079 * 1080 * exit: 1081 * If a non-zero vna_other field is seen, versym->gnu_needed is set. 1082 * 1083 * versym->max_verndx has been updated to contain the largest 1084 * version index seen. 1085 */ 1086 static void 1087 update_gnu_verndx(Verneed *vnd, Word vnd_num, VERSYM_STATE *versym) 1088 { 1089 Word cnt; 1090 1091 for (cnt = 1; cnt <= vnd_num; cnt++, 1092 vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) { 1093 Half vcnt = vnd->vn_cnt; 1094 Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux); 1095 1096 /* 1097 * A non-zero value of vna_other indicates that this 1098 * object references VERNEED items from the VERSYM 1099 * array. 1100 */ 1101 if (vnap->vna_other != 0) { 1102 versym->gnu_needed = 1; 1103 if (vnap->vna_other > versym->max_verndx) 1104 versym->max_verndx = vnap->vna_other; 1105 } 1106 1107 /* 1108 * Check any additional version dependencies. 1109 */ 1110 if (vcnt) { 1111 vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next); 1112 for (vcnt--; vcnt; vcnt--, 1113 vnap = (Vernaux *)((uintptr_t)vnap + 1114 vnap->vna_next)) { 1115 if (vnap->vna_other == 0) 1116 continue; 1117 1118 versym->gnu_needed = 1; 1119 if (vnap->vna_other > versym->max_verndx) 1120 versym->max_verndx = vnap->vna_other; 1121 } 1122 } 1123 } 1124 } 1125 1126 /* 1127 * Display version section information if the flags require it. 1128 * Return version information needed by other output. 1129 * 1130 * entry: 1131 * cache - Cache of all section headers 1132 * shnum - # of sections in cache 1133 * file - Name of file 1134 * flags - Command line option flags 1135 * versym - VERSYM_STATE block to be filled in. 1136 */ 1137 static void 1138 versions(Cache *cache, Word shnum, const char *file, uint_t flags, 1139 VERSYM_STATE *versym) 1140 { 1141 GElf_Word cnt; 1142 Cache *verdef_cache = NULL, *verneed_cache = NULL; 1143 1144 1145 /* Gather information about the version sections */ 1146 bzero(versym, sizeof (*versym)); 1147 versym->max_verndx = 1; 1148 for (cnt = 1; cnt < shnum; cnt++) { 1149 Cache *_cache = &cache[cnt]; 1150 Shdr *shdr = _cache->c_shdr; 1151 Dyn *dyn; 1152 ulong_t numdyn; 1153 1154 switch (shdr->sh_type) { 1155 case SHT_DYNAMIC: 1156 /* 1157 * The GNU ld puts a DT_VERSYM entry in the dynamic 1158 * section so that the runtime linker can use it to 1159 * implement their versioning rules. They allow multiple 1160 * incompatible functions with the same name to exist 1161 * in different versions. The Solaris ld does not 1162 * support this mechanism, and as such, does not 1163 * produce DT_VERSYM. We use this fact to determine 1164 * which ld produced this object, and how to interpret 1165 * the version values. 1166 */ 1167 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0) || 1168 (_cache->c_data == NULL)) 1169 continue; 1170 numdyn = shdr->sh_size / shdr->sh_entsize; 1171 dyn = (Dyn *)_cache->c_data->d_buf; 1172 for (; numdyn-- > 0; dyn++) 1173 if (dyn->d_tag == DT_VERSYM) { 1174 versym->gnu_full = 1175 versym->gnu_needed = 1; 1176 break; 1177 } 1178 break; 1179 1180 case SHT_SUNW_versym: 1181 /* Record data address for later symbol processing */ 1182 if (_cache->c_data != NULL) { 1183 versym->cache = _cache; 1184 versym->data = _cache->c_data->d_buf; 1185 continue; 1186 } 1187 break; 1188 1189 case SHT_SUNW_verdef: 1190 case SHT_SUNW_verneed: 1191 /* 1192 * Ensure the data is non-NULL and the number 1193 * of items is non-zero. Otherwise, we don't 1194 * understand the section, and will not use it. 1195 */ 1196 if ((_cache->c_data == NULL) || 1197 (_cache->c_data->d_buf == NULL)) { 1198 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 1199 file, _cache->c_name); 1200 continue; 1201 } 1202 if (shdr->sh_info == 0) { 1203 (void) fprintf(stderr, 1204 MSG_INTL(MSG_ERR_BADSHINFO), 1205 file, _cache->c_name, 1206 EC_WORD(shdr->sh_info)); 1207 continue; 1208 } 1209 1210 /* Make sure the string table index is in range */ 1211 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) { 1212 (void) fprintf(stderr, 1213 MSG_INTL(MSG_ERR_BADSHLINK), file, 1214 _cache->c_name, EC_WORD(shdr->sh_link)); 1215 continue; 1216 } 1217 1218 /* 1219 * The section is usable. Save the cache entry. 1220 */ 1221 if (shdr->sh_type == SHT_SUNW_verdef) { 1222 verdef_cache = _cache; 1223 /* 1224 * Under Solaris rules, if there is a verdef 1225 * section, the max versym index is number 1226 * of version definitions it supplies. 1227 */ 1228 versym->max_verndx = shdr->sh_info; 1229 } else { 1230 verneed_cache = _cache; 1231 } 1232 break; 1233 } 1234 } 1235 1236 /* 1237 * If there is a Verneed section, examine it for information 1238 * related to GNU style versioning. 1239 */ 1240 if (verneed_cache != NULL) 1241 update_gnu_verndx((Verneed *)verneed_cache->c_data->d_buf, 1242 verneed_cache->c_shdr->sh_info, versym); 1243 1244 /* 1245 * Now that all the information is available, display the 1246 * Verdef and Verneed section contents, if requested. 1247 */ 1248 if ((flags & FLG_SHOW_VERSIONS) == 0) 1249 return; 1250 if (verdef_cache != NULL) { 1251 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 1252 dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERDEF), 1253 verdef_cache->c_name); 1254 version_def((Verdef *)verdef_cache->c_data->d_buf, 1255 verdef_cache->c_shdr->sh_info, verdef_cache, 1256 &cache[verdef_cache->c_shdr->sh_link], file); 1257 } 1258 if (verneed_cache != NULL) { 1259 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 1260 dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERNEED), 1261 verneed_cache->c_name); 1262 /* 1263 * If GNU versioning applies to this object, version_need() 1264 * will update versym->max_verndx, and it is not 1265 * necessary to call update_gnu_verndx(). 1266 */ 1267 version_need((Verneed *)verneed_cache->c_data->d_buf, 1268 verneed_cache->c_shdr->sh_info, verneed_cache, 1269 &cache[verneed_cache->c_shdr->sh_link], file, versym); 1270 } 1271 } 1272 1273 /* 1274 * Initialize a symbol table state structure 1275 * 1276 * entry: 1277 * state - State structure to be initialized 1278 * cache - Cache of all section headers 1279 * shnum - # of sections in cache 1280 * secndx - Index of symbol table section 1281 * ehdr - ELF header for file 1282 * versym - Information about versym section 1283 * file - Name of file 1284 * flags - Command line option flags 1285 */ 1286 static int 1287 init_symtbl_state(SYMTBL_STATE *state, Cache *cache, Word shnum, Word secndx, 1288 Ehdr *ehdr, VERSYM_STATE *versym, const char *file, uint_t flags) 1289 { 1290 Shdr *shdr; 1291 1292 state->file = file; 1293 state->ehdr = ehdr; 1294 state->cache = cache; 1295 state->shnum = shnum; 1296 state->seccache = &cache[secndx]; 1297 state->secndx = secndx; 1298 state->secname = state->seccache->c_name; 1299 state->flags = flags; 1300 state->shxndx.checked = 0; 1301 state->shxndx.data = NULL; 1302 state->shxndx.n = 0; 1303 1304 shdr = state->seccache->c_shdr; 1305 1306 /* 1307 * Check the symbol data and per-item size. 1308 */ 1309 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) { 1310 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 1311 file, state->secname); 1312 return (0); 1313 } 1314 if (state->seccache->c_data == NULL) 1315 return (0); 1316 1317 /* LINTED */ 1318 state->symn = (Word)(shdr->sh_size / shdr->sh_entsize); 1319 state->sym = (Sym *)state->seccache->c_data->d_buf; 1320 1321 /* 1322 * Check associated string table section. 1323 */ 1324 if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) { 1325 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 1326 file, state->secname, EC_WORD(shdr->sh_link)); 1327 return (0); 1328 } 1329 1330 /* 1331 * Determine if there is a associated Versym section 1332 * with this Symbol Table. 1333 */ 1334 if (versym->cache && 1335 (versym->cache->c_shdr->sh_link == state->secndx)) 1336 state->versym = versym; 1337 else 1338 state->versym = NULL; 1339 1340 1341 return (1); 1342 } 1343 1344 /* 1345 * Determine the extended section index used for symbol tables entries. 1346 */ 1347 static void 1348 symbols_getxindex(SYMTBL_STATE *state) 1349 { 1350 uint_t symn; 1351 Word symcnt; 1352 1353 state->shxndx.checked = 1; /* Note that we've been called */ 1354 for (symcnt = 1; symcnt < state->shnum; symcnt++) { 1355 Cache *_cache = &state->cache[symcnt]; 1356 Shdr *shdr = _cache->c_shdr; 1357 1358 if ((shdr->sh_type != SHT_SYMTAB_SHNDX) || 1359 (shdr->sh_link != state->secndx)) 1360 continue; 1361 1362 if ((shdr->sh_entsize) && 1363 /* LINTED */ 1364 ((symn = (uint_t)(shdr->sh_size / shdr->sh_entsize)) == 0)) 1365 continue; 1366 1367 if (_cache->c_data == NULL) 1368 continue; 1369 1370 state->shxndx.data = _cache->c_data->d_buf; 1371 state->shxndx.n = symn; 1372 return; 1373 } 1374 } 1375 1376 /* 1377 * Produce a line of output for the given symbol 1378 * 1379 * entry: 1380 * state - Symbol table state 1381 * symndx - Index of symbol within the table 1382 * info - Value of st_info (indicates local/global range) 1383 * symndx_disp - Index to display. This may not be the same 1384 * as symndx if the display is relative to the logical 1385 * combination of the SUNW_ldynsym/dynsym tables. 1386 * sym - Symbol to display 1387 */ 1388 static void 1389 output_symbol(SYMTBL_STATE *state, Word symndx, Word info, Word disp_symndx, 1390 Sym *sym) 1391 { 1392 /* 1393 * Symbol types for which we check that the specified 1394 * address/size land inside the target section. 1395 */ 1396 static const int addr_symtype[] = { 1397 0, /* STT_NOTYPE */ 1398 1, /* STT_OBJECT */ 1399 1, /* STT_FUNC */ 1400 0, /* STT_SECTION */ 1401 0, /* STT_FILE */ 1402 1, /* STT_COMMON */ 1403 0, /* STT_TLS */ 1404 0, /* STT_IFUNC */ 1405 0, /* 8 */ 1406 0, /* 9 */ 1407 0, /* 10 */ 1408 0, /* 11 */ 1409 0, /* 12 */ 1410 0, /* STT_SPARC_REGISTER */ 1411 0, /* 14 */ 1412 0, /* 15 */ 1413 }; 1414 #if STT_NUM != (STT_IFUNC + 1) 1415 #error "STT_NUM has grown. Update addr_symtype[]" 1416 #endif 1417 1418 char index[MAXNDXSIZE]; 1419 const char *symname, *sec; 1420 Versym verndx; 1421 int gnuver; 1422 uchar_t type; 1423 Shdr *tshdr; 1424 Word shndx; 1425 Conv_inv_buf_t inv_buf; 1426 1427 /* Ensure symbol index is in range */ 1428 if (symndx >= state->symn) { 1429 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORTNDX), 1430 state->file, state->secname, EC_WORD(symndx)); 1431 return; 1432 } 1433 1434 /* 1435 * If we are using extended symbol indexes, find the 1436 * corresponding SHN_SYMTAB_SHNDX table. 1437 */ 1438 if ((sym->st_shndx == SHN_XINDEX) && (state->shxndx.checked == 0)) 1439 symbols_getxindex(state); 1440 1441 /* LINTED */ 1442 symname = string(state->seccache, symndx, 1443 &state->cache[state->seccache->c_shdr->sh_link], state->file, 1444 sym->st_name); 1445 1446 tshdr = NULL; 1447 sec = NULL; 1448 1449 if (state->ehdr->e_type == ET_CORE) { 1450 sec = (char *)MSG_INTL(MSG_STR_UNKNOWN); 1451 } else if (state->flags & FLG_CTL_FAKESHDR) { 1452 /* 1453 * If we are using fake section headers derived from 1454 * the program headers, then the section indexes 1455 * in the symbols do not correspond to these headers. 1456 * The section names are not available, so all we can 1457 * do is to display them in numeric form. 1458 */ 1459 sec = conv_sym_shndx(sym->st_shndx, &inv_buf); 1460 } else if ((sym->st_shndx < SHN_LORESERVE) && 1461 (sym->st_shndx < state->shnum)) { 1462 shndx = sym->st_shndx; 1463 tshdr = state->cache[shndx].c_shdr; 1464 sec = state->cache[shndx].c_name; 1465 } else if (sym->st_shndx == SHN_XINDEX) { 1466 if (state->shxndx.data) { 1467 Word _shxndx; 1468 1469 if (symndx > state->shxndx.n) { 1470 (void) fprintf(stderr, 1471 MSG_INTL(MSG_ERR_BADSYMXINDEX1), 1472 state->file, state->secname, 1473 EC_WORD(symndx)); 1474 } else if ((_shxndx = 1475 state->shxndx.data[symndx]) > state->shnum) { 1476 (void) fprintf(stderr, 1477 MSG_INTL(MSG_ERR_BADSYMXINDEX2), 1478 state->file, state->secname, 1479 EC_WORD(symndx), EC_WORD(_shxndx)); 1480 } else { 1481 shndx = _shxndx; 1482 tshdr = state->cache[shndx].c_shdr; 1483 sec = state->cache[shndx].c_name; 1484 } 1485 } else { 1486 (void) fprintf(stderr, 1487 MSG_INTL(MSG_ERR_BADSYMXINDEX3), 1488 state->file, state->secname, EC_WORD(symndx)); 1489 } 1490 } else if ((sym->st_shndx < SHN_LORESERVE) && 1491 (sym->st_shndx >= state->shnum)) { 1492 (void) fprintf(stderr, 1493 MSG_INTL(MSG_ERR_BADSYM5), state->file, 1494 state->secname, EC_WORD(symndx), 1495 demangle(symname, state->flags), sym->st_shndx); 1496 } 1497 1498 /* 1499 * If versioning is available display the 1500 * version index. If not, then use 0. 1501 */ 1502 if (state->versym) { 1503 Versym test_verndx; 1504 1505 verndx = test_verndx = state->versym->data[symndx]; 1506 gnuver = state->versym->gnu_full; 1507 1508 /* 1509 * Check to see if this is a defined symbol with a 1510 * version index that is outside the valid range for 1511 * the file. The interpretation of this depends on 1512 * the style of versioning used by the object. 1513 * 1514 * Versions >= VER_NDX_LORESERVE have special meanings, 1515 * and are exempt from this checking. 1516 * 1517 * GNU style version indexes use the top bit of the 1518 * 16-bit index value (0x8000) as the "hidden bit". 1519 * We must mask off this bit in order to compare 1520 * the version against the maximum value. 1521 */ 1522 if (gnuver) 1523 test_verndx &= ~0x8000; 1524 1525 if ((test_verndx > state->versym->max_verndx) && 1526 (verndx < VER_NDX_LORESERVE)) 1527 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADVER), 1528 state->file, state->secname, EC_WORD(symndx), 1529 EC_HALF(test_verndx), state->versym->max_verndx); 1530 } else { 1531 verndx = 0; 1532 gnuver = 0; 1533 } 1534 1535 /* 1536 * Error checking for TLS. 1537 */ 1538 type = ELF_ST_TYPE(sym->st_info); 1539 if (type == STT_TLS) { 1540 if (tshdr && 1541 (sym->st_shndx != SHN_UNDEF) && 1542 ((tshdr->sh_flags & SHF_TLS) == 0)) { 1543 (void) fprintf(stderr, 1544 MSG_INTL(MSG_ERR_BADSYM3), state->file, 1545 state->secname, EC_WORD(symndx), 1546 demangle(symname, state->flags)); 1547 } 1548 } else if ((type != STT_SECTION) && sym->st_size && 1549 tshdr && (tshdr->sh_flags & SHF_TLS)) { 1550 (void) fprintf(stderr, 1551 MSG_INTL(MSG_ERR_BADSYM4), state->file, 1552 state->secname, EC_WORD(symndx), 1553 demangle(symname, state->flags)); 1554 } 1555 1556 /* 1557 * If a symbol with non-zero size has a type that 1558 * specifies an address, then make sure the location 1559 * it references is actually contained within the 1560 * section. UNDEF symbols don't count in this case, 1561 * so we ignore them. 1562 * 1563 * The meaning of the st_value field in a symbol 1564 * depends on the type of object. For a relocatable 1565 * object, it is the offset within the section. 1566 * For sharable objects, it is the offset relative to 1567 * the base of the object, and for other types, it is 1568 * the virtual address. To get an offset within the 1569 * section for non-ET_REL files, we subtract the 1570 * base address of the section. 1571 */ 1572 if (addr_symtype[type] && (sym->st_size > 0) && 1573 (sym->st_shndx != SHN_UNDEF) && ((sym->st_shndx < SHN_LORESERVE) || 1574 (sym->st_shndx == SHN_XINDEX)) && (tshdr != NULL)) { 1575 Word v = sym->st_value; 1576 if (state->ehdr->e_type != ET_REL) 1577 v -= tshdr->sh_addr; 1578 if (((v + sym->st_size) > tshdr->sh_size)) { 1579 (void) fprintf(stderr, 1580 MSG_INTL(MSG_ERR_BADSYM6), state->file, 1581 state->secname, EC_WORD(symndx), 1582 demangle(symname, state->flags), 1583 EC_WORD(shndx), EC_XWORD(tshdr->sh_size), 1584 EC_XWORD(sym->st_value), EC_XWORD(sym->st_size)); 1585 } 1586 } 1587 1588 /* 1589 * A typical symbol table uses the sh_info field to indicate one greater 1590 * than the symbol table index of the last local symbol, STB_LOCAL. 1591 * Therefore, symbol indexes less than sh_info should have local 1592 * binding. Symbol indexes greater than, or equal to sh_info, should 1593 * have global binding. Note, we exclude UNDEF/NOTY symbols with zero 1594 * value and size, as these symbols may be the result of an mcs(1) 1595 * section deletion. 1596 */ 1597 if (info) { 1598 uchar_t bind = ELF_ST_BIND(sym->st_info); 1599 1600 if ((symndx < info) && (bind != STB_LOCAL)) { 1601 (void) fprintf(stderr, 1602 MSG_INTL(MSG_ERR_BADSYM7), state->file, 1603 state->secname, EC_WORD(symndx), 1604 demangle(symname, state->flags), EC_XWORD(info)); 1605 1606 } else if ((symndx >= info) && (bind == STB_LOCAL) && 1607 ((sym->st_shndx != SHN_UNDEF) || 1608 (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) || 1609 (sym->st_size != 0) || (sym->st_value != 0))) { 1610 (void) fprintf(stderr, 1611 MSG_INTL(MSG_ERR_BADSYM8), state->file, 1612 state->secname, EC_WORD(symndx), 1613 demangle(symname, state->flags), EC_XWORD(info)); 1614 } 1615 } 1616 1617 (void) snprintf(index, MAXNDXSIZE, 1618 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(disp_symndx)); 1619 Elf_syms_table_entry(0, ELF_DBG_ELFDUMP, index, 1620 state->ehdr->e_machine, sym, verndx, gnuver, sec, symname); 1621 } 1622 1623 /* 1624 * Search for and process any symbol tables. 1625 */ 1626 void 1627 symbols(Cache *cache, Word shnum, Ehdr *ehdr, VERSYM_STATE *versym, 1628 const char *file, uint_t flags) 1629 { 1630 SYMTBL_STATE state; 1631 Cache *_cache; 1632 Word secndx; 1633 1634 for (secndx = 1; secndx < shnum; secndx++) { 1635 Word symcnt; 1636 Shdr *shdr; 1637 1638 _cache = &cache[secndx]; 1639 shdr = _cache->c_shdr; 1640 1641 if ((shdr->sh_type != SHT_SYMTAB) && 1642 (shdr->sh_type != SHT_DYNSYM) && 1643 (shdr->sh_type != SHT_SUNW_LDYNSYM)) 1644 continue; 1645 if (!match(MATCH_F_ALL, _cache->c_name, secndx, shdr->sh_type)) 1646 continue; 1647 1648 if (!init_symtbl_state(&state, cache, shnum, secndx, ehdr, 1649 versym, file, flags)) 1650 continue; 1651 /* 1652 * Loop through the symbol tables entries. 1653 */ 1654 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 1655 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMTAB), state.secname); 1656 Elf_syms_table_title(0, ELF_DBG_ELFDUMP); 1657 1658 for (symcnt = 0; symcnt < state.symn; symcnt++) 1659 output_symbol(&state, symcnt, shdr->sh_info, symcnt, 1660 state.sym + symcnt); 1661 } 1662 } 1663 1664 /* 1665 * Search for and process any SHT_SUNW_symsort or SHT_SUNW_tlssort sections. 1666 * These sections are always associated with the .SUNW_ldynsym./.dynsym pair. 1667 */ 1668 static void 1669 sunw_sort(Cache *cache, Word shnum, Ehdr *ehdr, VERSYM_STATE *versym, 1670 const char *file, uint_t flags) 1671 { 1672 SYMTBL_STATE ldynsym_state, dynsym_state; 1673 Cache *sortcache, *symcache; 1674 Shdr *sortshdr, *symshdr; 1675 Word sortsecndx, symsecndx; 1676 Word ldynsym_cnt; 1677 Word *ndx; 1678 Word ndxn; 1679 int output_cnt = 0; 1680 Conv_inv_buf_t inv_buf; 1681 1682 for (sortsecndx = 1; sortsecndx < shnum; sortsecndx++) { 1683 1684 sortcache = &cache[sortsecndx]; 1685 sortshdr = sortcache->c_shdr; 1686 1687 if ((sortshdr->sh_type != SHT_SUNW_symsort) && 1688 (sortshdr->sh_type != SHT_SUNW_tlssort)) 1689 continue; 1690 if (!match(MATCH_F_ALL, sortcache->c_name, sortsecndx, 1691 sortshdr->sh_type)) 1692 continue; 1693 1694 /* 1695 * If the section references a SUNW_ldynsym, then we 1696 * expect to see the associated .dynsym immediately 1697 * following. If it references a .dynsym, there is no 1698 * SUNW_ldynsym. If it is any other type, then we don't 1699 * know what to do with it. 1700 */ 1701 if ((sortshdr->sh_link == 0) || (sortshdr->sh_link >= shnum)) { 1702 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 1703 file, sortcache->c_name, 1704 EC_WORD(sortshdr->sh_link)); 1705 continue; 1706 } 1707 symcache = &cache[sortshdr->sh_link]; 1708 symshdr = symcache->c_shdr; 1709 symsecndx = sortshdr->sh_link; 1710 ldynsym_cnt = 0; 1711 switch (symshdr->sh_type) { 1712 case SHT_SUNW_LDYNSYM: 1713 if (!init_symtbl_state(&ldynsym_state, cache, shnum, 1714 symsecndx, ehdr, versym, file, flags)) 1715 continue; 1716 ldynsym_cnt = ldynsym_state.symn; 1717 /* 1718 * We know that the dynsym follows immediately 1719 * after the SUNW_ldynsym, and so, should be at 1720 * (sortshdr->sh_link + 1). However, elfdump is a 1721 * diagnostic tool, so we do the full paranoid 1722 * search instead. 1723 */ 1724 for (symsecndx = 1; symsecndx < shnum; symsecndx++) { 1725 symcache = &cache[symsecndx]; 1726 symshdr = symcache->c_shdr; 1727 if (symshdr->sh_type == SHT_DYNSYM) 1728 break; 1729 } 1730 if (symsecndx >= shnum) { /* Dynsym not found! */ 1731 (void) fprintf(stderr, 1732 MSG_INTL(MSG_ERR_NODYNSYM), 1733 file, sortcache->c_name); 1734 continue; 1735 } 1736 /* Fallthrough to process associated dynsym */ 1737 /* FALLTHROUGH */ 1738 case SHT_DYNSYM: 1739 if (!init_symtbl_state(&dynsym_state, cache, shnum, 1740 symsecndx, ehdr, versym, file, flags)) 1741 continue; 1742 break; 1743 default: 1744 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADNDXSEC), 1745 file, sortcache->c_name, conv_sec_type( 1746 ehdr->e_machine, symshdr->sh_type, 0, &inv_buf)); 1747 continue; 1748 } 1749 1750 /* 1751 * Output header 1752 */ 1753 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 1754 if (ldynsym_cnt > 0) { 1755 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMSORT2), 1756 sortcache->c_name, ldynsym_state.secname, 1757 dynsym_state.secname); 1758 /* 1759 * The data for .SUNW_ldynsym and dynsym sections 1760 * is supposed to be adjacent with SUNW_ldynsym coming 1761 * first. Check, and issue a warning if it isn't so. 1762 */ 1763 if (((ldynsym_state.sym + ldynsym_state.symn) 1764 != dynsym_state.sym) && 1765 ((flags & FLG_CTL_FAKESHDR) == 0)) 1766 (void) fprintf(stderr, 1767 MSG_INTL(MSG_ERR_LDYNNOTADJ), file, 1768 ldynsym_state.secname, 1769 dynsym_state.secname); 1770 } else { 1771 dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMSORT1), 1772 sortcache->c_name, dynsym_state.secname); 1773 } 1774 Elf_syms_table_title(0, ELF_DBG_ELFDUMP); 1775 1776 /* If not first one, insert a line of whitespace */ 1777 if (output_cnt++ > 0) 1778 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 1779 1780 /* 1781 * SUNW_dynsymsort and SUNW_dyntlssort are arrays of 1782 * symbol indices. Iterate over the array entries, 1783 * dispaying the referenced symbols. 1784 */ 1785 ndxn = sortshdr->sh_size / sortshdr->sh_entsize; 1786 ndx = (Word *)sortcache->c_data->d_buf; 1787 for (; ndxn-- > 0; ndx++) { 1788 if (*ndx >= ldynsym_cnt) { 1789 Word sec_ndx = *ndx - ldynsym_cnt; 1790 1791 output_symbol(&dynsym_state, sec_ndx, 0, 1792 *ndx, dynsym_state.sym + sec_ndx); 1793 } else { 1794 output_symbol(&ldynsym_state, *ndx, 0, 1795 *ndx, ldynsym_state.sym + *ndx); 1796 } 1797 } 1798 } 1799 } 1800 1801 /* 1802 * Search for and process any relocation sections. 1803 */ 1804 static void 1805 reloc(Cache *cache, Word shnum, Ehdr *ehdr, const char *file) 1806 { 1807 Word cnt; 1808 1809 for (cnt = 1; cnt < shnum; cnt++) { 1810 Word type, symnum; 1811 Xword relndx, relnum, relsize; 1812 void *rels; 1813 Sym *syms; 1814 Cache *symsec, *strsec; 1815 Cache *_cache = &cache[cnt]; 1816 Shdr *shdr = _cache->c_shdr; 1817 char *relname = _cache->c_name; 1818 Conv_inv_buf_t inv_buf; 1819 1820 if (((type = shdr->sh_type) != SHT_RELA) && 1821 (type != SHT_REL)) 1822 continue; 1823 if (!match(MATCH_F_ALL, relname, cnt, type)) 1824 continue; 1825 1826 /* 1827 * Decide entry size. 1828 */ 1829 if (((relsize = shdr->sh_entsize) == 0) || 1830 (relsize > shdr->sh_size)) { 1831 if (type == SHT_RELA) 1832 relsize = sizeof (Rela); 1833 else 1834 relsize = sizeof (Rel); 1835 } 1836 1837 /* 1838 * Determine the number of relocations available. 1839 */ 1840 if (shdr->sh_size == 0) { 1841 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 1842 file, relname); 1843 continue; 1844 } 1845 if (_cache->c_data == NULL) 1846 continue; 1847 1848 rels = _cache->c_data->d_buf; 1849 relnum = shdr->sh_size / relsize; 1850 1851 /* 1852 * Get the data buffer for the associated symbol table and 1853 * string table. 1854 */ 1855 if (stringtbl(cache, 1, cnt, shnum, file, 1856 &symnum, &symsec, &strsec) == 0) 1857 continue; 1858 1859 syms = symsec->c_data->d_buf; 1860 1861 /* 1862 * Loop through the relocation entries. 1863 */ 1864 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 1865 dbg_print(0, MSG_INTL(MSG_ELF_SCN_RELOC), _cache->c_name); 1866 Elf_reloc_title(0, ELF_DBG_ELFDUMP, type); 1867 1868 for (relndx = 0; relndx < relnum; relndx++, 1869 rels = (void *)((char *)rels + relsize)) { 1870 Half mach = ehdr->e_machine; 1871 char section[BUFSIZ]; 1872 const char *symname; 1873 Word symndx, reltype; 1874 Rela *rela; 1875 Rel *rel; 1876 1877 /* 1878 * Unravel the relocation and determine the symbol with 1879 * which this relocation is associated. 1880 */ 1881 if (type == SHT_RELA) { 1882 rela = (Rela *)rels; 1883 symndx = ELF_R_SYM(rela->r_info); 1884 reltype = ELF_R_TYPE(rela->r_info, mach); 1885 } else { 1886 rel = (Rel *)rels; 1887 symndx = ELF_R_SYM(rel->r_info); 1888 reltype = ELF_R_TYPE(rel->r_info, mach); 1889 } 1890 1891 symname = relsymname(cache, _cache, strsec, symndx, 1892 symnum, relndx, syms, section, BUFSIZ, file); 1893 1894 /* 1895 * A zero symbol index is only valid for a few 1896 * relocations. 1897 */ 1898 if (symndx == 0) { 1899 int badrel = 0; 1900 1901 if ((mach == EM_SPARC) || 1902 (mach == EM_SPARC32PLUS) || 1903 (mach == EM_SPARCV9)) { 1904 if ((reltype != R_SPARC_NONE) && 1905 (reltype != R_SPARC_REGISTER) && 1906 (reltype != R_SPARC_RELATIVE)) 1907 badrel++; 1908 } else if (mach == EM_386) { 1909 if ((reltype != R_386_NONE) && 1910 (reltype != R_386_RELATIVE)) 1911 badrel++; 1912 } else if (mach == EM_AMD64) { 1913 if ((reltype != R_AMD64_NONE) && 1914 (reltype != R_AMD64_RELATIVE)) 1915 badrel++; 1916 } 1917 1918 if (badrel) { 1919 (void) fprintf(stderr, 1920 MSG_INTL(MSG_ERR_BADREL1), file, 1921 conv_reloc_type(mach, reltype, 1922 0, &inv_buf)); 1923 } 1924 } 1925 1926 Elf_reloc_entry_1(0, ELF_DBG_ELFDUMP, 1927 MSG_ORIG(MSG_STR_EMPTY), ehdr->e_machine, type, 1928 rels, relname, symname, 0); 1929 } 1930 } 1931 } 1932 1933 1934 /* 1935 * This value controls which test dyn_test() performs. 1936 */ 1937 typedef enum { DYN_TEST_ADDR, DYN_TEST_SIZE, DYN_TEST_ENTSIZE } dyn_test_t; 1938 1939 /* 1940 * Used by dynamic() to compare the value of a dynamic element against 1941 * the starting address of the section it references. 1942 * 1943 * entry: 1944 * test_type - Specify which dyn item is being tested. 1945 * sh_type - SHT_* type value for required section. 1946 * sec_cache - Cache entry for section, or NULL if the object lacks 1947 * a section of this type. 1948 * dyn - Dyn entry to be tested 1949 * dynsec_cnt - # of dynamic section being examined. The first 1950 * dynamic section is 1, the next is 2, and so on... 1951 * ehdr - ELF header for file 1952 * file - Name of file 1953 */ 1954 static void 1955 dyn_test(dyn_test_t test_type, Word sh_type, Cache *sec_cache, Dyn *dyn, 1956 Word dynsec_cnt, Ehdr *ehdr, const char *file) 1957 { 1958 Conv_inv_buf_t buf1, buf2; 1959 1960 /* 1961 * These tests are based around the implicit assumption that 1962 * there is only one dynamic section in an object, and also only 1963 * one of the sections it references. We have therefore gathered 1964 * all of the necessary information to test this in a single pass 1965 * over the section headers, which is very efficient. We are not 1966 * aware of any case where more than one dynamic section would 1967 * be meaningful in an ELF object, so this is a reasonable solution. 1968 * 1969 * To test multiple dynamic sections correctly would be more 1970 * expensive in code and time. We would have to build a data structure 1971 * containing all the dynamic elements. Then, we would use the address 1972 * to locate the section it references and ensure the section is of 1973 * the right type and that the address in the dynamic element is 1974 * to the start of the section. Then, we could check the size and 1975 * entsize values against those same sections. This is O(n^2), and 1976 * also complicated. 1977 * 1978 * In the highly unlikely case that there is more than one dynamic 1979 * section, we only test the first one, and simply allow the values 1980 * of the subsequent one to be displayed unchallenged. 1981 */ 1982 if (dynsec_cnt != 1) 1983 return; 1984 1985 /* 1986 * A DT_ item that references a section address should always find 1987 * the section in the file. 1988 */ 1989 if (sec_cache == NULL) { 1990 const char *name; 1991 1992 /* 1993 * Supply section names instead of section types for 1994 * things that reference progbits so that the error 1995 * message will make more sense. 1996 */ 1997 switch (dyn->d_tag) { 1998 case DT_INIT: 1999 name = MSG_ORIG(MSG_ELF_INIT); 2000 break; 2001 case DT_FINI: 2002 name = MSG_ORIG(MSG_ELF_FINI); 2003 break; 2004 default: 2005 name = conv_sec_type(ehdr->e_machine, sh_type, 2006 0, &buf1); 2007 break; 2008 } 2009 (void) fprintf(stderr, MSG_INTL(MSG_ERR_DYNNOBCKSEC), file, 2010 name, conv_dyn_tag(dyn->d_tag, ehdr->e_machine, 0, &buf2)); 2011 return; 2012 } 2013 2014 2015 switch (test_type) { 2016 case DYN_TEST_ADDR: 2017 /* The section address should match the DT_ item value */ 2018 if (dyn->d_un.d_val != sec_cache->c_shdr->sh_addr) 2019 (void) fprintf(stderr, 2020 MSG_INTL(MSG_ERR_DYNBADADDR), file, 2021 conv_dyn_tag(dyn->d_tag, ehdr->e_machine, 0, &buf1), 2022 EC_ADDR(dyn->d_un.d_val), sec_cache->c_ndx, 2023 sec_cache->c_name, 2024 EC_ADDR(sec_cache->c_shdr->sh_addr)); 2025 break; 2026 2027 case DYN_TEST_SIZE: 2028 /* The section size should match the DT_ item value */ 2029 if (dyn->d_un.d_val != sec_cache->c_shdr->sh_size) 2030 (void) fprintf(stderr, 2031 MSG_INTL(MSG_ERR_DYNBADSIZE), file, 2032 conv_dyn_tag(dyn->d_tag, ehdr->e_machine, 0, &buf1), 2033 EC_XWORD(dyn->d_un.d_val), 2034 sec_cache->c_ndx, sec_cache->c_name, 2035 EC_XWORD(sec_cache->c_shdr->sh_size)); 2036 break; 2037 2038 case DYN_TEST_ENTSIZE: 2039 /* The sh_entsize value should match the DT_ item value */ 2040 if (dyn->d_un.d_val != sec_cache->c_shdr->sh_entsize) 2041 (void) fprintf(stderr, 2042 MSG_INTL(MSG_ERR_DYNBADENTSIZE), file, 2043 conv_dyn_tag(dyn->d_tag, ehdr->e_machine, 0, &buf1), 2044 EC_XWORD(dyn->d_un.d_val), 2045 sec_cache->c_ndx, sec_cache->c_name, 2046 EC_XWORD(sec_cache->c_shdr->sh_entsize)); 2047 break; 2048 } 2049 } 2050 2051 2052 /* 2053 * There are some DT_ entries that have corresponding symbols 2054 * (e.g. DT_INIT and _init). It is expected that these items will 2055 * both have the same value if both are present. This routine 2056 * examines the well known symbol tables for such symbols and 2057 * issues warnings for any that don't match. 2058 * 2059 * entry: 2060 * dyn - Dyn entry to be tested 2061 * symname - Name of symbol that corresponds to dyn 2062 * symtab_cache, dynsym_cache, ldynsym_cache - Symbol tables to check 2063 * cache - Cache of all section headers 2064 * shnum - # of sections in cache 2065 * ehdr - ELF header for file 2066 * file - Name of file 2067 */ 2068 static void 2069 dyn_symtest(Dyn *dyn, const char *symname, Cache *symtab_cache, 2070 Cache *dynsym_cache, Cache *ldynsym_cache, Cache *cache, 2071 Word shnum, Ehdr *ehdr, const char *file) 2072 { 2073 Conv_inv_buf_t buf; 2074 int i; 2075 Sym *sym; 2076 Cache *_cache; 2077 2078 for (i = 0; i < 3; i++) { 2079 switch (i) { 2080 case 0: 2081 _cache = symtab_cache; 2082 break; 2083 case 1: 2084 _cache = dynsym_cache; 2085 break; 2086 case 2: 2087 _cache = ldynsym_cache; 2088 break; 2089 } 2090 2091 if ((_cache != NULL) && 2092 symlookup(symname, cache, shnum, &sym, _cache, file) && 2093 (sym->st_value != dyn->d_un.d_val)) 2094 (void) fprintf(stderr, MSG_INTL(MSG_ERR_DYNSYMVAL), 2095 file, _cache->c_name, 2096 conv_dyn_tag(dyn->d_tag, ehdr->e_machine, 0, &buf), 2097 symname, EC_ADDR(sym->st_value)); 2098 } 2099 } 2100 2101 2102 /* 2103 * Search for and process a .dynamic section. 2104 */ 2105 static void 2106 dynamic(Cache *cache, Word shnum, Ehdr *ehdr, const char *file) 2107 { 2108 struct { 2109 Cache *symtab; 2110 Cache *dynstr; 2111 Cache *dynsym; 2112 Cache *hash; 2113 Cache *fini; 2114 Cache *fini_array; 2115 Cache *init; 2116 Cache *init_array; 2117 Cache *preinit_array; 2118 Cache *rel; 2119 Cache *rela; 2120 Cache *sunw_cap; 2121 Cache *sunw_ldynsym; 2122 Cache *sunw_move; 2123 Cache *sunw_syminfo; 2124 Cache *sunw_symsort; 2125 Cache *sunw_tlssort; 2126 Cache *sunw_verdef; 2127 Cache *sunw_verneed; 2128 Cache *sunw_versym; 2129 } sec; 2130 Word dynsec_ndx; 2131 Word dynsec_num; 2132 int dynsec_cnt; 2133 Word cnt; 2134 2135 /* 2136 * Make a pass over all the sections, gathering section information 2137 * we'll need below. 2138 */ 2139 dynsec_num = 0; 2140 bzero(&sec, sizeof (sec)); 2141 for (cnt = 1; cnt < shnum; cnt++) { 2142 Cache *_cache = &cache[cnt]; 2143 2144 switch (_cache->c_shdr->sh_type) { 2145 case SHT_DYNAMIC: 2146 if (dynsec_num == 0) { 2147 dynsec_ndx = cnt; 2148 2149 /* Does it have a valid string table? */ 2150 (void) stringtbl(cache, 0, cnt, shnum, file, 2151 0, 0, &sec.dynstr); 2152 } 2153 dynsec_num++; 2154 break; 2155 2156 2157 case SHT_PROGBITS: 2158 /* 2159 * We want to detect the .init and .fini sections, 2160 * if present. These are SHT_PROGBITS, so all we 2161 * have to go on is the section name. Normally comparing 2162 * names is a bad idea, but there are some special 2163 * names (i.e. .init/.fini/.interp) that are very 2164 * difficult to use in any other context, and for 2165 * these symbols, we do the heuristic match. 2166 */ 2167 if (strcmp(_cache->c_name, 2168 MSG_ORIG(MSG_ELF_INIT)) == 0) { 2169 if (sec.init == NULL) 2170 sec.init = _cache; 2171 } else if (strcmp(_cache->c_name, 2172 MSG_ORIG(MSG_ELF_FINI)) == 0) { 2173 if (sec.fini == NULL) 2174 sec.fini = _cache; 2175 } 2176 break; 2177 2178 case SHT_REL: 2179 /* 2180 * We want the SHT_REL section with the lowest 2181 * offset. The linker gathers them together, 2182 * and puts the address of the first one 2183 * into the DT_REL dynamic element. 2184 */ 2185 if ((sec.rel == NULL) || 2186 (_cache->c_shdr->sh_offset < 2187 sec.rel->c_shdr->sh_offset)) 2188 sec.rel = _cache; 2189 break; 2190 2191 case SHT_RELA: 2192 /* RELA is handled just like RELA above */ 2193 if ((sec.rela == NULL) || 2194 (_cache->c_shdr->sh_offset < 2195 sec.rela->c_shdr->sh_offset)) 2196 sec.rela = _cache; 2197 break; 2198 2199 /* 2200 * The GRAB macro is used for the simple case in which 2201 * we simply grab the first section of the desired type. 2202 */ 2203 #define GRAB(_sec_type, _sec_field) \ 2204 case _sec_type: \ 2205 if (sec._sec_field == NULL) \ 2206 sec._sec_field = _cache; \ 2207 break 2208 GRAB(SHT_SYMTAB, symtab); 2209 GRAB(SHT_DYNSYM, dynsym); 2210 GRAB(SHT_FINI_ARRAY, fini_array); 2211 GRAB(SHT_HASH, hash); 2212 GRAB(SHT_INIT_ARRAY, init_array); 2213 GRAB(SHT_SUNW_move, sunw_move); 2214 GRAB(SHT_PREINIT_ARRAY, preinit_array); 2215 GRAB(SHT_SUNW_cap, sunw_cap); 2216 GRAB(SHT_SUNW_LDYNSYM, sunw_ldynsym); 2217 GRAB(SHT_SUNW_syminfo, sunw_syminfo); 2218 GRAB(SHT_SUNW_symsort, sunw_symsort); 2219 GRAB(SHT_SUNW_tlssort, sunw_tlssort); 2220 GRAB(SHT_SUNW_verdef, sunw_verdef); 2221 GRAB(SHT_SUNW_verneed, sunw_verneed); 2222 GRAB(SHT_SUNW_versym, sunw_versym); 2223 #undef GRAB 2224 } 2225 } 2226 2227 /* 2228 * If no dynamic section, return immediately. If more than one 2229 * dynamic section, then something odd is going on and an error 2230 * is in order, but then continue on and display them all. 2231 */ 2232 if (dynsec_num == 0) 2233 return; 2234 if (dynsec_num > 1) 2235 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTDYN), 2236 file, EC_WORD(dynsec_num)); 2237 2238 2239 dynsec_cnt = 0; 2240 for (cnt = dynsec_ndx; (cnt < shnum) && (dynsec_cnt < dynsec_num); 2241 cnt++) { 2242 Dyn *dyn; 2243 ulong_t numdyn; 2244 int ndx, end_ndx; 2245 Cache *_cache = &cache[cnt], *strsec; 2246 Shdr *shdr = _cache->c_shdr; 2247 int dumped = 0; 2248 2249 if (shdr->sh_type != SHT_DYNAMIC) 2250 continue; 2251 dynsec_cnt++; 2252 2253 /* 2254 * Verify the associated string table section. 2255 */ 2256 if (stringtbl(cache, 0, cnt, shnum, file, 0, 0, &strsec) == 0) 2257 continue; 2258 2259 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) { 2260 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 2261 file, _cache->c_name); 2262 continue; 2263 } 2264 if (_cache->c_data == NULL) 2265 continue; 2266 2267 numdyn = shdr->sh_size / shdr->sh_entsize; 2268 dyn = (Dyn *)_cache->c_data->d_buf; 2269 2270 /* 2271 * We expect the REL/RELA entries to reference the reloc 2272 * section with the lowest address. However, this is 2273 * not true for dumped objects. Detect if this object has 2274 * been dumped so that we can skip the reloc address test 2275 * in that case. 2276 */ 2277 for (ndx = 0; ndx < numdyn; dyn++, ndx++) { 2278 if (dyn->d_tag == DT_FLAGS_1) { 2279 dumped = (dyn->d_un.d_val & DF_1_CONFALT) != 0; 2280 break; 2281 } 2282 } 2283 dyn = (Dyn *)_cache->c_data->d_buf; 2284 2285 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 2286 dbg_print(0, MSG_INTL(MSG_ELF_SCN_DYNAMIC), _cache->c_name); 2287 2288 Elf_dyn_title(0); 2289 2290 for (ndx = 0; ndx < numdyn; dyn++, ndx++) { 2291 union { 2292 Conv_inv_buf_t inv; 2293 Conv_dyn_flag_buf_t flag; 2294 Conv_dyn_flag1_buf_t flag1; 2295 Conv_dyn_posflag1_buf_t posflag1; 2296 Conv_dyn_feature1_buf_t feature1; 2297 } c_buf; 2298 const char *name = NULL; 2299 2300 /* 2301 * Print the information numerically, and if possible 2302 * as a string. If a string is available, name is 2303 * set to reference it. 2304 * 2305 * Also, take this opportunity to sanity check 2306 * the values of DT elements. In the code above, 2307 * we gathered information on sections that are 2308 * referenced by the dynamic section. Here, we 2309 * compare the attributes of those sections to 2310 * the DT_ items that reference them and report 2311 * on inconsistencies. 2312 * 2313 * Things not currently tested that could be improved 2314 * in later revisions include: 2315 * - We don't check PLT or GOT related items 2316 * - We don't handle computing the lengths of 2317 * relocation arrays. To handle this 2318 * requires examining data that spans 2319 * across sections, in a contiguous span 2320 * within a single segment. 2321 * - DT_VERDEFNUM and DT_VERNEEDNUM can't be 2322 * verified without parsing the sections. 2323 * - We don't handle DT_SUNW_SYMSZ, which would 2324 * be the sum of the lengths of .dynsym and 2325 * .SUNW_ldynsym 2326 * - DT_SUNW_STRPAD can't be verified other than 2327 * to check that it's not larger than 2328 * the string table. 2329 * - Some items come in "all or none" clusters 2330 * that give an address, element size, 2331 * and data length in bytes. We don't 2332 * verify that there are no missing items 2333 * in such groups. 2334 */ 2335 switch (dyn->d_tag) { 2336 case DT_NULL: 2337 /* 2338 * Special case: DT_NULLs can come in groups 2339 * that we prefer to reduce to a single line. 2340 */ 2341 end_ndx = ndx; 2342 while ((end_ndx < (numdyn - 1)) && 2343 ((dyn + 1)->d_tag == DT_NULL)) { 2344 dyn++; 2345 end_ndx++; 2346 } 2347 Elf_dyn_null_entry(0, dyn, ndx, end_ndx); 2348 ndx = end_ndx; 2349 continue; 2350 2351 /* 2352 * String items all reference the dynstr. The string() 2353 * function does the necessary sanity checking. 2354 */ 2355 case DT_NEEDED: 2356 case DT_SONAME: 2357 case DT_FILTER: 2358 case DT_AUXILIARY: 2359 case DT_CONFIG: 2360 case DT_RPATH: 2361 case DT_RUNPATH: 2362 case DT_USED: 2363 case DT_DEPAUDIT: 2364 case DT_AUDIT: 2365 case DT_SUNW_AUXILIARY: 2366 case DT_SUNW_FILTER: 2367 name = string(_cache, ndx, strsec, 2368 file, dyn->d_un.d_ptr); 2369 break; 2370 2371 case DT_FLAGS: 2372 name = conv_dyn_flag(dyn->d_un.d_val, 2373 0, &c_buf.flag); 2374 break; 2375 case DT_FLAGS_1: 2376 name = conv_dyn_flag1(dyn->d_un.d_val, 0, 2377 &c_buf.flag1); 2378 break; 2379 case DT_POSFLAG_1: 2380 name = conv_dyn_posflag1(dyn->d_un.d_val, 0, 2381 &c_buf.posflag1); 2382 break; 2383 case DT_FEATURE_1: 2384 name = conv_dyn_feature1(dyn->d_un.d_val, 0, 2385 &c_buf.feature1); 2386 break; 2387 case DT_DEPRECATED_SPARC_REGISTER: 2388 name = MSG_INTL(MSG_STR_DEPRECATED); 2389 break; 2390 2391 case DT_SUNW_LDMACH: 2392 name = conv_ehdr_mach((Half)dyn->d_un.d_val, 0, 2393 &c_buf.inv); 2394 break; 2395 2396 /* 2397 * Cases below this point are strictly sanity checking, 2398 * and do not generate a name string. The TEST_ macros 2399 * are used to hide the boilerplate arguments neeeded 2400 * by dyn_test(). 2401 */ 2402 #define TEST_ADDR(_sh_type, _sec_field) \ 2403 dyn_test(DYN_TEST_ADDR, _sh_type, \ 2404 sec._sec_field, dyn, dynsec_cnt, ehdr, file) 2405 #define TEST_SIZE(_sh_type, _sec_field) \ 2406 dyn_test(DYN_TEST_SIZE, _sh_type, \ 2407 sec._sec_field, dyn, dynsec_cnt, ehdr, file) 2408 #define TEST_ENTSIZE(_sh_type, _sec_field) \ 2409 dyn_test(DYN_TEST_ENTSIZE, _sh_type, \ 2410 sec._sec_field, dyn, dynsec_cnt, ehdr, file) 2411 2412 case DT_FINI: 2413 dyn_symtest(dyn, MSG_ORIG(MSG_SYM_FINI), 2414 sec.symtab, sec.dynsym, sec.sunw_ldynsym, 2415 cache, shnum, ehdr, file); 2416 TEST_ADDR(SHT_PROGBITS, fini); 2417 break; 2418 2419 case DT_FINI_ARRAY: 2420 TEST_ADDR(SHT_FINI_ARRAY, fini_array); 2421 break; 2422 2423 case DT_FINI_ARRAYSZ: 2424 TEST_SIZE(SHT_FINI_ARRAY, fini_array); 2425 break; 2426 2427 case DT_HASH: 2428 TEST_ADDR(SHT_HASH, hash); 2429 break; 2430 2431 case DT_INIT: 2432 dyn_symtest(dyn, MSG_ORIG(MSG_SYM_INIT), 2433 sec.symtab, sec.dynsym, sec.sunw_ldynsym, 2434 cache, shnum, ehdr, file); 2435 TEST_ADDR(SHT_PROGBITS, init); 2436 break; 2437 2438 case DT_INIT_ARRAY: 2439 TEST_ADDR(SHT_INIT_ARRAY, init_array); 2440 break; 2441 2442 case DT_INIT_ARRAYSZ: 2443 TEST_SIZE(SHT_INIT_ARRAY, init_array); 2444 break; 2445 2446 case DT_MOVEENT: 2447 TEST_ENTSIZE(SHT_SUNW_move, sunw_move); 2448 break; 2449 2450 case DT_MOVESZ: 2451 TEST_SIZE(SHT_SUNW_move, sunw_move); 2452 break; 2453 2454 case DT_MOVETAB: 2455 TEST_ADDR(SHT_SUNW_move, sunw_move); 2456 break; 2457 2458 case DT_PREINIT_ARRAY: 2459 TEST_ADDR(SHT_PREINIT_ARRAY, preinit_array); 2460 break; 2461 2462 case DT_PREINIT_ARRAYSZ: 2463 TEST_SIZE(SHT_PREINIT_ARRAY, preinit_array); 2464 break; 2465 2466 case DT_REL: 2467 if (!dumped) 2468 TEST_ADDR(SHT_REL, rel); 2469 break; 2470 2471 case DT_RELENT: 2472 TEST_ENTSIZE(SHT_REL, rel); 2473 break; 2474 2475 case DT_RELA: 2476 if (!dumped) 2477 TEST_ADDR(SHT_RELA, rela); 2478 break; 2479 2480 case DT_RELAENT: 2481 TEST_ENTSIZE(SHT_RELA, rela); 2482 break; 2483 2484 case DT_STRTAB: 2485 TEST_ADDR(SHT_STRTAB, dynstr); 2486 break; 2487 2488 case DT_STRSZ: 2489 TEST_SIZE(SHT_STRTAB, dynstr); 2490 break; 2491 2492 case DT_SUNW_CAP: 2493 TEST_ADDR(SHT_SUNW_cap, sunw_cap); 2494 break; 2495 2496 case DT_SUNW_SYMTAB: 2497 TEST_ADDR(SHT_SUNW_LDYNSYM, sunw_ldynsym); 2498 break; 2499 2500 case DT_SYMENT: 2501 TEST_ENTSIZE(SHT_DYNSYM, dynsym); 2502 break; 2503 2504 case DT_SYMINENT: 2505 TEST_ENTSIZE(SHT_SUNW_syminfo, sunw_syminfo); 2506 break; 2507 2508 case DT_SYMINFO: 2509 TEST_ADDR(SHT_SUNW_syminfo, sunw_syminfo); 2510 break; 2511 2512 case DT_SYMINSZ: 2513 TEST_SIZE(SHT_SUNW_syminfo, sunw_syminfo); 2514 break; 2515 2516 case DT_SYMTAB: 2517 TEST_ADDR(SHT_DYNSYM, dynsym); 2518 break; 2519 2520 case DT_SUNW_SORTENT: 2521 /* 2522 * This entry is related to both the symsort and 2523 * tlssort sections. 2524 */ 2525 { 2526 int test_tls = 2527 (sec.sunw_tlssort != NULL); 2528 int test_sym = 2529 (sec.sunw_symsort != NULL) || 2530 !test_tls; 2531 if (test_sym) 2532 TEST_ENTSIZE(SHT_SUNW_symsort, 2533 sunw_symsort); 2534 if (test_tls) 2535 TEST_ENTSIZE(SHT_SUNW_tlssort, 2536 sunw_tlssort); 2537 } 2538 break; 2539 2540 2541 case DT_SUNW_SYMSORT: 2542 TEST_ADDR(SHT_SUNW_symsort, sunw_symsort); 2543 break; 2544 2545 case DT_SUNW_SYMSORTSZ: 2546 TEST_SIZE(SHT_SUNW_symsort, sunw_symsort); 2547 break; 2548 2549 case DT_SUNW_TLSSORT: 2550 TEST_ADDR(SHT_SUNW_tlssort, sunw_tlssort); 2551 break; 2552 2553 case DT_SUNW_TLSSORTSZ: 2554 TEST_SIZE(SHT_SUNW_tlssort, sunw_tlssort); 2555 break; 2556 2557 case DT_VERDEF: 2558 TEST_ADDR(SHT_SUNW_verdef, sunw_verdef); 2559 break; 2560 2561 case DT_VERNEED: 2562 TEST_ADDR(SHT_SUNW_verneed, sunw_verneed); 2563 break; 2564 2565 case DT_VERSYM: 2566 TEST_ADDR(SHT_SUNW_versym, sunw_versym); 2567 break; 2568 #undef TEST_ADDR 2569 #undef TEST_SIZE 2570 #undef TEST_ENTSIZE 2571 } 2572 2573 if (name == NULL) 2574 name = MSG_ORIG(MSG_STR_EMPTY); 2575 Elf_dyn_entry(0, dyn, ndx, name, ehdr->e_machine); 2576 } 2577 } 2578 } 2579 2580 /* 2581 * Search for and process a MOVE section. 2582 */ 2583 static void 2584 move(Cache *cache, Word shnum, const char *file, uint_t flags) 2585 { 2586 Word cnt; 2587 const char *fmt = NULL; 2588 2589 for (cnt = 1; cnt < shnum; cnt++) { 2590 Word movenum, symnum, ndx; 2591 Sym *syms; 2592 Cache *_cache = &cache[cnt]; 2593 Shdr *shdr = _cache->c_shdr; 2594 Cache *symsec, *strsec; 2595 Move *move; 2596 2597 if (shdr->sh_type != SHT_SUNW_move) 2598 continue; 2599 if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type)) 2600 continue; 2601 2602 /* 2603 * Determine the move data and number. 2604 */ 2605 if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) { 2606 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 2607 file, _cache->c_name); 2608 continue; 2609 } 2610 if (_cache->c_data == NULL) 2611 continue; 2612 2613 move = (Move *)_cache->c_data->d_buf; 2614 movenum = shdr->sh_size / shdr->sh_entsize; 2615 2616 /* 2617 * Get the data buffer for the associated symbol table and 2618 * string table. 2619 */ 2620 if (stringtbl(cache, 1, cnt, shnum, file, 2621 &symnum, &symsec, &strsec) == 0) 2622 return; 2623 2624 syms = (Sym *)symsec->c_data->d_buf; 2625 2626 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 2627 dbg_print(0, MSG_INTL(MSG_ELF_SCN_MOVE), _cache->c_name); 2628 dbg_print(0, MSG_INTL(MSG_MOVE_TITLE)); 2629 2630 if (fmt == NULL) 2631 fmt = MSG_INTL(MSG_MOVE_ENTRY); 2632 2633 for (ndx = 0; ndx < movenum; move++, ndx++) { 2634 const char *symname; 2635 char index[MAXNDXSIZE], section[BUFSIZ]; 2636 Word symndx, shndx; 2637 Sym *sym; 2638 2639 /* 2640 * Check for null entries 2641 */ 2642 if ((move->m_info == 0) && (move->m_value == 0) && 2643 (move->m_poffset == 0) && (move->m_repeat == 0) && 2644 (move->m_stride == 0)) { 2645 dbg_print(0, fmt, MSG_ORIG(MSG_STR_EMPTY), 2646 EC_XWORD(move->m_poffset), 0, 0, 0, 2647 EC_LWORD(0), MSG_ORIG(MSG_STR_EMPTY)); 2648 continue; 2649 } 2650 if (((symndx = ELF_M_SYM(move->m_info)) == 0) || 2651 (symndx >= symnum)) { 2652 (void) fprintf(stderr, 2653 MSG_INTL(MSG_ERR_BADMINFO), file, 2654 _cache->c_name, EC_XWORD(move->m_info)); 2655 2656 (void) snprintf(index, MAXNDXSIZE, 2657 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(symndx)); 2658 dbg_print(0, fmt, index, 2659 EC_XWORD(move->m_poffset), 2660 ELF_M_SIZE(move->m_info), move->m_repeat, 2661 move->m_stride, move->m_value, 2662 MSG_INTL(MSG_STR_UNKNOWN)); 2663 continue; 2664 } 2665 2666 symname = relsymname(cache, _cache, strsec, 2667 symndx, symnum, ndx, syms, section, BUFSIZ, file); 2668 sym = (Sym *)(syms + symndx); 2669 2670 /* 2671 * Additional sanity check. 2672 */ 2673 shndx = sym->st_shndx; 2674 if (!((shndx == SHN_COMMON) || 2675 (((shndx >= 1) && (shndx <= shnum)) && 2676 (cache[shndx].c_shdr)->sh_type == SHT_NOBITS))) { 2677 (void) fprintf(stderr, 2678 MSG_INTL(MSG_ERR_BADSYM2), file, 2679 _cache->c_name, EC_WORD(symndx), 2680 demangle(symname, flags)); 2681 } 2682 2683 (void) snprintf(index, MAXNDXSIZE, 2684 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(symndx)); 2685 dbg_print(0, fmt, index, EC_XWORD(move->m_poffset), 2686 ELF_M_SIZE(move->m_info), move->m_repeat, 2687 move->m_stride, move->m_value, 2688 demangle(symname, flags)); 2689 } 2690 } 2691 } 2692 2693 /* 2694 * Callback function for use with conv_str_to_c_literal() below. 2695 */ 2696 /*ARGSUSED2*/ 2697 static void 2698 c_literal_cb(const void *ptr, size_t size, void *uvalue) 2699 { 2700 (void) fwrite(ptr, size, 1, stdout); 2701 } 2702 2703 /* 2704 * Traverse a note section analyzing each note information block. 2705 * The data buffers size is used to validate references before they are made, 2706 * and is decremented as each element is processed. 2707 */ 2708 void 2709 note_entry(Cache *cache, Word *data, size_t size, Ehdr *ehdr, const char *file) 2710 { 2711 size_t bsize = size; 2712 int cnt = 0; 2713 int is_corenote; 2714 int do_swap; 2715 Conv_inv_buf_t inv_buf; 2716 2717 do_swap = _elf_sys_encoding() != ehdr->e_ident[EI_DATA]; 2718 2719 /* 2720 * Print out a single `note' information block. 2721 */ 2722 while (size > 0) { 2723 size_t namesz, descsz, type, pad, noteoff; 2724 2725 noteoff = bsize - size; 2726 /* 2727 * Make sure we can at least reference the 3 initial entries 2728 * (4-byte words) of the note information block. 2729 */ 2730 if (size >= (sizeof (Word) * 3)) 2731 size -= (sizeof (Word) * 3); 2732 else { 2733 (void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADDATASZ), 2734 file, cache->c_name, EC_WORD(noteoff)); 2735 return; 2736 } 2737 2738 /* 2739 * Make sure any specified name string can be referenced. 2740 */ 2741 if ((namesz = *data++) != 0) { 2742 if (size >= namesz) 2743 size -= namesz; 2744 else { 2745 (void) fprintf(stderr, 2746 MSG_INTL(MSG_NOTE_BADNMSZ), file, 2747 cache->c_name, EC_WORD(noteoff), 2748 EC_WORD(namesz)); 2749 return; 2750 } 2751 } 2752 2753 /* 2754 * Make sure any specified descriptor can be referenced. 2755 */ 2756 if ((descsz = *data++) != 0) { 2757 /* 2758 * If namesz isn't a 4-byte multiple, account for any 2759 * padding that must exist before the descriptor. 2760 */ 2761 if ((pad = (namesz & (sizeof (Word) - 1))) != 0) { 2762 pad = sizeof (Word) - pad; 2763 size -= pad; 2764 } 2765 if (size >= descsz) 2766 size -= descsz; 2767 else { 2768 (void) fprintf(stderr, 2769 MSG_INTL(MSG_NOTE_BADDESZ), file, 2770 cache->c_name, EC_WORD(noteoff), 2771 EC_WORD(namesz)); 2772 return; 2773 } 2774 } 2775 2776 type = *data++; 2777 2778 /* 2779 * Is this a Solaris core note? Such notes all have 2780 * the name "CORE". 2781 */ 2782 is_corenote = (ehdr->e_type == ET_CORE) && 2783 (namesz == (MSG_STR_CORE_SIZE + 1)) && 2784 (strncmp(MSG_ORIG(MSG_STR_CORE), (char *)data, 2785 MSG_STR_CORE_SIZE + 1) == 0); 2786 2787 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 2788 dbg_print(0, MSG_INTL(MSG_FMT_NOTEENTNDX), EC_WORD(cnt)); 2789 cnt++; 2790 dbg_print(0, MSG_ORIG(MSG_NOTE_NAMESZ), EC_WORD(namesz)); 2791 dbg_print(0, MSG_ORIG(MSG_NOTE_DESCSZ), EC_WORD(descsz)); 2792 2793 if (is_corenote) 2794 dbg_print(0, MSG_ORIG(MSG_NOTE_TYPE_STR), 2795 conv_cnote_type(type, 0, &inv_buf)); 2796 else 2797 dbg_print(0, MSG_ORIG(MSG_NOTE_TYPE), EC_WORD(type)); 2798 if (namesz) { 2799 char *name = (char *)data; 2800 2801 2802 dbg_print(0, MSG_ORIG(MSG_NOTE_NAME)); 2803 /* 2804 * The name string can contain embedded 'null' 2805 * bytes and/or unprintable characters. Also, 2806 * the final NULL is documented in the ELF ABI 2807 * as being included in the namesz. So, display 2808 * the name using C literal string notation, and 2809 * include the terminating NULL in the output. 2810 * We don't show surrounding double quotes, as 2811 * that implies the termination that we are showing 2812 * explicitly. 2813 */ 2814 (void) fwrite(MSG_ORIG(MSG_STR_8SP), 2815 MSG_STR_8SP_SIZE, 1, stdout); 2816 conv_str_to_c_literal(name, namesz, c_literal_cb, NULL); 2817 name = name + ((namesz + (sizeof (Word) - 1)) & 2818 ~(sizeof (Word) - 1)); 2819 /* LINTED */ 2820 data = (Word *)name; 2821 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 2822 } 2823 2824 /* 2825 * If multiple information blocks exist within a .note section 2826 * account for any padding that must exist before the next 2827 * information block. 2828 */ 2829 if ((pad = (descsz & (sizeof (Word) - 1))) != 0) { 2830 pad = sizeof (Word) - pad; 2831 if (size > pad) 2832 size -= pad; 2833 } 2834 2835 if (descsz) { 2836 int hexdump = 1; 2837 const char *desc = (const char *)data; 2838 2839 /* 2840 * If this is a core note, let the corenote() 2841 * function handle it. 2842 */ 2843 if (is_corenote) { 2844 /* We only issue the bad arch error once */ 2845 static int badnote_done = 0; 2846 corenote_ret_t corenote_ret; 2847 2848 corenote_ret = corenote(ehdr->e_machine, 2849 do_swap, type, desc, descsz); 2850 switch (corenote_ret) { 2851 case CORENOTE_R_OK: 2852 hexdump = 0; 2853 break; 2854 case CORENOTE_R_BADDATA: 2855 (void) fprintf(stderr, 2856 MSG_INTL(MSG_NOTE_BADCOREDATA), 2857 file); 2858 break; 2859 case CORENOTE_R_BADARCH: 2860 if (badnote_done) 2861 break; 2862 (void) fprintf(stderr, 2863 MSG_INTL(MSG_NOTE_BADCOREARCH), 2864 file, 2865 conv_ehdr_mach(ehdr->e_machine, 2866 0, &inv_buf)); 2867 break; 2868 } 2869 } 2870 2871 /* 2872 * The default thing when we don't understand 2873 * the note data is to display it as hex bytes. 2874 */ 2875 if (hexdump) { 2876 dbg_print(0, MSG_ORIG(MSG_NOTE_DESC)); 2877 dump_hex_bytes(desc, descsz, 8, 4, 4); 2878 } 2879 desc += descsz + pad; 2880 2881 /* LINTED */ 2882 data = (Word *)desc; 2883 } 2884 } 2885 } 2886 2887 /* 2888 * Search for and process .note sections. 2889 * 2890 * Returns the number of note sections seen. 2891 */ 2892 static Word 2893 note(Cache *cache, Word shnum, Ehdr *ehdr, const char *file) 2894 { 2895 Word cnt, note_cnt = 0; 2896 2897 /* 2898 * Otherwise look for any .note sections. 2899 */ 2900 for (cnt = 1; cnt < shnum; cnt++) { 2901 Cache *_cache = &cache[cnt]; 2902 Shdr *shdr = _cache->c_shdr; 2903 2904 if (shdr->sh_type != SHT_NOTE) 2905 continue; 2906 note_cnt++; 2907 if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type)) 2908 continue; 2909 2910 /* 2911 * As these sections are often hand rolled, make sure they're 2912 * properly aligned before proceeding, and issue an error 2913 * as necessary. 2914 * 2915 * Note that we will continue on to display the note even 2916 * if it has bad alignment. We can do this safely, because 2917 * libelf knows the alignment required for SHT_NOTE, and 2918 * takes steps to deliver a properly aligned buffer to us 2919 * even if the actual file is misaligned. 2920 */ 2921 if (shdr->sh_offset & (sizeof (Word) - 1)) 2922 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADALIGN), 2923 file, _cache->c_name); 2924 2925 if (_cache->c_data == NULL) 2926 continue; 2927 2928 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 2929 dbg_print(0, MSG_INTL(MSG_ELF_SCN_NOTE), _cache->c_name); 2930 note_entry(_cache, (Word *)_cache->c_data->d_buf, 2931 /* LINTED */ 2932 (Word)_cache->c_data->d_size, ehdr, file); 2933 } 2934 2935 return (note_cnt); 2936 } 2937 2938 /* 2939 * Determine an individual hash entry. This may be the initial hash entry, 2940 * or an associated chain entry. 2941 */ 2942 static void 2943 hash_entry(Cache *refsec, Cache *strsec, const char *hsecname, Word hashndx, 2944 Word symndx, Word symn, Sym *syms, const char *file, ulong_t bkts, 2945 uint_t flags, int chain) 2946 { 2947 Sym *sym; 2948 const char *symname, *str; 2949 char _bucket[MAXNDXSIZE], _symndx[MAXNDXSIZE]; 2950 ulong_t nbkt, nhash; 2951 2952 if (symndx > symn) { 2953 (void) fprintf(stderr, MSG_INTL(MSG_ERR_HSBADSYMNDX), file, 2954 EC_WORD(symndx), EC_WORD(hashndx)); 2955 symname = MSG_INTL(MSG_STR_UNKNOWN); 2956 } else { 2957 sym = (Sym *)(syms + symndx); 2958 symname = string(refsec, symndx, strsec, file, sym->st_name); 2959 } 2960 2961 if (chain == 0) { 2962 (void) snprintf(_bucket, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INTEGER), 2963 hashndx); 2964 str = (const char *)_bucket; 2965 } else 2966 str = MSG_ORIG(MSG_STR_EMPTY); 2967 2968 (void) snprintf(_symndx, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX2), 2969 EC_WORD(symndx)); 2970 dbg_print(0, MSG_ORIG(MSG_FMT_HASH_INFO), str, _symndx, 2971 demangle(symname, flags)); 2972 2973 /* 2974 * Determine if this string is in the correct bucket. 2975 */ 2976 nhash = elf_hash(symname); 2977 nbkt = nhash % bkts; 2978 2979 if (nbkt != hashndx) { 2980 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADHASH), file, 2981 hsecname, symname, EC_WORD(hashndx), nbkt); 2982 } 2983 } 2984 2985 #define MAXCOUNT 500 2986 2987 static void 2988 hash(Cache *cache, Word shnum, const char *file, uint_t flags) 2989 { 2990 static int count[MAXCOUNT]; 2991 Word cnt; 2992 ulong_t ndx, bkts; 2993 char number[MAXNDXSIZE]; 2994 2995 for (cnt = 1; cnt < shnum; cnt++) { 2996 uint_t *hash, *chain; 2997 Cache *_cache = &cache[cnt]; 2998 Shdr *sshdr, *hshdr = _cache->c_shdr; 2999 char *ssecname, *hsecname = _cache->c_name; 3000 Sym *syms; 3001 Word symn; 3002 3003 if (hshdr->sh_type != SHT_HASH) 3004 continue; 3005 3006 /* 3007 * Determine the hash table data and size. 3008 */ 3009 if ((hshdr->sh_entsize == 0) || (hshdr->sh_size == 0)) { 3010 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 3011 file, hsecname); 3012 continue; 3013 } 3014 if (_cache->c_data == NULL) 3015 continue; 3016 3017 hash = (uint_t *)_cache->c_data->d_buf; 3018 bkts = *hash; 3019 chain = hash + 2 + bkts; 3020 hash += 2; 3021 3022 /* 3023 * Get the data buffer for the associated symbol table. 3024 */ 3025 if ((hshdr->sh_link == 0) || (hshdr->sh_link >= shnum)) { 3026 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 3027 file, hsecname, EC_WORD(hshdr->sh_link)); 3028 continue; 3029 } 3030 3031 _cache = &cache[hshdr->sh_link]; 3032 ssecname = _cache->c_name; 3033 3034 if (_cache->c_data == NULL) 3035 continue; 3036 3037 if ((syms = (Sym *)_cache->c_data->d_buf) == NULL) { 3038 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 3039 file, ssecname); 3040 continue; 3041 } 3042 3043 sshdr = _cache->c_shdr; 3044 /* LINTED */ 3045 symn = (Word)(sshdr->sh_size / sshdr->sh_entsize); 3046 3047 /* 3048 * Get the associated string table section. 3049 */ 3050 if ((sshdr->sh_link == 0) || (sshdr->sh_link >= shnum)) { 3051 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK), 3052 file, ssecname, EC_WORD(sshdr->sh_link)); 3053 continue; 3054 } 3055 3056 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 3057 dbg_print(0, MSG_INTL(MSG_ELF_SCN_HASH), hsecname); 3058 dbg_print(0, MSG_INTL(MSG_ELF_HASH_INFO)); 3059 3060 /* 3061 * Loop through the hash buckets, printing the appropriate 3062 * symbols. 3063 */ 3064 for (ndx = 0; ndx < bkts; ndx++, hash++) { 3065 Word _ndx, _cnt; 3066 3067 if (*hash == 0) { 3068 count[0]++; 3069 continue; 3070 } 3071 3072 hash_entry(_cache, &cache[sshdr->sh_link], hsecname, 3073 ndx, *hash, symn, syms, file, bkts, flags, 0); 3074 3075 /* 3076 * Determine if any other symbols are chained to this 3077 * bucket. 3078 */ 3079 _ndx = chain[*hash]; 3080 _cnt = 1; 3081 while (_ndx) { 3082 hash_entry(_cache, &cache[sshdr->sh_link], 3083 hsecname, ndx, _ndx, symn, syms, file, 3084 bkts, flags, 1); 3085 _ndx = chain[_ndx]; 3086 _cnt++; 3087 } 3088 3089 if (_cnt >= MAXCOUNT) { 3090 (void) fprintf(stderr, 3091 MSG_INTL(MSG_HASH_OVERFLW), file, 3092 _cache->c_name, EC_WORD(ndx), 3093 EC_WORD(_cnt)); 3094 } else 3095 count[_cnt]++; 3096 } 3097 break; 3098 } 3099 3100 /* 3101 * Print out the count information. 3102 */ 3103 bkts = cnt = 0; 3104 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 3105 3106 for (ndx = 0; ndx < MAXCOUNT; ndx++) { 3107 Word _cnt; 3108 3109 if ((_cnt = count[ndx]) == 0) 3110 continue; 3111 3112 (void) snprintf(number, MAXNDXSIZE, 3113 MSG_ORIG(MSG_FMT_INTEGER), _cnt); 3114 dbg_print(0, MSG_INTL(MSG_ELF_HASH_BKTS1), number, 3115 EC_WORD(ndx)); 3116 bkts += _cnt; 3117 cnt += (Word)(ndx * _cnt); 3118 } 3119 if (cnt) { 3120 (void) snprintf(number, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INTEGER), 3121 bkts); 3122 dbg_print(0, MSG_INTL(MSG_ELF_HASH_BKTS2), number, 3123 EC_WORD(cnt)); 3124 } 3125 } 3126 3127 static void 3128 group(Cache *cache, Word shnum, const char *file, uint_t flags) 3129 { 3130 Word scnt; 3131 3132 for (scnt = 1; scnt < shnum; scnt++) { 3133 Cache *_cache = &cache[scnt]; 3134 Shdr *shdr = _cache->c_shdr; 3135 Word *grpdata, gcnt, grpcnt, symnum, unknown; 3136 Cache *symsec, *strsec; 3137 Sym *syms, *sym; 3138 char flgstrbuf[MSG_GRP_COMDAT_SIZE + 10]; 3139 3140 if (shdr->sh_type != SHT_GROUP) 3141 continue; 3142 if (!match(MATCH_F_ALL, _cache->c_name, scnt, shdr->sh_type)) 3143 continue; 3144 if ((_cache->c_data == NULL) || 3145 ((grpdata = (Word *)_cache->c_data->d_buf) == NULL)) 3146 continue; 3147 grpcnt = shdr->sh_size / sizeof (Word); 3148 3149 /* 3150 * Get the data buffer for the associated symbol table and 3151 * string table. 3152 */ 3153 if (stringtbl(cache, 1, scnt, shnum, file, 3154 &symnum, &symsec, &strsec) == 0) 3155 return; 3156 3157 syms = symsec->c_data->d_buf; 3158 3159 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 3160 dbg_print(0, MSG_INTL(MSG_ELF_SCN_GRP), _cache->c_name); 3161 dbg_print(0, MSG_INTL(MSG_GRP_TITLE)); 3162 3163 /* 3164 * The first element of the group defines the group. The 3165 * associated symbol is defined by the sh_link field. 3166 */ 3167 if ((shdr->sh_info == SHN_UNDEF) || (shdr->sh_info > symnum)) { 3168 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO), 3169 file, _cache->c_name, EC_WORD(shdr->sh_info)); 3170 return; 3171 } 3172 3173 (void) strcpy(flgstrbuf, MSG_ORIG(MSG_STR_OSQBRKT)); 3174 if (grpdata[0] & GRP_COMDAT) { 3175 (void) strcat(flgstrbuf, MSG_ORIG(MSG_GRP_COMDAT)); 3176 } 3177 if ((unknown = (grpdata[0] & ~GRP_COMDAT)) != 0) { 3178 size_t len = strlen(flgstrbuf); 3179 3180 (void) snprintf(&flgstrbuf[len], 3181 (MSG_GRP_COMDAT_SIZE + 10 - len), 3182 MSG_ORIG(MSG_GRP_UNKNOWN), unknown); 3183 } 3184 (void) strcat(flgstrbuf, MSG_ORIG(MSG_STR_CSQBRKT)); 3185 sym = (Sym *)(syms + shdr->sh_info); 3186 3187 dbg_print(0, MSG_INTL(MSG_GRP_SIGNATURE), flgstrbuf, 3188 demangle(string(_cache, 0, strsec, file, sym->st_name), 3189 flags)); 3190 3191 for (gcnt = 1; gcnt < grpcnt; gcnt++) { 3192 char index[MAXNDXSIZE]; 3193 const char *name; 3194 3195 (void) snprintf(index, MAXNDXSIZE, 3196 MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(gcnt)); 3197 3198 if (grpdata[gcnt] >= shnum) 3199 name = MSG_INTL(MSG_GRP_INVALSCN); 3200 else 3201 name = cache[grpdata[gcnt]].c_name; 3202 3203 (void) printf(MSG_ORIG(MSG_GRP_ENTRY), index, name, 3204 EC_XWORD(grpdata[gcnt])); 3205 } 3206 } 3207 } 3208 3209 static void 3210 got(Cache *cache, Word shnum, Ehdr *ehdr, const char *file) 3211 { 3212 Cache *gotcache = NULL, *symtab = NULL; 3213 Addr gotbgn, gotend; 3214 Shdr *gotshdr; 3215 Word cnt, gotents, gotndx; 3216 size_t gentsize; 3217 Got_info *gottable; 3218 char *gotdata; 3219 Sym *gotsym; 3220 Xword gotsymaddr; 3221 uint_t sys_encoding; 3222 3223 /* 3224 * First, find the got. 3225 */ 3226 for (cnt = 1; cnt < shnum; cnt++) { 3227 if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT), 3228 MSG_ELF_GOT_SIZE) == 0) { 3229 gotcache = &cache[cnt]; 3230 break; 3231 } 3232 } 3233 if (gotcache == NULL) 3234 return; 3235 3236 /* 3237 * A got section within a relocatable object is suspicious. 3238 */ 3239 if (ehdr->e_type == ET_REL) { 3240 (void) fprintf(stderr, MSG_INTL(MSG_GOT_UNEXPECTED), file, 3241 gotcache->c_name); 3242 } 3243 3244 gotshdr = gotcache->c_shdr; 3245 if (gotshdr->sh_size == 0) { 3246 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 3247 file, gotcache->c_name); 3248 return; 3249 } 3250 3251 gotbgn = gotshdr->sh_addr; 3252 gotend = gotbgn + gotshdr->sh_size; 3253 3254 /* 3255 * Some architectures don't properly set the sh_entsize for the GOT 3256 * table. If it's not set, default to a size of a pointer. 3257 */ 3258 if ((gentsize = gotshdr->sh_entsize) == 0) 3259 gentsize = sizeof (Xword); 3260 3261 if (gotcache->c_data == NULL) 3262 return; 3263 3264 /* LINTED */ 3265 gotents = (Word)(gotshdr->sh_size / gentsize); 3266 gotdata = gotcache->c_data->d_buf; 3267 3268 if ((gottable = calloc(gotents, sizeof (Got_info))) == 0) { 3269 int err = errno; 3270 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), file, 3271 strerror(err)); 3272 return; 3273 } 3274 3275 /* 3276 * Now we scan through all the sections looking for any relocations 3277 * that may be against the GOT. Since these may not be isolated to a 3278 * .rel[a].got section we check them all. 3279 * While scanning sections save the symbol table entry (a symtab 3280 * overriding a dynsym) so that we can lookup _GLOBAL_OFFSET_TABLE_. 3281 */ 3282 for (cnt = 1; cnt < shnum; cnt++) { 3283 Word type, symnum; 3284 Xword relndx, relnum, relsize; 3285 void *rels; 3286 Sym *syms; 3287 Cache *symsec, *strsec; 3288 Cache *_cache = &cache[cnt]; 3289 Shdr *shdr; 3290 3291 shdr = _cache->c_shdr; 3292 type = shdr->sh_type; 3293 3294 if ((symtab == 0) && (type == SHT_DYNSYM)) { 3295 symtab = _cache; 3296 continue; 3297 } 3298 if (type == SHT_SYMTAB) { 3299 symtab = _cache; 3300 continue; 3301 } 3302 if ((type != SHT_RELA) && (type != SHT_REL)) 3303 continue; 3304 3305 /* 3306 * Decide entry size. 3307 */ 3308 if (((relsize = shdr->sh_entsize) == 0) || 3309 (relsize > shdr->sh_size)) { 3310 if (type == SHT_RELA) 3311 relsize = sizeof (Rela); 3312 else 3313 relsize = sizeof (Rel); 3314 } 3315 3316 /* 3317 * Determine the number of relocations available. 3318 */ 3319 if (shdr->sh_size == 0) { 3320 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ), 3321 file, _cache->c_name); 3322 continue; 3323 } 3324 if (_cache->c_data == NULL) 3325 continue; 3326 3327 rels = _cache->c_data->d_buf; 3328 relnum = shdr->sh_size / relsize; 3329 3330 /* 3331 * Get the data buffer for the associated symbol table and 3332 * string table. 3333 */ 3334 if (stringtbl(cache, 1, cnt, shnum, file, 3335 &symnum, &symsec, &strsec) == 0) 3336 continue; 3337 3338 syms = symsec->c_data->d_buf; 3339 3340 /* 3341 * Loop through the relocation entries. 3342 */ 3343 for (relndx = 0; relndx < relnum; relndx++, 3344 rels = (void *)((char *)rels + relsize)) { 3345 char section[BUFSIZ]; 3346 Addr offset; 3347 Got_info *gip; 3348 Word symndx, reltype; 3349 Rela *rela; 3350 Rel *rel; 3351 3352 /* 3353 * Unravel the relocation. 3354 */ 3355 if (type == SHT_RELA) { 3356 rela = (Rela *)rels; 3357 symndx = ELF_R_SYM(rela->r_info); 3358 reltype = ELF_R_TYPE(rela->r_info, 3359 ehdr->e_machine); 3360 offset = rela->r_offset; 3361 } else { 3362 rel = (Rel *)rels; 3363 symndx = ELF_R_SYM(rel->r_info); 3364 reltype = ELF_R_TYPE(rel->r_info, 3365 ehdr->e_machine); 3366 offset = rel->r_offset; 3367 } 3368 3369 /* 3370 * Only pay attention to relocations against the GOT. 3371 */ 3372 if ((offset < gotbgn) || (offset >= gotend)) 3373 continue; 3374 3375 /* LINTED */ 3376 gotndx = (Word)((offset - gotbgn) / 3377 gotshdr->sh_entsize); 3378 gip = &gottable[gotndx]; 3379 3380 if (gip->g_reltype != 0) { 3381 (void) fprintf(stderr, 3382 MSG_INTL(MSG_GOT_MULTIPLE), file, 3383 EC_WORD(gotndx), EC_ADDR(offset)); 3384 continue; 3385 } 3386 3387 if (symndx) 3388 gip->g_symname = relsymname(cache, _cache, 3389 strsec, symndx, symnum, relndx, syms, 3390 section, BUFSIZ, file); 3391 gip->g_reltype = reltype; 3392 gip->g_rel = rels; 3393 } 3394 } 3395 3396 if (symlookup(MSG_ORIG(MSG_SYM_GOT), cache, shnum, &gotsym, symtab, 3397 file)) 3398 gotsymaddr = gotsym->st_value; 3399 else 3400 gotsymaddr = gotbgn; 3401 3402 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 3403 dbg_print(0, MSG_INTL(MSG_ELF_SCN_GOT), gotcache->c_name); 3404 Elf_got_title(0); 3405 3406 sys_encoding = _elf_sys_encoding(); 3407 for (gotndx = 0; gotndx < gotents; gotndx++) { 3408 Got_info *gip; 3409 Sword gindex; 3410 Addr gaddr; 3411 Xword gotentry; 3412 3413 gip = &gottable[gotndx]; 3414 3415 gaddr = gotbgn + (gotndx * gentsize); 3416 gindex = (Sword)(gaddr - gotsymaddr) / (Sword)gentsize; 3417 3418 if (gentsize == sizeof (Word)) 3419 /* LINTED */ 3420 gotentry = (Xword)(*((Word *)(gotdata) + gotndx)); 3421 else 3422 /* LINTED */ 3423 gotentry = *((Xword *)(gotdata) + gotndx); 3424 3425 Elf_got_entry(0, gindex, gaddr, gotentry, ehdr->e_machine, 3426 ehdr->e_ident[EI_DATA], sys_encoding, 3427 gip->g_reltype, gip->g_rel, gip->g_symname); 3428 } 3429 free(gottable); 3430 } 3431 3432 void 3433 checksum(Elf *elf) 3434 { 3435 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 3436 dbg_print(0, MSG_INTL(MSG_STR_CHECKSUM), elf_checksum(elf)); 3437 } 3438 3439 /* 3440 * This variable is used by regular() to communicate the address of 3441 * the section header cache to sort_shdr_ndx_arr(). Unfortunately, 3442 * the qsort() interface does not include a userdata argument by which 3443 * such arbitrary data can be passed, so we are stuck using global data. 3444 */ 3445 static Cache *sort_shdr_ndx_arr_cache; 3446 3447 3448 /* 3449 * Used with qsort() to sort the section indices so that they can be 3450 * used to access the section headers in order of increasing data offset. 3451 * 3452 * entry: 3453 * sort_shdr_ndx_arr_cache - Contains address of 3454 * section header cache. 3455 * v1, v2 - Point at elements of sort_shdr_bits array to be compared. 3456 * 3457 * exit: 3458 * Returns -1 (less than), 0 (equal) or 1 (greater than). 3459 */ 3460 static int 3461 sort_shdr_ndx_arr(const void *v1, const void *v2) 3462 { 3463 Cache *cache1 = sort_shdr_ndx_arr_cache + *((size_t *)v1); 3464 Cache *cache2 = sort_shdr_ndx_arr_cache + *((size_t *)v2); 3465 3466 if (cache1->c_shdr->sh_offset < cache2->c_shdr->sh_offset) 3467 return (-1); 3468 3469 if (cache1->c_shdr->sh_offset > cache2->c_shdr->sh_offset) 3470 return (1); 3471 3472 return (0); 3473 } 3474 3475 3476 static int 3477 shdr_cache(const char *file, Elf *elf, Ehdr *ehdr, size_t shstrndx, 3478 size_t shnum, Cache **cache_ret, Word flags) 3479 { 3480 Elf_Scn *scn; 3481 Elf_Data *data; 3482 size_t ndx; 3483 Shdr *nameshdr; 3484 char *names = NULL; 3485 Cache *cache, *_cache; 3486 size_t *shdr_ndx_arr, shdr_ndx_arr_cnt; 3487 3488 3489 /* 3490 * Obtain the .shstrtab data buffer to provide the required section 3491 * name strings. 3492 */ 3493 if (shstrndx == SHN_UNDEF) { 3494 /* 3495 * It is rare, but legal, for an object to lack a 3496 * header string table section. 3497 */ 3498 names = NULL; 3499 (void) fprintf(stderr, MSG_INTL(MSG_ERR_NOSHSTRSEC), file); 3500 } else if ((scn = elf_getscn(elf, shstrndx)) == NULL) { 3501 failure(file, MSG_ORIG(MSG_ELF_GETSCN)); 3502 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SHDR), 3503 EC_XWORD(shstrndx)); 3504 3505 } else if ((data = elf_getdata(scn, NULL)) == NULL) { 3506 failure(file, MSG_ORIG(MSG_ELF_GETDATA)); 3507 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_DATA), 3508 EC_XWORD(shstrndx)); 3509 3510 } else if ((nameshdr = elf_getshdr(scn)) == NULL) { 3511 failure(file, MSG_ORIG(MSG_ELF_GETSHDR)); 3512 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN), 3513 EC_WORD(elf_ndxscn(scn))); 3514 3515 } else if ((names = data->d_buf) == NULL) 3516 (void) fprintf(stderr, MSG_INTL(MSG_ERR_SHSTRNULL), file); 3517 3518 /* 3519 * Allocate a cache to maintain a descriptor for each section. 3520 */ 3521 if ((*cache_ret = cache = malloc(shnum * sizeof (Cache))) == NULL) { 3522 int err = errno; 3523 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 3524 file, strerror(err)); 3525 return (0); 3526 } 3527 3528 *cache = cache_init; 3529 _cache = cache; 3530 _cache++; 3531 3532 /* 3533 * Allocate an array that will hold the section index for 3534 * each section that has data in the ELF file: 3535 * 3536 * - Is not a NOBITS section 3537 * - Data has non-zero length 3538 * 3539 * Note that shnum is an upper bound on the size required. It 3540 * is likely that we won't use a few of these array elements. 3541 * Allocating a modest amount of extra memory in this case means 3542 * that we can avoid an extra loop to count the number of needed 3543 * items, and can fill this array immediately in the first loop 3544 * below. 3545 */ 3546 if ((shdr_ndx_arr = malloc(shnum * sizeof (*shdr_ndx_arr))) == NULL) { 3547 int err = errno; 3548 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 3549 file, strerror(err)); 3550 return (0); 3551 } 3552 shdr_ndx_arr_cnt = 0; 3553 3554 /* 3555 * Traverse the sections of the file. This gathering of data is 3556 * carried out in two passes. First, the section headers are captured 3557 * and the section header names are evaluated. A verification pass is 3558 * then carried out over the section information. Files have been 3559 * known to exhibit overlapping (and hence erroneous) section header 3560 * information. 3561 * 3562 * Finally, the data for each section is obtained. This processing is 3563 * carried out after section verification because should any section 3564 * header overlap occur, and a file needs translating (ie. xlate'ing 3565 * information from a non-native architecture file), then the process 3566 * of translation can corrupt the section header information. Of 3567 * course, if there is any section overlap, the data related to the 3568 * sections is going to be compromised. However, it is the translation 3569 * of this data that has caused problems with elfdump()'s ability to 3570 * extract the data. 3571 */ 3572 for (ndx = 1, scn = NULL; scn = elf_nextscn(elf, scn); 3573 ndx++, _cache++) { 3574 char scnndxnm[100]; 3575 3576 _cache->c_ndx = ndx; 3577 _cache->c_scn = scn; 3578 3579 if ((_cache->c_shdr = elf_getshdr(scn)) == NULL) { 3580 failure(file, MSG_ORIG(MSG_ELF_GETSHDR)); 3581 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN), 3582 EC_WORD(elf_ndxscn(scn))); 3583 } 3584 3585 /* 3586 * If this section has data in the file, include it in 3587 * the array of sections to check for address overlap. 3588 */ 3589 if ((_cache->c_shdr->sh_size != 0) && 3590 (_cache->c_shdr->sh_type != SHT_NOBITS)) 3591 shdr_ndx_arr[shdr_ndx_arr_cnt++] = ndx; 3592 3593 /* 3594 * If a shstrtab exists, assign the section name. 3595 */ 3596 if (names && _cache->c_shdr) { 3597 if (_cache->c_shdr->sh_name && 3598 /* LINTED */ 3599 (nameshdr->sh_size > _cache->c_shdr->sh_name)) { 3600 const char *symname; 3601 char *secname; 3602 3603 secname = names + _cache->c_shdr->sh_name; 3604 3605 /* 3606 * A SUN naming convention employs a "%" within 3607 * a section name to indicate a section/symbol 3608 * name. This originated from the compilers 3609 * -xF option, that places functions into their 3610 * own sections. This convention (which has no 3611 * formal standard) has also been followed for 3612 * COMDAT sections. To demangle the symbol 3613 * name, the name must be separated from the 3614 * section name. 3615 */ 3616 if (((flags & FLG_CTL_DEMANGLE) == 0) || 3617 ((symname = strchr(secname, '%')) == NULL)) 3618 _cache->c_name = secname; 3619 else { 3620 size_t secsz = ++symname - secname; 3621 size_t strsz; 3622 3623 symname = demangle(symname, flags); 3624 strsz = secsz + strlen(symname) + 1; 3625 3626 if ((_cache->c_name = 3627 malloc(strsz)) == NULL) { 3628 int err = errno; 3629 (void) fprintf(stderr, 3630 MSG_INTL(MSG_ERR_MALLOC), 3631 file, strerror(err)); 3632 return (0); 3633 } 3634 (void) snprintf(_cache->c_name, strsz, 3635 MSG_ORIG(MSG_FMT_SECSYM), 3636 EC_WORD(secsz), secname, symname); 3637 } 3638 3639 continue; 3640 } 3641 3642 /* 3643 * Generate an error if the section name index is zero 3644 * or exceeds the shstrtab data. Fall through to 3645 * fabricate a section name. 3646 */ 3647 if ((_cache->c_shdr->sh_name == 0) || 3648 /* LINTED */ 3649 (nameshdr->sh_size <= _cache->c_shdr->sh_name)) { 3650 (void) fprintf(stderr, 3651 MSG_INTL(MSG_ERR_BADSHNAME), file, 3652 EC_WORD(ndx), 3653 EC_XWORD(_cache->c_shdr->sh_name)); 3654 } 3655 } 3656 3657 /* 3658 * If there exists no shstrtab data, or a section header has no 3659 * name (an invalid index of 0), then compose a name for the 3660 * section. 3661 */ 3662 (void) snprintf(scnndxnm, sizeof (scnndxnm), 3663 MSG_INTL(MSG_FMT_SCNNDX), ndx); 3664 3665 if ((_cache->c_name = malloc(strlen(scnndxnm) + 1)) == NULL) { 3666 int err = errno; 3667 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 3668 file, strerror(err)); 3669 return (0); 3670 } 3671 (void) strcpy(_cache->c_name, scnndxnm); 3672 } 3673 3674 /* 3675 * Having collected all the sections, validate their address range. 3676 * Cases have existed where the section information has been invalid. 3677 * This can lead to all sorts of other, hard to diagnose errors, as 3678 * each section is processed individually (ie. with elf_getdata()). 3679 * Here, we carry out some address comparisons to catch a family of 3680 * overlapping memory issues we have observed (likely, there are others 3681 * that we have yet to discover). 3682 * 3683 * Note, should any memory overlap occur, obtaining any additional 3684 * data from the file is questionable. However, it might still be 3685 * possible to inspect the ELF header, Programs headers, or individual 3686 * sections, so rather than bailing on an error condition, continue 3687 * processing to see if any data can be salvaged. 3688 */ 3689 if (shdr_ndx_arr_cnt > 1) { 3690 sort_shdr_ndx_arr_cache = cache; 3691 qsort(shdr_ndx_arr, shdr_ndx_arr_cnt, 3692 sizeof (*shdr_ndx_arr), sort_shdr_ndx_arr); 3693 } 3694 for (ndx = 0; ndx < shdr_ndx_arr_cnt; ndx++) { 3695 Cache *_cache = cache + shdr_ndx_arr[ndx]; 3696 Shdr *shdr = _cache->c_shdr; 3697 Off bgn1, bgn = shdr->sh_offset; 3698 Off end1, end = shdr->sh_offset + shdr->sh_size; 3699 size_t ndx1; 3700 3701 /* 3702 * Check the section against all following ones, reporting 3703 * any overlaps. Since we've sorted the sections by offset, 3704 * we can stop after the first comparison that fails. There 3705 * are no overlaps in a properly formed ELF file, in which 3706 * case this algorithm runs in O(n) time. This will degenerate 3707 * to O(n^2) for a completely broken file. Such a file is 3708 * (1) highly unlikely, and (2) unusable, so it is reasonable 3709 * for the analysis to take longer. 3710 */ 3711 for (ndx1 = ndx + 1; ndx1 < shdr_ndx_arr_cnt; ndx1++) { 3712 Cache *_cache1 = cache + shdr_ndx_arr[ndx1]; 3713 Shdr *shdr1 = _cache1->c_shdr; 3714 3715 bgn1 = shdr1->sh_offset; 3716 end1 = shdr1->sh_offset + shdr1->sh_size; 3717 3718 if (((bgn1 <= bgn) && (end1 > bgn)) || 3719 ((bgn1 < end) && (end1 >= end))) { 3720 (void) fprintf(stderr, 3721 MSG_INTL(MSG_ERR_SECMEMOVER), file, 3722 EC_WORD(elf_ndxscn(_cache->c_scn)), 3723 _cache->c_name, EC_OFF(bgn), EC_OFF(end), 3724 EC_WORD(elf_ndxscn(_cache1->c_scn)), 3725 _cache1->c_name, EC_OFF(bgn1), 3726 EC_OFF(end1)); 3727 } else { /* No overlap, so can stop */ 3728 break; 3729 } 3730 } 3731 3732 /* 3733 * In addition to checking for sections overlapping 3734 * each other (done above), we should also make sure 3735 * the section doesn't overlap the section header array. 3736 */ 3737 bgn1 = ehdr->e_shoff; 3738 end1 = ehdr->e_shoff + (ehdr->e_shentsize * ehdr->e_shnum); 3739 3740 if (((bgn1 <= bgn) && (end1 > bgn)) || 3741 ((bgn1 < end) && (end1 >= end))) { 3742 (void) fprintf(stderr, 3743 MSG_INTL(MSG_ERR_SHDRMEMOVER), file, EC_OFF(bgn1), 3744 EC_OFF(end1), 3745 EC_WORD(elf_ndxscn(_cache->c_scn)), 3746 _cache->c_name, EC_OFF(bgn), EC_OFF(end)); 3747 } 3748 } 3749 3750 /* 3751 * Obtain the data for each section. 3752 */ 3753 for (ndx = 1; ndx < shnum; ndx++) { 3754 Cache *_cache = &cache[ndx]; 3755 Elf_Scn *scn = _cache->c_scn; 3756 3757 if ((_cache->c_data = elf_getdata(scn, NULL)) == NULL) { 3758 failure(file, MSG_ORIG(MSG_ELF_GETDATA)); 3759 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCNDATA), 3760 EC_WORD(elf_ndxscn(scn))); 3761 } 3762 3763 /* 3764 * If a string table, verify that it has NULL first and 3765 * final bytes. 3766 */ 3767 if ((_cache->c_shdr->sh_type == SHT_STRTAB) && 3768 (_cache->c_data->d_buf != NULL) && 3769 (_cache->c_data->d_size > 0)) { 3770 const char *s = _cache->c_data->d_buf; 3771 3772 if ((*s != '\0') || 3773 (*(s + _cache->c_data->d_size - 1) != '\0')) 3774 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALSTR), 3775 file, _cache->c_name); 3776 } 3777 } 3778 3779 return (1); 3780 } 3781 3782 3783 3784 int 3785 regular(const char *file, int fd, Elf *elf, uint_t flags, 3786 const char *wname, int wfd) 3787 { 3788 Elf_Scn *scn; 3789 Ehdr *ehdr; 3790 size_t ndx, shstrndx, shnum, phnum; 3791 Shdr *shdr; 3792 Cache *cache; 3793 VERSYM_STATE versym; 3794 int ret = 0; 3795 int addr_align; 3796 3797 if ((ehdr = elf_getehdr(elf)) == NULL) { 3798 failure(file, MSG_ORIG(MSG_ELF_GETEHDR)); 3799 return (ret); 3800 } 3801 3802 if (elf_getshnum(elf, &shnum) == 0) { 3803 failure(file, MSG_ORIG(MSG_ELF_GETSHNUM)); 3804 return (ret); 3805 } 3806 3807 if (elf_getshstrndx(elf, &shstrndx) == 0) { 3808 failure(file, MSG_ORIG(MSG_ELF_GETSHSTRNDX)); 3809 return (ret); 3810 } 3811 3812 if (elf_getphnum(elf, &phnum) == 0) { 3813 failure(file, MSG_ORIG(MSG_ELF_GETPHNUM)); 3814 return (ret); 3815 } 3816 /* 3817 * If the user requested section headers derived from the 3818 * program headers (-P option) and this file doesn't have 3819 * any program headers (i.e. ET_REL), then we can't do it. 3820 */ 3821 if ((phnum == 0) && (flags & FLG_CTL_FAKESHDR)) { 3822 (void) fprintf(stderr, MSG_INTL(MSG_ERR_PNEEDSPH), file); 3823 return (ret); 3824 } 3825 3826 3827 if ((scn = elf_getscn(elf, 0)) != NULL) { 3828 if ((shdr = elf_getshdr(scn)) == NULL) { 3829 failure(file, MSG_ORIG(MSG_ELF_GETSHDR)); 3830 (void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN), 0); 3831 return (ret); 3832 } 3833 } else 3834 shdr = NULL; 3835 3836 /* 3837 * Print the elf header. 3838 */ 3839 if (flags & FLG_SHOW_EHDR) 3840 Elf_ehdr(0, ehdr, shdr); 3841 3842 /* 3843 * If the section headers or program headers have inadequate 3844 * alignment for the class of object, print a warning. libelf 3845 * can handle such files, but programs that use them can crash 3846 * when they dereference unaligned items. 3847 * 3848 * Note that the AMD64 ABI, although it is a 64-bit architecture, 3849 * allows access to data types smaller than 128-bits to be on 3850 * word alignment. 3851 */ 3852 if (ehdr->e_machine == EM_AMD64) 3853 addr_align = sizeof (Word); 3854 else 3855 addr_align = sizeof (Addr); 3856 3857 if (ehdr->e_phoff & (addr_align - 1)) 3858 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADPHDRALIGN), file); 3859 if (ehdr->e_shoff & (addr_align - 1)) 3860 (void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHDRALIGN), file); 3861 3862 /* 3863 * Print the program headers. 3864 */ 3865 if ((flags & FLG_SHOW_PHDR) && (phnum != 0)) { 3866 Phdr *phdr; 3867 3868 if ((phdr = elf_getphdr(elf)) == NULL) { 3869 failure(file, MSG_ORIG(MSG_ELF_GETPHDR)); 3870 return (ret); 3871 } 3872 3873 for (ndx = 0; ndx < phnum; phdr++, ndx++) { 3874 if (!match(MATCH_F_PHDR| MATCH_F_NDX | MATCH_F_TYPE, 3875 NULL, ndx, phdr->p_type)) 3876 continue; 3877 3878 dbg_print(0, MSG_ORIG(MSG_STR_EMPTY)); 3879 dbg_print(0, MSG_INTL(MSG_ELF_PHDR), EC_WORD(ndx)); 3880 Elf_phdr(0, ehdr->e_machine, phdr); 3881 } 3882 } 3883 3884 /* 3885 * If we have flag bits set that explicitly require a show or calc 3886 * operation, but none of them require the section headers, then 3887 * we are done and can return now. 3888 */ 3889 if (((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) != 0) && 3890 ((flags & (FLG_MASK_SHOW_SHDR | FLG_MASK_CALC_SHDR)) == 0)) 3891 return (ret); 3892 3893 /* 3894 * If there are no section headers, then resort to synthesizing 3895 * section headers from the program headers. This is normally 3896 * only done by explicit request, but in this case there's no 3897 * reason not to go ahead, since the alternative is simply to quit. 3898 */ 3899 if ((shnum <= 1) && ((flags & FLG_CTL_FAKESHDR) == 0)) { 3900 (void) fprintf(stderr, MSG_INTL(MSG_ERR_NOSHDR), file); 3901 flags |= FLG_CTL_FAKESHDR; 3902 } 3903 3904 /* 3905 * Generate a cache of section headers and related information 3906 * for use by the rest of elfdump. If requested (or the file 3907 * contains no section headers), we generate a fake set of 3908 * headers from the information accessible from the program headers. 3909 * Otherwise, we use the real section headers contained in the file. 3910 */ 3911 3912 if (flags & FLG_CTL_FAKESHDR) { 3913 if (fake_shdr_cache(file, fd, elf, ehdr, &cache, &shnum) == 0) 3914 return (ret); 3915 } else { 3916 if (shdr_cache(file, elf, ehdr, shstrndx, shnum, 3917 &cache, flags) == 0) 3918 return (ret); 3919 } 3920 3921 /* 3922 * Everything from this point on requires section headers. 3923 * If we have no section headers, there is no reason to continue. 3924 */ 3925 if (shnum <= 1) 3926 goto done; 3927 3928 /* 3929 * If -w was specified, find and write out the section(s) data. 3930 */ 3931 if (wfd) { 3932 for (ndx = 1; ndx < shnum; ndx++) { 3933 Cache *_cache = &cache[ndx]; 3934 3935 if (match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name, 3936 ndx, _cache->c_shdr->sh_type) && 3937 _cache->c_data && _cache->c_data->d_buf) { 3938 if (write(wfd, _cache->c_data->d_buf, 3939 _cache->c_data->d_size) != 3940 _cache->c_data->d_size) { 3941 int err = errno; 3942 (void) fprintf(stderr, 3943 MSG_INTL(MSG_ERR_WRITE), wname, 3944 strerror(err)); 3945 /* 3946 * Return an exit status of 1, because 3947 * the failure is not related to the 3948 * ELF file, but by system resources. 3949 */ 3950 ret = 1; 3951 goto done; 3952 } 3953 } 3954 } 3955 } 3956 3957 /* 3958 * If we have no flag bits set that explicitly require a show or calc 3959 * operation, but match options (-I, -N, -T) were used, then run 3960 * through the section headers and see if we can't deduce show flags 3961 * from the match options given. 3962 * 3963 * We don't do this if -w was specified, because (-I, -N, -T) used 3964 * with -w in lieu of some other option is supposed to be quiet. 3965 */ 3966 if ((wfd == 0) && (flags & FLG_CTL_MATCH) && 3967 ((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) == 0)) { 3968 for (ndx = 1; ndx < shnum; ndx++) { 3969 Cache *_cache = &cache[ndx]; 3970 3971 if (!match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name, 3972 ndx, _cache->c_shdr->sh_type)) 3973 continue; 3974 3975 switch (_cache->c_shdr->sh_type) { 3976 case SHT_PROGBITS: 3977 /* 3978 * Heuristic time: It is usually bad form 3979 * to assume the meaning/format of a PROGBITS 3980 * section based on its name. However, there 3981 * are exceptions: The ELF ABI specifies 3982 * .interp and .got sections by name. Existing 3983 * practice has similarly pinned down the 3984 * meaning of unwind sections (.eh_frame and 3985 * .eh_frame_hdr). 3986 * 3987 * Check for these special names. 3988 */ 3989 if (strcmp(_cache->c_name, 3990 MSG_ORIG(MSG_ELF_INTERP)) == 0) 3991 flags |= FLG_SHOW_INTERP; 3992 else if (strcmp(_cache->c_name, 3993 MSG_ORIG(MSG_ELF_GOT)) == 0) 3994 flags |= FLG_SHOW_GOT; 3995 else if (strncmp(_cache->c_name, 3996 MSG_ORIG(MSG_SCN_FRM), 3997 MSG_SCN_FRM_SIZE) == 0) 3998 flags |= FLG_SHOW_UNWIND; 3999 break; 4000 4001 case SHT_SYMTAB: 4002 case SHT_DYNSYM: 4003 case SHT_SUNW_LDYNSYM: 4004 case SHT_SUNW_versym: 4005 case SHT_SYMTAB_SHNDX: 4006 flags |= FLG_SHOW_SYMBOLS; 4007 break; 4008 4009 case SHT_RELA: 4010 case SHT_REL: 4011 flags |= FLG_SHOW_RELOC; 4012 break; 4013 4014 case SHT_HASH: 4015 flags |= FLG_SHOW_HASH; 4016 break; 4017 4018 case SHT_DYNAMIC: 4019 flags |= FLG_SHOW_DYNAMIC; 4020 break; 4021 4022 case SHT_NOTE: 4023 flags |= FLG_SHOW_NOTE; 4024 break; 4025 4026 case SHT_GROUP: 4027 flags |= FLG_SHOW_GROUP; 4028 break; 4029 4030 case SHT_SUNW_symsort: 4031 case SHT_SUNW_tlssort: 4032 flags |= FLG_SHOW_SORT; 4033 break; 4034 4035 case SHT_SUNW_cap: 4036 flags |= FLG_SHOW_CAP; 4037 break; 4038 4039 case SHT_SUNW_move: 4040 flags |= FLG_SHOW_MOVE; 4041 break; 4042 4043 case SHT_SUNW_syminfo: 4044 flags |= FLG_SHOW_SYMINFO; 4045 break; 4046 4047 case SHT_SUNW_verdef: 4048 case SHT_SUNW_verneed: 4049 flags |= FLG_SHOW_VERSIONS; 4050 break; 4051 4052 case SHT_AMD64_UNWIND: 4053 flags |= FLG_SHOW_UNWIND; 4054 break; 4055 } 4056 } 4057 } 4058 4059 4060 if (flags & FLG_SHOW_SHDR) 4061 sections(file, cache, shnum, ehdr); 4062 4063 if (flags & FLG_SHOW_INTERP) 4064 interp(file, cache, shnum, phnum, elf); 4065 4066 versions(cache, shnum, file, flags, &versym); 4067 4068 if (flags & FLG_SHOW_SYMBOLS) 4069 symbols(cache, shnum, ehdr, &versym, file, flags); 4070 4071 if (flags & FLG_SHOW_SORT) 4072 sunw_sort(cache, shnum, ehdr, &versym, file, flags); 4073 4074 if (flags & FLG_SHOW_HASH) 4075 hash(cache, shnum, file, flags); 4076 4077 if (flags & FLG_SHOW_GOT) 4078 got(cache, shnum, ehdr, file); 4079 4080 if (flags & FLG_SHOW_GROUP) 4081 group(cache, shnum, file, flags); 4082 4083 if (flags & FLG_SHOW_SYMINFO) 4084 syminfo(cache, shnum, file); 4085 4086 if (flags & FLG_SHOW_RELOC) 4087 reloc(cache, shnum, ehdr, file); 4088 4089 if (flags & FLG_SHOW_DYNAMIC) 4090 dynamic(cache, shnum, ehdr, file); 4091 4092 if (flags & FLG_SHOW_NOTE) { 4093 Word note_cnt; 4094 size_t note_shnum; 4095 Cache *note_cache; 4096 4097 note_cnt = note(cache, shnum, ehdr, file); 4098 4099 /* 4100 * Solaris core files have section headers, but these 4101 * headers do not include SHT_NOTE sections that reference 4102 * the core note sections. This means that note() won't 4103 * find the core notes. Fake section headers (-P option) 4104 * recover these sections, but it is inconvenient to require 4105 * users to specify -P in this situation. If the following 4106 * are all true: 4107 * 4108 * - No note sections were found 4109 * - This is a core file 4110 * - We are not already using fake section headers 4111 * 4112 * then we will automatically generate fake section headers 4113 * and then process them in a second call to note(). 4114 */ 4115 if ((note_cnt == 0) && (ehdr->e_type == ET_CORE) && 4116 !(flags & FLG_CTL_FAKESHDR) && 4117 (fake_shdr_cache(file, fd, elf, ehdr, 4118 ¬e_cache, ¬e_shnum) != 0)) { 4119 (void) note(note_cache, note_shnum, ehdr, file); 4120 fake_shdr_cache_free(note_cache, note_shnum); 4121 } 4122 } 4123 4124 if (flags & FLG_SHOW_MOVE) 4125 move(cache, shnum, file, flags); 4126 4127 if (flags & FLG_CALC_CHECKSUM) 4128 checksum(elf); 4129 4130 if (flags & FLG_SHOW_CAP) 4131 cap(file, cache, shnum, phnum, ehdr, elf); 4132 4133 if (flags & FLG_SHOW_UNWIND) 4134 unwind(cache, shnum, phnum, ehdr, file, elf); 4135 4136 4137 /* Release the memory used to cache section headers */ 4138 done: 4139 if (flags & FLG_CTL_FAKESHDR) 4140 fake_shdr_cache_free(cache, shnum); 4141 else 4142 free(cache); 4143 4144 return (ret); 4145 } 4146