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 * Generate a cache of section header information for an ELF 29 * object from the information found in its program headers. 30 * 31 * Malicious code can remove or corrupt section headers. The 32 * resulting program will be difficult to analyze, but is still 33 * runnable. Hence, scribbling on the section headers or removing 34 * them is an effective form of obfuscation. On the other hand, 35 * program headers must be accurate or the program will not run. 36 * Section headers derived from them will necessarily lack information 37 * found in the originals (particularly for non-allocable sections), 38 * but will provide essential symbol information. The focus is on 39 * recovering information that elfdump knows how to display, and that 40 * might be interesting in a forensic situation. 41 * 42 * There are some things we don't attempt to create sections for: 43 * 44 * plt, got 45 * We have no way to determine the length of either of 46 * these sections from the information available via 47 * the program headers or dynamic section. The data in 48 * the PLT is of little use to elfdump. The data in the 49 * GOT might be somewhat more interesting, especially as 50 * it pertains to relocations. However, the sizing issue 51 * remains. 52 * 53 * text, data, bss 54 * Although we could create these, there is little value 55 * to doing so. elfdump cannot display the arbitrary 56 * data in these sections, so this would amount to a 57 * simple repetition of the information already displayed 58 * in the program headers, with no additional benefit. 59 */ 60 61 62 63 #include <sys/elf_amd64.h> 64 #include <stdio.h> 65 #include <unistd.h> 66 #include <errno.h> 67 #include <string.h> 68 #include <strings.h> 69 #include <conv.h> 70 #include <msg.h> 71 #include <_elfdump.h> 72 73 74 75 /* 76 * Common information about the object that is needed by 77 * all the routines in this module. 78 */ 79 typedef struct { 80 const char *file; 81 int fd; 82 Ehdr *ehdr; 83 Phdr *phdr; 84 size_t phnum; 85 } FSTATE; 86 87 88 89 /* 90 * These values uniquely identify the sections that we know 91 * how to recover. 92 * 93 * Note: We write the sections to the cache array in this same order. 94 * It simplifies this code if the dynamic, dynstr, dynsym, and ldynsym 95 * sections occupy known slots in the cache array. Other sections reference 96 * them by index, and if they are at a known spot, there is no need 97 * for a fixup pass. Putting them in positions [1-4] solves this. 98 * 99 * The order they are in was chosen such that if any one of them exists, 100 * all of the ones before it must also exist. This means that if the 101 * desired section exists, it will end up in the desired index in the 102 * cache array. 103 * 104 * The order of the other sections is arbitrary. I've arranged them 105 * in roughly related groups. 106 */ 107 typedef enum { 108 SINFO_T_NULL = 0, 109 SINFO_T_DYN = 1, 110 SINFO_T_DYNSTR = 2, 111 SINFO_T_DYNSYM = 3, 112 SINFO_T_LDYNSYM = 4, 113 114 SINFO_T_HASH = 5, 115 SINFO_T_SYMINFO = 6, 116 SINFO_T_SYMSORT = 7, 117 SINFO_T_TLSSORT = 8, 118 SINFO_T_VERNEED = 9, 119 SINFO_T_VERDEF = 10, 120 SINFO_T_VERSYM = 11, 121 SINFO_T_INTERP = 12, 122 SINFO_T_CAP = 13, 123 SINFO_T_UNWIND = 14, 124 SINFO_T_MOVE = 15, 125 SINFO_T_REL = 16, 126 SINFO_T_RELA = 17, 127 SINFO_T_PREINITARR = 18, 128 SINFO_T_INITARR = 19, 129 SINFO_T_FINIARR = 20, 130 SINFO_T_NOTE = 21, 131 132 SINFO_T_NUM = 22 /* Count of items. Must come last */ 133 } SINFO_TYPE; 134 135 136 137 /* 138 * Table of per-section constant data used to set up the section 139 * header cache and the various sub-parts it references. Indexed by 140 * SINFO_T value. 141 * 142 * note: The sh_flags value should be either SHF_ALLOC, or 0. 143 * get_data() sets SHF_WRITE if the program header containing the 144 * section is writable. The other flags require information that 145 * the program headers don't contain (i.e. SHF_STRINGS, etc) so 146 * we don't set them. 147 */ 148 typedef struct { 149 const char *name; 150 Word sh_type; 151 Word sh_flags; 152 Word sh_addralign; 153 Word sh_entsize; 154 Elf_Type libelf_type; 155 } SINFO_DATA; 156 157 /* 158 * Many of these sections use an alignment given by M_WORD_ALIGN, a 159 * value that varies depending on the object target machine. Since we 160 * don't know that value at compile time, we settle for a value of 161 * 4 for ELFCLASS32 objects, and 8 for ELFCLASS64. This matches the 162 * platforms we current support (sparc and x86), and is good enough for 163 * a fake section header in any event, as the resulting object is only 164 * analyzed, and is not executed. 165 */ 166 #ifdef _ELF64 167 #define FAKE_M_WORD_ALIGN 8 168 #else 169 #define FAKE_M_WORD_ALIGN 4 170 #endif 171 172 static SINFO_DATA sinfo_data[SINFO_T_NUM] = { 173 /* SINFO_T_NULL */ 174 { 0 }, 175 176 /* SINFO_T_DYN */ 177 { MSG_ORIG(MSG_PHDRNAM_DYN), SHT_DYNAMIC, SHF_ALLOC, 178 FAKE_M_WORD_ALIGN, sizeof (Dyn), ELF_T_DYN }, 179 180 /* SINFO_T_DYNSTR */ 181 { MSG_ORIG(MSG_PHDRNAM_DYNSTR), SHT_STRTAB, SHF_ALLOC, 182 1, 0, ELF_T_BYTE }, 183 184 /* SINFO_T_DYNSYM */ 185 { MSG_ORIG(MSG_PHDRNAM_DYNSYM), SHT_DYNSYM, SHF_ALLOC, 186 FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, 187 188 /* SINFO_T_LDYNSYM */ 189 { MSG_ORIG(MSG_PHDRNAM_LDYNSYM), SHT_SUNW_LDYNSYM, SHF_ALLOC, 190 FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, 191 192 /* SINFO_T_HASH */ 193 { MSG_ORIG(MSG_PHDRNAM_HASH), SHT_HASH, SHF_ALLOC, 194 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, 195 196 /* SINFO_T_SYMINFO */ 197 { MSG_ORIG(MSG_PHDRNAM_SYMINFO), SHT_SUNW_syminfo, SHF_ALLOC, 198 FAKE_M_WORD_ALIGN, sizeof (Syminfo), ELF_T_SYMINFO }, 199 200 /* SINFO_T_SYMSORT */ 201 { MSG_ORIG(MSG_PHDRNAM_SYMSORT), SHT_SUNW_symsort, SHF_ALLOC, 202 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, 203 204 /* SINFO_T_TLSSORT */ 205 { MSG_ORIG(MSG_PHDRNAM_TLSSORT), SHT_SUNW_tlssort, SHF_ALLOC, 206 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, 207 208 /* SINFO_T_VERNEED */ 209 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verneed, SHF_ALLOC, 210 FAKE_M_WORD_ALIGN, 1, ELF_T_VNEED }, 211 212 /* SINFO_T_VERDEF */ 213 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verdef, SHF_ALLOC, 214 FAKE_M_WORD_ALIGN, 1, ELF_T_VDEF }, 215 216 /* SINFO_T_VERSYM */ 217 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_versym, SHF_ALLOC, 218 FAKE_M_WORD_ALIGN, sizeof (Versym), ELF_T_HALF }, 219 220 /* SINFO_T_INTERP */ 221 { MSG_ORIG(MSG_PHDRNAM_INTERP), SHT_PROGBITS, SHF_ALLOC, 222 1, 0, ELF_T_BYTE }, 223 224 /* SINFO_T_CAP */ 225 { MSG_ORIG(MSG_PHDRNAM_CAP), SHT_SUNW_cap, SHF_ALLOC, 226 sizeof (Addr), sizeof (Cap), ELF_T_CAP }, 227 228 /* SINFO_T_UNWIND */ 229 { MSG_ORIG(MSG_PHDRNAM_UNWIND), SHT_AMD64_UNWIND, SHF_ALLOC, 230 sizeof (Addr), 0, ELF_T_BYTE }, 231 232 /* SINFO_T_MOVE */ 233 { MSG_ORIG(MSG_PHDRNAM_MOVE), SHT_SUNW_move, SHF_ALLOC, 234 sizeof (Lword), sizeof (Move), ELF_T_MOVE }, 235 236 /* SINFO_T_REL */ 237 { MSG_ORIG(MSG_PHDRNAM_REL), SHT_REL, SHF_ALLOC, 238 FAKE_M_WORD_ALIGN, sizeof (Rel), ELF_T_REL }, 239 240 /* SINFO_T_RELA */ 241 { MSG_ORIG(MSG_PHDRNAM_RELA), SHT_RELA, SHF_ALLOC, 242 FAKE_M_WORD_ALIGN, sizeof (Rela), ELF_T_RELA }, 243 244 /* SINFO_T_PREINITARR */ 245 { MSG_ORIG(MSG_PHDRNAM_PREINITARR), SHT_PREINIT_ARRAY, SHF_ALLOC, 246 sizeof (Addr), sizeof (Addr), ELF_T_ADDR }, 247 248 /* SINFO_T_INITARR */ 249 { MSG_ORIG(MSG_PHDRNAM_INITARR), SHT_INIT_ARRAY, SHF_ALLOC, 250 sizeof (Addr), sizeof (Addr), ELF_T_ADDR }, 251 252 /* SINFO_T_FINIARR */ 253 { MSG_ORIG(MSG_PHDRNAM_FINIARR), SHT_FINI_ARRAY, SHF_ALLOC, 254 sizeof (Addr), sizeof (Addr), ELF_T_ADDR }, 255 256 /* SINFO_T_NOTE */ 257 { MSG_ORIG(MSG_PHDRNAM_NOTE), SHT_NOTE, 0, 258 FAKE_M_WORD_ALIGN, 1, ELF_T_NOTE } 259 }; 260 261 262 263 264 265 /* 266 * As we read program headers and dynamic elements, we build up 267 * the data for our fake section headers in variables of the 268 * SINFO type. SINFO is used to track the sections that can only 269 * appear a fixed number of times (usually once). 270 * 271 * SINFO_LISTELT is used for sections that can occur an arbitrary 272 * number of times. They are kept in a doubly linked circular 273 * buffer. 274 */ 275 typedef struct { 276 SINFO_TYPE type; /* Our type code for the section */ 277 Addr vaddr; /* Virtual memory address */ 278 Off offset; /* File offset of data. Ignored unless */ 279 /* vaddr is 0. Used by program headers */ 280 size_t size; /* # bytes in section */ 281 size_t vercnt; /* Used by verdef and verneed to hold count */ 282 Shdr *shdr; /* Constructed shdr */ 283 Elf_Data *data; /* Constructed data descriptor */ 284 } SINFO; 285 286 typedef struct _sinfo_listelt { 287 struct _sinfo_listelt *next; 288 struct _sinfo_listelt *prev; 289 SINFO sinfo; 290 } SINFO_LISTELT; 291 292 293 294 /* 295 * Free dynamic memory used by SINFO structures. 296 * 297 * entry: 298 * sinfo - Address of first SINFO structure to free 299 * n - # of structures to clear 300 * 301 * exit: 302 * For each SINFO struct, the section header, data descriptor, 303 * and data buffer are freed if non-NULL. The relevant 304 * fields are set to NULL, and the type is set to SINFO_T_NULL. 305 */ 306 static void 307 sinfo_free(SINFO *sinfo, size_t n) 308 { 309 for (; n-- > 0; sinfo++) { 310 if (sinfo->data != NULL) { 311 if (sinfo->data->d_buf != NULL) 312 free(sinfo->data->d_buf); 313 free(sinfo->data); 314 sinfo->data = NULL; 315 } 316 317 if (sinfo->shdr) { 318 free(sinfo->shdr); 319 sinfo->shdr = NULL; 320 } 321 sinfo->type = SINFO_T_NULL; 322 } 323 } 324 325 326 327 /* 328 * Allocate a new SINFO_LISTELT and put it at the end of the 329 * doubly linked list anchored by the given list root node. 330 * 331 * On success, a new node has been put at the end of the circular 332 * doubly linked list, and a pointer to the SINFO sub-structure is 333 * returned. On failure, an error is printed, and NULL is returned. 334 */ 335 336 static SINFO * 337 sinfo_list_alloc(FSTATE *fstate, SINFO_LISTELT *root) 338 { 339 SINFO_LISTELT *elt; 340 341 if ((elt = malloc(sizeof (*elt))) == NULL) { 342 int err = errno; 343 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 344 fstate->file, strerror(err)); 345 return (0); 346 } 347 348 elt->next = root; 349 elt->prev = root->prev; 350 351 root->prev = elt; 352 elt->prev->next = elt; 353 354 bzero(&elt->sinfo, sizeof (elt->sinfo)); 355 return (&elt->sinfo); 356 } 357 358 359 360 /* 361 * Release the memory used by the given list, restoring it to 362 * an empty list. 363 */ 364 static void 365 sinfo_list_free_all(SINFO_LISTELT *root) 366 { 367 SINFO_LISTELT *elt; 368 369 for (elt = root->next; elt != root; elt = elt->next) 370 sinfo_free(&elt->sinfo, 1); 371 372 root->next = root->prev = root; 373 } 374 375 376 377 /* 378 * Given a virtual address and desired size of the data to be found 379 * at that address, look through the program headers for the PT_LOAD 380 * segment that contains it and return the offset within the ELF file 381 * at which it resides. 382 * 383 * entry: 384 * fstate - Object state 385 * addr - virtual address to be translated 386 * size - Size of the data to be found at that address, in bytes 387 * zero_bytes - NULL, or address to receive the number of data 388 * bytes at the end of the data that are not contained 389 * in the file, and which must be zero filled by the caller. 390 * If zero_bytes is NULL, the file must contain all of the 391 * desired data. If zero_bytes is not NULL, then the program 392 * header must reserve the space for all of the data (p_memsz) 393 * but it is acceptable for only part of the data to be in 394 * the file (p_filesz). *zero_bytes is set to the difference 395 * in size, and is the number of bytes the caller must 396 * set to 0 rather than reading from the file. 397 * phdr_ret - NULL, or address of variable to receive pointer 398 * to program header that contains offset. 399 * exit: 400 * On success: If zero_bytes is non-NULL, it is updated. If phdr_ret 401 * is non-NULL, it is updated. The file offset is returned. 402 * 403 * On failure, 0 is returned. Since any ELF file we can understand 404 * must start with an ELF magic number, 0 cannot be a valid file 405 * offset for a virtual address, and is therefore unambiguous as 406 * a failure indication. 407 */ 408 static Off 409 map_addr_to_offset(FSTATE *fstate, Addr addr, size_t size, size_t *zero_bytes, 410 Phdr **phdr_ret) 411 { 412 Off offset; 413 Addr end_addr = addr + size; 414 size_t avail_file; 415 Phdr *phdr = fstate->phdr; 416 size_t phnum = fstate->phnum; 417 418 for (; phnum--; phdr++) { 419 if (phdr->p_type != PT_LOAD) 420 continue; 421 422 if ((addr >= phdr->p_vaddr) && 423 (end_addr <= (phdr->p_vaddr + phdr->p_memsz))) { 424 /* 425 * Subtract segment virtual address, leaving the 426 * offset relative to the segment (not the file). 427 */ 428 offset = addr - phdr->p_vaddr; 429 avail_file = phdr->p_filesz - offset; 430 431 /* 432 * The addr/size are in bounds for this segment. 433 * Is there enough data in the file to satisfy 434 * the request? If zero_bytes is NULL, it must 435 * all be in the file. Otherwise it can be 436 * zero filled. 437 */ 438 if (zero_bytes == NULL) { 439 if (size > avail_file) 440 continue; 441 } else { 442 *zero_bytes = (size > avail_file) ? 443 (size - avail_file) : 0; 444 } 445 446 if (phdr_ret != NULL) 447 *phdr_ret = phdr; 448 449 /* Add segment file offset, giving overall offset */ 450 return (phdr->p_offset + offset); 451 } 452 } 453 454 /* If we get here, the mapping failed */ 455 return (0); 456 } 457 458 459 460 /* 461 * This routine is the same thing as map_addr_to_offset(), except that 462 * it goes the other way, mapping from offset to virtual address. 463 * 464 * The comments for map_addr_to_offset() are applicable if you 465 * reverse offset and address. 466 */ 467 468 static Addr 469 map_offset_to_addr(FSTATE *fstate, Off offset, size_t size, size_t *zero_bytes, 470 Phdr **phdr_ret) 471 { 472 Off end_offset = offset + size; 473 size_t avail_file; 474 Phdr *phdr = fstate->phdr; 475 size_t phnum = fstate->phnum; 476 477 for (; phnum--; phdr++) { 478 if (phdr->p_type != PT_LOAD) 479 continue; 480 481 if ((offset >= phdr->p_offset) && 482 (end_offset <= (phdr->p_offset + phdr->p_memsz))) { 483 /* 484 * Subtract segment offset, leaving the 485 * offset relative to the segment (not the file). 486 */ 487 offset -= phdr->p_offset; 488 avail_file = phdr->p_filesz - offset; 489 490 /* 491 * The offset/size are in bounds for this segment. 492 * Is there enough data in the file to satisfy 493 * the request? If zero_bytes is NULL, it must 494 * all be in the file. Otherwise it can be 495 * zero filled. 496 */ 497 if (zero_bytes == NULL) { 498 if (size > avail_file) 499 continue; 500 } else { 501 *zero_bytes = (size > avail_file) ? 502 (size - avail_file) : 0; 503 } 504 505 if (phdr_ret != NULL) 506 *phdr_ret = phdr; 507 508 /* Add segment virtual address, giving overall addr */ 509 return (phdr->p_vaddr + offset); 510 } 511 } 512 513 /* If we get here, the mapping failed */ 514 return (0); 515 } 516 517 518 519 /* 520 * Use elf_xlatetom() to convert the bytes in buf from their 521 * in-file representation to their in-memory representation. 522 * 523 * Returns True(1) for success. On failure, an error message is printed 524 * and False(0) is returned. 525 */ 526 static int 527 xlate_data(FSTATE *fstate, void *buf, size_t nbyte, Elf_Type xlate_type) 528 { 529 Elf_Data data; 530 531 data.d_type = xlate_type; 532 data.d_size = nbyte; 533 data.d_off = 0; 534 data.d_align = 0; 535 data.d_version = fstate->ehdr->e_version; 536 data.d_buf = buf; 537 538 if (elf_xlatetom(&data, &data, 539 fstate->ehdr->e_ident[EI_DATA]) == NULL) { 540 failure(fstate->file, MSG_ORIG(MSG_ELF_XLATETOM)); 541 return (0); 542 } 543 544 return (1); 545 } 546 547 548 /* 549 * Read nbytes of data into buf, starting at the specified offset 550 * within the ELF file. 551 * 552 * entry: 553 * fstate - Object state 554 * offset - Offset within the file at which desired data resides. 555 * buf - Buffer to receive the data 556 * nbyte - # of bytes to read into buf 557 * xlate_type - An ELF xlate type, specifying the type of data 558 * being input. If xlate_type is ELF_T_BYTE, xlate is not 559 * done. Otherwise, xlate_data() is called to convert the 560 * data into its in-memory representation. 561 * exit: 562 * On success, the data has been written into buf, xlate_data() 563 * called on it if required, and True(1) is returned. Otherwise 564 * False(0) is returned. 565 * 566 * note: 567 * This routine does not move the file pointer. 568 */ 569 static int 570 read_data(FSTATE *fstate, Off offset, void *buf, size_t nbyte, 571 Elf_Type xlate_type) 572 { 573 if (pread(fstate->fd, buf, nbyte, offset) != nbyte) { 574 int err = errno; 575 576 (void) fprintf(stderr, MSG_INTL(MSG_ERR_READ), 577 fstate->file, strerror(err)); 578 return (0); 579 } 580 581 if (xlate_type != ELF_T_BYTE) 582 return (xlate_data(fstate, buf, nbyte, xlate_type)); 583 584 return (1); 585 } 586 587 588 589 /* 590 * Read the hash nbucket/nchain values from the start of the hash 591 * table found at the given virtual address in the mapped ELF object. 592 * 593 * On success, *nbucket, and *nchain have been filled in with their 594 * values, *total contains the number of elements in the hash table, 595 * and this routine returns True (1). 596 * 597 * On failure, False (0) is returned. 598 */ 599 static int 600 hash_size(FSTATE *fstate, SINFO *hash_sinfo, 601 Word *nbucket, Word *nchain, size_t *total) 602 { 603 Off offset; 604 Word buf[2]; 605 606 offset = map_addr_to_offset(fstate, hash_sinfo->vaddr, 607 sizeof (buf), NULL, NULL); 608 if (offset == 0) 609 return (0); 610 611 if (read_data(fstate, offset, buf, sizeof (buf), ELF_T_WORD) == 0) 612 return (0); 613 614 *nbucket = buf[0]; 615 *nchain = buf[1]; 616 *total = 2 + *nbucket + *nchain; 617 return (1); 618 } 619 620 621 622 /* 623 * Read a Verdef structure at the specified file offset and return 624 * its vd_cnt, vd_aux, and vd_next fields. 625 */ 626 static int 627 read_verdef(FSTATE *fstate, Off offset, Half *cnt, Word *aux, Word *next) 628 { 629 Verdef verdef; 630 631 if (read_data(fstate, offset, &verdef, sizeof (verdef), 632 ELF_T_BYTE) == 0) 633 return (0); 634 635 /* xlate vd_cnt */ 636 if (xlate_data(fstate, &verdef.vd_cnt, sizeof (verdef.vd_cnt), 637 ELF_T_HALF) == 0) 638 return (0); 639 640 /* 641 * xlate vd_aux and vd_next. These items are adjacent and are 642 * both Words, so they can be handled in a single operation. 643 */ 644 if (xlate_data(fstate, &verdef.vd_aux, 645 2 * sizeof (Word), ELF_T_WORD) == 0) 646 return (0); 647 648 *cnt = verdef.vd_cnt; 649 *aux = verdef.vd_aux; 650 *next = verdef.vd_next; 651 652 return (1); 653 } 654 655 656 657 /* 658 * Read a Verdaux structure at the specified file offset and return 659 * its vda_next field. 660 */ 661 static int 662 read_verdaux(FSTATE *fstate, Off offset, Word *next) 663 { 664 Verdaux verdaux; 665 666 if (read_data(fstate, offset, &verdaux, sizeof (verdaux), 667 ELF_T_BYTE) == 0) 668 return (0); 669 670 /* xlate vda_next */ 671 if (xlate_data(fstate, &verdaux.vda_next, sizeof (verdaux.vda_next), 672 ELF_T_WORD) == 0) 673 return (0); 674 675 *next = verdaux.vda_next; 676 677 return (1); 678 } 679 680 681 682 /* 683 * Read a Verneed structure at the specified file offset and return 684 * its vn_cnt, vn_aux, and vn_next fields. 685 */ 686 static int 687 read_verneed(FSTATE *fstate, Off offset, Half *cnt, Word *aux, Word *next) 688 { 689 Verneed verneed; 690 691 if (read_data(fstate, offset, &verneed, sizeof (verneed), 692 ELF_T_BYTE) == 0) 693 return (0); 694 695 /* xlate vn_cnt */ 696 if (xlate_data(fstate, &verneed.vn_cnt, sizeof (verneed.vn_cnt), 697 ELF_T_HALF) == 0) 698 return (0); 699 700 /* 701 * xlate vn_aux and vn_next. These items are adjacent and are 702 * both Words, so they can be handled in a single operation. 703 */ 704 if (xlate_data(fstate, &verneed.vn_aux, 705 2 * sizeof (Word), ELF_T_WORD) == 0) 706 return (0); 707 708 *cnt = verneed.vn_cnt; 709 *aux = verneed.vn_aux; 710 *next = verneed.vn_next; 711 712 return (1); 713 } 714 715 716 717 /* 718 * Read a Vernaux structure at the specified file offset and return 719 * its vna_next field. 720 */ 721 static int 722 read_vernaux(FSTATE *fstate, Off offset, Word *next) 723 { 724 Vernaux vernaux; 725 726 if (read_data(fstate, offset, &vernaux, sizeof (vernaux), 727 ELF_T_BYTE) == 0) 728 return (0); 729 730 /* xlate vna_next */ 731 if (xlate_data(fstate, &vernaux.vna_next, sizeof (vernaux.vna_next), 732 ELF_T_WORD) == 0) 733 return (0); 734 735 *next = vernaux.vna_next; 736 737 return (1); 738 } 739 740 741 742 /* 743 * Compute the size of Verdef and Verneed sections. Both of these 744 * sections are made up of interleaved main nodes (Verdef and Verneed) 745 * and auxiliary blocks (Verdaux and Vernaux). These nodes refer to 746 * each other by relative offsets. The linker has a lot of flexibility 747 * in how it lays out these items, and we cannot assume a standard 748 * layout. To determine the size of the section, we must read each 749 * main node and compute the high water mark of the memory it and its 750 * auxiliary structs access. 751 * 752 * Although Verdef/Verdaux and Verneed/Vernaux are different types, 753 * their logical organization is the same. Each main block has 754 * a cnt field that tells how many auxiliary blocks it has, an 755 * aux field that gives the offset of the first auxiliary block, and 756 * an offset to the next main block. Each auxiliary block contains 757 * an offset to the next auxiliary block. By breaking the type specific 758 * code into separate sub-functions, we can process both Verdef and 759 * sections Verdaux from a single routine. 760 * 761 * entry: 762 * fstate - Object state 763 * sec - Section to be processed (SINFO_T_VERDEF or SINFO_T_VERNEED). 764 * 765 * exit: 766 * On success, sec->size is set to the section size in bytes, and 767 * True (1) is returned. On failure, False (0) is returned. 768 */ 769 static int 770 verdefneed_size(FSTATE *fstate, SINFO *sec) 771 { 772 int (* read_main)(FSTATE *, Off, Half *, Word *, Word *); 773 int (* read_aux)(FSTATE *, Off, Word *); 774 size_t size_main, size_aux; 775 776 Off offset, aux_offset; 777 Off highwater, extent; 778 size_t num_main = sec->vercnt; 779 Half v_cnt; 780 Word v_aux, v_next, va_next; 781 782 783 /* 784 * Set up the function pointers to the type-specific code 785 * for fetching data from the main and auxiliary blocks. 786 */ 787 if (sec->type == SINFO_T_VERDEF) { 788 read_main = read_verdef; 789 read_aux = read_verdaux; 790 size_main = sizeof (Verdef); 791 size_aux = sizeof (Verdaux); 792 } else { /* SINFO_T_VERNEED */ 793 read_main = read_verneed; 794 read_aux = read_vernaux; 795 size_main = sizeof (Verneed); 796 size_aux = sizeof (Vernaux); 797 } 798 799 /* 800 * Map starting address to file offset. Save the starting offset 801 * in the SINFO size field. Once we have the high water offset, we 802 * can subtract this from it to get the size. 803 * 804 * Note: The size argument set here is a lower bound --- the 805 * size of the main blocks without any auxiliary ones. It's 806 * the best we can do until the size has been determined for real. 807 */ 808 offset = highwater = map_addr_to_offset(fstate, sec->vaddr, 809 size_main * num_main, NULL, NULL); 810 if (offset == 0) 811 return (0); 812 sec->size = offset; 813 814 for (; num_main-- > 0; offset += v_next) { 815 /* Does this move the high water mark up? */ 816 extent = offset + size_main; 817 if (extent > highwater) 818 highwater = extent; 819 820 if ((*read_main)(fstate, offset, &v_cnt, &v_aux, &v_next) == 0) 821 return (0); 822 823 /* 824 * If there are auxiliary structures referenced, 825 * check their position to see if it pushes 826 * the high water mark. 827 */ 828 aux_offset = offset + v_aux; 829 for (; v_cnt-- > 0; aux_offset += va_next) { 830 extent = aux_offset + size_aux; 831 if (extent > highwater) 832 highwater = extent; 833 834 if ((*read_aux)(fstate, aux_offset, &va_next) == 0) 835 return (0); 836 } 837 } 838 839 sec->size = highwater - sec->size; 840 return (1); 841 } 842 843 844 /* 845 * Allocate and fill in a fake section header, data descriptor, 846 * and data buffer for the given section. Fill them in and read 847 * the associated data into the buffer. 848 * 849 * entry: 850 * fstate - Object state 851 * sec - Section information 852 * 853 * exit: 854 * On success, the actions described above are complete, and 855 * True (1) is returned. 856 * 857 * On failure, an error is reported, all resources used by sec 858 * are released, and sec->type is set to SINFO_T_NULL, effectively 859 * eliminating its contents from any further use. False (0) is 860 * returned. 861 */ 862 static int 863 get_data(FSTATE *fstate, SINFO *sec) 864 { 865 866 SINFO_DATA *tinfo; 867 size_t read_bytes, zero_bytes; 868 Phdr *phdr = NULL; 869 870 /* 871 * If this is a NULL section, or if we've already processed 872 * this item, then we are already done. 873 */ 874 if ((sec->type == SINFO_T_NULL) || (sec->shdr != NULL)) 875 return (1); 876 877 if (((sec->shdr = malloc(sizeof (*sec->shdr))) == NULL) || 878 ((sec->data = malloc(sizeof (*sec->data))) == NULL)) { 879 int err = errno; 880 sinfo_free(sec, 1); 881 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 882 fstate->file, strerror(err)); 883 return (0); 884 } 885 tinfo = &sinfo_data[sec->type]; 886 887 888 889 /* 890 * Fill in fake section header 891 * 892 * sh_name should be the offset of the name in the shstrtab 893 * section referenced by the ELF header. There is no 894 * value to elfdump in creating shstrtab, so we set 895 * sh_name to 0, knowing that elfdump doesn't look at it. 896 */ 897 sec->shdr->sh_name = 0; 898 sec->shdr->sh_type = tinfo->sh_type; 899 sec->shdr->sh_flags = tinfo->sh_flags; 900 if ((tinfo->sh_flags & SHF_ALLOC) == 0) { 901 /* 902 * Non-allocable section: Pass the addr (which is probably 903 * 0) and offset through without inspection. 904 */ 905 sec->shdr->sh_addr = sec->vaddr; 906 sec->shdr->sh_offset = sec->offset; 907 zero_bytes = 0; 908 } else if (sec->vaddr == 0) { 909 /* 910 * Allocable section with a 0 vaddr. Figure out the 911 * real address by mapping the offset to it using the 912 * program headers. 913 */ 914 sec->shdr->sh_addr = map_offset_to_addr(fstate, sec->offset, 915 sec->size, &zero_bytes, &phdr); 916 sec->shdr->sh_offset = sec->offset; 917 } else { 918 /* 919 * Allocable section with non-0 vaddr. Use the vaddr 920 * to derive the offset. 921 */ 922 sec->shdr->sh_addr = sec->vaddr; 923 sec->shdr->sh_offset = map_addr_to_offset(fstate, 924 sec->vaddr, sec->size, &zero_bytes, &phdr); 925 } 926 if (sec->shdr->sh_offset == 0) { 927 sinfo_free(sec, 1); 928 return (0); 929 } 930 /* 931 * If the program header has its write flags set, then set 932 * the section write flag. 933 */ 934 if (phdr && ((phdr->p_flags & PF_W) != 0)) 935 sec->shdr->sh_flags |= SHF_WRITE; 936 sec->shdr->sh_size = sec->size; 937 sec->shdr->sh_link = 0; 938 sec->shdr->sh_info = 0; 939 sec->shdr->sh_addralign = tinfo->sh_addralign; 940 sec->shdr->sh_entsize = tinfo->sh_entsize; 941 942 /* 943 * Some sections define special meanings for sh_link and sh_info. 944 */ 945 switch (tinfo->sh_type) { 946 case SHT_DYNAMIC: 947 sec->shdr->sh_link = SINFO_T_DYNSTR; 948 break; 949 950 case SHT_DYNSYM: 951 sec->shdr->sh_link = SINFO_T_DYNSTR; 952 sec->shdr->sh_info = 1; /* First global symbol */ 953 break; 954 955 case SHT_SUNW_LDYNSYM: 956 sec->shdr->sh_link = SINFO_T_DYNSTR; 957 /* 958 * ldynsym is all local symbols, so the index of the 959 * first global is equivalent to the number of symbols. 960 */ 961 sec->shdr->sh_info = sec->shdr->sh_size / sizeof (Sym); 962 break; 963 964 case SHT_HASH: 965 case SHT_SUNW_move: 966 case SHT_REL: 967 case SHT_RELA: 968 case SHT_SUNW_versym: 969 sec->shdr->sh_link = SINFO_T_DYNSYM; 970 break; 971 972 case SHT_SUNW_verdef: 973 case SHT_SUNW_verneed: 974 sec->shdr->sh_link = SINFO_T_DYNSTR; 975 sec->shdr->sh_info = sec->vercnt; 976 break; 977 978 case SHT_SUNW_syminfo: 979 sec->shdr->sh_link = SINFO_T_DYNSYM; 980 sec->shdr->sh_info = SINFO_T_DYN; 981 break; 982 983 case SHT_SUNW_symsort: 984 case SHT_SUNW_tlssort: 985 sec->shdr->sh_link = SINFO_T_LDYNSYM; 986 break; 987 } 988 989 990 991 /* Fill in fake Elf_Data descriptor */ 992 sec->data->d_type = tinfo->libelf_type; 993 sec->data->d_size = sec->size; 994 sec->data->d_off = 0; 995 sec->data->d_align = tinfo->sh_addralign; 996 sec->data->d_version = fstate->ehdr->e_version; 997 998 if (sec->size == 0) { 999 sec->data->d_buf = NULL; 1000 return (1); 1001 } 1002 1003 if ((sec->data->d_buf = malloc(sec->size)) == NULL) { 1004 int err = errno; 1005 1006 sinfo_free(sec, 1); 1007 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 1008 fstate->file, strerror(err)); 1009 return (0); 1010 } 1011 1012 read_bytes = sec->size - zero_bytes; 1013 if ((read_bytes > 0) && 1014 (read_data(fstate, sec->shdr->sh_offset, sec->data->d_buf, 1015 read_bytes, ELF_T_BYTE) == 0)) { 1016 sinfo_free(sec, 1); 1017 return (0); 1018 } 1019 if (zero_bytes > 0) 1020 bzero(read_bytes + (char *)sec->data->d_buf, zero_bytes); 1021 1022 if ((tinfo->libelf_type != ELF_T_BYTE) && 1023 (elf_xlatetom(sec->data, sec->data, 1024 fstate->ehdr->e_ident[EI_DATA]) == NULL)) { 1025 sinfo_free(sec, 1); 1026 failure(fstate->file, MSG_ORIG(MSG_ELF_XLATETOM)); 1027 return (0); 1028 } 1029 1030 return (1); 1031 } 1032 1033 1034 1035 /* 1036 * Generate a section header cache made up of information derived 1037 * from the program headers. 1038 * 1039 * entry: 1040 * file - Name of object 1041 * fd - Open file handle for object 1042 * elf - ELF descriptor 1043 * ehdr - Elf header 1044 * cache, shnum - Addresses of variables to receive resulting 1045 * cache and number of sections. 1046 * 1047 * exit: 1048 * On success, *cache and *shnum are set, and True (1) is returned. 1049 * On failure, False (0) is returned. 1050 * 1051 * note: 1052 * The cache returned by this routine must be freed using 1053 * fake_shdr_cache_free(), and not by a direct call to free(). 1054 * Otherwise, memory will leak. 1055 */ 1056 int 1057 fake_shdr_cache(const char *file, int fd, Elf *elf, Ehdr *ehdr, 1058 Cache **cache, size_t *shnum) 1059 { 1060 /* 1061 * The C language guarantees that a structure of homogeneous 1062 * items will receive exactly the same layout in a structure 1063 * as a plain array of the same type. Hence, this structure, which 1064 * gives us by-name or by-index access to the various section 1065 * info descriptors we maintain. 1066 * 1067 * We use this for sections where 1068 * - Only one instance is allowed 1069 * - We need to be able to access them easily by 1070 * name (for instance, when mining the .dynamic 1071 * section for information to build them up. 1072 * 1073 * NOTE: These fields must be in the same order as the 1074 * SINFO_T_ type codes that correspond to them. Otherwise, 1075 * they will end up in the wrong order in the cache array, 1076 * and the sh_link/sh_info fields may be wrong. 1077 */ 1078 struct { 1079 /* Note: No entry is needed for SINFO_T_NULL */ 1080 SINFO dyn; 1081 SINFO dynstr; 1082 SINFO dynsym; 1083 SINFO ldynsym; 1084 1085 SINFO hash; 1086 SINFO syminfo; 1087 SINFO symsort; 1088 SINFO tlssort; 1089 SINFO verneed; 1090 SINFO verdef; 1091 SINFO versym; 1092 SINFO interp; 1093 SINFO cap; 1094 SINFO unwind; 1095 SINFO move; 1096 SINFO rel; 1097 SINFO rela; 1098 SINFO preinitarr; 1099 SINFO initarr; 1100 SINFO finiarr; 1101 } sec; 1102 static const size_t sinfo_n = sizeof (sec) / sizeof (sec.dyn); 1103 SINFO *secarr = (SINFO *) &sec; 1104 1105 /* 1106 * Doubly linked circular list, used to track sections 1107 * where multiple sections of a given type can exist. 1108 * seclist is the root of the list. Its sinfo field is not 1109 * used --- it serves to anchor the root of the list, allowing 1110 * rapid access to the first and last element in the list. 1111 */ 1112 SINFO_LISTELT seclist; 1113 1114 FSTATE fstate; 1115 size_t ndx; 1116 size_t num_sinfo, num_list_sinfo; 1117 SINFO *sinfo; 1118 SINFO_LISTELT *sinfo_list; 1119 Cache *_cache; 1120 1121 1122 fstate.file = file; 1123 fstate.fd = fd; 1124 fstate.ehdr = ehdr; 1125 if (elf_getphnum(elf, &fstate.phnum) == 0) { 1126 failure(file, MSG_ORIG(MSG_ELF_GETPHNUM)); 1127 return (0); 1128 } 1129 if ((fstate.phdr = elf_getphdr(elf)) == NULL) { 1130 failure(file, MSG_ORIG(MSG_ELF_GETPHDR)); 1131 return (0); 1132 } 1133 1134 bzero(&sec, sizeof (sec)); /* Initialize "by-name" sec info */ 1135 seclist.next = seclist.prev = &seclist; /* Empty circular list */ 1136 1137 /* 1138 * Go through the program headers and look for information 1139 * we can use to synthesize section headers. By far the most 1140 * valuable thing is a dynamic section, the contents of 1141 * which point at all sections used by ld.so.1. 1142 */ 1143 for (ndx = 0; ndx < fstate.phnum; ndx++) { 1144 /* 1145 * A program header with no file size does 1146 * not have a backing section. 1147 */ 1148 if (fstate.phdr[ndx].p_filesz == 0) 1149 continue; 1150 1151 1152 switch (fstate.phdr[ndx].p_type) { 1153 default: 1154 /* Header we can't use. Move on to next one */ 1155 continue; 1156 1157 case PT_DYNAMIC: 1158 sec.dyn.type = SINFO_T_DYN; 1159 sinfo = &sec.dyn; 1160 break; 1161 1162 case PT_INTERP: 1163 sec.interp.type = SINFO_T_INTERP; 1164 sinfo = &sec.interp; 1165 break; 1166 1167 case PT_NOTE: 1168 if ((sinfo = sinfo_list_alloc(&fstate, &seclist)) == 1169 NULL) 1170 continue; 1171 sinfo->type = SINFO_T_NOTE; 1172 break; 1173 1174 case PT_SUNW_UNWIND: 1175 case PT_SUNW_EH_FRAME: 1176 sec.unwind.type = SINFO_T_UNWIND; 1177 sinfo = &sec.unwind; 1178 break; 1179 1180 case PT_SUNWCAP: 1181 sec.cap.type = SINFO_T_CAP; 1182 sinfo = &sec.cap; 1183 break; 1184 } 1185 1186 /* 1187 * Capture the position/extent information for 1188 * the header in the SINFO struct set up by the 1189 * switch statement above. 1190 */ 1191 sinfo->vaddr = fstate.phdr[ndx].p_vaddr; 1192 sinfo->offset = fstate.phdr[ndx].p_offset; 1193 sinfo->size = fstate.phdr[ndx].p_filesz; 1194 } 1195 1196 /* 1197 * If we found a dynamic section, look through it and 1198 * gather information about the sections it references. 1199 */ 1200 if (sec.dyn.type == SINFO_T_DYN) 1201 (void) get_data(&fstate, &sec.dyn); 1202 if ((sec.dyn.type == SINFO_T_DYN) && (sec.dyn.data->d_buf != NULL)) { 1203 Dyn *dyn; 1204 for (dyn = sec.dyn.data->d_buf; dyn->d_tag != DT_NULL; dyn++) { 1205 switch (dyn->d_tag) { 1206 case DT_HASH: 1207 sec.hash.type = SINFO_T_HASH; 1208 sec.hash.vaddr = dyn->d_un.d_ptr; 1209 break; 1210 1211 case DT_STRTAB: 1212 sec.dynstr.type = SINFO_T_DYNSTR; 1213 sec.dynstr.vaddr = dyn->d_un.d_ptr; 1214 break; 1215 1216 case DT_SYMTAB: 1217 sec.dynsym.type = SINFO_T_DYNSYM; 1218 sec.dynsym.vaddr = dyn->d_un.d_ptr; 1219 break; 1220 1221 case DT_RELA: 1222 sec.rela.type = SINFO_T_RELA; 1223 sec.rela.vaddr = dyn->d_un.d_ptr; 1224 break; 1225 1226 case DT_RELASZ: 1227 sec.rela.size = dyn->d_un.d_val; 1228 break; 1229 1230 case DT_STRSZ: 1231 sec.dynstr.size = dyn->d_un.d_val; 1232 break; 1233 1234 case DT_REL: 1235 sec.rel.type = SINFO_T_REL; 1236 sec.rel.vaddr = dyn->d_un.d_ptr; 1237 break; 1238 1239 case DT_RELSZ: 1240 sec.rel.size = dyn->d_un.d_val; 1241 break; 1242 1243 case DT_INIT_ARRAY: 1244 sec.initarr.type = SINFO_T_INITARR; 1245 sec.initarr.vaddr = dyn->d_un.d_ptr; 1246 break; 1247 1248 case DT_INIT_ARRAYSZ: 1249 sec.initarr.size = dyn->d_un.d_val; 1250 break; 1251 1252 case DT_FINI_ARRAY: 1253 sec.finiarr.type = SINFO_T_FINIARR; 1254 sec.finiarr.vaddr = dyn->d_un.d_ptr; 1255 break; 1256 1257 case DT_FINI_ARRAYSZ: 1258 sec.finiarr.size = dyn->d_un.d_val; 1259 break; 1260 1261 case DT_PREINIT_ARRAY: 1262 sec.preinitarr.type = SINFO_T_PREINITARR; 1263 sec.preinitarr.vaddr = dyn->d_un.d_ptr; 1264 break; 1265 1266 case DT_PREINIT_ARRAYSZ: 1267 sec.preinitarr.size = dyn->d_un.d_val; 1268 break; 1269 1270 case DT_SUNW_SYMTAB: 1271 sec.ldynsym.type = SINFO_T_LDYNSYM; 1272 sec.ldynsym.vaddr = dyn->d_un.d_ptr; 1273 break; 1274 1275 case DT_SUNW_SYMSZ: 1276 sec.ldynsym.size = dyn->d_un.d_val; 1277 break; 1278 1279 case DT_SUNW_SYMSORT: 1280 sec.symsort.type = SINFO_T_SYMSORT; 1281 sec.symsort.vaddr = dyn->d_un.d_ptr; 1282 break; 1283 1284 case DT_SUNW_SYMSORTSZ: 1285 sec.symsort.size = dyn->d_un.d_val; 1286 break; 1287 1288 case DT_SUNW_TLSSORT: 1289 sec.tlssort.type = SINFO_T_TLSSORT; 1290 sec.tlssort.vaddr = dyn->d_un.d_ptr; 1291 break; 1292 1293 case DT_SUNW_TLSSORTSZ: 1294 sec.tlssort.size = dyn->d_un.d_val; 1295 break; 1296 1297 case DT_MOVETAB: 1298 sec.move.type = SINFO_T_MOVE; 1299 sec.move.vaddr = dyn->d_un.d_ptr; 1300 break; 1301 1302 case DT_MOVESZ: 1303 sec.move.size = dyn->d_un.d_val; 1304 break; 1305 1306 case DT_SYMINFO: 1307 sec.syminfo.type = SINFO_T_SYMINFO; 1308 sec.syminfo.vaddr = dyn->d_un.d_ptr; 1309 break; 1310 1311 case DT_SYMINSZ: 1312 sec.syminfo.size = dyn->d_un.d_val; 1313 break; 1314 1315 case DT_VERSYM: 1316 sec.versym.type = SINFO_T_VERSYM; 1317 sec.versym.vaddr = dyn->d_un.d_ptr; 1318 break; 1319 1320 case DT_VERDEF: 1321 sec.verdef.type = SINFO_T_VERDEF; 1322 sec.verdef.vaddr = dyn->d_un.d_ptr; 1323 break; 1324 1325 case DT_VERDEFNUM: 1326 sec.verdef.vercnt = dyn->d_un.d_val; 1327 sec.verdef.size = sizeof (Verdef) * 1328 dyn->d_un.d_val; 1329 break; 1330 1331 case DT_VERNEED: 1332 sec.verneed.type = SINFO_T_VERNEED; 1333 sec.verneed.vaddr = dyn->d_un.d_ptr; 1334 break; 1335 1336 case DT_VERNEEDNUM: 1337 sec.verneed.vercnt = dyn->d_un.d_val; 1338 sec.verneed.size = sizeof (Verneed) * 1339 dyn->d_un.d_val; 1340 break; 1341 } 1342 } 1343 } 1344 1345 /* 1346 * Different sections depend on each other, and are meaningless 1347 * without them. For instance, even if a .dynsym exists, 1348 * no use can be made of it without a dynstr. These relationships 1349 * fan out: Disqualifying the .dynsym will disqualify the hash 1350 * section, and so forth. 1351 * 1352 * Disqualify sections that don't have the necessary prerequisites. 1353 */ 1354 1355 /* Things that need the dynamic string table */ 1356 if (sec.dynstr.size == 0) 1357 sec.dynstr.type = SINFO_T_NULL; 1358 if (sec.dynstr.type != SINFO_T_DYNSTR) { 1359 sinfo_free(&sec.dyn, 1); /* Data already fetched */ 1360 sec.dynsym.type = SINFO_T_NULL; 1361 sec.dynsym.type = SINFO_T_NULL; 1362 sec.verdef.type = SINFO_T_NULL; 1363 sec.verneed.type = SINFO_T_NULL; 1364 } 1365 1366 /* 1367 * The length of the hash section is encoded in its first two 1368 * elements (nbucket, and nchain). The length of the dynsym, 1369 * ldynsym, and versym are not given in the dynamic section, 1370 * but are known to be the same as nchain. 1371 * 1372 * If we don't have a hash table, or cannot read nbuckets and 1373 * nchain, we have to invalidate all of these. 1374 */ 1375 if (sec.hash.type == SINFO_T_HASH) { 1376 Word nbucket; 1377 Word nchain; 1378 size_t total; 1379 1380 if (hash_size(&fstate, &sec.hash, 1381 &nbucket, &nchain, &total) == 0) { 1382 sec.hash.type = SINFO_T_NULL; 1383 } else { 1384 /* Use these counts to set sizes for related sections */ 1385 sec.hash.size = total * sizeof (Word); 1386 sec.dynsym.size = nchain * sizeof (Sym); 1387 sec.versym.size = nchain * sizeof (Versym); 1388 1389 /* 1390 * The ldynsym size received the DT_SUNW_SYMSZ 1391 * value, which is the combined size of .dynsym 1392 * and .ldynsym. Now that we have the dynsym size, 1393 * use it to lower the ldynsym size to its real size. 1394 */ 1395 if (sec.ldynsym.size > sec.dynsym.size) 1396 sec.ldynsym.size -= sec.dynsym.size; 1397 } 1398 } 1399 /* 1400 * If the hash table is not present, or if the call to 1401 * hash_size() failed, then discard the sections that 1402 * need it to determine their length. 1403 */ 1404 if (sec.hash.type != SINFO_T_HASH) { 1405 sec.dynsym.type = SINFO_T_NULL; 1406 sec.ldynsym.type = SINFO_T_NULL; 1407 sec.versym.type = SINFO_T_NULL; 1408 } 1409 1410 /* 1411 * The runtime linker does not receive size information for 1412 * Verdef and Verneed sections. We have to read their data 1413 * in pieces and calculate it. 1414 */ 1415 if ((sec.verdef.type == SINFO_T_VERDEF) && 1416 (verdefneed_size(&fstate, &sec.verdef) == 0)) 1417 sec.verdef.type = SINFO_T_NULL; 1418 if ((sec.verneed.type == SINFO_T_VERNEED) && 1419 (verdefneed_size(&fstate, &sec.verneed) == 0)) 1420 sec.verneed.type = SINFO_T_NULL; 1421 1422 /* Discard any section with a zero length */ 1423 ndx = sinfo_n; 1424 for (sinfo = secarr; ndx-- > 0; sinfo++) 1425 if ((sinfo->type != SINFO_T_NULL) && (sinfo->size == 0)) 1426 sinfo->type = SINFO_T_NULL; 1427 1428 /* Things that need the dynamic symbol table */ 1429 if (sec.dynsym.type != SINFO_T_DYNSYM) { 1430 sec.ldynsym.type = SINFO_T_NULL; 1431 sec.hash.type = SINFO_T_NULL; 1432 sec.syminfo.type = SINFO_T_NULL; 1433 sec.versym.type = SINFO_T_NULL; 1434 sec.move.type = SINFO_T_NULL; 1435 sec.rel.type = SINFO_T_NULL; 1436 sec.rela.type = SINFO_T_NULL; 1437 } 1438 1439 /* Things that need the dynamic local symbol table */ 1440 if (sec.ldynsym.type != SINFO_T_DYNSYM) { 1441 sec.symsort.type = SINFO_T_NULL; 1442 sec.tlssort.type = SINFO_T_NULL; 1443 } 1444 1445 /* 1446 * Look through the results and fetch the data for any sections 1447 * we have found. At the same time, count the number. 1448 */ 1449 num_sinfo = num_list_sinfo = 0; 1450 ndx = sinfo_n; 1451 for (sinfo = secarr; ndx-- > 0; sinfo++) { 1452 if ((sinfo->type != SINFO_T_NULL) && (sinfo->data == NULL)) 1453 (void) get_data(&fstate, sinfo); 1454 if (sinfo->data != NULL) 1455 num_sinfo++; 1456 } 1457 for (sinfo_list = seclist.next; sinfo_list != &seclist; 1458 sinfo_list = sinfo_list->next) { 1459 sinfo = &sinfo_list->sinfo; 1460 if ((sinfo->type != SINFO_T_NULL) && (sinfo->data == NULL)) 1461 (void) get_data(&fstate, sinfo); 1462 if (sinfo->data != NULL) 1463 num_list_sinfo++; 1464 } 1465 1466 /* 1467 * Allocate the cache array and fill it in. The cache array 1468 * ends up taking all the dynamic memory we've allocated 1469 * to build up sec and seclist, so on success, we have nothing 1470 * left to clean up. If we can't allocate the cache array 1471 * though, we have to free up everything else. 1472 */ 1473 *shnum = num_sinfo + num_list_sinfo + 1; /* Extra for 1st NULL sec. */ 1474 if ((*cache = _cache = malloc((*shnum) * sizeof (Cache))) == NULL) { 1475 int err = errno; 1476 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 1477 file, strerror(err)); 1478 sinfo_free(secarr, num_sinfo); 1479 sinfo_list_free_all(&seclist); 1480 return (0); 1481 } 1482 *_cache = cache_init; 1483 _cache++; 1484 ndx = 1; 1485 for (sinfo = secarr; num_sinfo > 0; sinfo++) { 1486 if (sinfo->data != NULL) { 1487 _cache->c_scn = NULL; 1488 _cache->c_shdr = sinfo->shdr; 1489 _cache->c_data = sinfo->data; 1490 _cache->c_name = (char *)sinfo_data[sinfo->type].name; 1491 _cache->c_ndx = ndx++; 1492 _cache++; 1493 num_sinfo--; 1494 } 1495 } 1496 for (sinfo_list = seclist.next; num_list_sinfo > 0; 1497 sinfo_list = sinfo_list->next) { 1498 sinfo = &sinfo_list->sinfo; 1499 if (sinfo->data != NULL) { 1500 _cache->c_scn = NULL; 1501 _cache->c_shdr = sinfo->shdr; 1502 _cache->c_data = sinfo->data; 1503 _cache->c_name = (char *)sinfo_data[sinfo->type].name; 1504 _cache->c_ndx = ndx++; 1505 _cache++; 1506 num_list_sinfo--; 1507 } 1508 } 1509 1510 return (1); 1511 } 1512 1513 1514 1515 1516 1517 /* 1518 * Release all the memory referenced by a cache array allocated 1519 * by fake_shdr_cache(). 1520 */ 1521 void 1522 fake_shdr_cache_free(Cache *cache, size_t shnum) 1523 { 1524 Cache *_cache; 1525 1526 for (_cache = cache; shnum--; _cache++) { 1527 if (_cache->c_data != NULL) { 1528 if (_cache->c_data->d_buf != NULL) 1529 free(_cache->c_data->d_buf); 1530 free(_cache->c_data); 1531 } 1532 if (_cache->c_shdr) 1533 free(_cache->c_shdr); 1534 } 1535 1536 free(cache); 1537 } 1538