1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Generate a cache of section header information for an ELF 30 * object from the information found in its program headers. 31 * 32 * Malicious code can remove or corrupt section headers. The 33 * resulting program will be difficult to analyze, but is still 34 * runnable. Hence, scribbling on the section headers or removing 35 * them is an effective form of obfuscation. On the other hand, 36 * program headers must be accurate or the program will not run. 37 * Section headers derived from them will necessarily lack information 38 * found in the originals (particularly for non-allocable sections), 39 * but will provide essential symbol information. The focus is on 40 * recovering information that elfdump knows how to display, and that 41 * might be interesting in a forensic situation. 42 * 43 * There are some things we don't attempt to create sections for: 44 * 45 * plt, got 46 * We have no way to determine the length of either of 47 * these sections from the information available via 48 * the program headers or dynamic section. The data in 49 * the PLT is of little use to elfdump. The data in the 50 * GOT might be somewhat more interesting, especially as 51 * it pertains to relocations. However, the sizing issue 52 * remains. 53 * 54 * text, data, bss 55 * Although we could create these, there is little value 56 * to doing so. elfdump cannot display the arbitrary 57 * data in these sections, so this would amount to a 58 * simple repetition of the information already displayed 59 * in the program headers, with no additional benefit. 60 */ 61 62 63 64 #include <sys/elf_amd64.h> 65 #include <stdio.h> 66 #include <unistd.h> 67 #include <errno.h> 68 #include <string.h> 69 #include <strings.h> 70 #include <conv.h> 71 #include <msg.h> 72 #include <_elfdump.h> 73 74 75 76 /* 77 * Common information about the object that is needed by 78 * all the routines in this module. 79 */ 80 typedef struct { 81 const char *file; 82 int fd; 83 Ehdr *ehdr; 84 Phdr *phdr; 85 size_t phnum; 86 } FSTATE; 87 88 89 90 /* 91 * These values uniquely identify the sections that we know 92 * how to recover. 93 * 94 * Note: We write the sections to the cache array in this same order. 95 * It simplifies this code if the dynamic, dynstr, dynsym, and ldynsym 96 * sections occupy known slots in the cache array. Other sections reference 97 * them by index, and if they are at a known spot, there is no need 98 * for a fixup pass. Putting them in positions [1-4] solves this. 99 * 100 * The order they are in was chosen such that if any one of them exists, 101 * all of the ones before it must also exist. This means that if the 102 * desired section exists, it will end up in the desired index in the 103 * cache array. 104 * 105 * The order of the other sections is arbitrary. I've arranged them 106 * in roughly related groups. 107 */ 108 typedef enum { 109 SINFO_T_NULL = 0, 110 SINFO_T_DYN = 1, 111 SINFO_T_DYNSTR = 2, 112 SINFO_T_DYNSYM = 3, 113 SINFO_T_LDYNSYM = 4, 114 115 SINFO_T_HASH = 5, 116 SINFO_T_SYMINFO = 6, 117 SINFO_T_SYMSORT = 7, 118 SINFO_T_TLSSORT = 8, 119 SINFO_T_VERNEED = 9, 120 SINFO_T_VERDEF = 10, 121 SINFO_T_VERSYM = 11, 122 SINFO_T_INTERP = 12, 123 SINFO_T_CAP = 13, 124 SINFO_T_UNWIND = 14, 125 SINFO_T_MOVE = 15, 126 SINFO_T_REL = 16, 127 SINFO_T_RELA = 17, 128 SINFO_T_PREINITARR = 18, 129 SINFO_T_INITARR = 19, 130 SINFO_T_FINIARR = 20, 131 SINFO_T_NOTE = 21, 132 133 SINFO_T_NUM = 22 /* Count of items. Must come last */ 134 } SINFO_TYPE; 135 136 137 138 /* 139 * Table of per-section constant data used to set up the section 140 * header cache and the various sub-parts it references. Indexed by 141 * SINFO_T value. 142 * 143 * note: The sh_flags value should be either SHF_ALLOC, or 0. 144 * get_data() sets SHF_WRITE if the program header containing the 145 * section is writable. The other flags require information that 146 * the program headers don't contain (i.e. SHF_STRINGS, etc) so 147 * we don't set them. 148 */ 149 typedef struct { 150 const char *name; 151 Word sh_type; 152 Word sh_flags; 153 Word sh_addralign; 154 Word sh_entsize; 155 Elf_Type libelf_type; 156 } SINFO_DATA; 157 158 /* 159 * Many of these sections use an alignment given by M_WORD_ALIGN, a 160 * value that varies depending on the object target machine. Since we 161 * don't know that value at compile time, we settle for a value of 162 * 4 for ELFCLASS32 objects, and 8 for ELFCLASS64. This matches the 163 * platforms we current support (sparc and x86), and is good enough for 164 * a fake section header in any event, as the resulting object is only 165 * analyzed, and is not executed. 166 */ 167 #ifdef _ELF64 168 #define FAKE_M_WORD_ALIGN 8 169 #else 170 #define FAKE_M_WORD_ALIGN 4 171 #endif 172 173 static SINFO_DATA sinfo_data[SINFO_T_NUM] = { 174 /* SINFO_T_NULL */ 175 { 0 }, 176 177 /* SINFO_T_DYN */ 178 { MSG_ORIG(MSG_PHDRNAM_DYN), SHT_DYNAMIC, SHF_ALLOC, 179 FAKE_M_WORD_ALIGN, sizeof (Dyn), ELF_T_DYN }, 180 181 /* SINFO_T_DYNSTR */ 182 { MSG_ORIG(MSG_PHDRNAM_DYNSTR), SHT_STRTAB, SHF_ALLOC, 183 1, 0, ELF_T_BYTE }, 184 185 /* SINFO_T_DYNSYM */ 186 { MSG_ORIG(MSG_PHDRNAM_DYNSYM), SHT_DYNSYM, SHF_ALLOC, 187 FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, 188 189 /* SINFO_T_LDYNSYM */ 190 { MSG_ORIG(MSG_PHDRNAM_LDYNSYM), SHT_SUNW_LDYNSYM, SHF_ALLOC, 191 FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM }, 192 193 /* SINFO_T_HASH */ 194 { MSG_ORIG(MSG_PHDRNAM_HASH), SHT_HASH, SHF_ALLOC, 195 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, 196 197 /* SINFO_T_SYMINFO */ 198 { MSG_ORIG(MSG_PHDRNAM_SYMINFO), SHT_SUNW_syminfo, SHF_ALLOC, 199 FAKE_M_WORD_ALIGN, sizeof (Syminfo), ELF_T_SYMINFO }, 200 201 /* SINFO_T_SYMSORT */ 202 { MSG_ORIG(MSG_PHDRNAM_SYMSORT), SHT_SUNW_symsort, SHF_ALLOC, 203 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, 204 205 /* SINFO_T_TLSSORT */ 206 { MSG_ORIG(MSG_PHDRNAM_TLSSORT), SHT_SUNW_tlssort, SHF_ALLOC, 207 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD }, 208 209 /* SINFO_T_VERNEED */ 210 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verneed, SHF_ALLOC, 211 FAKE_M_WORD_ALIGN, 1, ELF_T_VNEED }, 212 213 /* SINFO_T_VERDEF */ 214 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verdef, SHF_ALLOC, 215 FAKE_M_WORD_ALIGN, 1, ELF_T_VDEF }, 216 217 /* SINFO_T_VERSYM */ 218 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_versym, SHF_ALLOC, 219 FAKE_M_WORD_ALIGN, sizeof (Versym), ELF_T_HALF }, 220 221 /* SINFO_T_INTERP */ 222 { MSG_ORIG(MSG_PHDRNAM_INTERP), SHT_PROGBITS, SHF_ALLOC, 223 1, 0, ELF_T_BYTE }, 224 225 /* SINFO_T_CAP */ 226 { MSG_ORIG(MSG_PHDRNAM_CAP), SHT_SUNW_cap, SHF_ALLOC, 227 sizeof (Addr), sizeof (Cap), ELF_T_CAP }, 228 229 /* SINFO_T_UNWIND */ 230 { MSG_ORIG(MSG_PHDRNAM_UNWIND), SHT_AMD64_UNWIND, SHF_ALLOC, 231 sizeof (Addr), 0, ELF_T_BYTE }, 232 233 /* SINFO_T_MOVE */ 234 { MSG_ORIG(MSG_PHDRNAM_MOVE), SHT_SUNW_move, SHF_ALLOC, 235 sizeof (Lword), sizeof (Move), ELF_T_MOVE }, 236 237 /* SINFO_T_REL */ 238 { MSG_ORIG(MSG_PHDRNAM_REL), SHT_REL, SHF_ALLOC, 239 FAKE_M_WORD_ALIGN, sizeof (Rel), ELF_T_REL }, 240 241 /* SINFO_T_RELA */ 242 { MSG_ORIG(MSG_PHDRNAM_RELA), SHT_RELA, SHF_ALLOC, 243 FAKE_M_WORD_ALIGN, sizeof (Rela), ELF_T_RELA }, 244 245 /* SINFO_T_PREINITARR */ 246 { MSG_ORIG(MSG_PHDRNAM_PREINITARR), SHT_PREINIT_ARRAY, SHF_ALLOC, 247 sizeof (Addr), sizeof (Addr), ELF_T_ADDR }, 248 249 /* SINFO_T_INITARR */ 250 { MSG_ORIG(MSG_PHDRNAM_INITARR), SHT_INIT_ARRAY, SHF_ALLOC, 251 sizeof (Addr), sizeof (Addr), ELF_T_ADDR }, 252 253 /* SINFO_T_FINIARR */ 254 { MSG_ORIG(MSG_PHDRNAM_FINIARR), SHT_FINI_ARRAY, SHF_ALLOC, 255 sizeof (Addr), sizeof (Addr), ELF_T_ADDR }, 256 257 /* SINFO_T_NOTE */ 258 { MSG_ORIG(MSG_PHDRNAM_NOTE), SHT_NOTE, 0, 259 FAKE_M_WORD_ALIGN, 1, ELF_T_NOTE } 260 }; 261 262 263 264 265 266 /* 267 * As we read program headers and dynamic elements, we build up 268 * the data for our fake section headers in variables of the 269 * SINFO type. SINFO is used to track the sections that can only 270 * appear a fixed number of times (usually once). 271 * 272 * SINFO_LISTELT is used for sections that can occur an arbitrary 273 * number of times. They are kept in a doubly linked circular 274 * buffer. 275 */ 276 typedef struct { 277 SINFO_TYPE type; /* Our type code for the section */ 278 Addr vaddr; /* Virtual memory address */ 279 Off offset; /* File offset of data. Ignored unless */ 280 /* vaddr is 0. Used by program headers */ 281 size_t size; /* # bytes in section */ 282 size_t vercnt; /* Used by verdef and verneed to hold count */ 283 Shdr *shdr; /* Constructed shdr */ 284 Elf_Data *data; /* Constructed data descriptor */ 285 } SINFO; 286 287 typedef struct _sinfo_listelt { 288 struct _sinfo_listelt *next; 289 struct _sinfo_listelt *prev; 290 SINFO sinfo; 291 } SINFO_LISTELT; 292 293 294 295 /* 296 * Free dynamic memory used by SINFO structures. 297 * 298 * entry: 299 * sinfo - Address of first SINFO structure to free 300 * n - # of structures to clear 301 * 302 * exit: 303 * For each SINFO struct, the section header, data descriptor, 304 * and data buffer are freed if non-NULL. The relevant 305 * fields are set to NULL, and the type is set to SINFO_T_NULL. 306 */ 307 static void 308 sinfo_free(SINFO *sinfo, size_t n) 309 { 310 for (; n-- > 0; sinfo++) { 311 if (sinfo->data != NULL) { 312 if (sinfo->data->d_buf != NULL) 313 free(sinfo->data->d_buf); 314 free(sinfo->data); 315 sinfo->data = NULL; 316 } 317 318 if (sinfo->shdr) { 319 free(sinfo->shdr); 320 sinfo->shdr = NULL; 321 } 322 sinfo->type = SINFO_T_NULL; 323 } 324 } 325 326 327 328 /* 329 * Allocate a new SINFO_LISTELT and put it at the end of the 330 * doubly linked list anchored by the given list root node. 331 * 332 * On success, a new node has been put at the end of the circular 333 * doubly linked list, and a pointer to the SINFO sub-structure is 334 * returned. On failure, an error is printed, and NULL is returned. 335 */ 336 337 static SINFO * 338 sinfo_list_alloc(FSTATE *fstate, SINFO_LISTELT *root) 339 { 340 SINFO_LISTELT *elt; 341 342 if ((elt = malloc(sizeof (*elt))) == NULL) { 343 int err = errno; 344 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 345 fstate->file, strerror(err)); 346 return (0); 347 } 348 349 elt->next = root; 350 elt->prev = root->prev; 351 352 root->prev = elt; 353 elt->prev->next = elt; 354 355 bzero(&elt->sinfo, sizeof (elt->sinfo)); 356 return (&elt->sinfo); 357 } 358 359 360 361 /* 362 * Release the memory used by the given list, restoring it to 363 * an empty list. 364 */ 365 static void 366 sinfo_list_free_all(SINFO_LISTELT *root) 367 { 368 SINFO_LISTELT *elt; 369 370 for (elt = root->next; elt != root; elt = elt->next) 371 sinfo_free(&elt->sinfo, 1); 372 373 root->next = root->prev = root; 374 } 375 376 377 378 /* 379 * Given a virtual address and desired size of the data to be found 380 * at that address, look through the program headers for the PT_LOAD 381 * segment that contains it and return the offset within the ELF file 382 * at which it resides. 383 * 384 * entry: 385 * fstate - Object state 386 * addr - virtual address to be translated 387 * size - Size of the data to be found at that address, in bytes 388 * zero_bytes - NULL, or address to receive the number of data 389 * bytes at the end of the data that are not contained 390 * in the file, and which must be zero filled by the caller. 391 * If zero_bytes is NULL, the file must contain all of the 392 * desired data. If zero_bytes is not NULL, then the program 393 * header must reserve the space for all of the data (p_memsz) 394 * but it is acceptable for only part of the data to be in 395 * the file (p_filesz). *zero_bytes is set to the difference 396 * in size, and is the number of bytes the caller must 397 * set to 0 rather than reading from the file. 398 * phdr_ret - NULL, or address of variable to receive pointer 399 * to program header that contains offset. 400 * exit: 401 * On success: If zero_bytes is non-NULL, it is updated. If phdr_ret 402 * is non-NULL, it is updated. The file offset is returned. 403 * 404 * On failure, 0 is returned. Since any ELF file we can understand 405 * must start with an ELF magic number, 0 cannot be a valid file 406 * offset for a virtual address, and is therefore unambiguous as 407 * a failure indication. 408 */ 409 static Off 410 map_addr_to_offset(FSTATE *fstate, Addr addr, size_t size, size_t *zero_bytes, 411 Phdr **phdr_ret) 412 { 413 Off offset; 414 Addr end_addr = addr + size; 415 size_t avail_file; 416 Phdr *phdr = fstate->phdr; 417 size_t phnum = fstate->phnum; 418 419 for (; phnum--; phdr++) { 420 if (phdr->p_type != PT_LOAD) 421 continue; 422 423 if ((addr >= phdr->p_vaddr) && 424 (end_addr <= (phdr->p_vaddr + phdr->p_memsz))) { 425 /* 426 * Subtract segment virtual address, leaving the 427 * offset relative to the segment (not the file). 428 */ 429 offset = addr - phdr->p_vaddr; 430 avail_file = phdr->p_filesz - offset; 431 432 /* 433 * The addr/size are in bounds for this segment. 434 * Is there enough data in the file to satisfy 435 * the request? If zero_bytes is NULL, it must 436 * all be in the file. Otherwise it can be 437 * zero filled. 438 */ 439 if (zero_bytes == NULL) { 440 if (size > avail_file) 441 continue; 442 } else { 443 *zero_bytes = (size > avail_file) ? 444 (size - avail_file) : 0; 445 } 446 447 if (phdr_ret != NULL) 448 *phdr_ret = phdr; 449 450 /* Add segment file offset, giving overall offset */ 451 return (phdr->p_offset + offset); 452 } 453 } 454 455 /* If we get here, the mapping failed */ 456 return (0); 457 } 458 459 460 461 /* 462 * This routine is the same thing as map_addr_to_offset(), except that 463 * it goes the other way, mapping from offset to virtual address. 464 * 465 * The comments for map_addr_to_offset() are applicable if you 466 * reverse offset and address. 467 */ 468 469 static Addr 470 map_offset_to_addr(FSTATE *fstate, Off offset, size_t size, size_t *zero_bytes, 471 Phdr **phdr_ret) 472 { 473 Off end_offset = offset + size; 474 size_t avail_file; 475 Phdr *phdr = fstate->phdr; 476 size_t phnum = fstate->phnum; 477 478 for (; phnum--; phdr++) { 479 if (phdr->p_type != PT_LOAD) 480 continue; 481 482 if ((offset >= phdr->p_offset) && 483 (end_offset <= (phdr->p_offset + phdr->p_memsz))) { 484 /* 485 * Subtract segment offset, leaving the 486 * offset relative to the segment (not the file). 487 */ 488 offset -= phdr->p_offset; 489 avail_file = phdr->p_filesz - offset; 490 491 /* 492 * The offset/size are in bounds for this segment. 493 * Is there enough data in the file to satisfy 494 * the request? If zero_bytes is NULL, it must 495 * all be in the file. Otherwise it can be 496 * zero filled. 497 */ 498 if (zero_bytes == NULL) { 499 if (size > avail_file) 500 continue; 501 } else { 502 *zero_bytes = (size > avail_file) ? 503 (size - avail_file) : 0; 504 } 505 506 if (phdr_ret != NULL) 507 *phdr_ret = phdr; 508 509 /* Add segment virtual address, giving overall addr */ 510 return (phdr->p_vaddr + offset); 511 } 512 } 513 514 /* If we get here, the mapping failed */ 515 return (0); 516 } 517 518 519 520 /* 521 * Use elf_xlatetom() to convert the bytes in buf from their 522 * in-file representation to their in-memory representation. 523 * 524 * Returns True(1) for success. On failure, an error message is printed 525 * and False(0) is returned. 526 */ 527 static int 528 xlate_data(FSTATE *fstate, void *buf, size_t nbyte, Elf_Type xlate_type) 529 { 530 Elf_Data data; 531 532 data.d_type = xlate_type; 533 data.d_size = nbyte; 534 data.d_off = 0; 535 data.d_align = 0; 536 data.d_version = fstate->ehdr->e_version; 537 data.d_buf = buf; 538 539 if (elf_xlatetom(&data, &data, 540 fstate->ehdr->e_ident[EI_DATA]) == NULL) { 541 failure(fstate->file, MSG_ORIG(MSG_ELF_XLATETOM)); 542 return (0); 543 } 544 545 return (1); 546 } 547 548 549 /* 550 * Read nbytes of data into buf, starting at the specified offset 551 * within the ELF file. 552 * 553 * entry: 554 * fstate - Object state 555 * offset - Offset within the file at which desired data resides. 556 * buf - Buffer to receive the data 557 * nbyte - # of bytes to read into buf 558 * xlate_type - An ELF xlate type, specifying the type of data 559 * being input. If xlate_type is ELF_T_BYTE, xlate is not 560 * done. Otherwise, xlate_data() is called to convert the 561 * data into its in-memory representation. 562 * exit: 563 * On success, the data has been written into buf, xlate_data() 564 * called on it if required, and True(1) is returned. Otherwise 565 * False(0) is returned. 566 * 567 * note: 568 * This routine does not move the file pointer. 569 */ 570 static int 571 read_data(FSTATE *fstate, Off offset, void *buf, size_t nbyte, 572 Elf_Type xlate_type) 573 { 574 if (pread(fstate->fd, buf, nbyte, offset) != nbyte) { 575 int err = errno; 576 577 (void) fprintf(stderr, MSG_INTL(MSG_ERR_READ), 578 fstate->file, strerror(err)); 579 return (0); 580 } 581 582 if (xlate_type != ELF_T_BYTE) 583 return (xlate_data(fstate, buf, nbyte, xlate_type)); 584 585 return (1); 586 } 587 588 589 590 /* 591 * Read the hash nbucket/nchain values from the start of the hash 592 * table found at the given virtual address in the mapped ELF object. 593 * 594 * On success, *nbucket, and *nchain have been filled in with their 595 * values, *total contains the number of elements in the hash table, 596 * and this routine returns True (1). 597 * 598 * On failure, False (0) is returned. 599 */ 600 static int 601 hash_size(FSTATE *fstate, SINFO *hash_sinfo, 602 Word *nbucket, Word *nchain, size_t *total) 603 { 604 Off offset; 605 Word buf[2]; 606 607 offset = map_addr_to_offset(fstate, hash_sinfo->vaddr, 608 sizeof (buf), NULL, NULL); 609 if (offset == 0) 610 return (0); 611 612 if (read_data(fstate, offset, buf, sizeof (buf), ELF_T_WORD) == 0) 613 return (0); 614 615 *nbucket = buf[0]; 616 *nchain = buf[1]; 617 *total = 2 + *nbucket + *nchain; 618 return (1); 619 } 620 621 622 623 /* 624 * Read a Verdef structure at the specified file offset and return 625 * its vd_cnt, vd_aux, and vd_next fields. 626 */ 627 static int 628 read_verdef(FSTATE *fstate, Off offset, Half *cnt, Word *aux, Word *next) 629 { 630 Verdef verdef; 631 632 if (read_data(fstate, offset, &verdef, sizeof (verdef), 633 ELF_T_BYTE) == 0) 634 return (0); 635 636 /* xlate vd_cnt */ 637 if (xlate_data(fstate, &verdef.vd_cnt, sizeof (verdef.vd_cnt), 638 ELF_T_HALF) == 0) 639 return (0); 640 641 /* 642 * xlate vd_aux and vd_next. These items are adjacent and are 643 * both Words, so they can be handled in a single operation. 644 */ 645 if (xlate_data(fstate, &verdef.vd_aux, 646 2 * sizeof (Word), ELF_T_WORD) == 0) 647 return (0); 648 649 *cnt = verdef.vd_cnt; 650 *aux = verdef.vd_aux; 651 *next = verdef.vd_next; 652 653 return (1); 654 } 655 656 657 658 /* 659 * Read a Verdaux structure at the specified file offset and return 660 * its vda_next field. 661 */ 662 static int 663 read_verdaux(FSTATE *fstate, Off offset, Word *next) 664 { 665 Verdaux verdaux; 666 667 if (read_data(fstate, offset, &verdaux, sizeof (verdaux), 668 ELF_T_BYTE) == 0) 669 return (0); 670 671 /* xlate vda_next */ 672 if (xlate_data(fstate, &verdaux.vda_next, sizeof (verdaux.vda_next), 673 ELF_T_WORD) == 0) 674 return (0); 675 676 *next = verdaux.vda_next; 677 678 return (1); 679 } 680 681 682 683 /* 684 * Read a Verneed structure at the specified file offset and return 685 * its vn_cnt, vn_aux, and vn_next fields. 686 */ 687 static int 688 read_verneed(FSTATE *fstate, Off offset, Half *cnt, Word *aux, Word *next) 689 { 690 Verneed verneed; 691 692 if (read_data(fstate, offset, &verneed, sizeof (verneed), 693 ELF_T_BYTE) == 0) 694 return (0); 695 696 /* xlate vn_cnt */ 697 if (xlate_data(fstate, &verneed.vn_cnt, sizeof (verneed.vn_cnt), 698 ELF_T_HALF) == 0) 699 return (0); 700 701 /* 702 * xlate vn_aux and vn_next. These items are adjacent and are 703 * both Words, so they can be handled in a single operation. 704 */ 705 if (xlate_data(fstate, &verneed.vn_aux, 706 2 * sizeof (Word), ELF_T_WORD) == 0) 707 return (0); 708 709 *cnt = verneed.vn_cnt; 710 *aux = verneed.vn_aux; 711 *next = verneed.vn_next; 712 713 return (1); 714 } 715 716 717 718 /* 719 * Read a Vernaux structure at the specified file offset and return 720 * its vna_next field. 721 */ 722 static int 723 read_vernaux(FSTATE *fstate, Off offset, Word *next) 724 { 725 Vernaux vernaux; 726 727 if (read_data(fstate, offset, &vernaux, sizeof (vernaux), 728 ELF_T_BYTE) == 0) 729 return (0); 730 731 /* xlate vna_next */ 732 if (xlate_data(fstate, &vernaux.vna_next, sizeof (vernaux.vna_next), 733 ELF_T_WORD) == 0) 734 return (0); 735 736 *next = vernaux.vna_next; 737 738 return (1); 739 } 740 741 742 743 /* 744 * Compute the size of Verdef and Verneed sections. Both of these 745 * sections are made up of interleaved main nodes (Verdef and Verneed) 746 * and auxiliary blocks (Verdaux and Vernaux). These nodes refer to 747 * each other by relative offsets. The linker has a lot of flexibility 748 * in how it lays out these items, and we cannot assume a standard 749 * layout. To determine the size of the section, we must read each 750 * main node and compute the high water mark of the memory it and its 751 * auxiliary structs access. 752 * 753 * Although Verdef/Verdaux and Verneed/Vernaux are different types, 754 * their logical organization is the same. Each main block has 755 * a cnt field that tells how many auxiliary blocks it has, an 756 * aux field that gives the offset of the first auxiliary block, and 757 * an offset to the next main block. Each auxiliary block contains 758 * an offset to the next auxiliary block. By breaking the type specific 759 * code into separate sub-functions, we can process both Verdef and 760 * sections Verdaux from a single routine. 761 * 762 * entry: 763 * fstate - Object state 764 * sec - Section to be processed (SINFO_T_VERDEF or SINFO_T_VERNEED). 765 * 766 * exit: 767 * On success, sec->size is set to the section size in bytes, and 768 * True (1) is returned. On failure, False (0) is returned. 769 */ 770 static int 771 verdefneed_size(FSTATE *fstate, SINFO *sec) 772 { 773 int (* read_main)(FSTATE *, Off, Half *, Word *, Word *); 774 int (* read_aux)(FSTATE *, Off, Word *); 775 size_t size_main, size_aux; 776 777 Off offset, aux_offset; 778 Off highwater, extent; 779 size_t num_main = sec->vercnt; 780 Half v_cnt; 781 Word v_aux, v_next, va_next; 782 783 784 /* 785 * Set up the function pointers to the type-specific code 786 * for fetching data from the main and auxiliary blocks. 787 */ 788 if (sec->type == SINFO_T_VERDEF) { 789 read_main = read_verdef; 790 read_aux = read_verdaux; 791 size_main = sizeof (Verdef); 792 size_aux = sizeof (Verdaux); 793 } else { /* SINFO_T_VERNEED */ 794 read_main = read_verneed; 795 read_aux = read_vernaux; 796 size_main = sizeof (Verneed); 797 size_aux = sizeof (Vernaux); 798 } 799 800 /* 801 * Map starting address to file offset. Save the starting offset 802 * in the SINFO size field. Once we have the high water offset, we 803 * can subtract this from it to get the size. 804 * 805 * Note: The size argument set here is a lower bound --- the 806 * size of the main blocks without any auxiliary ones. It's 807 * the best we can do until the size has been determined for real. 808 */ 809 offset = highwater = map_addr_to_offset(fstate, sec->vaddr, 810 size_main * num_main, NULL, NULL); 811 if (offset == 0) 812 return (0); 813 sec->size = offset; 814 815 for (; num_main-- > 0; offset += v_next) { 816 /* Does this move the high water mark up? */ 817 extent = offset + size_main; 818 if (extent > highwater) 819 highwater = extent; 820 821 if ((*read_main)(fstate, offset, &v_cnt, &v_aux, &v_next) == 0) 822 return (0); 823 824 /* 825 * If there are auxiliary structures referenced, 826 * check their position to see if it pushes 827 * the high water mark. 828 */ 829 aux_offset = offset + v_aux; 830 for (; v_cnt-- > 0; aux_offset += va_next) { 831 extent = aux_offset + size_aux; 832 if (extent > highwater) 833 highwater = extent; 834 835 if ((*read_aux)(fstate, aux_offset, &va_next) == 0) 836 return (0); 837 } 838 } 839 840 sec->size = highwater - sec->size; 841 return (1); 842 } 843 844 845 /* 846 * Allocate and fill in a fake section header, data descriptor, 847 * and data buffer for the given section. Fill them in and read 848 * the associated data into the buffer. 849 * 850 * entry: 851 * fstate - Object state 852 * sec - Section information 853 * 854 * exit: 855 * On success, the actions described above are complete, and 856 * True (1) is returned. 857 * 858 * On failure, an error is reported, all resources used by sec 859 * are released, and sec->type is set to SINFO_T_NULL, effectively 860 * eliminating its contents from any further use. False (0) is 861 * returned. 862 */ 863 static int 864 get_data(FSTATE *fstate, SINFO *sec) 865 { 866 867 SINFO_DATA *tinfo; 868 size_t read_bytes, zero_bytes; 869 Phdr *phdr = NULL; 870 871 /* 872 * If this is a NULL section, or if we've already processed 873 * this item, then we are already done. 874 */ 875 if ((sec->type == SINFO_T_NULL) || (sec->shdr != NULL)) 876 return (1); 877 878 if (((sec->shdr = malloc(sizeof (*sec->shdr))) == NULL) || 879 ((sec->data = malloc(sizeof (*sec->data))) == NULL)) { 880 int err = errno; 881 sinfo_free(sec, 1); 882 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 883 fstate->file, strerror(err)); 884 return (0); 885 } 886 tinfo = &sinfo_data[sec->type]; 887 888 889 890 /* 891 * Fill in fake section header 892 * 893 * sh_name should be the offset of the name in the shstrtab 894 * section referenced by the ELF header. There is no 895 * value to elfdump in creating shstrtab, so we set 896 * sh_name to 0, knowing that elfdump doesn't look at it. 897 */ 898 sec->shdr->sh_name = 0; 899 sec->shdr->sh_type = tinfo->sh_type; 900 sec->shdr->sh_flags = tinfo->sh_flags; 901 if ((tinfo->sh_flags & SHF_ALLOC) == 0) { 902 /* 903 * Non-allocable section: Pass the addr (which is probably 904 * 0) and offset through without inspection. 905 */ 906 sec->shdr->sh_addr = sec->vaddr; 907 sec->shdr->sh_offset = sec->offset; 908 zero_bytes = 0; 909 } else if (sec->vaddr == 0) { 910 /* 911 * Allocable section with a 0 vaddr. Figure out the 912 * real address by mapping the offset to it using the 913 * program headers. 914 */ 915 sec->shdr->sh_addr = map_offset_to_addr(fstate, sec->offset, 916 sec->size, &zero_bytes, &phdr); 917 sec->shdr->sh_offset = sec->offset; 918 } else { 919 /* 920 * Allocable section with non-0 vaddr. Use the vaddr 921 * to derive the offset. 922 */ 923 sec->shdr->sh_addr = sec->vaddr; 924 sec->shdr->sh_offset = map_addr_to_offset(fstate, 925 sec->vaddr, sec->size, &zero_bytes, &phdr); 926 } 927 if (sec->shdr->sh_offset == 0) { 928 sinfo_free(sec, 1); 929 return (0); 930 } 931 /* 932 * If the program header has its write flags set, then set 933 * the section write flag. 934 */ 935 if (phdr && ((phdr->p_flags & PF_W) != 0)) 936 sec->shdr->sh_flags |= SHF_WRITE; 937 sec->shdr->sh_size = sec->size; 938 sec->shdr->sh_link = 0; 939 sec->shdr->sh_info = 0; 940 sec->shdr->sh_addralign = tinfo->sh_addralign; 941 sec->shdr->sh_entsize = tinfo->sh_entsize; 942 943 /* 944 * Some sections define special meanings for sh_link and sh_info. 945 */ 946 switch (tinfo->sh_type) { 947 case SHT_DYNAMIC: 948 sec->shdr->sh_link = SINFO_T_DYNSTR; 949 break; 950 951 case SHT_DYNSYM: 952 sec->shdr->sh_link = SINFO_T_DYNSTR; 953 sec->shdr->sh_info = 1; /* First global symbol */ 954 break; 955 956 case SHT_SUNW_LDYNSYM: 957 sec->shdr->sh_link = SINFO_T_DYNSTR; 958 /* 959 * ldynsym is all local symbols, so the index of the 960 * first global is equivalent to the number of symbols. 961 */ 962 sec->shdr->sh_info = sec->shdr->sh_size / sizeof (Sym); 963 break; 964 965 case SHT_HASH: 966 case SHT_SUNW_move: 967 case SHT_REL: 968 case SHT_RELA: 969 case SHT_SUNW_versym: 970 sec->shdr->sh_link = SINFO_T_DYNSYM; 971 break; 972 973 case SHT_SUNW_verdef: 974 case SHT_SUNW_verneed: 975 sec->shdr->sh_link = SINFO_T_DYNSTR; 976 sec->shdr->sh_info = sec->vercnt; 977 break; 978 979 case SHT_SUNW_syminfo: 980 sec->shdr->sh_link = SINFO_T_DYNSYM; 981 sec->shdr->sh_info = SINFO_T_DYN; 982 break; 983 984 case SHT_SUNW_symsort: 985 case SHT_SUNW_tlssort: 986 sec->shdr->sh_link = SINFO_T_LDYNSYM; 987 break; 988 } 989 990 991 992 /* Fill in fake Elf_Data descriptor */ 993 sec->data->d_type = tinfo->libelf_type; 994 sec->data->d_size = sec->size; 995 sec->data->d_off = 0; 996 sec->data->d_align = tinfo->sh_addralign; 997 sec->data->d_version = fstate->ehdr->e_version; 998 999 if (sec->size == 0) { 1000 sec->data->d_buf = NULL; 1001 return (1); 1002 } 1003 1004 if ((sec->data->d_buf = malloc(sec->size)) == NULL) { 1005 int err = errno; 1006 1007 sinfo_free(sec, 1); 1008 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), 1009 fstate->file, strerror(err)); 1010 return (0); 1011 } 1012 1013 read_bytes = sec->size - zero_bytes; 1014 if ((read_bytes > 0) && 1015 (read_data(fstate, sec->shdr->sh_offset, sec->data->d_buf, 1016 read_bytes, ELF_T_BYTE) == 0)) { 1017 sinfo_free(sec, 1); 1018 return (0); 1019 } 1020 if (zero_bytes > 0) 1021 bzero(read_bytes + (char *)sec->data->d_buf, zero_bytes); 1022 1023 if ((tinfo->libelf_type != ELF_T_BYTE) && 1024 (elf_xlatetom(sec->data, sec->data, 1025 fstate->ehdr->e_ident[EI_DATA]) == NULL)) { 1026 sinfo_free(sec, 1); 1027 failure(fstate->file, MSG_ORIG(MSG_ELF_XLATETOM)); 1028 return (0); 1029 } 1030 1031 return (1); 1032 } 1033 1034 1035 1036 /* 1037 * Generate a section header cache made up of information derived 1038 * from the program headers. 1039 * 1040 * entry: 1041 * file - Name of object 1042 * fd - Open file handle for object 1043 * elf - ELF descriptor 1044 * ehdr - Elf header 1045 * cache, shnum - Addresses of variables to receive resulting 1046 * cache and number of sections. 1047 * 1048 * exit: 1049 * On success, *cache and *shnum are set, and True (1) is returned. 1050 * On failure, False (0) is returned. 1051 * 1052 * note: 1053 * The cache returned by this routine must be freed using 1054 * fake_shdr_cache_free(), and not by a direct call to free(). 1055 * Otherwise, memory will leak. 1056 */ 1057 int 1058 fake_shdr_cache(const char *file, int fd, Elf *elf, Ehdr *ehdr, 1059 Cache **cache, size_t *shnum) 1060 { 1061 /* 1062 * The C language guarantees that a structure of homogeneous 1063 * items will receive exactly the same layout in a structure 1064 * as a plain array of the same type. Hence, this structure, which 1065 * gives us by-name or by-index access to the various section 1066 * info descriptors we maintain. 1067 * 1068 * We use this for sections where 1069 * - Only one instance is allowed 1070 * - We need to be able to access them easily by 1071 * name (for instance, when mining the .dynamic 1072 * section for information to build them up. 1073 * 1074 * NOTE: These fields must be in the same order as the 1075 * SINFO_T_ type codes that correspond to them. Otherwise, 1076 * they will end up in the wrong order in the cache array, 1077 * and the sh_link/sh_info fields may be wrong. 1078 */ 1079 struct { 1080 /* Note: No entry is needed for SINFO_T_NULL */ 1081 SINFO dyn; 1082 SINFO dynstr; 1083 SINFO dynsym; 1084 SINFO ldynsym; 1085 1086 SINFO hash; 1087 SINFO syminfo; 1088 SINFO symsort; 1089 SINFO tlssort; 1090 SINFO verneed; 1091 SINFO verdef; 1092 SINFO versym; 1093 SINFO interp; 1094 SINFO cap; 1095 SINFO unwind; 1096 SINFO move; 1097 SINFO rel; 1098 SINFO rela; 1099 SINFO preinitarr; 1100 SINFO initarr; 1101 SINFO finiarr; 1102 } sec; 1103 static const size_t sinfo_n = sizeof (sec) / sizeof (sec.dyn); 1104 SINFO *secarr = (SINFO *) &sec; 1105 1106 /* 1107 * Doubly linked circular list, used to track sections 1108 * where multiple sections of a given type can exist. 1109 * seclist is the root of the list. Its sinfo field is not 1110 * used --- it serves to anchor the root of the list, allowing 1111 * rapid access to the first and last element in the list. 1112 */ 1113 SINFO_LISTELT seclist; 1114 1115 FSTATE fstate; 1116 size_t ndx; 1117 size_t num_sinfo, num_list_sinfo; 1118 SINFO *sinfo; 1119 SINFO_LISTELT *sinfo_list; 1120 Cache *_cache; 1121 1122 1123 fstate.file = file; 1124 fstate.fd = fd; 1125 fstate.ehdr = ehdr; 1126 if (elf_getphnum(elf, &fstate.phnum) == 0) { 1127 failure(file, MSG_ORIG(MSG_ELF_GETPHNUM)); 1128 return (0); 1129 } 1130 if ((fstate.phdr = elf_getphdr(elf)) == NULL) { 1131 failure(file, MSG_ORIG(MSG_ELF_GETPHDR)); 1132 return (0); 1133 } 1134 1135 bzero(&sec, sizeof (sec)); /* Initialize "by-name" sec info */ 1136 seclist.next = seclist.prev = &seclist; /* Empty circular list */ 1137 1138 /* 1139 * Go through the program headers and look for information 1140 * we can use to synthesize section headers. By far the most 1141 * valuable thing is a dynamic section, the contents of 1142 * which point at all sections used by ld.so.1. 1143 */ 1144 for (ndx = 0; ndx < fstate.phnum; ndx++) { 1145 /* 1146 * A program header with no file size does 1147 * not have a backing section. 1148 */ 1149 if (fstate.phdr[ndx].p_filesz == 0) 1150 continue; 1151 1152 1153 switch (fstate.phdr[ndx].p_type) { 1154 default: 1155 /* Header we can't use. Move on to next one */ 1156 continue; 1157 1158 case PT_DYNAMIC: 1159 sec.dyn.type = SINFO_T_DYN; 1160 sinfo = &sec.dyn; 1161 break; 1162 1163 case PT_INTERP: 1164 sec.interp.type = SINFO_T_INTERP; 1165 sinfo = &sec.interp; 1166 break; 1167 1168 case PT_NOTE: 1169 if ((sinfo = sinfo_list_alloc(&fstate, &seclist)) == 1170 NULL) 1171 continue; 1172 sinfo->type = SINFO_T_NOTE; 1173 break; 1174 1175 case PT_SUNW_UNWIND: 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