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