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