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