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