fake_shdr.c revision 11827:d7ef53deac3f
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 */
79typedef 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 */
107typedef 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 */
150typedef 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
174static 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 */
285typedef 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
296typedef 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 */
316static void
317sinfo_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
346static SINFO *
347sinfo_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 */
374static void
375sinfo_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 */
418static Off
419map_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
478static Addr
479map_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 */
536static int
537xlate_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 */
579static int
580read_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 */
609static int
610hash_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 */
636static int
637read_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 */
671static int
672read_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 */
696static int
697read_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 */
731static int
732read_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 */
779static int
780verdefneed_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 */
872static int
873get_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 */
1066int
1067fake_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 */
1543void
1544fake_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