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