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