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