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