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