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