dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / sgs / elfdump / common / fake_shdr.c
blobafaedb90d32614388ec5ba1033cbe68227d87fd0
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Generate a cache of section header information for an ELF
29 * object from the information found in its program headers.
31 * Malicious code can remove or corrupt section headers. The
32 * resulting program will be difficult to analyze, but is still
33 * runnable. Hence, scribbling on the section headers or removing
34 * them is an effective form of obfuscation. On the other hand,
35 * program headers must be accurate or the program will not run.
36 * Section headers derived from them will necessarily lack information
37 * found in the originals (particularly for non-allocable sections),
38 * but will provide essential symbol information. The focus is on
39 * recovering information that elfdump knows how to display, and that
40 * might be interesting in a forensic situation.
42 * There are some things we don't attempt to create sections for:
44 * plt, got
45 * We have no way to determine the length of either of
46 * these sections from the information available via
47 * the program headers or dynamic section. The data in
48 * the PLT is of little use to elfdump. The data in the
49 * GOT might be somewhat more interesting, especially as
50 * it pertains to relocations. However, the sizing issue
51 * remains.
53 * text, data, bss
54 * Although we could create these, there is little value
55 * to doing so. elfdump cannot display the arbitrary
56 * data in these sections, so this would amount to a
57 * simple repetition of the information already displayed
58 * in the program headers, with no additional benefit.
63 #include <sys/elf_amd64.h>
64 #include <stdio.h>
65 #include <unistd.h>
66 #include <errno.h>
67 #include <string.h>
68 #include <strings.h>
69 #include <conv.h>
70 #include <msg.h>
71 #include <_elfdump.h>
76 * Common information about the object that is needed by
77 * all the routines in this module.
79 typedef struct {
80 const char *file;
81 int fd;
82 Ehdr *ehdr;
83 Phdr *phdr;
84 size_t phnum;
85 } FSTATE;
90 * These values uniquely identify the sections that we know
91 * how to recover.
93 * Note: We write the sections to the cache array in this same order.
94 * It simplifies this code if the dynamic, dynstr, dynsym, and ldynsym
95 * sections occupy known slots in the cache array. Other sections reference
96 * them by index, and if they are at a known spot, there is no need
97 * for a fixup pass. Putting them in positions [1-4] solves this.
99 * The order they are in was chosen such that if any one of them exists,
100 * all of the ones before it must also exist. This means that if the
101 * desired section exists, it will end up in the desired index in the
102 * cache array.
104 * The order of the other sections is arbitrary. I've arranged them
105 * in roughly related groups.
107 typedef enum {
108 SINFO_T_NULL = 0,
109 SINFO_T_DYN = 1,
110 SINFO_T_DYNSTR = 2,
111 SINFO_T_DYNSYM = 3,
112 SINFO_T_LDYNSYM = 4,
114 SINFO_T_HASH = 5,
115 SINFO_T_SYMINFO = 6,
116 SINFO_T_SYMSORT = 7,
117 SINFO_T_TLSSORT = 8,
118 SINFO_T_VERNEED = 9,
119 SINFO_T_VERDEF = 10,
120 SINFO_T_VERSYM = 11,
121 SINFO_T_INTERP = 12,
122 SINFO_T_CAP = 13,
123 SINFO_T_CAPINFO = 14,
124 SINFO_T_CAPCHAIN = 15,
125 SINFO_T_UNWIND = 16,
126 SINFO_T_MOVE = 17,
127 SINFO_T_REL = 18,
128 SINFO_T_RELA = 19,
129 SINFO_T_PREINITARR = 20,
130 SINFO_T_INITARR = 21,
131 SINFO_T_FINIARR = 22,
132 SINFO_T_NOTE = 23,
134 SINFO_T_NUM = 24 /* Count of items. Must come last */
135 } SINFO_TYPE;
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.
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.
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;
160 * Many of these sections use an alignment given by M_WORD_ALIGN, a
161 * value that varies depending on the object target machine. Since we
162 * don't know that value at compile time, we settle for a value of
163 * 4 for ELFCLASS32 objects, and 8 for ELFCLASS64. This matches the
164 * platforms we current support (sparc and x86), and is good enough for
165 * a fake section header in any event, as the resulting object is only
166 * analyzed, and is not executed.
168 #ifdef _ELF64
169 #define FAKE_M_WORD_ALIGN 8
170 #else
171 #define FAKE_M_WORD_ALIGN 4
172 #endif
174 static SINFO_DATA sinfo_data[SINFO_T_NUM] = {
175 /* SINFO_T_NULL */
176 { 0 },
178 /* SINFO_T_DYN */
179 { MSG_ORIG(MSG_PHDRNAM_DYN), SHT_DYNAMIC, SHF_ALLOC,
180 FAKE_M_WORD_ALIGN, sizeof (Dyn), ELF_T_DYN },
182 /* SINFO_T_DYNSTR */
183 { MSG_ORIG(MSG_PHDRNAM_DYNSTR), SHT_STRTAB, SHF_ALLOC,
184 1, 0, ELF_T_BYTE },
186 /* SINFO_T_DYNSYM */
187 { MSG_ORIG(MSG_PHDRNAM_DYNSYM), SHT_DYNSYM, SHF_ALLOC,
188 FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM },
190 /* SINFO_T_LDYNSYM */
191 { MSG_ORIG(MSG_PHDRNAM_LDYNSYM), SHT_SUNW_LDYNSYM, SHF_ALLOC,
192 FAKE_M_WORD_ALIGN, sizeof (Sym), ELF_T_SYM },
194 /* SINFO_T_HASH */
195 { MSG_ORIG(MSG_PHDRNAM_HASH), SHT_HASH, SHF_ALLOC,
196 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD },
198 /* SINFO_T_SYMINFO */
199 { MSG_ORIG(MSG_PHDRNAM_SYMINFO), SHT_SUNW_syminfo, SHF_ALLOC,
200 FAKE_M_WORD_ALIGN, sizeof (Syminfo), ELF_T_SYMINFO },
202 /* SINFO_T_SYMSORT */
203 { MSG_ORIG(MSG_PHDRNAM_SYMSORT), SHT_SUNW_symsort, SHF_ALLOC,
204 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD },
206 /* SINFO_T_TLSSORT */
207 { MSG_ORIG(MSG_PHDRNAM_TLSSORT), SHT_SUNW_tlssort, SHF_ALLOC,
208 FAKE_M_WORD_ALIGN, sizeof (Word), ELF_T_WORD },
210 /* SINFO_T_VERNEED */
211 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verneed, SHF_ALLOC,
212 FAKE_M_WORD_ALIGN, 1, ELF_T_VNEED },
214 /* SINFO_T_VERDEF */
215 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_verdef, SHF_ALLOC,
216 FAKE_M_WORD_ALIGN, 1, ELF_T_VDEF },
218 /* SINFO_T_VERSYM */
219 { MSG_ORIG(MSG_PHDRNAM_VER), SHT_SUNW_versym, SHF_ALLOC,
220 FAKE_M_WORD_ALIGN, sizeof (Versym), ELF_T_HALF },
222 /* SINFO_T_INTERP */
223 { MSG_ORIG(MSG_PHDRNAM_INTERP), SHT_PROGBITS, SHF_ALLOC,
224 1, 0, ELF_T_BYTE },
226 /* SINFO_T_CAP */
227 { MSG_ORIG(MSG_PHDRNAM_CAP), SHT_SUNW_cap, SHF_ALLOC,
228 sizeof (Addr), sizeof (Cap), ELF_T_CAP },
230 /* SINFO_T_CAPINFO */
231 { MSG_ORIG(MSG_PHDRNAM_CAPINFO), SHT_SUNW_capinfo, SHF_ALLOC,
232 FAKE_M_WORD_ALIGN, sizeof (Capinfo), ELF_T_WORD },
234 /* SINFO_T_CAPCHAIN */
235 { MSG_ORIG(MSG_PHDRNAM_CAPCHAIN), SHT_SUNW_capchain, SHF_ALLOC,
236 FAKE_M_WORD_ALIGN, sizeof (Capchain), ELF_T_WORD },
238 /* SINFO_T_UNWIND */
239 { MSG_ORIG(MSG_PHDRNAM_UNWIND), SHT_AMD64_UNWIND, SHF_ALLOC,
240 sizeof (Addr), 0, ELF_T_BYTE },
242 /* SINFO_T_MOVE */
243 { MSG_ORIG(MSG_PHDRNAM_MOVE), SHT_SUNW_move, SHF_ALLOC,
244 sizeof (Lword), sizeof (Move), ELF_T_MOVE },
246 /* SINFO_T_REL */
247 { MSG_ORIG(MSG_PHDRNAM_REL), SHT_REL, SHF_ALLOC,
248 FAKE_M_WORD_ALIGN, sizeof (Rel), ELF_T_REL },
250 /* SINFO_T_RELA */
251 { MSG_ORIG(MSG_PHDRNAM_RELA), SHT_RELA, SHF_ALLOC,
252 FAKE_M_WORD_ALIGN, sizeof (Rela), ELF_T_RELA },
254 /* SINFO_T_PREINITARR */
255 { MSG_ORIG(MSG_PHDRNAM_PREINITARR), SHT_PREINIT_ARRAY, SHF_ALLOC,
256 sizeof (Addr), sizeof (Addr), ELF_T_ADDR },
258 /* SINFO_T_INITARR */
259 { MSG_ORIG(MSG_PHDRNAM_INITARR), SHT_INIT_ARRAY, SHF_ALLOC,
260 sizeof (Addr), sizeof (Addr), ELF_T_ADDR },
262 /* SINFO_T_FINIARR */
263 { MSG_ORIG(MSG_PHDRNAM_FINIARR), SHT_FINI_ARRAY, SHF_ALLOC,
264 sizeof (Addr), sizeof (Addr), ELF_T_ADDR },
266 /* SINFO_T_NOTE */
267 { MSG_ORIG(MSG_PHDRNAM_NOTE), SHT_NOTE, 0,
268 FAKE_M_WORD_ALIGN, 1, ELF_T_NOTE }
276 * As we read program headers and dynamic elements, we build up
277 * the data for our fake section headers in variables of the
278 * SINFO type. SINFO is used to track the sections that can only
279 * appear a fixed number of times (usually once).
281 * SINFO_LISTELT is used for sections that can occur an arbitrary
282 * number of times. They are kept in a doubly linked circular
283 * buffer.
285 typedef struct {
286 SINFO_TYPE type; /* Our type code for the section */
287 Addr vaddr; /* Virtual memory address */
288 Off offset; /* File offset of data. Ignored unless */
289 /* vaddr is 0. Used by program headers */
290 size_t size; /* # bytes in section */
291 size_t vercnt; /* Used by verdef and verneed to hold count */
292 Shdr *shdr; /* Constructed shdr */
293 Elf_Data *data; /* Constructed data descriptor */
294 } SINFO;
296 typedef struct _sinfo_listelt {
297 struct _sinfo_listelt *next;
298 struct _sinfo_listelt *prev;
299 SINFO sinfo;
300 } SINFO_LISTELT;
305 * Free dynamic memory used by SINFO structures.
307 * entry:
308 * sinfo - Address of first SINFO structure to free
309 * n - # of structures to clear
311 * exit:
312 * For each SINFO struct, the section header, data descriptor,
313 * and data buffer are freed if non-NULL. The relevant
314 * fields are set to NULL, and the type is set to SINFO_T_NULL.
316 static void
317 sinfo_free(SINFO *sinfo, size_t n)
319 for (; n-- > 0; sinfo++) {
320 if (sinfo->data != NULL) {
321 free(sinfo->data->d_buf);
322 free(sinfo->data);
323 sinfo->data = NULL;
326 if (sinfo->shdr) {
327 free(sinfo->shdr);
328 sinfo->shdr = NULL;
330 sinfo->type = SINFO_T_NULL;
337 * Allocate a new SINFO_LISTELT and put it at the end of the
338 * doubly linked list anchored by the given list root node.
340 * On success, a new node has been put at the end of the circular
341 * doubly linked list, and a pointer to the SINFO sub-structure is
342 * returned. On failure, an error is printed, and NULL is returned.
345 static SINFO *
346 sinfo_list_alloc(FSTATE *fstate, SINFO_LISTELT *root)
348 SINFO_LISTELT *elt;
350 if ((elt = malloc(sizeof (*elt))) == NULL) {
351 int err = errno;
352 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
353 fstate->file, strerror(err));
354 return (0);
357 elt->next = root;
358 elt->prev = root->prev;
360 root->prev = elt;
361 elt->prev->next = elt;
363 bzero(&elt->sinfo, sizeof (elt->sinfo));
364 return (&elt->sinfo);
370 * Release the memory used by the given list, restoring it to
371 * an empty list.
373 static void
374 sinfo_list_free_all(SINFO_LISTELT *root)
376 SINFO_LISTELT *elt;
378 for (elt = root->next; elt != root; elt = elt->next)
379 sinfo_free(&elt->sinfo, 1);
381 root->next = root->prev = root;
387 * Given a virtual address and desired size of the data to be found
388 * at that address, look through the program headers for the PT_LOAD
389 * segment that contains it and return the offset within the ELF file
390 * at which it resides.
392 * entry:
393 * fstate - Object state
394 * addr - virtual address to be translated
395 * size - Size of the data to be found at that address, in bytes
396 * zero_bytes - NULL, or address to receive the number of data
397 * bytes at the end of the data that are not contained
398 * in the file, and which must be zero filled by the caller.
399 * If zero_bytes is NULL, the file must contain all of the
400 * desired data. If zero_bytes is not NULL, then the program
401 * header must reserve the space for all of the data (p_memsz)
402 * but it is acceptable for only part of the data to be in
403 * the file (p_filesz). *zero_bytes is set to the difference
404 * in size, and is the number of bytes the caller must
405 * set to 0 rather than reading from the file.
406 * phdr_ret - NULL, or address of variable to receive pointer
407 * to program header that contains offset.
408 * exit:
409 * On success: If zero_bytes is non-NULL, it is updated. If phdr_ret
410 * is non-NULL, it is updated. The file offset is returned.
412 * On failure, 0 is returned. Since any ELF file we can understand
413 * must start with an ELF magic number, 0 cannot be a valid file
414 * offset for a virtual address, and is therefore unambiguous as
415 * a failure indication.
417 static Off
418 map_addr_to_offset(FSTATE *fstate, Addr addr, size_t size, size_t *zero_bytes,
419 Phdr **phdr_ret)
421 Off offset;
422 Addr end_addr = addr + size;
423 size_t avail_file;
424 Phdr *phdr = fstate->phdr;
425 size_t phnum = fstate->phnum;
427 for (; phnum--; phdr++) {
428 if (phdr->p_type != PT_LOAD)
429 continue;
431 if ((addr >= phdr->p_vaddr) &&
432 (end_addr <= (phdr->p_vaddr + phdr->p_memsz))) {
434 * Subtract segment virtual address, leaving the
435 * offset relative to the segment (not the file).
437 offset = addr - phdr->p_vaddr;
438 avail_file = phdr->p_filesz - offset;
441 * The addr/size are in bounds for this segment.
442 * Is there enough data in the file to satisfy
443 * the request? If zero_bytes is NULL, it must
444 * all be in the file. Otherwise it can be
445 * zero filled.
447 if (zero_bytes == NULL) {
448 if (size > avail_file)
449 continue;
450 } else {
451 *zero_bytes = (size > avail_file) ?
452 (size - avail_file) : 0;
455 if (phdr_ret != NULL)
456 *phdr_ret = phdr;
458 /* Add segment file offset, giving overall offset */
459 return (phdr->p_offset + offset);
463 /* If we get here, the mapping failed */
464 return (0);
470 * This routine is the same thing as map_addr_to_offset(), except that
471 * it goes the other way, mapping from offset to virtual address.
473 * The comments for map_addr_to_offset() are applicable if you
474 * reverse offset and address.
477 static Addr
478 map_offset_to_addr(FSTATE *fstate, Off offset, size_t size, size_t *zero_bytes,
479 Phdr **phdr_ret)
481 Off end_offset = offset + size;
482 size_t avail_file;
483 Phdr *phdr = fstate->phdr;
484 size_t phnum = fstate->phnum;
486 for (; phnum--; phdr++) {
487 if (phdr->p_type != PT_LOAD)
488 continue;
490 if ((offset >= phdr->p_offset) &&
491 (end_offset <= (phdr->p_offset + phdr->p_memsz))) {
493 * Subtract segment offset, leaving the
494 * offset relative to the segment (not the file).
496 offset -= phdr->p_offset;
497 avail_file = phdr->p_filesz - offset;
500 * The offset/size are in bounds for this segment.
501 * Is there enough data in the file to satisfy
502 * the request? If zero_bytes is NULL, it must
503 * all be in the file. Otherwise it can be
504 * zero filled.
506 if (zero_bytes == NULL) {
507 if (size > avail_file)
508 continue;
509 } else {
510 *zero_bytes = (size > avail_file) ?
511 (size - avail_file) : 0;
514 if (phdr_ret != NULL)
515 *phdr_ret = phdr;
517 /* Add segment virtual address, giving overall addr */
518 return (phdr->p_vaddr + offset);
522 /* If we get here, the mapping failed */
523 return (0);
529 * Use elf_xlatetom() to convert the bytes in buf from their
530 * in-file representation to their in-memory representation.
532 * Returns True(1) for success. On failure, an error message is printed
533 * and False(0) is returned.
535 static int
536 xlate_data(FSTATE *fstate, void *buf, size_t nbyte, Elf_Type xlate_type)
538 Elf_Data data;
540 data.d_type = xlate_type;
541 data.d_size = nbyte;
542 data.d_off = 0;
543 data.d_align = 0;
544 data.d_version = fstate->ehdr->e_version;
545 data.d_buf = buf;
547 if (elf_xlatetom(&data, &data,
548 fstate->ehdr->e_ident[EI_DATA]) == NULL) {
549 failure(fstate->file, MSG_ORIG(MSG_ELF_XLATETOM));
550 return (0);
553 return (1);
558 * Read nbytes of data into buf, starting at the specified offset
559 * within the ELF file.
561 * entry:
562 * fstate - Object state
563 * offset - Offset within the file at which desired data resides.
564 * buf - Buffer to receive the data
565 * nbyte - # of bytes to read into buf
566 * xlate_type - An ELF xlate type, specifying the type of data
567 * being input. If xlate_type is ELF_T_BYTE, xlate is not
568 * done. Otherwise, xlate_data() is called to convert the
569 * data into its in-memory representation.
570 * exit:
571 * On success, the data has been written into buf, xlate_data()
572 * called on it if required, and True(1) is returned. Otherwise
573 * False(0) is returned.
575 * note:
576 * This routine does not move the file pointer.
578 static int
579 read_data(FSTATE *fstate, Off offset, void *buf, size_t nbyte,
580 Elf_Type xlate_type)
582 if (pread(fstate->fd, buf, nbyte, offset) != nbyte) {
583 int err = errno;
585 (void) fprintf(stderr, MSG_INTL(MSG_ERR_READ),
586 fstate->file, strerror(err));
587 return (0);
590 if (xlate_type != ELF_T_BYTE)
591 return (xlate_data(fstate, buf, nbyte, xlate_type));
593 return (1);
599 * Read the hash nbucket/nchain values from the start of the hash
600 * table found at the given virtual address in the mapped ELF object.
602 * On success, *nbucket, and *nchain have been filled in with their
603 * values, *total contains the number of elements in the hash table,
604 * and this routine returns True (1).
606 * On failure, False (0) is returned.
608 static int
609 hash_size(FSTATE *fstate, SINFO *hash_sinfo,
610 Word *nbucket, Word *nchain, size_t *total)
612 Off offset;
613 Word buf[2];
615 offset = map_addr_to_offset(fstate, hash_sinfo->vaddr,
616 sizeof (buf), NULL, NULL);
617 if (offset == 0)
618 return (0);
620 if (read_data(fstate, offset, buf, sizeof (buf), ELF_T_WORD) == 0)
621 return (0);
623 *nbucket = buf[0];
624 *nchain = buf[1];
625 *total = 2 + *nbucket + *nchain;
626 return (1);
632 * Read a Verdef structure at the specified file offset and return
633 * its vd_cnt, vd_aux, and vd_next fields.
635 static int
636 read_verdef(FSTATE *fstate, Off offset, Half *cnt, Word *aux, Word *next)
638 Verdef verdef;
640 if (read_data(fstate, offset, &verdef, sizeof (verdef),
641 ELF_T_BYTE) == 0)
642 return (0);
644 /* xlate vd_cnt */
645 if (xlate_data(fstate, &verdef.vd_cnt, sizeof (verdef.vd_cnt),
646 ELF_T_HALF) == 0)
647 return (0);
650 * xlate vd_aux and vd_next. These items are adjacent and are
651 * both Words, so they can be handled in a single operation.
653 if (xlate_data(fstate, &verdef.vd_aux,
654 2 * sizeof (Word), ELF_T_WORD) == 0)
655 return (0);
657 *cnt = verdef.vd_cnt;
658 *aux = verdef.vd_aux;
659 *next = verdef.vd_next;
661 return (1);
667 * Read a Verdaux structure at the specified file offset and return
668 * its vda_next field.
670 static int
671 read_verdaux(FSTATE *fstate, Off offset, Word *next)
673 Verdaux verdaux;
675 if (read_data(fstate, offset, &verdaux, sizeof (verdaux),
676 ELF_T_BYTE) == 0)
677 return (0);
679 /* xlate vda_next */
680 if (xlate_data(fstate, &verdaux.vda_next, sizeof (verdaux.vda_next),
681 ELF_T_WORD) == 0)
682 return (0);
684 *next = verdaux.vda_next;
686 return (1);
692 * Read a Verneed structure at the specified file offset and return
693 * its vn_cnt, vn_aux, and vn_next fields.
695 static int
696 read_verneed(FSTATE *fstate, Off offset, Half *cnt, Word *aux, Word *next)
698 Verneed verneed;
700 if (read_data(fstate, offset, &verneed, sizeof (verneed),
701 ELF_T_BYTE) == 0)
702 return (0);
704 /* xlate vn_cnt */
705 if (xlate_data(fstate, &verneed.vn_cnt, sizeof (verneed.vn_cnt),
706 ELF_T_HALF) == 0)
707 return (0);
710 * xlate vn_aux and vn_next. These items are adjacent and are
711 * both Words, so they can be handled in a single operation.
713 if (xlate_data(fstate, &verneed.vn_aux,
714 2 * sizeof (Word), ELF_T_WORD) == 0)
715 return (0);
717 *cnt = verneed.vn_cnt;
718 *aux = verneed.vn_aux;
719 *next = verneed.vn_next;
721 return (1);
727 * Read a Vernaux structure at the specified file offset and return
728 * its vna_next field.
730 static int
731 read_vernaux(FSTATE *fstate, Off offset, Word *next)
733 Vernaux vernaux;
735 if (read_data(fstate, offset, &vernaux, sizeof (vernaux),
736 ELF_T_BYTE) == 0)
737 return (0);
739 /* xlate vna_next */
740 if (xlate_data(fstate, &vernaux.vna_next, sizeof (vernaux.vna_next),
741 ELF_T_WORD) == 0)
742 return (0);
744 *next = vernaux.vna_next;
746 return (1);
752 * Compute the size of Verdef and Verneed sections. Both of these
753 * sections are made up of interleaved main nodes (Verdef and Verneed)
754 * and auxiliary blocks (Verdaux and Vernaux). These nodes refer to
755 * each other by relative offsets. The linker has a lot of flexibility
756 * in how it lays out these items, and we cannot assume a standard
757 * layout. To determine the size of the section, we must read each
758 * main node and compute the high water mark of the memory it and its
759 * auxiliary structs access.
761 * Although Verdef/Verdaux and Verneed/Vernaux are different types,
762 * their logical organization is the same. Each main block has
763 * a cnt field that tells how many auxiliary blocks it has, an
764 * aux field that gives the offset of the first auxiliary block, and
765 * an offset to the next main block. Each auxiliary block contains
766 * an offset to the next auxiliary block. By breaking the type specific
767 * code into separate sub-functions, we can process both Verdef and
768 * sections Verdaux from a single routine.
770 * entry:
771 * fstate - Object state
772 * sec - Section to be processed (SINFO_T_VERDEF or SINFO_T_VERNEED).
774 * exit:
775 * On success, sec->size is set to the section size in bytes, and
776 * True (1) is returned. On failure, False (0) is returned.
778 static int
779 verdefneed_size(FSTATE *fstate, SINFO *sec)
781 int (* read_main)(FSTATE *, Off, Half *, Word *, Word *);
782 int (* read_aux)(FSTATE *, Off, Word *);
783 size_t size_main, size_aux;
785 Off offset, aux_offset;
786 Off highwater, extent;
787 size_t num_main = sec->vercnt;
788 Half v_cnt;
789 Word v_aux, v_next, va_next;
793 * Set up the function pointers to the type-specific code
794 * for fetching data from the main and auxiliary blocks.
796 if (sec->type == SINFO_T_VERDEF) {
797 read_main = read_verdef;
798 read_aux = read_verdaux;
799 size_main = sizeof (Verdef);
800 size_aux = sizeof (Verdaux);
801 } else { /* SINFO_T_VERNEED */
802 read_main = read_verneed;
803 read_aux = read_vernaux;
804 size_main = sizeof (Verneed);
805 size_aux = sizeof (Vernaux);
809 * Map starting address to file offset. Save the starting offset
810 * in the SINFO size field. Once we have the high water offset, we
811 * can subtract this from it to get the size.
813 * Note: The size argument set here is a lower bound --- the
814 * size of the main blocks without any auxiliary ones. It's
815 * the best we can do until the size has been determined for real.
817 offset = highwater = map_addr_to_offset(fstate, sec->vaddr,
818 size_main * num_main, NULL, NULL);
819 if (offset == 0)
820 return (0);
821 sec->size = offset;
823 for (; num_main-- > 0; offset += v_next) {
824 /* Does this move the high water mark up? */
825 extent = offset + size_main;
826 if (extent > highwater)
827 highwater = extent;
829 if ((*read_main)(fstate, offset, &v_cnt, &v_aux, &v_next) == 0)
830 return (0);
833 * If there are auxiliary structures referenced,
834 * check their position to see if it pushes
835 * the high water mark.
837 aux_offset = offset + v_aux;
838 for (; v_cnt-- > 0; aux_offset += va_next) {
839 extent = aux_offset + size_aux;
840 if (extent > highwater)
841 highwater = extent;
843 if ((*read_aux)(fstate, aux_offset, &va_next) == 0)
844 return (0);
848 sec->size = highwater - sec->size;
849 return (1);
854 * Allocate and fill in a fake section header, data descriptor,
855 * and data buffer for the given section. Fill them in and read
856 * the associated data into the buffer.
858 * entry:
859 * fstate - Object state
860 * sec - Section information
862 * exit:
863 * On success, the actions described above are complete, and
864 * True (1) is returned.
866 * On failure, an error is reported, all resources used by sec
867 * are released, and sec->type is set to SINFO_T_NULL, effectively
868 * eliminating its contents from any further use. False (0) is
869 * returned.
871 static int
872 get_data(FSTATE *fstate, SINFO *sec)
875 SINFO_DATA *tinfo;
876 size_t read_bytes, zero_bytes;
877 Phdr *phdr = NULL;
880 * If this is a NULL section, or if we've already processed
881 * this item, then we are already done.
883 if ((sec->type == SINFO_T_NULL) || (sec->shdr != NULL))
884 return (1);
886 if (((sec->shdr = malloc(sizeof (*sec->shdr))) == NULL) ||
887 ((sec->data = malloc(sizeof (*sec->data))) == NULL)) {
888 int err = errno;
889 sinfo_free(sec, 1);
890 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
891 fstate->file, strerror(err));
892 return (0);
894 tinfo = &sinfo_data[sec->type];
899 * Fill in fake section header
901 * sh_name should be the offset of the name in the shstrtab
902 * section referenced by the ELF header. There is no
903 * value to elfdump in creating shstrtab, so we set
904 * sh_name to 0, knowing that elfdump doesn't look at it.
906 sec->shdr->sh_name = 0;
907 sec->shdr->sh_type = tinfo->sh_type;
908 sec->shdr->sh_flags = tinfo->sh_flags;
909 if ((tinfo->sh_flags & SHF_ALLOC) == 0) {
911 * Non-allocable section: Pass the addr (which is probably
912 * 0) and offset through without inspection.
914 sec->shdr->sh_addr = sec->vaddr;
915 sec->shdr->sh_offset = sec->offset;
916 zero_bytes = 0;
917 } else if (sec->vaddr == 0) {
919 * Allocable section with a 0 vaddr. Figure out the
920 * real address by mapping the offset to it using the
921 * program headers.
923 sec->shdr->sh_addr = map_offset_to_addr(fstate, sec->offset,
924 sec->size, &zero_bytes, &phdr);
925 sec->shdr->sh_offset = sec->offset;
926 } else {
928 * Allocable section with non-0 vaddr. Use the vaddr
929 * to derive the offset.
931 sec->shdr->sh_addr = sec->vaddr;
932 sec->shdr->sh_offset = map_addr_to_offset(fstate,
933 sec->vaddr, sec->size, &zero_bytes, &phdr);
935 if (sec->shdr->sh_offset == 0) {
936 sinfo_free(sec, 1);
937 return (0);
940 * If the program header has its write flags set, then set
941 * the section write flag.
943 if (phdr && ((phdr->p_flags & PF_W) != 0))
944 sec->shdr->sh_flags |= SHF_WRITE;
945 sec->shdr->sh_size = sec->size;
946 sec->shdr->sh_link = 0;
947 sec->shdr->sh_info = 0;
948 sec->shdr->sh_addralign = tinfo->sh_addralign;
949 sec->shdr->sh_entsize = tinfo->sh_entsize;
952 * Some sections define special meanings for sh_link and sh_info.
954 switch (tinfo->sh_type) {
955 case SHT_DYNAMIC:
956 sec->shdr->sh_link = SINFO_T_DYNSTR;
957 break;
959 case SHT_DYNSYM:
960 sec->shdr->sh_link = SINFO_T_DYNSTR;
961 sec->shdr->sh_info = 1; /* First global symbol */
962 break;
964 case SHT_SUNW_LDYNSYM:
965 sec->shdr->sh_link = SINFO_T_DYNSTR;
967 * ldynsym is all local symbols, so the index of the
968 * first global is equivalent to the number of symbols.
970 sec->shdr->sh_info = sec->shdr->sh_size / sizeof (Sym);
971 break;
973 case SHT_HASH:
974 case SHT_SUNW_move:
975 case SHT_REL:
976 case SHT_RELA:
977 case SHT_SUNW_versym:
978 sec->shdr->sh_link = SINFO_T_DYNSYM;
979 break;
981 case SHT_SUNW_verdef:
982 case SHT_SUNW_verneed:
983 sec->shdr->sh_link = SINFO_T_DYNSTR;
984 sec->shdr->sh_info = sec->vercnt;
985 break;
987 case SHT_SUNW_syminfo:
988 sec->shdr->sh_link = SINFO_T_DYNSYM;
989 sec->shdr->sh_info = SINFO_T_DYN;
990 break;
992 case SHT_SUNW_symsort:
993 case SHT_SUNW_tlssort:
994 sec->shdr->sh_link = SINFO_T_LDYNSYM;
995 break;
1000 /* Fill in fake Elf_Data descriptor */
1001 sec->data->d_type = tinfo->libelf_type;
1002 sec->data->d_size = sec->size;
1003 sec->data->d_off = 0;
1004 sec->data->d_align = tinfo->sh_addralign;
1005 sec->data->d_version = fstate->ehdr->e_version;
1007 if (sec->size == 0) {
1008 sec->data->d_buf = NULL;
1009 return (1);
1012 if ((sec->data->d_buf = malloc(sec->size)) == NULL) {
1013 int err = errno;
1015 sinfo_free(sec, 1);
1016 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
1017 fstate->file, strerror(err));
1018 return (0);
1021 read_bytes = sec->size - zero_bytes;
1022 if ((read_bytes > 0) &&
1023 (read_data(fstate, sec->shdr->sh_offset, sec->data->d_buf,
1024 read_bytes, ELF_T_BYTE) == 0)) {
1025 sinfo_free(sec, 1);
1026 return (0);
1028 if (zero_bytes > 0)
1029 bzero(read_bytes + (char *)sec->data->d_buf, zero_bytes);
1031 if ((tinfo->libelf_type != ELF_T_BYTE) &&
1032 (elf_xlatetom(sec->data, sec->data,
1033 fstate->ehdr->e_ident[EI_DATA]) == NULL)) {
1034 sinfo_free(sec, 1);
1035 failure(fstate->file, MSG_ORIG(MSG_ELF_XLATETOM));
1036 return (0);
1039 return (1);
1045 * Generate a section header cache made up of information derived
1046 * from the program headers.
1048 * entry:
1049 * file - Name of object
1050 * fd - Open file handle for object
1051 * elf - ELF descriptor
1052 * ehdr - Elf header
1053 * cache, shnum - Addresses of variables to receive resulting
1054 * cache and number of sections.
1056 * exit:
1057 * On success, *cache and *shnum are set, and True (1) is returned.
1058 * On failure, False (0) is returned.
1060 * note:
1061 * The cache returned by this routine must be freed using
1062 * fake_shdr_cache_free(), and not by a direct call to free().
1063 * Otherwise, memory will leak.
1066 fake_shdr_cache(const char *file, int fd, Elf *elf, Ehdr *ehdr,
1067 Cache **cache, size_t *shnum)
1070 * The C language guarantees that a structure of homogeneous
1071 * items will receive exactly the same layout in a structure
1072 * as a plain array of the same type. Hence, this structure, which
1073 * gives us by-name or by-index access to the various section
1074 * info descriptors we maintain.
1076 * We use this for sections where
1077 * - Only one instance is allowed
1078 * - We need to be able to access them easily by
1079 * name (for instance, when mining the .dynamic
1080 * section for information to build them up.
1082 * NOTE: These fields must be in the same order as the
1083 * SINFO_T_ type codes that correspond to them. Otherwise,
1084 * they will end up in the wrong order in the cache array,
1085 * and the sh_link/sh_info fields may be wrong.
1087 struct {
1088 /* Note: No entry is needed for SINFO_T_NULL */
1089 SINFO dyn;
1090 SINFO dynstr;
1091 SINFO dynsym;
1092 SINFO ldynsym;
1094 SINFO hash;
1095 SINFO syminfo;
1096 SINFO symsort;
1097 SINFO tlssort;
1098 SINFO verneed;
1099 SINFO verdef;
1100 SINFO versym;
1101 SINFO interp;
1102 SINFO cap;
1103 SINFO capinfo;
1104 SINFO capchain;
1105 SINFO unwind;
1106 SINFO move;
1107 SINFO rel;
1108 SINFO rela;
1109 SINFO preinitarr;
1110 SINFO initarr;
1111 SINFO finiarr;
1112 } sec;
1113 static const size_t sinfo_n = sizeof (sec) / sizeof (sec.dyn);
1114 SINFO *secarr = (SINFO *) &sec;
1117 * Doubly linked circular list, used to track sections
1118 * where multiple sections of a given type can exist.
1119 * seclist is the root of the list. Its sinfo field is not
1120 * used --- it serves to anchor the root of the list, allowing
1121 * rapid access to the first and last element in the list.
1123 SINFO_LISTELT seclist;
1125 FSTATE fstate;
1126 size_t ndx;
1127 size_t num_sinfo, num_list_sinfo;
1128 SINFO *sinfo;
1129 SINFO_LISTELT *sinfo_list;
1130 Cache *_cache;
1133 fstate.file = file;
1134 fstate.fd = fd;
1135 fstate.ehdr = ehdr;
1136 if (elf_getphdrnum(elf, &fstate.phnum) == -1) {
1137 failure(file, MSG_ORIG(MSG_ELF_GETPHDRNUM));
1138 return (0);
1140 if ((fstate.phdr = elf_getphdr(elf)) == NULL) {
1141 failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
1142 return (0);
1145 bzero(&sec, sizeof (sec)); /* Initialize "by-name" sec info */
1146 seclist.next = seclist.prev = &seclist; /* Empty circular list */
1149 * Go through the program headers and look for information
1150 * we can use to synthesize section headers. By far the most
1151 * valuable thing is a dynamic section, the contents of
1152 * which point at all sections used by ld.so.1.
1154 for (ndx = 0; ndx < fstate.phnum; ndx++) {
1156 * A program header with no file size does
1157 * not have a backing section.
1159 if (fstate.phdr[ndx].p_filesz == 0)
1160 continue;
1163 switch (fstate.phdr[ndx].p_type) {
1164 default:
1165 /* Header we can't use. Move on to next one */
1166 continue;
1168 case PT_DYNAMIC:
1169 sec.dyn.type = SINFO_T_DYN;
1170 sinfo = &sec.dyn;
1171 break;
1173 case PT_INTERP:
1174 sec.interp.type = SINFO_T_INTERP;
1175 sinfo = &sec.interp;
1176 break;
1178 case PT_NOTE:
1179 if ((sinfo = sinfo_list_alloc(&fstate, &seclist)) ==
1180 NULL)
1181 continue;
1182 sinfo->type = SINFO_T_NOTE;
1183 break;
1185 case PT_SUNW_UNWIND:
1186 case PT_SUNW_EH_FRAME:
1187 sec.unwind.type = SINFO_T_UNWIND;
1188 sinfo = &sec.unwind;
1189 break;
1191 case PT_SUNWCAP:
1192 sec.cap.type = SINFO_T_CAP;
1193 sinfo = &sec.cap;
1194 break;
1198 * Capture the position/extent information for
1199 * the header in the SINFO struct set up by the
1200 * switch statement above.
1202 sinfo->vaddr = fstate.phdr[ndx].p_vaddr;
1203 sinfo->offset = fstate.phdr[ndx].p_offset;
1204 sinfo->size = fstate.phdr[ndx].p_filesz;
1208 * If we found a dynamic section, look through it and
1209 * gather information about the sections it references.
1211 if (sec.dyn.type == SINFO_T_DYN)
1212 (void) get_data(&fstate, &sec.dyn);
1213 if ((sec.dyn.type == SINFO_T_DYN) && (sec.dyn.data->d_buf != NULL)) {
1214 Dyn *dyn;
1215 for (dyn = sec.dyn.data->d_buf; dyn->d_tag != DT_NULL; dyn++) {
1216 switch (dyn->d_tag) {
1217 case DT_HASH:
1218 sec.hash.type = SINFO_T_HASH;
1219 sec.hash.vaddr = dyn->d_un.d_ptr;
1220 break;
1222 case DT_STRTAB:
1223 sec.dynstr.type = SINFO_T_DYNSTR;
1224 sec.dynstr.vaddr = dyn->d_un.d_ptr;
1225 break;
1227 case DT_SYMTAB:
1228 sec.dynsym.type = SINFO_T_DYNSYM;
1229 sec.dynsym.vaddr = dyn->d_un.d_ptr;
1230 break;
1232 case DT_RELA:
1233 sec.rela.type = SINFO_T_RELA;
1234 sec.rela.vaddr = dyn->d_un.d_ptr;
1235 break;
1237 case DT_RELASZ:
1238 sec.rela.size = dyn->d_un.d_val;
1239 break;
1241 case DT_STRSZ:
1242 sec.dynstr.size = dyn->d_un.d_val;
1243 break;
1245 case DT_REL:
1246 sec.rel.type = SINFO_T_REL;
1247 sec.rel.vaddr = dyn->d_un.d_ptr;
1248 break;
1250 case DT_RELSZ:
1251 sec.rel.size = dyn->d_un.d_val;
1252 break;
1254 case DT_INIT_ARRAY:
1255 sec.initarr.type = SINFO_T_INITARR;
1256 sec.initarr.vaddr = dyn->d_un.d_ptr;
1257 break;
1259 case DT_INIT_ARRAYSZ:
1260 sec.initarr.size = dyn->d_un.d_val;
1261 break;
1263 case DT_FINI_ARRAY:
1264 sec.finiarr.type = SINFO_T_FINIARR;
1265 sec.finiarr.vaddr = dyn->d_un.d_ptr;
1266 break;
1268 case DT_FINI_ARRAYSZ:
1269 sec.finiarr.size = dyn->d_un.d_val;
1270 break;
1272 case DT_PREINIT_ARRAY:
1273 sec.preinitarr.type = SINFO_T_PREINITARR;
1274 sec.preinitarr.vaddr = dyn->d_un.d_ptr;
1275 break;
1277 case DT_PREINIT_ARRAYSZ:
1278 sec.preinitarr.size = dyn->d_un.d_val;
1279 break;
1281 case DT_SUNW_CAPINFO:
1282 sec.capinfo.type = SINFO_T_CAPINFO;
1283 sec.capinfo.vaddr = dyn->d_un.d_ptr;
1284 break;
1286 case DT_SUNW_CAPCHAIN:
1287 sec.capchain.type = SINFO_T_CAPCHAIN;
1288 sec.capchain.vaddr = dyn->d_un.d_ptr;
1289 break;
1291 case DT_SUNW_SYMTAB:
1292 sec.ldynsym.type = SINFO_T_LDYNSYM;
1293 sec.ldynsym.vaddr = dyn->d_un.d_ptr;
1294 break;
1296 case DT_SUNW_SYMSZ:
1297 sec.ldynsym.size = dyn->d_un.d_val;
1298 break;
1300 case DT_SUNW_SYMSORT:
1301 sec.symsort.type = SINFO_T_SYMSORT;
1302 sec.symsort.vaddr = dyn->d_un.d_ptr;
1303 break;
1305 case DT_SUNW_SYMSORTSZ:
1306 sec.symsort.size = dyn->d_un.d_val;
1307 break;
1309 case DT_SUNW_TLSSORT:
1310 sec.tlssort.type = SINFO_T_TLSSORT;
1311 sec.tlssort.vaddr = dyn->d_un.d_ptr;
1312 break;
1314 case DT_SUNW_TLSSORTSZ:
1315 sec.tlssort.size = dyn->d_un.d_val;
1316 break;
1318 case DT_MOVETAB:
1319 sec.move.type = SINFO_T_MOVE;
1320 sec.move.vaddr = dyn->d_un.d_ptr;
1321 break;
1323 case DT_MOVESZ:
1324 sec.move.size = dyn->d_un.d_val;
1325 break;
1327 case DT_SYMINFO:
1328 sec.syminfo.type = SINFO_T_SYMINFO;
1329 sec.syminfo.vaddr = dyn->d_un.d_ptr;
1330 break;
1332 case DT_SYMINSZ:
1333 sec.syminfo.size = dyn->d_un.d_val;
1334 break;
1336 case DT_VERSYM:
1337 sec.versym.type = SINFO_T_VERSYM;
1338 sec.versym.vaddr = dyn->d_un.d_ptr;
1339 break;
1341 case DT_VERDEF:
1342 sec.verdef.type = SINFO_T_VERDEF;
1343 sec.verdef.vaddr = dyn->d_un.d_ptr;
1344 break;
1346 case DT_VERDEFNUM:
1347 sec.verdef.vercnt = dyn->d_un.d_val;
1348 sec.verdef.size = sizeof (Verdef) *
1349 dyn->d_un.d_val;
1350 break;
1352 case DT_VERNEED:
1353 sec.verneed.type = SINFO_T_VERNEED;
1354 sec.verneed.vaddr = dyn->d_un.d_ptr;
1355 break;
1357 case DT_VERNEEDNUM:
1358 sec.verneed.vercnt = dyn->d_un.d_val;
1359 sec.verneed.size = sizeof (Verneed) *
1360 dyn->d_un.d_val;
1361 break;
1367 * Different sections depend on each other, and are meaningless
1368 * without them. For instance, even if a .dynsym exists,
1369 * no use can be made of it without a dynstr. These relationships
1370 * fan out: Disqualifying the .dynsym will disqualify the hash
1371 * section, and so forth.
1373 * Disqualify sections that don't have the necessary prerequisites.
1376 /* Things that need the dynamic string table */
1377 if (sec.dynstr.size == 0)
1378 sec.dynstr.type = SINFO_T_NULL;
1379 if (sec.dynstr.type != SINFO_T_DYNSTR) {
1380 sinfo_free(&sec.dyn, 1); /* Data already fetched */
1381 sec.dynsym.type = SINFO_T_NULL;
1382 sec.dynsym.type = SINFO_T_NULL;
1383 sec.verdef.type = SINFO_T_NULL;
1384 sec.verneed.type = SINFO_T_NULL;
1388 * The length of the hash section is encoded in its first two
1389 * elements (nbucket, and nchain). The length of the dynsym,
1390 * ldynsym, and versym are not given in the dynamic section,
1391 * but are known to be the same as nchain.
1393 * If we don't have a hash table, or cannot read nbuckets and
1394 * nchain, we have to invalidate all of these.
1396 if (sec.hash.type == SINFO_T_HASH) {
1397 Word nbucket;
1398 Word nchain;
1399 size_t total;
1401 if (hash_size(&fstate, &sec.hash,
1402 &nbucket, &nchain, &total) == 0) {
1403 sec.hash.type = SINFO_T_NULL;
1404 } else {
1405 /* Use these counts to set sizes for related sections */
1406 sec.hash.size = total * sizeof (Word);
1407 sec.dynsym.size = nchain * sizeof (Sym);
1408 sec.versym.size = nchain * sizeof (Versym);
1411 * The ldynsym size received the DT_SUNW_SYMSZ
1412 * value, which is the combined size of .dynsym
1413 * and .ldynsym. Now that we have the dynsym size,
1414 * use it to lower the ldynsym size to its real size.
1416 if (sec.ldynsym.size > sec.dynsym.size)
1417 sec.ldynsym.size -= sec.dynsym.size;
1421 * If the hash table is not present, or if the call to
1422 * hash_size() failed, then discard the sections that
1423 * need it to determine their length.
1425 if (sec.hash.type != SINFO_T_HASH) {
1426 sec.dynsym.type = SINFO_T_NULL;
1427 sec.ldynsym.type = SINFO_T_NULL;
1428 sec.versym.type = SINFO_T_NULL;
1432 * The runtime linker does not receive size information for
1433 * Verdef and Verneed sections. We have to read their data
1434 * in pieces and calculate it.
1436 if ((sec.verdef.type == SINFO_T_VERDEF) &&
1437 (verdefneed_size(&fstate, &sec.verdef) == 0))
1438 sec.verdef.type = SINFO_T_NULL;
1439 if ((sec.verneed.type == SINFO_T_VERNEED) &&
1440 (verdefneed_size(&fstate, &sec.verneed) == 0))
1441 sec.verneed.type = SINFO_T_NULL;
1443 /* Discard any section with a zero length */
1444 ndx = sinfo_n;
1445 for (sinfo = secarr; ndx-- > 0; sinfo++)
1446 if ((sinfo->type != SINFO_T_NULL) && (sinfo->size == 0))
1447 sinfo->type = SINFO_T_NULL;
1449 /* Things that need the dynamic symbol table */
1450 if (sec.dynsym.type != SINFO_T_DYNSYM) {
1451 sec.ldynsym.type = SINFO_T_NULL;
1452 sec.hash.type = SINFO_T_NULL;
1453 sec.syminfo.type = SINFO_T_NULL;
1454 sec.versym.type = SINFO_T_NULL;
1455 sec.move.type = SINFO_T_NULL;
1456 sec.rel.type = SINFO_T_NULL;
1457 sec.rela.type = SINFO_T_NULL;
1460 /* Things that need the dynamic local symbol table */
1461 if (sec.ldynsym.type != SINFO_T_DYNSYM) {
1462 sec.symsort.type = SINFO_T_NULL;
1463 sec.tlssort.type = SINFO_T_NULL;
1467 * Look through the results and fetch the data for any sections
1468 * we have found. At the same time, count the number.
1470 num_sinfo = num_list_sinfo = 0;
1471 ndx = sinfo_n;
1472 for (sinfo = secarr; ndx-- > 0; sinfo++) {
1473 if ((sinfo->type != SINFO_T_NULL) && (sinfo->data == NULL))
1474 (void) get_data(&fstate, sinfo);
1475 if (sinfo->data != NULL)
1476 num_sinfo++;
1478 for (sinfo_list = seclist.next; sinfo_list != &seclist;
1479 sinfo_list = sinfo_list->next) {
1480 sinfo = &sinfo_list->sinfo;
1481 if ((sinfo->type != SINFO_T_NULL) && (sinfo->data == NULL))
1482 (void) get_data(&fstate, sinfo);
1483 if (sinfo->data != NULL)
1484 num_list_sinfo++;
1488 * Allocate the cache array and fill it in. The cache array
1489 * ends up taking all the dynamic memory we've allocated
1490 * to build up sec and seclist, so on success, we have nothing
1491 * left to clean up. If we can't allocate the cache array
1492 * though, we have to free up everything else.
1494 *shnum = num_sinfo + num_list_sinfo + 1; /* Extra for 1st NULL sec. */
1495 if ((*cache = _cache = malloc((*shnum) * sizeof (Cache))) == NULL) {
1496 int err = errno;
1497 (void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
1498 file, strerror(err));
1499 sinfo_free(secarr, num_sinfo);
1500 sinfo_list_free_all(&seclist);
1501 return (0);
1503 *_cache = cache_init;
1504 _cache++;
1505 ndx = 1;
1506 for (sinfo = secarr; num_sinfo > 0; sinfo++) {
1507 if (sinfo->data != NULL) {
1508 _cache->c_scn = NULL;
1509 _cache->c_shdr = sinfo->shdr;
1510 _cache->c_data = sinfo->data;
1511 _cache->c_name = (char *)sinfo_data[sinfo->type].name;
1512 _cache->c_ndx = ndx++;
1513 _cache++;
1514 num_sinfo--;
1517 for (sinfo_list = seclist.next; num_list_sinfo > 0;
1518 sinfo_list = sinfo_list->next) {
1519 sinfo = &sinfo_list->sinfo;
1520 if (sinfo->data != NULL) {
1521 _cache->c_scn = NULL;
1522 _cache->c_shdr = sinfo->shdr;
1523 _cache->c_data = sinfo->data;
1524 _cache->c_name = (char *)sinfo_data[sinfo->type].name;
1525 _cache->c_ndx = ndx++;
1526 _cache++;
1527 num_list_sinfo--;
1531 return (1);
1539 * Release all the memory referenced by a cache array allocated
1540 * by fake_shdr_cache().
1542 void
1543 fake_shdr_cache_free(Cache *cache, size_t shnum)
1545 Cache *_cache;
1547 for (_cache = cache; shnum--; _cache++) {
1548 if (_cache->c_data != NULL) {
1549 free(_cache->c_data->d_buf);
1550 free(_cache->c_data);
1552 free(_cache->c_shdr);
1555 free(cache);