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 * Dump an elf file.
29 */
30#include	<stddef.h>
31#include	<sys/elf_386.h>
32#include	<sys/elf_amd64.h>
33#include	<sys/elf_SPARC.h>
34#include	<_libelf.h>
35#include	<dwarf.h>
36#include	<stdio.h>
37#include	<unistd.h>
38#include	<errno.h>
39#include	<strings.h>
40#include	<debug.h>
41#include	<conv.h>
42#include	<msg.h>
43#include	<_elfdump.h>
44
45
46/*
47 * VERSYM_STATE is used to maintain information about the VERSYM section
48 * in the object being analyzed. It is filled in by versions(), and used
49 * by init_symtbl_state() when displaying symbol information.
50 *
51 * There are three forms of symbol versioning known to us:
52 *
53 * 1) The original form, introduced with Solaris 2.5, in which
54 *	the Versym contains indexes to Verdef records, and the
55 *	Versym values for UNDEF symbols resolved by other objects
56 *	are all set to 0.
57 * 2) The GNU form, which is backward compatible with the original
58 *	Solaris form, but which adds several extensions:
59 *	- The Versym also contains indexes to Verneed records, recording
60 *		which object/version contributed the external symbol at
61 *		link time. These indexes start with the next value following
62 *		the final Verdef index. The index is written to the previously
63 *		reserved vna_other field of the ELF Vernaux structure.
64 *	- The top bit of the Versym value is no longer part of the index,
65 *		but is used as a "hidden bit" to prevent binding to the symbol.
66 *	- Multiple implementations of a given symbol, contained in varying
67 *		versions are allowed, using special assembler pseudo ops,
68 *		and encoded in the symbol name using '@' characters.
69 * 3) Modified Solaris form, in which we adopt the first GNU extension
70 *	(Versym indexes to Verneed records), but not the others.
71 *
72 * elfdump can handle any of these cases. The presence of a DT_VERSYM
73 * dynamic element indicates a full GNU object. An object that lacks
74 * a DT_VERSYM entry, but which has non-zero vna_other fields in the Vernaux
75 * structures is a modified Solaris object. An object that has neither of
76 * these uses the original form.
77 *
78 * max_verndx contains the largest version index that can appear
79 * in a Versym entry. This can never be less than 1: In the case where
80 * there is no verdef/verneed sections, the [0] index is reserved
81 * for local symbols, and the [1] index for globals. If the original
82 * Solaris versioning rules are in effect and there is a verdef section,
83 * then max_verndex is the number of defined versions. If one of the
84 * other versioning forms is in effect, then:
85 *	1) If there is no verneed section, it is the same as for
86 *		original Solaris versioning.
87 *	2) If there is a verneed section, the vna_other field of the
88 *		Vernaux structs contain versions, and max_verndx is the
89 *		largest such index.
90 *
91 * If gnu_full is True, the object uses the full GNU form of versioning.
92 * The value of the gnu_full field is based on the presence of
93 * a DT_VERSYM entry in the dynamic section: GNU ld produces these, and
94 * Solaris ld does not.
95 *
96 * The gnu_needed field is True if the Versym contains indexes to
97 * Verneed records, as indicated by non-zero vna_other fields in the Verneed
98 * section. If gnu_full is True, then gnu_needed will always be true.
99 * However, gnu_needed can be true without gnu_full. This is the modified
100 * Solaris form.
101 */
102typedef struct {
103	Cache	*cache;		/* Pointer to cache entry for VERSYM */
104	Versym	*data;		/* Pointer to versym array */
105	int	gnu_full;	/* True if object uses GNU versioning rules */
106	int	gnu_needed;	/* True if object uses VERSYM indexes for */
107				/*	VERNEED (subset of gnu_full) */
108	int	max_verndx;	/* largest versym index value */
109} VERSYM_STATE;
110
111/*
112 * SYMTBL_STATE is used to maintain information about a single symbol
113 * table section, for use by the routines that display symbol information.
114 */
115typedef struct {
116	const char	*file;		/* Name of file */
117	Ehdr		*ehdr;		/* ELF header for file */
118	Cache		*cache;		/* Cache of all section headers */
119	uchar_t		osabi;		/* OSABI to use */
120	Word		shnum;		/* # of sections in cache */
121	Cache		*seccache;	/* Cache of symbol table section hdr */
122	Word		secndx;		/* Index of symbol table section hdr */
123	const char	*secname;	/* Name of section */
124	uint_t		flags;		/* Command line option flags */
125	struct {			/* Extended section index data */
126		int	checked;	/* TRUE if already checked for shxndx */
127		Word	*data;		/* NULL, or extended section index */
128					/*	used for symbol table entries */
129		uint_t	n;		/* # items in shxndx.data */
130	} shxndx;
131	VERSYM_STATE	*versym;	/* NULL, or associated VERSYM section */
132	Sym 		*sym;		/* Array of symbols */
133	Word		symn;		/* # of symbols */
134} SYMTBL_STATE;
135
136/*
137 * A variable of this type is used to track information related to
138 * .eh_frame and .eh_frame_hdr sections across calls to unwind_eh_frame().
139 */
140typedef struct {
141	Word		frame_cnt;	/* # .eh_frame sections seen */
142	Word		frame_ndx;	/* Section index of 1st .eh_frame */
143	Word		hdr_cnt;	/* # .eh_frame_hdr sections seen */
144	Word		hdr_ndx;	/* Section index of 1st .eh_frame_hdr */
145	uint64_t	frame_ptr;	/* Value of FramePtr field from first */
146					/*	.eh_frame_hdr section */
147	uint64_t	frame_base;	/* Data addr of 1st .eh_frame  */
148} gnu_eh_state_t;
149
150/*
151 * C++ .exception_ranges entries make use of the signed ptrdiff_t
152 * type to record self-relative pointer values. We need a type
153 * for this that is matched to the ELFCLASS being processed.
154 */
155#if	defined(_ELF64)
156	typedef int64_t PTRDIFF_T;
157#else
158	typedef int32_t PTRDIFF_T;
159#endif
160
161/*
162 * The Sun C++ ABI uses this struct to define each .exception_ranges
163 * entry. From the ABI:
164 *
165 * The field ret_addr is a self relative pointer to the start of the address
166 * range. The name was chosen because in the current implementation the range
167 * typically starts at the return address for a call site.
168 *
169 * The field length is the difference, in bytes, between the pc of the last
170 * instruction covered by the exception range and the first. When only a
171 * single call site is represented without optimization, this will equal zero.
172 *
173 * The field handler_addr is a relative pointer which stores the difference
174 * between the start of the exception range and the address of all code to
175 * catch exceptions and perform the cleanup for stack unwinding.
176 *
177 * The field type_block is a relative pointer which stores the difference
178 * between the start of the exception range and the address of an array used
179 * for storing a list of the types of exceptions which can be caught within
180 * the exception range.
181 */
182typedef struct {
183	PTRDIFF_T	ret_addr;
184	Xword		length;
185	PTRDIFF_T	handler_addr;
186	PTRDIFF_T	type_block;
187	Xword		reserved;
188} exception_range_entry;
189
190/*
191 * Focal point for verifying symbol names.
192 */
193static const char *
194string(Cache *refsec, Word ndx, Cache *strsec, const char *file, Word name)
195{
196	/*
197	 * If an error in this routine is due to a property of the string
198	 * section, as opposed to a bad offset into the section (a property of
199	 * the referencing section), then we will detect the same error on
200	 * every call involving those sections. We use these static variables
201	 * to retain the information needed to only issue each such error once.
202	 */
203	static Cache	*last_refsec;	/* Last referencing section seen */
204	static int	strsec_err;	/* True if error issued */
205
206	const char	*strs;
207	Word		strn;
208
209	if (strsec->c_data == NULL)
210		return (NULL);
211
212	strs = (char *)strsec->c_data->d_buf;
213	strn = strsec->c_data->d_size;
214
215	/*
216	 * We only print a diagnostic regarding a bad string table once per
217	 * input section being processed. If the refsec has changed, reset
218	 * our retained error state.
219	 */
220	if (last_refsec != refsec) {
221		last_refsec = refsec;
222		strsec_err = 0;
223	}
224
225	/* Verify that strsec really is a string table */
226	if (strsec->c_shdr->sh_type != SHT_STRTAB) {
227		if (!strsec_err) {
228			(void) fprintf(stderr, MSG_INTL(MSG_ERR_NOTSTRTAB),
229			    file, strsec->c_ndx, refsec->c_ndx);
230			strsec_err = 1;
231		}
232		return (MSG_INTL(MSG_STR_UNKNOWN));
233	}
234
235	/*
236	 * Is the string table offset within range of the available strings?
237	 */
238	if (name >= strn) {
239		/*
240		 * Do we have a empty string table?
241		 */
242		if (strs == NULL) {
243			if (!strsec_err) {
244				(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
245				    file, strsec->c_name);
246				strsec_err = 1;
247			}
248		} else {
249			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSTOFF),
250			    file, refsec->c_name, EC_WORD(ndx), strsec->c_name,
251			    EC_WORD(name), EC_WORD(strn - 1));
252		}
253
254		/*
255		 * Return the empty string so that the calling function can
256		 * continue it's output diagnostics.
257		 */
258		return (MSG_INTL(MSG_STR_UNKNOWN));
259	}
260	return (strs + name);
261}
262
263/*
264 * Relocations can reference section symbols and standard symbols.  If the
265 * former, establish the section name.
266 */
267static const char *
268relsymname(Cache *cache, Cache *csec, Cache *strsec, Word symndx, Word symnum,
269    Word relndx, Sym *syms, char *secstr, size_t secsz, const char *file)
270{
271	Sym		*sym;
272	const char	*name;
273
274	if (symndx >= symnum) {
275		(void) fprintf(stderr, MSG_INTL(MSG_ERR_RELBADSYMNDX),
276		    file, EC_WORD(symndx), EC_WORD(relndx));
277		return (MSG_INTL(MSG_STR_UNKNOWN));
278	}
279
280	sym = (Sym *)(syms + symndx);
281	name = string(csec, symndx, strsec, file, sym->st_name);
282
283	/*
284	 * If the symbol represents a section offset construct an appropriate
285	 * string.  Note, although section symbol table entries typically have
286	 * a NULL name pointer, entries do exist that point into the string
287	 * table to their own NULL strings.
288	 */
289	if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) &&
290	    ((sym->st_name == 0) || (*name == '\0'))) {
291		(void) snprintf(secstr, secsz, MSG_INTL(MSG_STR_SECTION),
292		    cache[sym->st_shndx].c_name);
293		return ((const char *)secstr);
294	}
295
296	return (name);
297}
298
299/*
300 * Focal point for establishing a string table section.  Data such as the
301 * dynamic information simply points to a string table.  Data such as
302 * relocations, reference a symbol table, which in turn is associated with a
303 * string table.
304 */
305static int
306stringtbl(Cache *cache, int symtab, Word ndx, Word shnum, const char *file,
307    Word *symnum, Cache **symsec, Cache **strsec)
308{
309	Shdr	*shdr = cache[ndx].c_shdr;
310
311	if (symtab) {
312		/*
313		 * Validate the symbol table section.
314		 */
315		if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
316			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
317			    file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
318			return (0);
319		}
320		if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
321			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
322			    file, cache[ndx].c_name);
323			return (0);
324		}
325
326		/*
327		 * Obtain, and verify the symbol table data.
328		 */
329		if ((cache[ndx].c_data == NULL) ||
330		    (cache[ndx].c_data->d_buf == NULL)) {
331			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
332			    file, cache[ndx].c_name);
333			return (0);
334		}
335
336		/*
337		 * Establish the string table index.
338		 */
339		ndx = shdr->sh_link;
340		shdr = cache[ndx].c_shdr;
341
342		/*
343		 * Return symbol table information.
344		 */
345		if (symnum)
346			*symnum = (shdr->sh_size / shdr->sh_entsize);
347		if (symsec)
348			*symsec = &cache[ndx];
349	}
350
351	/*
352	 * Validate the associated string table section.
353	 */
354	if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
355		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
356		    file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
357		return (0);
358	}
359
360	if (strsec)
361		*strsec = &cache[shdr->sh_link];
362
363	return (1);
364}
365
366/*
367 * Lookup a symbol and set Sym accordingly.
368 *
369 * entry:
370 *	name - Name of symbol to lookup
371 *	cache - Cache of all section headers
372 *	shnum - # of sections in cache
373 *	sym - Address of pointer to receive symbol
374 *	target - NULL, or section to which the symbol must be associated.
375 *	symtab - Symbol table to search for symbol
376 *	file - Name of file
377 *
378 * exit:
379 *	If the symbol is found, *sym is set to reference it, and True is
380 *	returned. If target is non-NULL, the symbol must reference the given
381 *	section --- otherwise the section is not checked.
382 *
383 *	If no symbol is found, False is returned.
384 */
385static int
386symlookup(const char *name, Cache *cache, Word shnum, Sym **sym,
387    Cache *target, Cache *symtab, const char *file)
388{
389	Shdr	*shdr;
390	Word	symn, cnt;
391	Sym	*syms;
392
393	if (symtab == 0)
394		return (0);
395
396	shdr = symtab->c_shdr;
397
398	/*
399	 * Determine the symbol data and number.
400	 */
401	if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
402		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
403		    file, symtab->c_name);
404		return (0);
405	}
406	if (symtab->c_data == NULL)
407		return (0);
408
409	/* LINTED */
410	symn = (Word)(shdr->sh_size / shdr->sh_entsize);
411	syms = (Sym *)symtab->c_data->d_buf;
412
413	/*
414	 * Get the associated string table section.
415	 */
416	if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
417		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
418		    file, symtab->c_name, EC_WORD(shdr->sh_link));
419		return (0);
420	}
421
422	/*
423	 * Loop through the symbol table to find a match.
424	 */
425	*sym = NULL;
426	for (cnt = 0; cnt < symn; syms++, cnt++) {
427		const char	*symname;
428
429		symname = string(symtab, cnt, &cache[shdr->sh_link], file,
430		    syms->st_name);
431
432		if (symname && (strcmp(name, symname) == 0) &&
433		    ((target == NULL) || (target->c_ndx == syms->st_shndx))) {
434			/*
435			 * It is possible, though rare, for a local and
436			 * global symbol of the same name to exist, each
437			 * contributed by a different input object. If the
438			 * symbol just found is local, remember it, but
439			 * continue looking.
440			 */
441			*sym = syms;
442			if (ELF_ST_BIND(syms->st_info) != STB_LOCAL)
443				break;
444		}
445	}
446
447	return (*sym != NULL);
448}
449
450/*
451 * Print section headers.
452 */
453static void
454sections(const char *file, Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi)
455{
456	size_t	seccnt;
457
458	for (seccnt = 1; seccnt < shnum; seccnt++) {
459		Cache		*_cache = &cache[seccnt];
460		Shdr		*shdr = _cache->c_shdr;
461		const char	*secname = _cache->c_name;
462
463		/*
464		 * Although numerous section header entries can be zero, it's
465		 * usually a sign of trouble if the type is zero.
466		 */
467		if (shdr->sh_type == 0) {
468			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHTYPE),
469			    file, secname, EC_WORD(shdr->sh_type));
470		}
471
472		if (!match(MATCH_F_ALL, secname, seccnt, shdr->sh_type))
473			continue;
474
475		/*
476		 * Identify any sections that are suspicious.  A .got section
477		 * shouldn't exist in a relocatable object.
478		 */
479		if (ehdr->e_type == ET_REL) {
480			if (strncmp(secname, MSG_ORIG(MSG_ELF_GOT),
481			    MSG_ELF_GOT_SIZE) == 0) {
482				(void) fprintf(stderr,
483				    MSG_INTL(MSG_GOT_UNEXPECTED), file,
484				    secname);
485			}
486		}
487
488		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
489		dbg_print(0, MSG_INTL(MSG_ELF_SHDR), EC_WORD(seccnt), secname);
490		Elf_shdr(0, osabi, ehdr->e_machine, shdr);
491	}
492}
493
494/*
495 * Obtain a specified Phdr entry.
496 */
497static Phdr *
498getphdr(Word phnum, Word *type_arr, Word type_cnt, const char *file, Elf *elf)
499{
500	Word	cnt, tcnt;
501	Phdr	*phdr;
502
503	if ((phdr = elf_getphdr(elf)) == NULL) {
504		failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
505		return (NULL);
506	}
507
508	for (cnt = 0; cnt < phnum; phdr++, cnt++) {
509		for (tcnt = 0; tcnt < type_cnt; tcnt++) {
510			if (phdr->p_type == type_arr[tcnt])
511				return (phdr);
512		}
513	}
514	return (NULL);
515}
516
517/*
518 * Display the contents of GNU/amd64 .eh_frame and .eh_frame_hdr
519 * sections.
520 *
521 * entry:
522 *	cache - Cache of all section headers
523 *	shndx - Index of .eh_frame or .eh_frame_hdr section to be displayed
524 *	uphdr - NULL, or unwind program header associated with
525 *		the .eh_frame_hdr section.
526 *	ehdr - ELF header for file
527 *	eh_state - Data used across calls to this routine. The
528 *		caller should zero it before the first call, and
529 *		pass it on every call.
530 *	osabi - OSABI to use in displaying information
531 *	file - Name of file
532 *	flags - Command line option flags
533 */
534static void
535unwind_eh_frame(Cache *cache, Word shndx, Phdr *uphdr, Ehdr *ehdr,
536    gnu_eh_state_t *eh_state, uchar_t osabi, const char *file, uint_t flags)
537{
538#if	defined(_ELF64)
539#define	MSG_UNW_BINSRTAB2	MSG_UNW_BINSRTAB2_64
540#define	MSG_UNW_BINSRTABENT	MSG_UNW_BINSRTABENT_64
541#else
542#define	MSG_UNW_BINSRTAB2	MSG_UNW_BINSRTAB2_32
543#define	MSG_UNW_BINSRTABENT	MSG_UNW_BINSRTABENT_32
544#endif
545
546	Cache			*_cache = &cache[shndx];
547	Shdr			*shdr = _cache->c_shdr;
548	uchar_t			*data = (uchar_t *)(_cache->c_data->d_buf);
549	size_t			datasize = _cache->c_data->d_size;
550	Conv_dwarf_ehe_buf_t	dwarf_ehe_buf;
551	uint64_t		ndx, frame_ptr, fde_cnt, tabndx;
552	uint_t			vers, frame_ptr_enc, fde_cnt_enc, table_enc;
553	uint64_t		initloc, initloc0;
554
555
556	/*
557	 * Is this a .eh_frame_hdr?
558	 */
559	if ((uphdr && (shdr->sh_addr == uphdr->p_vaddr)) ||
560	    (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
561	    MSG_SCN_FRMHDR_SIZE) == 0)) {
562		/*
563		 * There can only be a single .eh_frame_hdr.
564		 * Flag duplicates.
565		 */
566		if (++eh_state->hdr_cnt > 1)
567			(void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTEHFRMHDR),
568			    file, EC_WORD(shndx), _cache->c_name);
569
570		dbg_print(0, MSG_ORIG(MSG_UNW_FRMHDR));
571		ndx = 0;
572
573		vers = data[ndx++];
574		frame_ptr_enc = data[ndx++];
575		fde_cnt_enc = data[ndx++];
576		table_enc = data[ndx++];
577
578		dbg_print(0, MSG_ORIG(MSG_UNW_FRMVERS), vers);
579
580		frame_ptr = dwarf_ehe_extract(data, &ndx, frame_ptr_enc,
581		    ehdr->e_ident, shdr->sh_addr, ndx);
582		if (eh_state->hdr_cnt == 1) {
583			eh_state->hdr_ndx = shndx;
584			eh_state->frame_ptr = frame_ptr;
585		}
586
587		dbg_print(0, MSG_ORIG(MSG_UNW_FRPTRENC),
588		    conv_dwarf_ehe(frame_ptr_enc, &dwarf_ehe_buf),
589		    EC_XWORD(frame_ptr));
590
591		fde_cnt = dwarf_ehe_extract(data, &ndx, fde_cnt_enc,
592		    ehdr->e_ident, shdr->sh_addr, ndx);
593
594		dbg_print(0, MSG_ORIG(MSG_UNW_FDCNENC),
595		    conv_dwarf_ehe(fde_cnt_enc, &dwarf_ehe_buf),
596		    EC_XWORD(fde_cnt));
597		dbg_print(0, MSG_ORIG(MSG_UNW_TABENC),
598		    conv_dwarf_ehe(table_enc, &dwarf_ehe_buf));
599		dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB1));
600		dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTAB2));
601
602		for (tabndx = 0; tabndx < fde_cnt; tabndx++) {
603			initloc = dwarf_ehe_extract(data, &ndx, table_enc,
604			    ehdr->e_ident, shdr->sh_addr, ndx);
605			/*LINTED:E_VAR_USED_BEFORE_SET*/
606			if ((tabndx != 0) && (initloc0 > initloc))
607				(void) fprintf(stderr,
608				    MSG_INTL(MSG_ERR_BADSORT), file,
609				    _cache->c_name, EC_WORD(tabndx));
610			dbg_print(0, MSG_ORIG(MSG_UNW_BINSRTABENT),
611			    EC_XWORD(initloc),
612			    EC_XWORD(dwarf_ehe_extract(data, &ndx,
613			    table_enc, ehdr->e_ident, shdr->sh_addr,
614			    ndx)));
615			initloc0 = initloc;
616		}
617	} else {		/* Display the .eh_frame section */
618		eh_state->frame_cnt++;
619		if (eh_state->frame_cnt == 1) {
620			eh_state->frame_ndx = shndx;
621			eh_state->frame_base = shdr->sh_addr;
622		} else if ((eh_state->frame_cnt >  1) &&
623		    (ehdr->e_type != ET_REL)) {
624			Conv_inv_buf_t	inv_buf;
625
626			(void) fprintf(stderr, MSG_INTL(MSG_WARN_MULTEHFRM),
627			    file, EC_WORD(shndx), _cache->c_name,
628			    conv_ehdr_type(osabi, ehdr->e_type, 0, &inv_buf));
629		}
630		dump_eh_frame(data, datasize, shdr->sh_addr,
631		    ehdr->e_machine, ehdr->e_ident);
632	}
633
634	/*
635	 * If we've seen the .eh_frame_hdr and the first .eh_frame section,
636	 * compare the header frame_ptr to the address of the actual frame
637	 * section to ensure the link-editor got this right.  Note, this
638	 * diagnostic is only produced when unwind information is explicitly
639	 * asked for, as shared objects built with an older ld(1) may reveal
640	 * this inconsistency.  Although an inconsistency, it doesn't seem to
641	 * have any adverse effect on existing tools.
642	 */
643	if (((flags & FLG_MASK_SHOW) != FLG_MASK_SHOW) &&
644	    (eh_state->hdr_cnt > 0) && (eh_state->frame_cnt > 0) &&
645	    (eh_state->frame_ptr != eh_state->frame_base))
646		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADEHFRMPTR),
647		    file, EC_WORD(eh_state->hdr_ndx),
648		    cache[eh_state->hdr_ndx].c_name,
649		    EC_XWORD(eh_state->frame_ptr),
650		    EC_WORD(eh_state->frame_ndx),
651		    cache[eh_state->frame_ndx].c_name,
652		    EC_XWORD(eh_state->frame_base));
653#undef MSG_UNW_BINSRTAB2
654#undef MSG_UNW_BINSRTABENT
655}
656
657/*
658 * Convert a self relative pointer into an address. A self relative
659 * pointer adds the address where the pointer resides to the offset
660 * contained in the pointer. The benefit is that the value of the
661 * pointer does not require relocation.
662 *
663 * entry:
664 *	base_addr - Address of the pointer.
665 *	delta - Offset relative to base_addr giving desired address
666 *
667 * exit:
668 *	The computed address is returned.
669 *
670 * note:
671 *	base_addr is an unsigned value, while ret_addr is signed. This routine
672 *	used explicit testing and casting to explicitly control type
673 *	conversion, and ensure that we handle the maximum possible range.
674 */
675static Addr
676srelptr(Addr base_addr, PTRDIFF_T delta)
677{
678	if (delta < 0)
679		return (base_addr - (Addr) (-delta));
680
681	return (base_addr + (Addr) delta);
682}
683
684/*
685 * Byte swap a PTRDIFF_T value.
686 */
687static PTRDIFF_T
688swap_ptrdiff(PTRDIFF_T value)
689{
690	PTRDIFF_T r;
691	uchar_t	*dst = (uchar_t *)&r;
692	uchar_t	*src = (uchar_t *)&value;
693
694	UL_ASSIGN_BSWAP_XWORD(dst, src);
695	return (r);
696}
697
698/*
699 * Display exception_range_entry items from the .exception_ranges section
700 * of a Sun C++ object.
701 */
702static void
703unwind_exception_ranges(Cache *_cache, const char *file, int do_swap)
704{
705	/*
706	 * Translate a PTRDIFF_T self-relative address field of
707	 * an exception_range_entry struct into an address.
708	 *
709	 * entry:
710	 *	exc_addr - Address of base of exception_range_entry struct
711	 *	cur_ent - Pointer to data in the struct to be translated
712	 *
713	 *	_f - Field of struct to be translated
714	 */
715#define	SRELPTR(_f) \
716	srelptr(exc_addr + offsetof(exception_range_entry, _f), cur_ent->_f)
717
718#if	defined(_ELF64)
719#define	MSG_EXR_TITLE	MSG_EXR_TITLE_64
720#define	MSG_EXR_ENTRY	MSG_EXR_ENTRY_64
721#else
722#define	MSG_EXR_TITLE	MSG_EXR_TITLE_32
723#define	MSG_EXR_ENTRY	MSG_EXR_ENTRY_32
724#endif
725
726	exception_range_entry	scratch, *ent, *cur_ent = &scratch;
727	char			index[MAXNDXSIZE];
728	Word			i, nelts;
729	Addr			addr, addr0, offset = 0;
730	Addr			exc_addr = _cache->c_shdr->sh_addr;
731
732	dbg_print(0, MSG_INTL(MSG_EXR_TITLE));
733	ent = (exception_range_entry *)(_cache->c_data->d_buf);
734	nelts = _cache->c_data->d_size / sizeof (exception_range_entry);
735
736	for (i = 0; i < nelts; i++, ent++) {
737		if (do_swap) {
738			/*
739			 * Copy byte swapped values into the scratch buffer.
740			 * The reserved field is not used, so we skip it.
741			 */
742			scratch.ret_addr = swap_ptrdiff(ent->ret_addr);
743			scratch.length = BSWAP_XWORD(ent->length);
744			scratch.handler_addr = swap_ptrdiff(ent->handler_addr);
745			scratch.type_block = swap_ptrdiff(ent->type_block);
746		} else {
747			cur_ent = ent;
748		}
749
750		/*
751		 * The table is required to be sorted by the address
752		 * derived from ret_addr, to allow binary searching. Ensure
753		 * that addresses grow monotonically.
754		 */
755		addr = SRELPTR(ret_addr);
756		/*LINTED:E_VAR_USED_BEFORE_SET*/
757		if ((i != 0) && (addr0 > addr))
758			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSORT),
759			    file, _cache->c_name, EC_WORD(i));
760
761		(void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
762		    EC_XWORD(i));
763		dbg_print(0, MSG_INTL(MSG_EXR_ENTRY), index, EC_ADDR(offset),
764		    EC_ADDR(addr), EC_ADDR(cur_ent->length),
765		    EC_ADDR(SRELPTR(handler_addr)),
766		    EC_ADDR(SRELPTR(type_block)));
767
768		addr0 = addr;
769		exc_addr += sizeof (exception_range_entry);
770		offset += sizeof (exception_range_entry);
771	}
772
773#undef SRELPTR
774#undef MSG_EXR_TITLE
775#undef MSG_EXR_ENTRY
776}
777
778/*
779 * Display information from unwind/exception sections:
780 *
781 * -	GNU/amd64 .eh_frame and .eh_frame_hdr
782 * -	Sun C++ .exception_ranges
783 *
784 */
785static void
786unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, uchar_t osabi,
787    const char *file, Elf *elf, uint_t flags)
788{
789	static Word phdr_types[] = { PT_SUNW_UNWIND, PT_SUNW_EH_FRAME };
790
791	Word			cnt;
792	Phdr			*uphdr = NULL;
793	gnu_eh_state_t		eh_state;
794
795	/*
796	 * Historical background: .eh_frame and .eh_frame_hdr sections
797	 * come from the GNU compilers (particularly C++), and are used
798	 * under all architectures. Their format is based on DWARF. When
799	 * the amd64 ABI was defined, these sections were adopted wholesale
800	 * from the existing practice.
801	 *
802	 * When amd64 support was added to Solaris, support for these
803	 * sections was added, using the SHT_AMD64_UNWIND section type
804	 * to identify them. At first, we ignored them in objects for
805	 * non-amd64 targets, but later broadened our support to include
806	 * other architectures in order to better support gcc-generated
807	 * objects.
808	 *
809	 * .exception_ranges implement the same basic concepts, but
810	 * were invented at Sun for the Sun C++ compiler.
811	 *
812	 * We match these sections by name, rather than section type,
813	 * because they can come in as either SHT_AMD64_UNWIND, or as
814	 * SHT_PROGBITS, and because the type isn't enough to determine
815	 * how they should be interpreted.
816	 */
817	/* Find the program header for .eh_frame_hdr if present */
818	if (phnum)
819		uphdr = getphdr(phnum, phdr_types,
820		    sizeof (phdr_types) / sizeof (*phdr_types), file, elf);
821
822	/*
823	 * eh_state is used to retain data used by unwind_eh_frame()
824	 * across calls.
825	 */
826	bzero(&eh_state, sizeof (eh_state));
827
828	for (cnt = 1; cnt < shnum; cnt++) {
829		Cache		*_cache = &cache[cnt];
830		Shdr		*shdr = _cache->c_shdr;
831		int		is_exrange;
832
833		/*
834		 * Skip sections of the wrong type. On amd64, they
835		 * can be SHT_AMD64_UNWIND. On all platforms, they
836		 * can be SHT_PROGBITS (including amd64, if using
837		 * the GNU compilers).
838		 *
839		 * Skip anything other than these two types. The name
840		 * test below will thin out the SHT_PROGBITS that don't apply.
841		 */
842		if ((shdr->sh_type != SHT_PROGBITS) &&
843		    (shdr->sh_type != SHT_AMD64_UNWIND))
844			continue;
845
846		/*
847		 * Only sections with certain well known names are of interest.
848		 * These are:
849		 *
850		 *	.eh_frame - amd64/GNU-compiler unwind sections
851		 *	.eh_frame_hdr - Sorted table referencing .eh_frame
852		 *	.exception_ranges - Sun C++ unwind sections
853		 *
854		 * We do a prefix comparison, allowing for naming conventions
855		 * like .eh_frame.foo, hence the use of strncmp() rather than
856		 * strcmp(). This means that we only really need to test for
857		 * .eh_frame, as it's a prefix of .eh_frame_hdr.
858		 */
859		is_exrange =  strncmp(_cache->c_name,
860		    MSG_ORIG(MSG_SCN_EXRANGE), MSG_SCN_EXRANGE_SIZE) == 0;
861		if ((strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRM),
862		    MSG_SCN_FRM_SIZE) != 0) && !is_exrange)
863			continue;
864
865		if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
866			continue;
867
868		if (_cache->c_data == NULL)
869			continue;
870
871		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
872		dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name);
873
874		if (is_exrange)
875			unwind_exception_ranges(_cache, file,
876			    _elf_sys_encoding() != ehdr->e_ident[EI_DATA]);
877		else
878			unwind_eh_frame(cache, cnt, uphdr, ehdr, &eh_state,
879			    osabi, file, flags);
880	}
881}
882
883/*
884 * Initialize a symbol table state structure
885 *
886 * entry:
887 *	state - State structure to be initialized
888 *	cache - Cache of all section headers
889 *	shnum - # of sections in cache
890 *	secndx - Index of symbol table section
891 *	ehdr - ELF header for file
892 *	versym - Information about versym section
893 *	file - Name of file
894 *	flags - Command line option flags
895 */
896static int
897init_symtbl_state(SYMTBL_STATE *state, Cache *cache, Word shnum, Word secndx,
898    Ehdr *ehdr, uchar_t osabi, VERSYM_STATE *versym, const char *file,
899    uint_t flags)
900{
901	Shdr *shdr;
902
903	state->file = file;
904	state->ehdr = ehdr;
905	state->cache = cache;
906	state->osabi = osabi;
907	state->shnum = shnum;
908	state->seccache = &cache[secndx];
909	state->secndx = secndx;
910	state->secname = state->seccache->c_name;
911	state->flags = flags;
912	state->shxndx.checked = 0;
913	state->shxndx.data = NULL;
914	state->shxndx.n = 0;
915
916	shdr = state->seccache->c_shdr;
917
918	/*
919	 * Check the symbol data and per-item size.
920	 */
921	if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
922		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
923		    file, state->secname);
924		return (0);
925	}
926	if (state->seccache->c_data == NULL)
927		return (0);
928
929	/* LINTED */
930	state->symn = (Word)(shdr->sh_size / shdr->sh_entsize);
931	state->sym = (Sym *)state->seccache->c_data->d_buf;
932
933	/*
934	 * Check associated string table section.
935	 */
936	if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
937		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
938		    file, state->secname, EC_WORD(shdr->sh_link));
939		return (0);
940	}
941
942	/*
943	 * Determine if there is a associated Versym section
944	 * with this Symbol Table.
945	 */
946	if (versym && versym->cache &&
947	    (versym->cache->c_shdr->sh_link == state->secndx))
948		state->versym = versym;
949	else
950		state->versym = NULL;
951
952
953	return (1);
954}
955
956/*
957 * Determine the extended section index used for symbol tables entries.
958 */
959static void
960symbols_getxindex(SYMTBL_STATE *state)
961{
962	uint_t	symn;
963	Word	symcnt;
964
965	state->shxndx.checked = 1;   /* Note that we've been called */
966	for (symcnt = 1; symcnt < state->shnum; symcnt++) {
967		Cache	*_cache = &state->cache[symcnt];
968		Shdr	*shdr = _cache->c_shdr;
969
970		if ((shdr->sh_type != SHT_SYMTAB_SHNDX) ||
971		    (shdr->sh_link != state->secndx))
972			continue;
973
974		if ((shdr->sh_entsize) &&
975		    /* LINTED */
976		    ((symn = (uint_t)(shdr->sh_size / shdr->sh_entsize)) == 0))
977			continue;
978
979		if (_cache->c_data == NULL)
980			continue;
981
982		state->shxndx.data = _cache->c_data->d_buf;
983		state->shxndx.n = symn;
984		return;
985	}
986}
987
988/*
989 * Produce a line of output for the given symbol
990 *
991 * entry:
992 *	state - Symbol table state
993 *	symndx - Index of symbol within the table
994 *	info - Value of st_info (indicates local/global range)
995 *	symndx_disp - Index to display. This may not be the same
996 *		as symndx if the display is relative to the logical
997 *		combination of the SUNW_ldynsym/dynsym tables.
998 *	sym - Symbol to display
999 */
1000static void
1001output_symbol(SYMTBL_STATE *state, Word symndx, Word info, Word disp_symndx,
1002    Sym *sym)
1003{
1004	/*
1005	 * Symbol types for which we check that the specified
1006	 * address/size land inside the target section.
1007	 */
1008	static const int addr_symtype[] = {
1009		0,			/* STT_NOTYPE */
1010		1,			/* STT_OBJECT */
1011		1,			/* STT_FUNC */
1012		0,			/* STT_SECTION */
1013		0,			/* STT_FILE */
1014		1,			/* STT_COMMON */
1015		0,			/* STT_TLS */
1016		0,			/* 7 */
1017		0,			/* 8 */
1018		0,			/* 9 */
1019		0,			/* 10 */
1020		0,			/* 11 */
1021		0,			/* 12 */
1022		0,			/* STT_SPARC_REGISTER */
1023		0,			/* 14 */
1024		0,			/* 15 */
1025	};
1026#if STT_NUM != (STT_TLS + 1)
1027#error "STT_NUM has grown. Update addr_symtype[]"
1028#endif
1029
1030	char		index[MAXNDXSIZE];
1031	const char	*symname, *sec;
1032	Versym		verndx;
1033	int		gnuver;
1034	uchar_t		type;
1035	Shdr		*tshdr;
1036	Word		shndx;
1037	Conv_inv_buf_t	inv_buf;
1038
1039	/* Ensure symbol index is in range */
1040	if (symndx >= state->symn) {
1041		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSYMNDX),
1042		    state->file, state->secname, EC_WORD(symndx));
1043		return;
1044	}
1045
1046	/*
1047	 * If we are using extended symbol indexes, find the
1048	 * corresponding SHN_SYMTAB_SHNDX table.
1049	 */
1050	if ((sym->st_shndx == SHN_XINDEX) && (state->shxndx.checked == 0))
1051		symbols_getxindex(state);
1052
1053	/* LINTED */
1054	symname = string(state->seccache, symndx,
1055	    &state->cache[state->seccache->c_shdr->sh_link], state->file,
1056	    sym->st_name);
1057
1058	tshdr = NULL;
1059	sec = NULL;
1060
1061	if (state->ehdr->e_type == ET_CORE) {
1062		sec = (char *)MSG_INTL(MSG_STR_UNKNOWN);
1063	} else if (state->flags & FLG_CTL_FAKESHDR) {
1064		/*
1065		 * If we are using fake section headers derived from
1066		 * the program headers, then the section indexes
1067		 * in the symbols do not correspond to these headers.
1068		 * The section names are not available, so all we can
1069		 * do is to display them in numeric form.
1070		 */
1071		sec = conv_sym_shndx(state->osabi, state->ehdr->e_machine,
1072		    sym->st_shndx, CONV_FMT_DECIMAL, &inv_buf);
1073	} else if ((sym->st_shndx < SHN_LORESERVE) &&
1074	    (sym->st_shndx < state->shnum)) {
1075		shndx = sym->st_shndx;
1076		tshdr = state->cache[shndx].c_shdr;
1077		sec = state->cache[shndx].c_name;
1078	} else if (sym->st_shndx == SHN_XINDEX) {
1079		if (state->shxndx.data) {
1080			Word	_shxndx;
1081
1082			if (symndx > state->shxndx.n) {
1083				(void) fprintf(stderr,
1084				    MSG_INTL(MSG_ERR_BADSYMXINDEX1),
1085				    state->file, state->secname,
1086				    EC_WORD(symndx));
1087			} else if ((_shxndx =
1088			    state->shxndx.data[symndx]) > state->shnum) {
1089				(void) fprintf(stderr,
1090				    MSG_INTL(MSG_ERR_BADSYMXINDEX2),
1091				    state->file, state->secname,
1092				    EC_WORD(symndx), EC_WORD(_shxndx));
1093			} else {
1094				shndx = _shxndx;
1095				tshdr = state->cache[shndx].c_shdr;
1096				sec = state->cache[shndx].c_name;
1097			}
1098		} else {
1099			(void) fprintf(stderr,
1100			    MSG_INTL(MSG_ERR_BADSYMXINDEX3),
1101			    state->file, state->secname, EC_WORD(symndx));
1102		}
1103	} else if ((sym->st_shndx < SHN_LORESERVE) &&
1104	    (sym->st_shndx >= state->shnum)) {
1105		(void) fprintf(stderr,
1106		    MSG_INTL(MSG_ERR_BADSYM5), state->file,
1107		    state->secname, EC_WORD(symndx),
1108		    demangle(symname, state->flags), sym->st_shndx);
1109	}
1110
1111	/*
1112	 * If versioning is available display the
1113	 * version index. If not, then use 0.
1114	 */
1115	if (state->versym) {
1116		Versym test_verndx;
1117
1118		verndx = test_verndx = state->versym->data[symndx];
1119		gnuver = state->versym->gnu_full;
1120
1121		/*
1122		 * Check to see if this is a defined symbol with a
1123		 * version index that is outside the valid range for
1124		 * the file. The interpretation of this depends on
1125		 * the style of versioning used by the object.
1126		 *
1127		 * Versions >= VER_NDX_LORESERVE have special meanings,
1128		 * and are exempt from this checking.
1129		 *
1130		 * GNU style version indexes use the top bit of the
1131		 * 16-bit index value (0x8000) as the "hidden bit".
1132		 * We must mask off this bit in order to compare
1133		 * the version against the maximum value.
1134		 */
1135		if (gnuver)
1136			test_verndx &= ~0x8000;
1137
1138		if ((test_verndx > state->versym->max_verndx) &&
1139		    (verndx < VER_NDX_LORESERVE))
1140			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADVER),
1141			    state->file, state->secname, EC_WORD(symndx),
1142			    EC_HALF(test_verndx), state->versym->max_verndx);
1143	} else {
1144		verndx = 0;
1145		gnuver = 0;
1146	}
1147
1148	/*
1149	 * Error checking for TLS.
1150	 */
1151	type = ELF_ST_TYPE(sym->st_info);
1152	if (type == STT_TLS) {
1153		if (tshdr &&
1154		    (sym->st_shndx != SHN_UNDEF) &&
1155		    ((tshdr->sh_flags & SHF_TLS) == 0)) {
1156			(void) fprintf(stderr,
1157			    MSG_INTL(MSG_ERR_BADSYM3), state->file,
1158			    state->secname, EC_WORD(symndx),
1159			    demangle(symname, state->flags));
1160		}
1161	} else if ((type != STT_SECTION) && sym->st_size &&
1162	    tshdr && (tshdr->sh_flags & SHF_TLS)) {
1163		(void) fprintf(stderr,
1164		    MSG_INTL(MSG_ERR_BADSYM4), state->file,
1165		    state->secname, EC_WORD(symndx),
1166		    demangle(symname, state->flags));
1167	}
1168
1169	/*
1170	 * If a symbol with non-zero size has a type that
1171	 * specifies an address, then make sure the location
1172	 * it references is actually contained within the
1173	 * section.  UNDEF symbols don't count in this case,
1174	 * so we ignore them.
1175	 *
1176	 * The meaning of the st_value field in a symbol
1177	 * depends on the type of object. For a relocatable
1178	 * object, it is the offset within the section.
1179	 * For sharable objects, it is the offset relative to
1180	 * the base of the object, and for other types, it is
1181	 * the virtual address. To get an offset within the
1182	 * section for non-ET_REL files, we subtract the
1183	 * base address of the section.
1184	 */
1185	if (addr_symtype[type] && (sym->st_size > 0) &&
1186	    (sym->st_shndx != SHN_UNDEF) && ((sym->st_shndx < SHN_LORESERVE) ||
1187	    (sym->st_shndx == SHN_XINDEX)) && (tshdr != NULL)) {
1188		Word v = sym->st_value;
1189			if (state->ehdr->e_type != ET_REL)
1190				v -= tshdr->sh_addr;
1191		if (((v + sym->st_size) > tshdr->sh_size)) {
1192			(void) fprintf(stderr,
1193			    MSG_INTL(MSG_ERR_BADSYM6), state->file,
1194			    state->secname, EC_WORD(symndx),
1195			    demangle(symname, state->flags),
1196			    EC_WORD(shndx), EC_XWORD(tshdr->sh_size),
1197			    EC_XWORD(sym->st_value), EC_XWORD(sym->st_size));
1198		}
1199	}
1200
1201	/*
1202	 * A typical symbol table uses the sh_info field to indicate one greater
1203	 * than the symbol table index of the last local symbol, STB_LOCAL.
1204	 * Therefore, symbol indexes less than sh_info should have local
1205	 * binding.  Symbol indexes greater than, or equal to sh_info, should
1206	 * have global binding.  Note, we exclude UNDEF/NOTY symbols with zero
1207	 * value and size, as these symbols may be the result of an mcs(1)
1208	 * section deletion.
1209	 */
1210	if (info) {
1211		uchar_t	bind = ELF_ST_BIND(sym->st_info);
1212
1213		if ((symndx < info) && (bind != STB_LOCAL)) {
1214			(void) fprintf(stderr,
1215			    MSG_INTL(MSG_ERR_BADSYM7), state->file,
1216			    state->secname, EC_WORD(symndx),
1217			    demangle(symname, state->flags), EC_XWORD(info));
1218
1219		} else if ((symndx >= info) && (bind == STB_LOCAL) &&
1220		    ((sym->st_shndx != SHN_UNDEF) ||
1221		    (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) ||
1222		    (sym->st_size != 0) || (sym->st_value != 0))) {
1223			(void) fprintf(stderr,
1224			    MSG_INTL(MSG_ERR_BADSYM8), state->file,
1225			    state->secname, EC_WORD(symndx),
1226			    demangle(symname, state->flags), EC_XWORD(info));
1227		}
1228	}
1229
1230	(void) snprintf(index, MAXNDXSIZE,
1231	    MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(disp_symndx));
1232	Elf_syms_table_entry(0, ELF_DBG_ELFDUMP, index, state->osabi,
1233	    state->ehdr->e_machine, sym, verndx, gnuver, sec, symname);
1234}
1235
1236/*
1237 * Process a SHT_SUNW_cap capabilities section.
1238 */
1239static int
1240cap_section(const char *file, Cache *cache, Word shnum, Cache *ccache,
1241    uchar_t osabi, Ehdr *ehdr, uint_t flags)
1242{
1243	SYMTBL_STATE	state;
1244	Word		cnum, capnum, nulls, symcaps;
1245	int		descapndx, objcap, title;
1246	Cap		*cap = (Cap *)ccache->c_data->d_buf;
1247	Shdr		*cishdr, *cshdr = ccache->c_shdr;
1248	Cache		*cicache, *strcache;
1249	Capinfo		*capinfo = NULL;
1250	Word		capinfonum;
1251	const char	*strs = NULL;
1252	size_t		strs_size;
1253
1254	if ((cshdr->sh_entsize == 0) || (cshdr->sh_size == 0)) {
1255		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
1256		    file, ccache->c_name);
1257		return (0);
1258	}
1259
1260	/*
1261	 * If this capabilities section is associated with symbols, then the
1262	 * sh_link field points to the associated capabilities information
1263	 * section.  The sh_link field of the capabilities information section
1264	 * points to the associated symbol table.
1265	 */
1266	if (cshdr->sh_link) {
1267		Cache	*scache;
1268		Shdr	*sshdr;
1269
1270		/*
1271		 * Validate that the sh_link field points to a capabilities
1272		 * information section.
1273		 */
1274		if (cshdr->sh_link >= shnum) {
1275			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1276			    file, ccache->c_name, EC_WORD(cshdr->sh_link));
1277			return (0);
1278		}
1279
1280		cicache = &cache[cshdr->sh_link];
1281		cishdr = cicache->c_shdr;
1282
1283		if (cishdr->sh_type != SHT_SUNW_capinfo) {
1284			(void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAP),
1285			    file, ccache->c_name, EC_WORD(cshdr->sh_link));
1286			return (0);
1287		}
1288
1289		capinfo = cicache->c_data->d_buf;
1290		capinfonum = (Word)(cishdr->sh_size / cishdr->sh_entsize);
1291
1292		/*
1293		 * Validate that the sh_link field of the capabilities
1294		 * information section points to a valid symbol table.
1295		 */
1296		if ((cishdr->sh_link == 0) || (cishdr->sh_link >= shnum)) {
1297			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1298			    file, cicache->c_name, EC_WORD(cishdr->sh_link));
1299			return (0);
1300		}
1301		scache = &cache[cishdr->sh_link];
1302		sshdr = scache->c_shdr;
1303
1304		if ((sshdr->sh_type != SHT_SYMTAB) &&
1305		    (sshdr->sh_type != SHT_DYNSYM)) {
1306			(void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAPINFO1),
1307			    file, cicache->c_name, EC_WORD(cishdr->sh_link));
1308			return (0);
1309		}
1310
1311		if (!init_symtbl_state(&state, cache, shnum,
1312		    cishdr->sh_link, ehdr, osabi, NULL, file, flags))
1313			return (0);
1314	}
1315
1316	/*
1317	 * If this capabilities section contains capability string entries,
1318	 * then determine the associated string table.  Capabilities entries
1319	 * that define names require that the capability section indicate
1320	 * which string table to use via sh_info.
1321	 */
1322	if (cshdr->sh_info) {
1323		Shdr	*strshdr;
1324
1325		/*
1326		 * Validate that the sh_info field points to a string table.
1327		 */
1328		if (cshdr->sh_info >= shnum) {
1329			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1330			    file, ccache->c_name, EC_WORD(cshdr->sh_info));
1331			return (0);
1332		}
1333
1334		strcache = &cache[cshdr->sh_info];
1335		strshdr = strcache->c_shdr;
1336
1337		if (strshdr->sh_type != SHT_STRTAB) {
1338			(void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAP),
1339			    file, ccache->c_name, EC_WORD(cshdr->sh_info));
1340			return (0);
1341		}
1342		strs = (const char *)strcache->c_data->d_buf;
1343		strs_size = strcache->c_data->d_size;
1344	}
1345
1346	dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1347	dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAP), ccache->c_name);
1348
1349	capnum = (Word)(cshdr->sh_size / cshdr->sh_entsize);
1350
1351	nulls = symcaps = 0;
1352	objcap = title = 1;
1353	descapndx = -1;
1354
1355	/*
1356	 * Traverse the capabilities section printing each capability group.
1357	 * The first capabilities group defines any object capabilities.  Any
1358	 * following groups define symbol capabilities.  In the case where no
1359	 * object capabilities exist, but symbol capabilities do, a single
1360	 * CA_SUNW_NULL terminator for the object capabilities exists.
1361	 */
1362	for (cnum = 0; cnum < capnum; cap++, cnum++) {
1363		if (cap->c_tag == CA_SUNW_NULL) {
1364			/*
1365			 * A CA_SUNW_NULL tag terminates a capabilities group.
1366			 * If the first capabilities tag is CA_SUNW_NULL, then
1367			 * no object capabilities exist.
1368			 */
1369			if ((nulls++ == 0) && (cnum == 0))
1370				objcap = 0;
1371			title = 1;
1372		} else {
1373			if (title) {
1374				if (nulls == 0) {
1375					/*
1376					 * If this capabilities group represents
1377					 * the object capabilities (i.e., no
1378					 * CA_SUNW_NULL tag has been processed
1379					 * yet), then display an object
1380					 * capabilities title.
1381					 */
1382					dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1383					dbg_print(0,
1384					    MSG_INTL(MSG_OBJ_CAP_TITLE));
1385				} else {
1386					/*
1387					 * If this is a symbols capabilities
1388					 * group (i.e., a CA_SUNW_NULL tag has
1389					 * already be found that terminates
1390					 * the object capabilities group), then
1391					 * display a symbol capabilities title,
1392					 * and retain this capabilities index
1393					 * for later processing.
1394					 */
1395					dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1396					dbg_print(0,
1397					    MSG_INTL(MSG_SYM_CAP_TITLE));
1398					descapndx = cnum;
1399				}
1400				Elf_cap_title(0);
1401				title = 0;
1402			}
1403
1404			/*
1405			 * Print the capabilities data.
1406			 *
1407			 * Note that CA_SUNW_PLAT, CA_SUNW_MACH and CA_SUNW_ID
1408			 * entries require a string table, which should have
1409			 * already been established.
1410			 */
1411			if ((strs == NULL) && ((cap->c_tag == CA_SUNW_PLAT) ||
1412			    (cap->c_tag == CA_SUNW_MACH) ||
1413			    (cap->c_tag == CA_SUNW_ID))) {
1414				(void) fprintf(stderr,
1415				    MSG_INTL(MSG_WARN_INVCAP4), file,
1416				    EC_WORD(elf_ndxscn(ccache->c_scn)),
1417				    ccache->c_name, EC_WORD(cshdr->sh_info));
1418			}
1419			Elf_cap_entry(0, cap, cnum, strs, strs_size,
1420			    ehdr->e_machine);
1421		}
1422
1423		/*
1424		 * If this CA_SUNW_NULL tag terminates a symbol capabilities
1425		 * group, determine the associated symbols.
1426		 */
1427		if ((cap->c_tag == CA_SUNW_NULL) && (nulls > 1) &&
1428		    (descapndx != -1)) {
1429			Capinfo	*cip;
1430			Word	inum;
1431
1432			symcaps++;
1433
1434			/*
1435			 * Make sure we've discovered a SHT_SUNW_capinfo table.
1436			 */
1437			if ((cip = capinfo) == NULL) {
1438				(void) fprintf(stderr,
1439				    MSG_INTL(MSG_ERR_INVCAP), file,
1440				    ccache->c_name, EC_WORD(cshdr->sh_link));
1441				return (0);
1442			}
1443
1444			/*
1445			 * Determine what symbols reference this capabilities
1446			 * group.
1447			 */
1448			dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1449			dbg_print(0, MSG_INTL(MSG_CAPINFO_ENTRIES));
1450			Elf_syms_table_title(0, ELF_DBG_ELFDUMP);
1451
1452			for (inum = 1, cip++; inum < capinfonum;
1453			    inum++, cip++) {
1454				Word	gndx = (Word)ELF_C_GROUP(*cip);
1455
1456				if (gndx && (gndx == descapndx)) {
1457					output_symbol(&state, inum, 0,
1458					    inum, state.sym + inum);
1459				}
1460			}
1461			descapndx = -1;
1462			continue;
1463		}
1464
1465		/*
1466		 * An SF1_SUNW_ADDR32 software capability tag in a 32-bit
1467		 * object is suspicious as it has no effect.
1468		 */
1469		if ((cap->c_tag == CA_SUNW_SF_1) &&
1470		    (ehdr->e_ident[EI_CLASS] == ELFCLASS32) &&
1471		    (cap->c_un.c_val & SF1_SUNW_ADDR32)) {
1472			(void) fprintf(stderr, MSG_INTL(MSG_WARN_INADDR32SF1),
1473			    file, ccache->c_name);
1474		}
1475	}
1476
1477	/*
1478	 * If this is a dynamic object, with symbol capabilities, then a
1479	 * .SUNW_capchain section should exist.  This section contains a chain
1480	 * of symbol indexes for each capabilities family.  This is the list
1481	 * that is searched by ld.so.1 to determine the best capabilities
1482	 * candidate.
1483	 *
1484	 * Note, more than one capabilities lead symbol can point to the same
1485	 * family chain.  For example, a weak/global pair of symbols can both
1486	 * represent the same family of capabilities symbols.  Therefore, to
1487	 * display all possible families we traverse the capabilities
1488	 * information section looking for CAPINFO_SUNW_GLOB lead symbols.
1489	 * From these we determine the associated capabilities chain to inspect.
1490	 */
1491	if (symcaps &&
1492	    ((ehdr->e_type == ET_EXEC) || (ehdr->e_type == ET_DYN))) {
1493		Capinfo		*cip;
1494		Capchain	*chain;
1495		Cache   	*chcache;
1496		Shdr		*chshdr;
1497		Word		chainnum, inum;
1498
1499		/*
1500		 * Validate that the sh_info field of the capabilities
1501		 * information section points to a capabilities chain section.
1502		 */
1503		if (cishdr->sh_info >= shnum) {
1504			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
1505			    file, cicache->c_name, EC_WORD(cishdr->sh_info));
1506			return (0);
1507		}
1508
1509		chcache = &cache[cishdr->sh_info];
1510		chshdr = chcache->c_shdr;
1511
1512		if (chshdr->sh_type != SHT_SUNW_capchain) {
1513			(void) fprintf(stderr, MSG_INTL(MSG_ERR_INVCAPINFO2),
1514			    file, cicache->c_name, EC_WORD(cishdr->sh_info));
1515			return (0);
1516		}
1517
1518		chainnum = (Word)(chshdr->sh_size / chshdr->sh_entsize);
1519		chain = (Capchain *)chcache->c_data->d_buf;
1520
1521		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1522		dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAPCHAIN), chcache->c_name);
1523
1524		/*
1525		 * Traverse the capabilities information section looking for
1526		 * CAPINFO_SUNW_GLOB lead capabilities symbols.
1527		 */
1528		cip = capinfo;
1529		for (inum = 1, cip++; inum < capinfonum; inum++, cip++) {
1530			const char	*name;
1531			Sym		*sym;
1532			Word		sndx, cndx;
1533			Word		gndx = (Word)ELF_C_GROUP(*cip);
1534
1535			if ((gndx == 0) || (gndx != CAPINFO_SUNW_GLOB))
1536				continue;
1537
1538			/*
1539			 * Determine the symbol that is associated with this
1540			 * capability information entry, and use this to
1541			 * identify this capability family.
1542			 */
1543			sym = (Sym *)(state.sym + inum);
1544			name = string(cicache, inum, strcache, file,
1545			    sym->st_name);
1546
1547			dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1548			dbg_print(0, MSG_INTL(MSG_CAPCHAIN_TITLE), name);
1549			dbg_print(0, MSG_INTL(MSG_CAPCHAIN_ENTRY));
1550
1551			cndx = (Word)ELF_C_SYM(*cip);
1552
1553			/*
1554			 * Traverse this families chain and identify each
1555			 * family member.
1556			 */
1557			for (;;) {
1558				char	_chain[MAXNDXSIZE], _symndx[MAXNDXSIZE];
1559
1560				if (cndx >= chainnum) {
1561					(void) fprintf(stderr,
1562					    MSG_INTL(MSG_ERR_INVCAPINFO3), file,
1563					    cicache->c_name, EC_WORD(inum),
1564					    EC_WORD(cndx));
1565					break;
1566				}
1567				if ((sndx = chain[cndx]) == 0)
1568					break;
1569
1570				/*
1571				 * Determine this entries symbol reference.
1572				 */
1573				if (sndx > state.symn) {
1574					(void) fprintf(stderr,
1575					    MSG_INTL(MSG_ERR_CHBADSYMNDX), file,
1576					    EC_WORD(sndx), chcache->c_name,
1577					    EC_WORD(cndx));
1578					name = MSG_INTL(MSG_STR_UNKNOWN);
1579				} else {
1580					sym = (Sym *)(state.sym + sndx);
1581					name = string(chcache, sndx,
1582					    strcache, file, sym->st_name);
1583				}
1584
1585				/*
1586				 * Display the family member.
1587				 */
1588				(void) snprintf(_chain, MAXNDXSIZE,
1589				    MSG_ORIG(MSG_FMT_INTEGER), cndx);
1590				(void) snprintf(_symndx, MAXNDXSIZE,
1591				    MSG_ORIG(MSG_FMT_INDEX2), EC_WORD(sndx));
1592				dbg_print(0, MSG_ORIG(MSG_FMT_CHAIN_INFO),
1593				    _chain, _symndx, demangle(name, flags));
1594
1595				cndx++;
1596			}
1597		}
1598	}
1599	return (objcap);
1600}
1601
1602/*
1603 * Print the capabilities.
1604 *
1605 * A .SUNW_cap section can contain one or more, CA_SUNW_NULL terminated,
1606 * capabilities groups.  The first group defines the object capabilities.
1607 * This group defines the minimum capability requirements of the entire
1608 * object file.  If this is a dynamic object, this group should be associated
1609 * with a PT_SUNWCAP program header.
1610 *
1611 * Additional capabilities groups define the association of individual symbols
1612 * to specific capabilities.
1613 */
1614static void
1615cap(const char *file, Cache *cache, Word shnum, Word phnum, Ehdr *ehdr,
1616    uchar_t osabi, Elf *elf, uint_t flags)
1617{
1618	Word		cnt;
1619	Shdr		*cshdr = NULL;
1620	Cache		*ccache;
1621	Off		cphdr_off = 0;
1622	Xword		cphdr_sz;
1623
1624	/*
1625	 * Determine if a global capabilities header exists.
1626	 */
1627	if (phnum) {
1628		Phdr	*phdr;
1629
1630		if ((phdr = elf_getphdr(elf)) == NULL) {
1631			failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
1632			return;
1633		}
1634
1635		for (cnt = 0; cnt < phnum; phdr++, cnt++) {
1636			if (phdr->p_type == PT_SUNWCAP) {
1637				cphdr_off = phdr->p_offset;
1638				cphdr_sz = phdr->p_filesz;
1639				break;
1640			}
1641		}
1642	}
1643
1644	/*
1645	 * Determine if a capabilities section exists.
1646	 */
1647	for (cnt = 1; cnt < shnum; cnt++) {
1648		Cache	*_cache = &cache[cnt];
1649		Shdr	*shdr = _cache->c_shdr;
1650
1651		/*
1652		 * Process any capabilities information.
1653		 */
1654		if (shdr->sh_type == SHT_SUNW_cap) {
1655			if (cap_section(file, cache, shnum, _cache, osabi,
1656			    ehdr, flags)) {
1657				/*
1658				 * If this section defined an object capability
1659				 * group, retain the section information for
1660				 * program header validation.
1661				 */
1662				ccache = _cache;
1663				cshdr = shdr;
1664			}
1665			continue;
1666		}
1667	}
1668
1669	if ((cshdr == NULL) && (cphdr_off == 0))
1670		return;
1671
1672	if (cphdr_off && (cshdr == NULL))
1673		(void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP1), file);
1674
1675	/*
1676	 * If this object is an executable or shared object, and it provided
1677	 * an object capabilities group, then the group should have an
1678	 * accompanying PT_SUNWCAP program header.
1679	 */
1680	if (cshdr && ((ehdr->e_type == ET_EXEC) || (ehdr->e_type == ET_DYN))) {
1681		if (cphdr_off == 0) {
1682			(void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP2),
1683			    file, EC_WORD(elf_ndxscn(ccache->c_scn)),
1684			    ccache->c_name);
1685		} else if ((cphdr_off != cshdr->sh_offset) ||
1686		    (cphdr_sz != cshdr->sh_size)) {
1687			(void) fprintf(stderr, MSG_INTL(MSG_WARN_INVCAP3),
1688			    file, EC_WORD(elf_ndxscn(ccache->c_scn)),
1689			    ccache->c_name);
1690		}
1691	}
1692}
1693
1694/*
1695 * Print the interpretor.
1696 */
1697static void
1698interp(const char *file, Cache *cache, Word shnum, Word phnum, Elf *elf)
1699{
1700	static Word phdr_types[] = { PT_INTERP };
1701
1702
1703	Word	cnt;
1704	Shdr	*ishdr = NULL;
1705	Cache	*icache;
1706	Off	iphdr_off = 0;
1707	Xword	iphdr_fsz;
1708
1709	/*
1710	 * Determine if an interp header exists.
1711	 */
1712	if (phnum) {
1713		Phdr	*phdr;
1714
1715		phdr = getphdr(phnum, phdr_types,
1716		    sizeof (phdr_types) / sizeof (*phdr_types), file, elf);
1717		if (phdr != NULL) {
1718			iphdr_off = phdr->p_offset;
1719			iphdr_fsz = phdr->p_filesz;
1720		}
1721	}
1722
1723	if (iphdr_off == 0)
1724		return;
1725
1726	/*
1727	 * Determine if an interp section exists.
1728	 */
1729	for (cnt = 1; cnt < shnum; cnt++) {
1730		Cache	*_cache = &cache[cnt];
1731		Shdr	*shdr = _cache->c_shdr;
1732
1733		/*
1734		 * Scan sections to find a section which contains the PT_INTERP
1735		 * string.  The target section can't be in a NOBITS section.
1736		 */
1737		if ((shdr->sh_type == SHT_NOBITS) ||
1738		    (iphdr_off < shdr->sh_offset) ||
1739		    (iphdr_off + iphdr_fsz) > (shdr->sh_offset + shdr->sh_size))
1740			continue;
1741
1742		icache = _cache;
1743		ishdr = shdr;
1744		break;
1745	}
1746
1747	/*
1748	 * Print the interpreter string based on the offset defined in the
1749	 * program header, as this is the offset used by the kernel.
1750	 */
1751	if (ishdr && icache->c_data) {
1752		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1753		dbg_print(0, MSG_INTL(MSG_ELF_SCN_INTERP), icache->c_name);
1754		dbg_print(0, MSG_ORIG(MSG_FMT_INDENT),
1755		    (char *)icache->c_data->d_buf +
1756		    (iphdr_off - ishdr->sh_offset));
1757	} else
1758		(void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP1), file);
1759
1760	/*
1761	 * If there are any inconsistences between the program header and
1762	 * section information, flag them.
1763	 */
1764	if (ishdr && ((iphdr_off != ishdr->sh_offset) ||
1765	    (iphdr_fsz != ishdr->sh_size))) {
1766		(void) fprintf(stderr, MSG_INTL(MSG_WARN_INVINTERP2), file,
1767		    icache->c_name);
1768	}
1769}
1770
1771/*
1772 * Print the syminfo section.
1773 */
1774static void
1775syminfo(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi, const char *file)
1776{
1777	Shdr		*infoshdr;
1778	Syminfo		*info;
1779	Sym		*syms;
1780	Dyn		*dyns;
1781	Word		infonum, cnt, ndx, symnum, dynnum;
1782	Cache		*infocache = NULL, *dyncache = NULL, *symsec, *strsec;
1783	Boolean		*dynerr;
1784
1785	for (cnt = 1; cnt < shnum; cnt++) {
1786		if (cache[cnt].c_shdr->sh_type == SHT_SUNW_syminfo) {
1787			infocache = &cache[cnt];
1788			break;
1789		}
1790	}
1791	if (infocache == NULL)
1792		return;
1793
1794	infoshdr = infocache->c_shdr;
1795	if ((infoshdr->sh_entsize == 0) || (infoshdr->sh_size == 0)) {
1796		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
1797		    file, infocache->c_name);
1798		return;
1799	}
1800	if (infocache->c_data == NULL)
1801		return;
1802
1803	infonum = (Word)(infoshdr->sh_size / infoshdr->sh_entsize);
1804	info = (Syminfo *)infocache->c_data->d_buf;
1805
1806	/*
1807	 * If there is no associated dynamic section, determine if one
1808	 * is needed, and if so issue a warning. If there is an
1809	 * associated dynamic section, validate it and get the data buffer
1810	 * for it.
1811	 */
1812	dyns = NULL;
1813	dynnum = 0;
1814	if (infoshdr->sh_info == 0) {
1815		Syminfo	*_info = info + 1;
1816
1817		for (ndx = 1; ndx < infonum; ndx++, _info++) {
1818			if ((_info->si_flags == 0) && (_info->si_boundto == 0))
1819				continue;
1820
1821			if (_info->si_boundto < SYMINFO_BT_LOWRESERVE)
1822				(void) fprintf(stderr,
1823				    MSG_INTL(MSG_ERR_BADSHINFO), file,
1824				    infocache->c_name,
1825				    EC_WORD(infoshdr->sh_info));
1826		}
1827	} else if ((infoshdr->sh_info >= shnum) ||
1828	    (cache[infoshdr->sh_info].c_shdr->sh_type != SHT_DYNAMIC)) {
1829		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO),
1830		    file, infocache->c_name, EC_WORD(infoshdr->sh_info));
1831	} else {
1832		dyncache = &cache[infoshdr->sh_info];
1833		if ((dyncache->c_data == NULL) ||
1834		    ((dyns = dyncache->c_data->d_buf) == NULL)) {
1835			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
1836			    file, dyncache->c_name);
1837		}
1838		if (dyns != NULL) {
1839			dynnum = dyncache->c_shdr->sh_size /
1840			    dyncache->c_shdr->sh_entsize;
1841
1842			/*
1843			 * We validate the type of dynamic elements referenced
1844			 * from the syminfo. This array is used report any
1845			 * bad dynamic entries.
1846			 */
1847			if ((dynerr = calloc(dynnum, sizeof (*dynerr))) ==
1848			    NULL) {
1849				int err = errno;
1850				(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
1851				    file, strerror(err));
1852				return;
1853			}
1854		}
1855	}
1856
1857	/*
1858	 * Get the data buffer for the associated symbol table and string table.
1859	 */
1860	if (stringtbl(cache, 1, cnt, shnum, file,
1861	    &symnum, &symsec, &strsec) == 0)
1862		return;
1863
1864	syms = symsec->c_data->d_buf;
1865
1866	/*
1867	 * Loop through the syminfo entries.
1868	 */
1869	dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
1870	dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMINFO), infocache->c_name);
1871	Elf_syminfo_title(0);
1872
1873	for (ndx = 1, info++; ndx < infonum; ndx++, info++) {
1874		Sym 		*sym;
1875		const char	*needed, *name;
1876		Word		expect_dt;
1877		Word		boundto = info->si_boundto;
1878
1879		if ((info->si_flags == 0) && (boundto == 0))
1880			continue;
1881
1882		sym = &syms[ndx];
1883		name = string(infocache, ndx, strsec, file, sym->st_name);
1884
1885		/* Is si_boundto set to one of the reserved values? */
1886		if (boundto >= SYMINFO_BT_LOWRESERVE) {
1887			Elf_syminfo_entry(0, ndx, info, name, NULL);
1888			continue;
1889		}
1890
1891		/*
1892		 * si_boundto is referencing a dynamic section. If we don't
1893		 * have one, an error was already issued above, so it suffices
1894		 * to display an empty string. If we are out of bounds, then
1895		 * report that and then display an empty string.
1896		 */
1897		if ((dyns == NULL) || (boundto >= dynnum)) {
1898			if (dyns != NULL)
1899				(void) fprintf(stderr,
1900				    MSG_INTL(MSG_ERR_BADSIDYNNDX), file,
1901				    infocache->c_ndx, infocache->c_name,
1902				    EC_WORD(ndx), EC_WORD(dynnum - 1),
1903				    EC_WORD(boundto));
1904			Elf_syminfo_entry(0, ndx, info, name,
1905			    MSG_ORIG(MSG_STR_EMPTY));
1906			continue;
1907		}
1908
1909		/*
1910		 * The si_boundto reference expects a specific dynamic element
1911		 * type at the given index. The dynamic element is always a
1912		 * string that gives an object name. The specific type depends
1913		 * on the si_flags present. Ensure that we've got the right
1914		 * type.
1915		 */
1916		if (info->si_flags & SYMINFO_FLG_FILTER)
1917			expect_dt = DT_SUNW_FILTER;
1918		else if (info->si_flags & SYMINFO_FLG_AUXILIARY)
1919			expect_dt = DT_SUNW_AUXILIARY;
1920		else if (info->si_flags & (SYMINFO_FLG_DIRECT |
1921		    SYMINFO_FLG_LAZYLOAD | SYMINFO_FLG_DIRECTBIND))
1922			expect_dt = DT_NEEDED;
1923		else
1924			expect_dt = DT_NULL;   /* means we ignore the type */
1925
1926		if ((dyns[boundto].d_tag != expect_dt) &&
1927		    (expect_dt != DT_NULL)) {
1928			Conv_inv_buf_t	buf1, buf2;
1929
1930			/* Only complain about each dynamic element once */
1931			if (!dynerr[boundto]) {
1932				(void) fprintf(stderr,
1933				    MSG_INTL(MSG_ERR_BADSIDYNTAG),
1934				    file, infocache->c_ndx, infocache->c_name,
1935				    EC_WORD(ndx), dyncache->c_ndx,
1936				    dyncache->c_name, EC_WORD(boundto),
1937				    conv_dyn_tag(expect_dt, osabi,
1938				    ehdr->e_machine, CONV_FMT_ALT_CF, &buf1),
1939				    conv_dyn_tag(dyns[boundto].d_tag, osabi,
1940				    ehdr->e_machine, CONV_FMT_ALT_CF, &buf2));
1941				dynerr[boundto] = TRUE;
1942			}
1943		}
1944
1945		/*
1946		 * Whether or not the DT item we're pointing at is
1947		 * of the right type, if it's a type we recognize as
1948		 * providing a string, go ahead and show it. Otherwise
1949		 * an empty string.
1950		 */
1951		switch (dyns[boundto].d_tag) {
1952		case DT_NEEDED:
1953		case DT_SONAME:
1954		case DT_RPATH:
1955		case DT_RUNPATH:
1956		case DT_CONFIG:
1957		case DT_DEPAUDIT:
1958		case DT_USED:
1959		case DT_AUDIT:
1960		case DT_SUNW_AUXILIARY:
1961		case DT_SUNW_FILTER:
1962		case DT_FILTER:
1963		case DT_AUXILIARY:
1964			needed = string(infocache, boundto,
1965			    strsec, file, dyns[boundto].d_un.d_val);
1966			break;
1967		default:
1968			needed = MSG_ORIG(MSG_STR_EMPTY);
1969		}
1970		Elf_syminfo_entry(0, ndx, info, name, needed);
1971	}
1972	if (dyns != NULL)
1973		free(dynerr);
1974}
1975
1976/*
1977 * Print version definition section entries.
1978 */
1979static void
1980version_def(Verdef *vdf, Word vdf_num, Cache *vcache, Cache *scache,
1981    const char *file)
1982{
1983	Word	cnt;
1984	char	index[MAXNDXSIZE];
1985
1986	Elf_ver_def_title(0);
1987
1988	for (cnt = 1; cnt <= vdf_num; cnt++,
1989	    vdf = (Verdef *)((uintptr_t)vdf + vdf->vd_next)) {
1990		Conv_ver_flags_buf_t	ver_flags_buf;
1991		const char		*name, *dep;
1992		Half			vcnt = vdf->vd_cnt - 1;
1993		Half			ndx = vdf->vd_ndx;
1994		Verdaux	*vdap = (Verdaux *)((uintptr_t)vdf + vdf->vd_aux);
1995
1996		/*
1997		 * Obtain the name and first dependency (if any).
1998		 */
1999		name = string(vcache, cnt, scache, file, vdap->vda_name);
2000		vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
2001		if (vcnt)
2002			dep = string(vcache, cnt, scache, file, vdap->vda_name);
2003		else
2004			dep = MSG_ORIG(MSG_STR_EMPTY);
2005
2006		(void) snprintf(index, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX),
2007		    EC_XWORD(ndx));
2008		Elf_ver_line_1(0, index, name, dep,
2009		    conv_ver_flags(vdf->vd_flags, 0, &ver_flags_buf));
2010
2011		/*
2012		 * Print any additional dependencies.
2013		 */
2014		if (vcnt) {
2015			vdap = (Verdaux *)((uintptr_t)vdap + vdap->vda_next);
2016			for (vcnt--; vcnt; vcnt--,
2017			    vdap = (Verdaux *)((uintptr_t)vdap +
2018			    vdap->vda_next)) {
2019				dep = string(vcache, cnt, scache, file,
2020				    vdap->vda_name);
2021				Elf_ver_line_2(0, MSG_ORIG(MSG_STR_EMPTY), dep);
2022			}
2023		}
2024	}
2025}
2026
2027/*
2028 * Print version needed section entries.
2029 *
2030 * entry:
2031 *	vnd - Address of verneed data
2032 *	vnd_num - # of Verneed entries
2033 *	vcache - Cache of verneed section being processed
2034 *	scache - Cache of associated string table section
2035 *	file - Name of object being processed.
2036 *	versym - Information about versym section
2037 *
2038 * exit:
2039 *	The versions have been printed. If GNU style versioning
2040 *	is in effect, versym->max_verndx has been updated to
2041 *	contain the largest version index seen.
2042 *
2043 * note:
2044 * 	The versym section of an object that follows the original
2045 *	Solaris versioning rules only contains indexes into the verdef
2046 *	section. Symbols defined in other objects (UNDEF) are given
2047 *	a version of 0, indicating that they are not defined by
2048 *	this file, and the Verneed entries do not have associated version
2049 *	indexes. For these reasons, we do not display a version index
2050 *	for original-style Verneed sections.
2051 *
2052 *	The GNU versioning extensions alter this: Symbols defined in other
2053 *	objects receive a version index in the range above those defined
2054 *	by the Verdef section, and the vna_other field of the Vernaux
2055 *	structs inside the Verneed section contain the version index for
2056 *	that item. We therefore  display the index when showing the
2057 *	contents of a GNU style Verneed section. You should not
2058 *	necessarily expect these indexes to appear in sorted
2059 *	order --- it seems that the GNU ld assigns the versions as
2060 *	symbols are encountered during linking, and then the results
2061 *	are assembled into the Verneed section afterwards.
2062 */
2063static void
2064version_need(Verneed *vnd, Word vnd_num, Cache *vcache, Cache *scache,
2065    const char *file, VERSYM_STATE *versym)
2066{
2067	Word		cnt;
2068	char		index[MAXNDXSIZE];
2069	const char	*index_str;
2070
2071	Elf_ver_need_title(0, versym->gnu_needed);
2072
2073	for (cnt = 1; cnt <= vnd_num; cnt++,
2074	    vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
2075		Conv_ver_flags_buf_t	ver_flags_buf;
2076		const char		*name, *dep;
2077		Half			vcnt = vnd->vn_cnt;
2078		Vernaux *vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux);
2079
2080		/*
2081		 * Obtain the name of the needed file and the version name
2082		 * within it that we're dependent on.  Note that the count
2083		 * should be at least one, otherwise this is a pretty bogus
2084		 * entry.
2085		 */
2086		name = string(vcache, cnt, scache, file, vnd->vn_file);
2087		if (vcnt)
2088			dep = string(vcache, cnt, scache, file, vnap->vna_name);
2089		else
2090			dep = MSG_INTL(MSG_STR_NULL);
2091
2092		if (vnap->vna_other == 0) {	/* Traditional form */
2093			index_str = MSG_ORIG(MSG_STR_EMPTY);
2094		} else {			/* GNU form */
2095			index_str = index;
2096			/* Format the version index value */
2097			(void) snprintf(index, MAXNDXSIZE,
2098			    MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(vnap->vna_other));
2099			if (vnap->vna_other > versym->max_verndx)
2100				versym->max_verndx = vnap->vna_other;
2101		}
2102		Elf_ver_line_1(0, index_str, name, dep,
2103		    conv_ver_flags(vnap->vna_flags, 0, &ver_flags_buf));
2104
2105		/*
2106		 * Print any additional version dependencies.
2107		 */
2108		if (vcnt) {
2109			vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next);
2110			for (vcnt--; vcnt; vcnt--,
2111			    vnap = (Vernaux *)((uintptr_t)vnap +
2112			    vnap->vna_next)) {
2113				dep = string(vcache, cnt, scache, file,
2114				    vnap->vna_name);
2115				if (vnap->vna_other > 0) {
2116					/* Format the next index value */
2117					(void) snprintf(index, MAXNDXSIZE,
2118					    MSG_ORIG(MSG_FMT_INDEX),
2119					    EC_XWORD(vnap->vna_other));
2120					Elf_ver_line_1(0, index,
2121					    MSG_ORIG(MSG_STR_EMPTY), dep,
2122					    conv_ver_flags(vnap->vna_flags,
2123					    0, &ver_flags_buf));
2124					if (vnap->vna_other >
2125					    versym->max_verndx)
2126						versym->max_verndx =
2127						    vnap->vna_other;
2128				} else {
2129					Elf_ver_line_3(0,
2130					    MSG_ORIG(MSG_STR_EMPTY), dep,
2131					    conv_ver_flags(vnap->vna_flags,
2132					    0, &ver_flags_buf));
2133				}
2134			}
2135		}
2136	}
2137}
2138
2139/*
2140 * Examine the Verneed section for information related to GNU
2141 * style Versym indexing:
2142 *	- A non-zero vna_other field indicates that Versym indexes can
2143 *		reference Verneed records.
2144 *	- If the object uses GNU style Versym indexing, the
2145 *	  maximum index value is needed to detect bad Versym entries.
2146 *
2147 * entry:
2148 *	vnd - Address of verneed data
2149 *	vnd_num - # of Verneed entries
2150 *	versym - Information about versym section
2151 *
2152 * exit:
2153 *	If a non-zero vna_other field is seen, versym->gnu_needed is set.
2154 *
2155 *	versym->max_verndx has been updated to contain the largest
2156 *	version index seen.
2157 */
2158static void
2159update_gnu_verndx(Verneed *vnd, Word vnd_num, VERSYM_STATE *versym)
2160{
2161	Word		cnt;
2162
2163	for (cnt = 1; cnt <= vnd_num; cnt++,
2164	    vnd = (Verneed *)((uintptr_t)vnd + vnd->vn_next)) {
2165		Half	vcnt = vnd->vn_cnt;
2166		Vernaux	*vnap = (Vernaux *)((uintptr_t)vnd + vnd->vn_aux);
2167
2168		/*
2169		 * A non-zero value of vna_other indicates that this
2170		 * object references VERNEED items from the VERSYM
2171		 * array.
2172		 */
2173		if (vnap->vna_other != 0) {
2174			versym->gnu_needed = 1;
2175			if (vnap->vna_other > versym->max_verndx)
2176				versym->max_verndx = vnap->vna_other;
2177		}
2178
2179		/*
2180		 * Check any additional version dependencies.
2181		 */
2182		if (vcnt) {
2183			vnap = (Vernaux *)((uintptr_t)vnap + vnap->vna_next);
2184			for (vcnt--; vcnt; vcnt--,
2185			    vnap = (Vernaux *)((uintptr_t)vnap +
2186			    vnap->vna_next)) {
2187				if (vnap->vna_other == 0)
2188					continue;
2189
2190				versym->gnu_needed = 1;
2191				if (vnap->vna_other > versym->max_verndx)
2192					versym->max_verndx = vnap->vna_other;
2193			}
2194		}
2195	}
2196}
2197
2198/*
2199 * Display version section information if the flags require it.
2200 * Return version information needed by other output.
2201 *
2202 * entry:
2203 *	cache - Cache of all section headers
2204 *	shnum - # of sections in cache
2205 *	file - Name of file
2206 *	flags - Command line option flags
2207 *	versym - VERSYM_STATE block to be filled in.
2208 */
2209static void
2210versions(Cache *cache, Word shnum, const char *file, uint_t flags,
2211    VERSYM_STATE *versym)
2212{
2213	GElf_Word	cnt;
2214	Cache		*verdef_cache = NULL, *verneed_cache = NULL;
2215
2216
2217	/* Gather information about the version sections */
2218	bzero(versym, sizeof (*versym));
2219	versym->max_verndx = 1;
2220	for (cnt = 1; cnt < shnum; cnt++) {
2221		Cache		*_cache = &cache[cnt];
2222		Shdr		*shdr = _cache->c_shdr;
2223		Dyn		*dyn;
2224		ulong_t		numdyn;
2225
2226		switch (shdr->sh_type) {
2227		case SHT_DYNAMIC:
2228			/*
2229			 * The GNU ld puts a DT_VERSYM entry in the dynamic
2230			 * section so that the runtime linker can use it to
2231			 * implement their versioning rules. They allow multiple
2232			 * incompatible functions with the same name to exist
2233			 * in different versions. The Solaris ld does not
2234			 * support this mechanism, and as such, does not
2235			 * produce DT_VERSYM. We use this fact to determine
2236			 * which ld produced this object, and how to interpret
2237			 * the version values.
2238			 */
2239			if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0) ||
2240			    (_cache->c_data == NULL))
2241				continue;
2242			numdyn = shdr->sh_size / shdr->sh_entsize;
2243			dyn = (Dyn *)_cache->c_data->d_buf;
2244			for (; numdyn-- > 0; dyn++)
2245				if (dyn->d_tag == DT_VERSYM) {
2246					versym->gnu_full =
2247					    versym->gnu_needed = 1;
2248					break;
2249				}
2250			break;
2251
2252		case SHT_SUNW_versym:
2253			/* Record data address for later symbol processing */
2254			if (_cache->c_data != NULL) {
2255				versym->cache = _cache;
2256				versym->data = _cache->c_data->d_buf;
2257				continue;
2258			}
2259			break;
2260
2261		case SHT_SUNW_verdef:
2262		case SHT_SUNW_verneed:
2263			/*
2264			 * Ensure the data is non-NULL and the number
2265			 * of items is non-zero. Otherwise, we don't
2266			 * understand the section, and will not use it.
2267			 */
2268			if ((_cache->c_data == NULL) ||
2269			    (_cache->c_data->d_buf == NULL)) {
2270				(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
2271				    file, _cache->c_name);
2272				continue;
2273			}
2274			if (shdr->sh_info == 0) {
2275				(void) fprintf(stderr,
2276				    MSG_INTL(MSG_ERR_BADSHINFO),
2277				    file, _cache->c_name,
2278				    EC_WORD(shdr->sh_info));
2279				continue;
2280			}
2281
2282			/* Make sure the string table index is in range */
2283			if ((shdr->sh_link == 0) || (shdr->sh_link >= shnum)) {
2284				(void) fprintf(stderr,
2285				    MSG_INTL(MSG_ERR_BADSHLINK), file,
2286				    _cache->c_name, EC_WORD(shdr->sh_link));
2287				continue;
2288			}
2289
2290			/*
2291			 * The section is usable. Save the cache entry.
2292			 */
2293			if (shdr->sh_type == SHT_SUNW_verdef) {
2294				verdef_cache = _cache;
2295				/*
2296				 * Under Solaris rules, if there is a verdef
2297				 * section, the max versym index is number
2298				 * of version definitions it supplies.
2299				 */
2300				versym->max_verndx = shdr->sh_info;
2301			} else {
2302				verneed_cache = _cache;
2303			}
2304			break;
2305		}
2306	}
2307
2308	/*
2309	 * If there is a Verneed section, examine it for information
2310	 * related to GNU style versioning.
2311	 */
2312	if (verneed_cache != NULL)
2313		update_gnu_verndx((Verneed *)verneed_cache->c_data->d_buf,
2314		    verneed_cache->c_shdr->sh_info, versym);
2315
2316	/*
2317	 * Now that all the information is available, display the
2318	 * Verdef and Verneed section contents, if requested.
2319	 */
2320	if ((flags & FLG_SHOW_VERSIONS) == 0)
2321		return;
2322	if (verdef_cache != NULL) {
2323		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2324		dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERDEF),
2325		    verdef_cache->c_name);
2326		version_def((Verdef *)verdef_cache->c_data->d_buf,
2327		    verdef_cache->c_shdr->sh_info, verdef_cache,
2328		    &cache[verdef_cache->c_shdr->sh_link], file);
2329	}
2330	if (verneed_cache != NULL) {
2331		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2332		dbg_print(0, MSG_INTL(MSG_ELF_SCN_VERNEED),
2333		    verneed_cache->c_name);
2334		/*
2335		 * If GNU versioning applies to this object, version_need()
2336		 * will update versym->max_verndx, and it is not
2337		 * necessary to call update_gnu_verndx().
2338		 */
2339		version_need((Verneed *)verneed_cache->c_data->d_buf,
2340		    verneed_cache->c_shdr->sh_info, verneed_cache,
2341		    &cache[verneed_cache->c_shdr->sh_link], file, versym);
2342	}
2343}
2344
2345/*
2346 * Search for and process any symbol tables.
2347 */
2348void
2349symbols(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi,
2350    VERSYM_STATE *versym, const char *file, uint_t flags)
2351{
2352	SYMTBL_STATE state;
2353	Cache *_cache;
2354	Word secndx;
2355
2356	for (secndx = 1; secndx < shnum; secndx++) {
2357		Word		symcnt;
2358		Shdr		*shdr;
2359
2360		_cache = &cache[secndx];
2361		shdr = _cache->c_shdr;
2362
2363		if ((shdr->sh_type != SHT_SYMTAB) &&
2364		    (shdr->sh_type != SHT_DYNSYM) &&
2365		    ((shdr->sh_type != SHT_SUNW_LDYNSYM) ||
2366		    (osabi != ELFOSABI_SOLARIS)))
2367			continue;
2368		if (!match(MATCH_F_ALL, _cache->c_name, secndx, shdr->sh_type))
2369			continue;
2370
2371		if (!init_symtbl_state(&state, cache, shnum, secndx, ehdr,
2372		    osabi, versym, file, flags))
2373			continue;
2374		/*
2375		 * Loop through the symbol tables entries.
2376		 */
2377		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2378		dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMTAB), state.secname);
2379		Elf_syms_table_title(0, ELF_DBG_ELFDUMP);
2380
2381		for (symcnt = 0; symcnt < state.symn; symcnt++)
2382			output_symbol(&state, symcnt, shdr->sh_info, symcnt,
2383			    state.sym + symcnt);
2384	}
2385}
2386
2387/*
2388 * Search for and process any SHT_SUNW_symsort or SHT_SUNW_tlssort sections.
2389 * These sections are always associated with the .SUNW_ldynsym./.dynsym pair.
2390 */
2391static void
2392sunw_sort(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi,
2393    VERSYM_STATE *versym, const char *file, uint_t flags)
2394{
2395	SYMTBL_STATE	ldynsym_state,	dynsym_state;
2396	Cache		*sortcache,	*symcache;
2397	Shdr		*sortshdr,	*symshdr;
2398	Word		sortsecndx,	symsecndx;
2399	Word		ldynsym_cnt;
2400	Word		*ndx;
2401	Word		ndxn;
2402	int		output_cnt = 0;
2403	Conv_inv_buf_t	inv_buf;
2404
2405	for (sortsecndx = 1; sortsecndx < shnum; sortsecndx++) {
2406
2407		sortcache = &cache[sortsecndx];
2408		sortshdr = sortcache->c_shdr;
2409
2410		if ((sortshdr->sh_type != SHT_SUNW_symsort) &&
2411		    (sortshdr->sh_type != SHT_SUNW_tlssort))
2412			continue;
2413		if (!match(MATCH_F_ALL, sortcache->c_name, sortsecndx,
2414		    sortshdr->sh_type))
2415			continue;
2416
2417		/*
2418		 * If the section references a SUNW_ldynsym, then we
2419		 * expect to see the associated .dynsym immediately
2420		 * following. If it references a .dynsym, there is no
2421		 * SUNW_ldynsym. If it is any other type, then we don't
2422		 * know what to do with it.
2423		 */
2424		if ((sortshdr->sh_link == 0) || (sortshdr->sh_link >= shnum)) {
2425			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
2426			    file, sortcache->c_name,
2427			    EC_WORD(sortshdr->sh_link));
2428			continue;
2429		}
2430		symcache = &cache[sortshdr->sh_link];
2431		symshdr = symcache->c_shdr;
2432		symsecndx = sortshdr->sh_link;
2433		ldynsym_cnt = 0;
2434		switch (symshdr->sh_type) {
2435		case SHT_SUNW_LDYNSYM:
2436			if (!init_symtbl_state(&ldynsym_state, cache, shnum,
2437			    symsecndx, ehdr, osabi, versym, file, flags))
2438				continue;
2439			ldynsym_cnt = ldynsym_state.symn;
2440			/*
2441			 * We know that the dynsym follows immediately
2442			 * after the SUNW_ldynsym, and so, should be at
2443			 * (sortshdr->sh_link + 1). However, elfdump is a
2444			 * diagnostic tool, so we do the full paranoid
2445			 * search instead.
2446			 */
2447			for (symsecndx = 1; symsecndx < shnum; symsecndx++) {
2448				symcache = &cache[symsecndx];
2449				symshdr = symcache->c_shdr;
2450				if (symshdr->sh_type == SHT_DYNSYM)
2451					break;
2452			}
2453			if (symsecndx >= shnum) {	/* Dynsym not found! */
2454				(void) fprintf(stderr,
2455				    MSG_INTL(MSG_ERR_NODYNSYM),
2456				    file, sortcache->c_name);
2457				continue;
2458			}
2459			/* Fallthrough to process associated dynsym */
2460			/* FALLTHROUGH */
2461		case SHT_DYNSYM:
2462			if (!init_symtbl_state(&dynsym_state, cache, shnum,
2463			    symsecndx, ehdr, osabi, versym, file, flags))
2464				continue;
2465			break;
2466		default:
2467			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADNDXSEC),
2468			    file, sortcache->c_name,
2469			    conv_sec_type(osabi, ehdr->e_machine,
2470			    symshdr->sh_type, 0, &inv_buf));
2471			continue;
2472		}
2473
2474		/*
2475		 * Output header
2476		 */
2477		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2478		if (ldynsym_cnt > 0) {
2479			dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMSORT2),
2480			    sortcache->c_name, ldynsym_state.secname,
2481			    dynsym_state.secname);
2482			/*
2483			 * The data for .SUNW_ldynsym and dynsym sections
2484			 * is supposed to be adjacent with SUNW_ldynsym coming
2485			 * first. Check, and issue a warning if it isn't so.
2486			 */
2487			if (((ldynsym_state.sym + ldynsym_state.symn)
2488			    != dynsym_state.sym) &&
2489			    ((flags & FLG_CTL_FAKESHDR) == 0))
2490				(void) fprintf(stderr,
2491				    MSG_INTL(MSG_ERR_LDYNNOTADJ), file,
2492				    ldynsym_state.secname,
2493				    dynsym_state.secname);
2494		} else {
2495			dbg_print(0, MSG_INTL(MSG_ELF_SCN_SYMSORT1),
2496			    sortcache->c_name, dynsym_state.secname);
2497		}
2498		Elf_syms_table_title(0, ELF_DBG_ELFDUMP);
2499
2500		/* If not first one, insert a line of white space */
2501		if (output_cnt++ > 0)
2502			dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2503
2504		/*
2505		 * SUNW_dynsymsort and SUNW_dyntlssort are arrays of
2506		 * symbol indices. Iterate over the array entries,
2507		 * dispaying the referenced symbols.
2508		 */
2509		ndxn = sortshdr->sh_size / sortshdr->sh_entsize;
2510		ndx = (Word *)sortcache->c_data->d_buf;
2511		for (; ndxn-- > 0; ndx++) {
2512			if (*ndx >= ldynsym_cnt) {
2513				Word sec_ndx = *ndx - ldynsym_cnt;
2514
2515				output_symbol(&dynsym_state, sec_ndx, 0,
2516				    *ndx, dynsym_state.sym + sec_ndx);
2517			} else {
2518				output_symbol(&ldynsym_state, *ndx, 0,
2519				    *ndx, ldynsym_state.sym + *ndx);
2520			}
2521		}
2522	}
2523}
2524
2525/*
2526 * Search for and process any relocation sections.
2527 */
2528static void
2529reloc(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
2530{
2531	Word	cnt;
2532
2533	for (cnt = 1; cnt < shnum; cnt++) {
2534		Word		type, symnum;
2535		Xword		relndx, relnum, relsize;
2536		void		*rels;
2537		Sym		*syms;
2538		Cache		*symsec, *strsec;
2539		Cache		*_cache = &cache[cnt];
2540		Shdr		*shdr = _cache->c_shdr;
2541		char		*relname = _cache->c_name;
2542		Conv_inv_buf_t	inv_buf;
2543
2544		if (((type = shdr->sh_type) != SHT_RELA) &&
2545		    (type != SHT_REL))
2546			continue;
2547		if (!match(MATCH_F_ALL, relname, cnt, type))
2548			continue;
2549
2550		/*
2551		 * Decide entry size.
2552		 */
2553		if (((relsize = shdr->sh_entsize) == 0) ||
2554		    (relsize > shdr->sh_size)) {
2555			if (type == SHT_RELA)
2556				relsize = sizeof (Rela);
2557			else
2558				relsize = sizeof (Rel);
2559		}
2560
2561		/*
2562		 * Determine the number of relocations available.
2563		 */
2564		if (shdr->sh_size == 0) {
2565			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
2566			    file, relname);
2567			continue;
2568		}
2569		if (_cache->c_data == NULL)
2570			continue;
2571
2572		rels = _cache->c_data->d_buf;
2573		relnum = shdr->sh_size / relsize;
2574
2575		/*
2576		 * Get the data buffer for the associated symbol table and
2577		 * string table.
2578		 */
2579		if (stringtbl(cache, 1, cnt, shnum, file,
2580		    &symnum, &symsec, &strsec) == 0)
2581			continue;
2582
2583		syms = symsec->c_data->d_buf;
2584
2585		/*
2586		 * Loop through the relocation entries.
2587		 */
2588		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
2589		dbg_print(0, MSG_INTL(MSG_ELF_SCN_RELOC), _cache->c_name);
2590		Elf_reloc_title(0, ELF_DBG_ELFDUMP, type);
2591
2592		for (relndx = 0; relndx < relnum; relndx++,
2593		    rels = (void *)((char *)rels + relsize)) {
2594			Half		mach = ehdr->e_machine;
2595			char		section[BUFSIZ];
2596			const char	*symname;
2597			Word		symndx, reltype;
2598			Rela		*rela;
2599			Rel		*rel;
2600
2601			/*
2602			 * Unravel the relocation and determine the symbol with
2603			 * which this relocation is associated.
2604			 */
2605			if (type == SHT_RELA) {
2606				rela = (Rela *)rels;
2607				symndx = ELF_R_SYM(rela->r_info);
2608				reltype = ELF_R_TYPE(rela->r_info, mach);
2609			} else {
2610				rel = (Rel *)rels;
2611				symndx = ELF_R_SYM(rel->r_info);
2612				reltype = ELF_R_TYPE(rel->r_info, mach);
2613			}
2614
2615			symname = relsymname(cache, _cache, strsec, symndx,
2616			    symnum, relndx, syms, section, BUFSIZ, file);
2617
2618			/*
2619			 * A zero symbol index is only valid for a few
2620			 * relocations.
2621			 */
2622			if (symndx == 0) {
2623				int	badrel = 0;
2624
2625				if ((mach == EM_SPARC) ||
2626				    (mach == EM_SPARC32PLUS) ||
2627				    (mach == EM_SPARCV9)) {
2628					if ((reltype != R_SPARC_NONE) &&
2629					    (reltype != R_SPARC_REGISTER) &&
2630					    (reltype != R_SPARC_RELATIVE))
2631						badrel++;
2632				} else if (mach == EM_386) {
2633					if ((reltype != R_386_NONE) &&
2634					    (reltype != R_386_RELATIVE))
2635						badrel++;
2636				} else if (mach == EM_AMD64) {
2637					if ((reltype != R_AMD64_NONE) &&
2638					    (reltype != R_AMD64_RELATIVE))
2639						badrel++;
2640				}
2641
2642				if (badrel) {
2643					(void) fprintf(stderr,
2644					    MSG_INTL(MSG_ERR_BADREL1), file,
2645					    conv_reloc_type(mach, reltype,
2646					    0, &inv_buf));
2647				}
2648			}
2649
2650			Elf_reloc_entry_1(0, ELF_DBG_ELFDUMP,
2651			    MSG_ORIG(MSG_STR_EMPTY), ehdr->e_machine, type,
2652			    rels, relname, symname, 0);
2653		}
2654	}
2655}
2656
2657
2658/*
2659 * This value controls which test dyn_test() performs.
2660 */
2661typedef enum { DYN_TEST_ADDR, DYN_TEST_SIZE, DYN_TEST_ENTSIZE } dyn_test_t;
2662
2663/*
2664 * Used by dynamic() to compare the value of a dynamic element against
2665 * the starting address of the section it references.
2666 *
2667 * entry:
2668 *	test_type - Specify which dyn item is being tested.
2669 *	sh_type - SHT_* type value for required section.
2670 *	sec_cache - Cache entry for section, or NULL if the object lacks
2671 *		a section of this type.
2672 *	dyn - Dyn entry to be tested
2673 *	dynsec_cnt - # of dynamic section being examined. The first
2674 *		dynamic section is 1, the next is 2, and so on...
2675 *	ehdr - ELF header for file
2676 *	file - Name of file
2677 */
2678static void
2679dyn_test(dyn_test_t test_type, Word sh_type, Cache *sec_cache, Dyn *dyn,
2680    Word dynsec_cnt, Ehdr *ehdr, uchar_t osabi, const char *file)
2681{
2682	Conv_inv_buf_t	buf1, buf2;
2683
2684	/*
2685	 * These tests are based around the implicit assumption that
2686	 * there is only one dynamic section in an object, and also only
2687	 * one of the sections it references. We have therefore gathered
2688	 * all of the necessary information to test this in a single pass
2689	 * over the section headers, which is very efficient. We are not
2690	 * aware of any case where more than one dynamic section would
2691	 * be meaningful in an ELF object, so this is a reasonable solution.
2692	 *
2693	 * To test multiple dynamic sections correctly would be more
2694	 * expensive in code and time. We would have to build a data structure
2695	 * containing all the dynamic elements. Then, we would use the address
2696	 * to locate the section it references and ensure the section is of
2697	 * the right type and that the address in the dynamic element is
2698	 * to the start of the section. Then, we could check the size and
2699	 * entsize values against those same sections. This is O(n^2), and
2700	 * also complicated.
2701	 *
2702	 * In the highly unlikely case that there is more than one dynamic
2703	 * section, we only test the first one, and simply allow the values
2704	 * of the subsequent one to be displayed unchallenged.
2705	 */
2706	if (dynsec_cnt != 1)
2707		return;
2708
2709	/*
2710	 * A DT_ item that references a section address should always find
2711	 * the section in the file.
2712	 */
2713	if (sec_cache == NULL) {
2714		const char *name;
2715
2716		/*
2717		 * Supply section names instead of section types for
2718		 * things that reference progbits so that the error
2719		 * message will make more sense.
2720		 */
2721		switch (dyn->d_tag) {
2722		case DT_INIT:
2723			name = MSG_ORIG(MSG_ELF_INIT);
2724			break;
2725		case DT_FINI:
2726			name = MSG_ORIG(MSG_ELF_FINI);
2727			break;
2728		default:
2729			name = conv_sec_type(osabi, ehdr->e_machine,
2730			    sh_type, 0, &buf1);
2731			break;
2732		}
2733		(void) fprintf(stderr, MSG_INTL(MSG_ERR_DYNNOBCKSEC), file,
2734		    name, conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2735		    CONV_FMT_ALT_CF, &buf2));
2736		return;
2737	}
2738
2739
2740	switch (test_type) {
2741	case DYN_TEST_ADDR:
2742		/* The section address should match the DT_ item value */
2743		if (dyn->d_un.d_val != sec_cache->c_shdr->sh_addr)
2744			(void) fprintf(stderr,
2745			    MSG_INTL(MSG_ERR_DYNBADADDR), file,
2746			    conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2747			    CONV_FMT_ALT_CF, &buf1), EC_ADDR(dyn->d_un.d_val),
2748			    sec_cache->c_ndx, sec_cache->c_name,
2749			    EC_ADDR(sec_cache->c_shdr->sh_addr));
2750		break;
2751
2752	case DYN_TEST_SIZE:
2753		/* The section size should match the DT_ item value */
2754		if (dyn->d_un.d_val != sec_cache->c_shdr->sh_size)
2755			(void) fprintf(stderr,
2756			    MSG_INTL(MSG_ERR_DYNBADSIZE), file,
2757			    conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2758			    CONV_FMT_ALT_CF, &buf1), EC_XWORD(dyn->d_un.d_val),
2759			    sec_cache->c_ndx, sec_cache->c_name,
2760			    EC_XWORD(sec_cache->c_shdr->sh_size));
2761		break;
2762
2763	case DYN_TEST_ENTSIZE:
2764		/* The sh_entsize value should match the DT_ item value */
2765		if (dyn->d_un.d_val != sec_cache->c_shdr->sh_entsize)
2766			(void) fprintf(stderr,
2767			    MSG_INTL(MSG_ERR_DYNBADENTSIZE), file,
2768			    conv_dyn_tag(dyn->d_tag, osabi, ehdr->e_machine,
2769			    CONV_FMT_ALT_CF, &buf1), EC_XWORD(dyn->d_un.d_val),
2770			    sec_cache->c_ndx, sec_cache->c_name,
2771			    EC_XWORD(sec_cache->c_shdr->sh_entsize));
2772		break;
2773	}
2774}
2775
2776/*
2777 * There are some DT_ entries that have corresponding symbols
2778 * (e.g. DT_INIT and _init). It is expected that these items will
2779 * both have the same value if both are present. This routine
2780 * examines the well known symbol tables for such symbols and
2781 * issues warnings for any that don't match.
2782 *
2783 * entry:
2784 *	dyn - Dyn entry to be tested
2785 *	symname - Name of symbol that corresponds to dyn
2786 *	symtab_cache, dynsym_cache, ldynsym_cache - Symbol tables to check
2787 *	target_cache - Section the symname section is expected to be
2788 *		associated with.
2789 *	cache - Cache of all section headers
2790 *	shnum - # of sections in cache
2791 *	ehdr - ELF header for file
2792 *	osabi - OSABI to apply when interpreting object
2793 *	file - Name of file
2794 */
2795static void
2796dyn_symtest(Dyn *dyn, const char *symname, Cache *symtab_cache,
2797    Cache *dynsym_cache, Cache *ldynsym_cache, Cache *target_cache,
2798    Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi, const char *file)
2799{
2800	Conv_inv_buf_t	buf;
2801	int		i;
2802	Sym		*sym;
2803	Cache		*_cache;
2804
2805	for (i = 0; i < 3; i++) {
2806		switch (i) {
2807		case 0:
2808			_cache = symtab_cache;
2809			break;
2810		case 1:
2811			_cache = dynsym_cache;
2812			break;
2813		case 2:
2814			_cache = ldynsym_cache;
2815			break;
2816		}
2817
2818		if ((_cache != NULL) &&
2819		    symlookup(symname, cache, shnum, &sym, target_cache,
2820		    _cache, file) && (sym->st_value != dyn->d_un.d_val))
2821			(void) fprintf(stderr, MSG_INTL(MSG_ERR_DYNSYMVAL),
2822			    file, _cache->c_name, conv_dyn_tag(dyn->d_tag,
2823			    osabi, ehdr->e_machine, CONV_FMT_ALT_CF, &buf),
2824			    symname, EC_ADDR(sym->st_value));
2825	}
2826}
2827
2828/*
2829 * Search for and process a .dynamic section.
2830 */
2831static void
2832dynamic(Cache *cache, Word shnum, Ehdr *ehdr, uchar_t osabi, const char *file)
2833{
2834	struct {
2835		Cache	*symtab;
2836		Cache	*dynstr;
2837		Cache	*dynsym;
2838		Cache	*hash;
2839		Cache	*fini;
2840		Cache	*fini_array;
2841		Cache	*init;
2842		Cache	*init_array;
2843		Cache	*preinit_array;
2844		Cache	*rel;
2845		Cache	*rela;
2846		Cache	*sunw_cap;
2847		Cache	*sunw_capinfo;
2848		Cache	*sunw_capchain;
2849		Cache	*sunw_ldynsym;
2850		Cache	*sunw_move;
2851		Cache	*sunw_syminfo;
2852		Cache	*sunw_symsort;
2853		Cache	*sunw_tlssort;
2854		Cache	*sunw_verdef;
2855		Cache	*sunw_verneed;
2856		Cache	*sunw_versym;
2857	} sec;
2858	Word	dynsec_ndx;
2859	Word	dynsec_num;
2860	int	dynsec_cnt;
2861	Word	cnt;
2862	int	osabi_solaris = osabi == ELFOSABI_SOLARIS;
2863
2864	/*
2865	 * Make a pass over all the sections, gathering section information
2866	 * we'll need below.
2867	 */
2868	dynsec_num = 0;
2869	bzero(&sec, sizeof (sec));
2870	for (cnt = 1; cnt < shnum; cnt++) {
2871		Cache	*_cache = &cache[cnt];
2872
2873		switch (_cache->c_shdr->sh_type) {
2874		case SHT_DYNAMIC:
2875			if (dynsec_num == 0) {
2876				dynsec_ndx = cnt;
2877
2878				/* Does it have a valid string table? */
2879				(void) stringtbl(cache, 0, cnt, shnum, file,
2880				    0, 0, &sec.dynstr);
2881			}
2882			dynsec_num++;
2883			break;
2884
2885
2886		case SHT_PROGBITS:
2887			/*
2888			 * We want to detect the .init and .fini sections,
2889			 * if present. These are SHT_PROGBITS, so all we
2890			 * have to go on is the section name. Normally comparing
2891			 * names is a bad idea, but there are some special
2892			 * names (i.e. .init/.fini/.interp) that are very
2893			 * difficult to use in any other context, and for
2894			 * these symbols, we do the heuristic match.
2895			 */
2896			if (strcmp(_cache->c_name,
2897			    MSG_ORIG(MSG_ELF_INIT)) == 0) {
2898				if (sec.init == NULL)
2899					sec.init = _cache;
2900			} else if (strcmp(_cache->c_name,
2901			    MSG_ORIG(MSG_ELF_FINI)) == 0) {
2902				if (sec.fini == NULL)
2903					sec.fini = _cache;
2904			}
2905			break;
2906
2907		case SHT_REL:
2908			/*
2909			 * We want the SHT_REL section with the lowest
2910			 * offset. The linker gathers them together,
2911			 * and puts the address of the first one
2912			 * into the DT_REL dynamic element.
2913			 */
2914			if ((sec.rel == NULL) ||
2915			    (_cache->c_shdr->sh_offset <
2916			    sec.rel->c_shdr->sh_offset))
2917				sec.rel = _cache;
2918			break;
2919
2920		case SHT_RELA:
2921			/* RELA is handled just like RELA above */
2922			if ((sec.rela == NULL) ||
2923			    (_cache->c_shdr->sh_offset <
2924			    sec.rela->c_shdr->sh_offset))
2925				sec.rela = _cache;
2926			break;
2927
2928		/*
2929		 * The GRAB macro is used for the simple case in which
2930		 * we simply grab the first section of the desired type.
2931		 */
2932#define	GRAB(_sec_type, _sec_field) \
2933		case _sec_type: \
2934			if (sec._sec_field == NULL) \
2935				sec._sec_field = _cache; \
2936				break
2937		GRAB(SHT_SYMTAB,	symtab);
2938		GRAB(SHT_DYNSYM,	dynsym);
2939		GRAB(SHT_FINI_ARRAY,	fini_array);
2940		GRAB(SHT_HASH,		hash);
2941		GRAB(SHT_INIT_ARRAY,	init_array);
2942		GRAB(SHT_SUNW_move,	sunw_move);
2943		GRAB(SHT_PREINIT_ARRAY,	preinit_array);
2944		GRAB(SHT_SUNW_cap,	sunw_cap);
2945		GRAB(SHT_SUNW_capinfo,	sunw_capinfo);
2946		GRAB(SHT_SUNW_capchain,	sunw_capchain);
2947		GRAB(SHT_SUNW_LDYNSYM,	sunw_ldynsym);
2948		GRAB(SHT_SUNW_syminfo,	sunw_syminfo);
2949		GRAB(SHT_SUNW_symsort,	sunw_symsort);
2950		GRAB(SHT_SUNW_tlssort,	sunw_tlssort);
2951		GRAB(SHT_SUNW_verdef,	sunw_verdef);
2952		GRAB(SHT_SUNW_verneed,	sunw_verneed);
2953		GRAB(SHT_SUNW_versym,	sunw_versym);
2954#undef GRAB
2955		}
2956	}
2957
2958	/*
2959	 * If no dynamic section, return immediately. If more than one
2960	 * dynamic section, then something odd is going on and an error
2961	 * is in order, but then continue on and display them all.
2962	 */
2963	if (dynsec_num == 0)
2964		return;
2965	if (dynsec_num > 1)
2966		(void) fprintf(stderr, MSG_INTL(MSG_ERR_MULTDYN),
2967		    file, EC_WORD(dynsec_num));
2968
2969
2970	dynsec_cnt = 0;
2971	for (cnt = dynsec_ndx; (cnt < shnum) && (dynsec_cnt < dynsec_num);
2972	    cnt++) {
2973		Dyn	*dyn;
2974		ulong_t	numdyn;
2975		int	ndx, end_ndx;
2976		Cache	*_cache = &cache[cnt], *strsec;
2977		Shdr	*shdr = _cache->c_shdr;
2978		int	dumped = 0;
2979
2980		if (shdr->sh_type != SHT_DYNAMIC)
2981			continue;
2982		dynsec_cnt++;
2983
2984		/*
2985		 * Verify the associated string table section.
2986		 */
2987		if (stringtbl(cache, 0, cnt, shnum, file, 0, 0, &strsec) == 0)
2988			continue;
2989
2990		if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
2991			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
2992			    file, _cache->c_name);
2993			continue;
2994		}
2995		if (_cache->c_data == NULL)
2996			continue;
2997
2998		numdyn = shdr->sh_size / shdr->sh_entsize;
2999		dyn = (Dyn *)_cache->c_data->d_buf;
3000
3001		/*
3002		 * We expect the REL/RELA entries to reference the reloc
3003		 * section with the lowest address. However, this is
3004		 * not true for dumped objects. Detect if this object has
3005		 * been dumped so that we can skip the reloc address test
3006		 * in that case.
3007		 */
3008		for (ndx = 0; ndx < numdyn; dyn++, ndx++) {
3009			if (dyn->d_tag == DT_FLAGS_1) {
3010				dumped = (dyn->d_un.d_val & DF_1_CONFALT) != 0;
3011				break;
3012			}
3013		}
3014		dyn = (Dyn *)_cache->c_data->d_buf;
3015
3016		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3017		dbg_print(0, MSG_INTL(MSG_ELF_SCN_DYNAMIC), _cache->c_name);
3018
3019		Elf_dyn_title(0);
3020
3021		for (ndx = 0; ndx < numdyn; dyn++, ndx++) {
3022			union {
3023				Conv_inv_buf_t		inv;
3024				Conv_dyn_flag_buf_t	flag;
3025				Conv_dyn_flag1_buf_t	flag1;
3026				Conv_dyn_posflag1_buf_t	posflag1;
3027				Conv_dyn_feature1_buf_t	feature1;
3028			} c_buf;
3029			const char	*name = NULL;
3030
3031			/*
3032			 * Print the information numerically, and if possible
3033			 * as a string. If a string is available, name is
3034			 * set to reference it.
3035			 *
3036			 * Also, take this opportunity to sanity check
3037			 * the values of DT elements. In the code above,
3038			 * we gathered information on sections that are
3039			 * referenced by the dynamic section. Here, we
3040			 * compare the attributes of those sections to
3041			 * the DT_ items that reference them and report
3042			 * on inconsistencies.
3043			 *
3044			 * Things not currently tested that could be improved
3045			 * in later revisions include:
3046			 *	- We don't check PLT or GOT related items
3047			 *	- We don't handle computing the lengths of
3048			 *		relocation arrays. To handle this
3049			 *		requires examining data that spans
3050			 *		across sections, in a contiguous span
3051			 *		within a single segment.
3052			 *	- DT_VERDEFNUM and DT_VERNEEDNUM can't be
3053			 *		verified without parsing the sections.
3054			 *	- We don't handle DT_SUNW_SYMSZ, which would
3055			 *		be the sum of the lengths of .dynsym and
3056			 *		.SUNW_ldynsym
3057			 *	- DT_SUNW_STRPAD can't be verified other than
3058			 *		to check that it's not larger than
3059			 *		the string table.
3060			 *	- Some items come in "all or none" clusters
3061			 *		that give an address, element size,
3062			 *		and data length in bytes. We don't
3063			 *		verify that there are no missing items
3064			 *		in such groups.
3065			 */
3066			switch (dyn->d_tag) {
3067			case DT_NULL:
3068				/*
3069				 * Special case: DT_NULLs can come in groups
3070				 * that we prefer to reduce to a single line.
3071				 */
3072				end_ndx = ndx;
3073				while ((end_ndx < (numdyn - 1)) &&
3074				    ((dyn + 1)->d_tag == DT_NULL)) {
3075					dyn++;
3076					end_ndx++;
3077				}
3078				Elf_dyn_null_entry(0, dyn, ndx, end_ndx);
3079				ndx = end_ndx;
3080				continue;
3081
3082			/*
3083			 * String items all reference the dynstr. The string()
3084			 * function does the necessary sanity checking.
3085			 */
3086			case DT_NEEDED:
3087			case DT_SONAME:
3088			case DT_FILTER:
3089			case DT_AUXILIARY:
3090			case DT_CONFIG:
3091			case DT_RPATH:
3092			case DT_RUNPATH:
3093			case DT_USED:
3094			case DT_DEPAUDIT:
3095			case DT_AUDIT:
3096				name = string(_cache, ndx, strsec,
3097				    file, dyn->d_un.d_ptr);
3098				break;
3099
3100			case DT_SUNW_AUXILIARY:
3101			case DT_SUNW_FILTER:
3102				if (osabi_solaris)
3103					name = string(_cache, ndx, strsec,
3104					    file, dyn->d_un.d_ptr);
3105				break;
3106
3107			case DT_FLAGS:
3108				name = conv_dyn_flag(dyn->d_un.d_val,
3109				    0, &c_buf.flag);
3110				break;
3111			case DT_FLAGS_1:
3112				name = conv_dyn_flag1(dyn->d_un.d_val, 0,
3113				    &c_buf.flag1);
3114				break;
3115			case DT_POSFLAG_1:
3116				name = conv_dyn_posflag1(dyn->d_un.d_val, 0,
3117				    &c_buf.posflag1);
3118				break;
3119			case DT_FEATURE_1:
3120				name = conv_dyn_feature1(dyn->d_un.d_val, 0,
3121				    &c_buf.feature1);
3122				break;
3123			case DT_DEPRECATED_SPARC_REGISTER:
3124				name = MSG_INTL(MSG_STR_DEPRECATED);
3125				break;
3126
3127			case DT_SUNW_LDMACH:
3128				if (!osabi_solaris)
3129					break;
3130				name = conv_ehdr_mach((Half)dyn->d_un.d_val,
3131				    0, &c_buf.inv);
3132				break;
3133
3134			/*
3135			 * Cases below this point are strictly sanity checking,
3136			 * and do not generate a name string. The TEST_ macros
3137			 * are used to hide the boiler plate arguments neeeded
3138			 * by dyn_test().
3139			 */
3140#define	TEST_ADDR(_sh_type, _sec_field) \
3141				dyn_test(DYN_TEST_ADDR, _sh_type, \
3142				    sec._sec_field, dyn, dynsec_cnt, ehdr, \
3143				    osabi, file)
3144#define	TEST_SIZE(_sh_type, _sec_field) \
3145				dyn_test(DYN_TEST_SIZE, _sh_type, \
3146				    sec._sec_field, dyn, dynsec_cnt, ehdr, \
3147				    osabi, file)
3148#define	TEST_ENTSIZE(_sh_type, _sec_field) \
3149				dyn_test(DYN_TEST_ENTSIZE, _sh_type, \
3150				    sec._sec_field, dyn, dynsec_cnt, ehdr, \
3151				    osabi, file)
3152
3153			case DT_FINI:
3154				dyn_symtest(dyn, MSG_ORIG(MSG_SYM_FINI),
3155				    sec.symtab, sec.dynsym, sec.sunw_ldynsym,
3156				    sec.fini, cache, shnum, ehdr, osabi, file);
3157				TEST_ADDR(SHT_PROGBITS, fini);
3158				break;
3159
3160			case DT_FINI_ARRAY:
3161				TEST_ADDR(SHT_FINI_ARRAY, fini_array);
3162				break;
3163
3164			case DT_FINI_ARRAYSZ:
3165				TEST_SIZE(SHT_FINI_ARRAY, fini_array);
3166				break;
3167
3168			case DT_HASH:
3169				TEST_ADDR(SHT_HASH, hash);
3170				break;
3171
3172			case DT_INIT:
3173				dyn_symtest(dyn, MSG_ORIG(MSG_SYM_INIT),
3174				    sec.symtab, sec.dynsym, sec.sunw_ldynsym,
3175				    sec.init, cache, shnum, ehdr, osabi, file);
3176				TEST_ADDR(SHT_PROGBITS, init);
3177				break;
3178
3179			case DT_INIT_ARRAY:
3180				TEST_ADDR(SHT_INIT_ARRAY, init_array);
3181				break;
3182
3183			case DT_INIT_ARRAYSZ:
3184				TEST_SIZE(SHT_INIT_ARRAY, init_array);
3185				break;
3186
3187			case DT_MOVEENT:
3188				TEST_ENTSIZE(SHT_SUNW_move, sunw_move);
3189				break;
3190
3191			case DT_MOVESZ:
3192				TEST_SIZE(SHT_SUNW_move, sunw_move);
3193				break;
3194
3195			case DT_MOVETAB:
3196				TEST_ADDR(SHT_SUNW_move, sunw_move);
3197				break;
3198
3199			case DT_PREINIT_ARRAY:
3200				TEST_ADDR(SHT_PREINIT_ARRAY, preinit_array);
3201				break;
3202
3203			case DT_PREINIT_ARRAYSZ:
3204				TEST_SIZE(SHT_PREINIT_ARRAY, preinit_array);
3205				break;
3206
3207			case DT_REL:
3208				if (!dumped)
3209					TEST_ADDR(SHT_REL, rel);
3210				break;
3211
3212			case DT_RELENT:
3213				TEST_ENTSIZE(SHT_REL, rel);
3214				break;
3215
3216			case DT_RELA:
3217				if (!dumped)
3218					TEST_ADDR(SHT_RELA, rela);
3219				break;
3220
3221			case DT_RELAENT:
3222				TEST_ENTSIZE(SHT_RELA, rela);
3223				break;
3224
3225			case DT_STRTAB:
3226				TEST_ADDR(SHT_STRTAB, dynstr);
3227				break;
3228
3229			case DT_STRSZ:
3230				TEST_SIZE(SHT_STRTAB, dynstr);
3231				break;
3232
3233			case DT_SUNW_CAP:
3234				if (osabi_solaris)
3235					TEST_ADDR(SHT_SUNW_cap, sunw_cap);
3236				break;
3237
3238			case DT_SUNW_CAPINFO:
3239				if (osabi_solaris)
3240					TEST_ADDR(SHT_SUNW_capinfo,
3241					    sunw_capinfo);
3242				break;
3243
3244			case DT_SUNW_CAPCHAIN:
3245				if (osabi_solaris)
3246					TEST_ADDR(SHT_SUNW_capchain,
3247					    sunw_capchain);
3248				break;
3249
3250			case DT_SUNW_SYMTAB:
3251				TEST_ADDR(SHT_SUNW_LDYNSYM, sunw_ldynsym);
3252				break;
3253
3254			case DT_SYMENT:
3255				TEST_ENTSIZE(SHT_DYNSYM, dynsym);
3256				break;
3257
3258			case DT_SYMINENT:
3259				TEST_ENTSIZE(SHT_SUNW_syminfo, sunw_syminfo);
3260				break;
3261
3262			case DT_SYMINFO:
3263				TEST_ADDR(SHT_SUNW_syminfo, sunw_syminfo);
3264				break;
3265
3266			case DT_SYMINSZ:
3267				TEST_SIZE(SHT_SUNW_syminfo, sunw_syminfo);
3268				break;
3269
3270			case DT_SYMTAB:
3271				TEST_ADDR(SHT_DYNSYM, dynsym);
3272				break;
3273
3274			case DT_SUNW_SORTENT:
3275				/*
3276				 * This entry is related to both the symsort and
3277				 * tlssort sections.
3278				 */
3279				if (osabi_solaris) {
3280					int test_tls =
3281					    (sec.sunw_tlssort != NULL);
3282					int test_sym =
3283					    (sec.sunw_symsort != NULL) ||
3284					    !test_tls;
3285					if (test_sym)
3286						TEST_ENTSIZE(SHT_SUNW_symsort,
3287						    sunw_symsort);
3288					if (test_tls)
3289						TEST_ENTSIZE(SHT_SUNW_tlssort,
3290						    sunw_tlssort);
3291				}
3292				break;
3293
3294
3295			case DT_SUNW_SYMSORT:
3296				if (osabi_solaris)
3297					TEST_ADDR(SHT_SUNW_symsort,
3298					    sunw_symsort);
3299				break;
3300
3301			case DT_SUNW_SYMSORTSZ:
3302				if (osabi_solaris)
3303					TEST_SIZE(SHT_SUNW_symsort,
3304					    sunw_symsort);
3305				break;
3306
3307			case DT_SUNW_TLSSORT:
3308				if (osabi_solaris)
3309					TEST_ADDR(SHT_SUNW_tlssort,
3310					    sunw_tlssort);
3311				break;
3312
3313			case DT_SUNW_TLSSORTSZ:
3314				if (osabi_solaris)
3315					TEST_SIZE(SHT_SUNW_tlssort,
3316					    sunw_tlssort);
3317				break;
3318
3319			case DT_VERDEF:
3320				TEST_ADDR(SHT_SUNW_verdef, sunw_verdef);
3321				break;
3322
3323			case DT_VERNEED:
3324				TEST_ADDR(SHT_SUNW_verneed, sunw_verneed);
3325				break;
3326
3327			case DT_VERSYM:
3328				TEST_ADDR(SHT_SUNW_versym, sunw_versym);
3329				break;
3330#undef TEST_ADDR
3331#undef TEST_SIZE
3332#undef TEST_ENTSIZE
3333			}
3334
3335			if (name == NULL)
3336				name = MSG_ORIG(MSG_STR_EMPTY);
3337			Elf_dyn_entry(0, dyn, ndx, name,
3338			    osabi, ehdr->e_machine);
3339		}
3340	}
3341}
3342
3343/*
3344 * Search for and process a MOVE section.
3345 */
3346static void
3347move(Cache *cache, Word shnum, const char *file, uint_t flags)
3348{
3349	Word		cnt;
3350	const char	*fmt = NULL;
3351
3352	for (cnt = 1; cnt < shnum; cnt++) {
3353		Word	movenum, symnum, ndx;
3354		Sym	*syms;
3355		Cache	*_cache = &cache[cnt];
3356		Shdr	*shdr = _cache->c_shdr;
3357		Cache	*symsec, *strsec;
3358		Move	*move;
3359
3360		if (shdr->sh_type != SHT_SUNW_move)
3361			continue;
3362		if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
3363			continue;
3364
3365		/*
3366		 * Determine the move data and number.
3367		 */
3368		if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
3369			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
3370			    file, _cache->c_name);
3371			continue;
3372		}
3373		if (_cache->c_data == NULL)
3374			continue;
3375
3376		move = (Move *)_cache->c_data->d_buf;
3377		movenum = shdr->sh_size / shdr->sh_entsize;
3378
3379		/*
3380		 * Get the data buffer for the associated symbol table and
3381		 * string table.
3382		 */
3383		if (stringtbl(cache, 1, cnt, shnum, file,
3384		    &symnum, &symsec, &strsec) == 0)
3385			return;
3386
3387		syms = (Sym *)symsec->c_data->d_buf;
3388
3389		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3390		dbg_print(0, MSG_INTL(MSG_ELF_SCN_MOVE), _cache->c_name);
3391		dbg_print(0, MSG_INTL(MSG_MOVE_TITLE));
3392
3393		if (fmt == NULL)
3394			fmt = MSG_INTL(MSG_MOVE_ENTRY);
3395
3396		for (ndx = 0; ndx < movenum; move++, ndx++) {
3397			const char	*symname;
3398			char		index[MAXNDXSIZE], section[BUFSIZ];
3399			Word		symndx, shndx;
3400			Sym		*sym;
3401
3402			/*
3403			 * Check for null entries
3404			 */
3405			if ((move->m_info == 0) && (move->m_value == 0) &&
3406			    (move->m_poffset == 0) && (move->m_repeat == 0) &&
3407			    (move->m_stride == 0)) {
3408				dbg_print(0, fmt, MSG_ORIG(MSG_STR_EMPTY),
3409				    EC_XWORD(move->m_poffset), 0, 0, 0,
3410				    EC_LWORD(0), MSG_ORIG(MSG_STR_EMPTY));
3411				continue;
3412			}
3413			if (((symndx = ELF_M_SYM(move->m_info)) == 0) ||
3414			    (symndx >= symnum)) {
3415				(void) fprintf(stderr,
3416				    MSG_INTL(MSG_ERR_BADMINFO), file,
3417				    _cache->c_name, EC_XWORD(move->m_info));
3418
3419				(void) snprintf(index, MAXNDXSIZE,
3420				    MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(symndx));
3421				dbg_print(0, fmt, index,
3422				    EC_XWORD(move->m_poffset),
3423				    ELF_M_SIZE(move->m_info), move->m_repeat,
3424				    move->m_stride, move->m_value,
3425				    MSG_INTL(MSG_STR_UNKNOWN));
3426				continue;
3427			}
3428
3429			symname = relsymname(cache, _cache, strsec,
3430			    symndx, symnum, ndx, syms, section, BUFSIZ, file);
3431			sym = (Sym *)(syms + symndx);
3432
3433			/*
3434			 * Additional sanity check.
3435			 */
3436			shndx = sym->st_shndx;
3437			if (!((shndx == SHN_COMMON) ||
3438			    (((shndx >= 1) && (shndx <= shnum)) &&
3439			    (cache[shndx].c_shdr)->sh_type == SHT_NOBITS))) {
3440				(void) fprintf(stderr,
3441				    MSG_INTL(MSG_ERR_BADSYM2), file,
3442				    _cache->c_name, EC_WORD(symndx),
3443				    demangle(symname, flags));
3444			}
3445
3446			(void) snprintf(index, MAXNDXSIZE,
3447			    MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(symndx));
3448			dbg_print(0, fmt, index, EC_XWORD(move->m_poffset),
3449			    ELF_M_SIZE(move->m_info), move->m_repeat,
3450			    move->m_stride, move->m_value,
3451			    demangle(symname, flags));
3452		}
3453	}
3454}
3455
3456/*
3457 * parse_note_t is used to track the state used by parse_note_entry()
3458 * between calls, and also to return the results of each call.
3459 */
3460typedef struct {
3461	/* pns_ fields track progress through the data */
3462	const char	*pns_file;	/* File name */
3463	Cache		*pns_cache;	/* Note section cache entry */
3464	size_t		pns_size;	/* # unprocessed data bytes */
3465	Word		*pns_data;	/* # to next unused data byte */
3466
3467	/* pn_ fields return the results for a single call */
3468	Word		pn_namesz;	/* Value of note namesz field */
3469	Word		pn_descsz;	/* Value of note descsz field */
3470	Word		pn_type;	/* Value of note type field */
3471	const char	*pn_name;	/* if (namesz > 0) ptr to name bytes */
3472	const char	*pn_desc;	/* if (descsx > 0) ptr to data bytes */
3473} parse_note_t;
3474
3475/*
3476 * Extract the various sub-parts of a note entry, and advance the
3477 * data pointer past it.
3478 *
3479 * entry:
3480 *	The state pns_ fields contain current values for the Note section
3481 *
3482 * exit:
3483 *	On success, True (1) is returned, the state pns_ fields have been
3484 *	advanced to point at the start of the next entry, and the information
3485 *	for the recovered note entry is found in the state pn_ fields.
3486 *
3487 *	On failure, False (0) is returned. The values contained in state
3488 *	are undefined.
3489 */
3490static int
3491parse_note_entry(parse_note_t *state)
3492{
3493	size_t	pad, noteoff;
3494
3495	noteoff = (Word)state->pns_cache->c_data->d_size - state->pns_size;
3496	/*
3497	 * Make sure we can at least reference the 3 initial entries
3498	 * (4-byte words) of the note information block.
3499	 */
3500	if (state->pns_size >= (sizeof (Word) * 3)) {
3501		state->pns_size -= (sizeof (Word) * 3);
3502	} else {
3503		(void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADDATASZ),
3504		    state->pns_file, state->pns_cache->c_name,
3505		    EC_WORD(noteoff));
3506		return (0);
3507	}
3508
3509	/*
3510	 * Make sure any specified name string can be referenced.
3511	 */
3512	if ((state->pn_namesz = *state->pns_data++) != 0) {
3513		if (state->pns_size >= state->pn_namesz) {
3514			state->pns_size -= state->pn_namesz;
3515		} else {
3516			(void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADNMSZ),
3517			    state->pns_file, state->pns_cache->c_name,
3518			    EC_WORD(noteoff), EC_WORD(state->pn_namesz));
3519			return (0);
3520		}
3521	}
3522
3523	/*
3524	 * Make sure any specified descriptor can be referenced.
3525	 */
3526	if ((state->pn_descsz = *state->pns_data++) != 0) {
3527		/*
3528		 * If namesz isn't a 4-byte multiple, account for any
3529		 * padding that must exist before the descriptor.
3530		 */
3531		if ((pad = (state->pn_namesz & (sizeof (Word) - 1))) != 0) {
3532			pad = sizeof (Word) - pad;
3533			state->pns_size -= pad;
3534		}
3535		if (state->pns_size >= state->pn_descsz) {
3536			state->pns_size -= state->pn_descsz;
3537		} else {
3538			(void) fprintf(stderr, MSG_INTL(MSG_NOTE_BADDESZ),
3539			    state->pns_file, state->pns_cache->c_name,
3540			    EC_WORD(noteoff), EC_WORD(state->pn_namesz));
3541			return (0);
3542		}
3543	}
3544
3545	state->pn_type = *state->pns_data++;
3546
3547	/* Name */
3548	if (state->pn_namesz) {
3549		state->pn_name = (char *)state->pns_data;
3550		pad = (state->pn_namesz +
3551		    (sizeof (Word) - 1)) & ~(sizeof (Word) - 1);
3552		/* LINTED */
3553		state->pns_data = (Word *)(state->pn_name + pad);
3554	}
3555
3556	/*
3557	 * If multiple information blocks exist within a .note section
3558	 * account for any padding that must exist before the next
3559	 * information block.
3560	 */
3561	if ((pad = (state->pn_descsz & (sizeof (Word) - 1))) != 0) {
3562		pad = sizeof (Word) - pad;
3563		if (state->pns_size > pad)
3564			state->pns_size -= pad;
3565	}
3566
3567	/* Data */
3568	if (state->pn_descsz) {
3569		state->pn_desc = (const char *)state->pns_data;
3570		/* LINTED */
3571		state->pns_data = (Word *)(state->pn_desc +
3572		    state->pn_descsz + pad);
3573	}
3574
3575	return (1);
3576}
3577
3578/*
3579 * Callback function for use with conv_str_to_c_literal() below.
3580 */
3581/*ARGSUSED2*/
3582static void
3583c_literal_cb(const void *ptr, size_t size, void *uvalue)
3584{
3585	(void) fwrite(ptr, size, 1, stdout);
3586}
3587
3588/*
3589 * Traverse a note section analyzing each note information block.
3590 * The data buffers size is used to validate references before they are made,
3591 * and is decremented as each element is processed.
3592 */
3593void
3594note_entry(Cache *cache, Word *data, size_t size, Ehdr *ehdr, const char *file)
3595{
3596	int		cnt = 0;
3597	int		is_corenote;
3598	int		do_swap;
3599	Conv_inv_buf_t	inv_buf;
3600	parse_note_t	pnstate;
3601
3602	pnstate.pns_file = file;
3603	pnstate.pns_cache = cache;
3604	pnstate.pns_size = size;
3605	pnstate.pns_data = data;
3606	do_swap = _elf_sys_encoding() != ehdr->e_ident[EI_DATA];
3607
3608	/*
3609	 * Print out a single `note' information block.
3610	 */
3611	while (pnstate.pns_size > 0) {
3612
3613		if (parse_note_entry(&pnstate) == 0)
3614			return;
3615
3616		/*
3617		 * Is this a Solaris core note? Such notes all have
3618		 * the name "CORE".
3619		 */
3620		is_corenote = (ehdr->e_type == ET_CORE) &&
3621		    (pnstate.pn_namesz == (MSG_STR_CORE_SIZE + 1)) &&
3622		    (strncmp(MSG_ORIG(MSG_STR_CORE), pnstate.pn_name,
3623		    MSG_STR_CORE_SIZE + 1) == 0);
3624
3625		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3626		dbg_print(0, MSG_INTL(MSG_FMT_NOTEENTNDX), EC_WORD(cnt));
3627		cnt++;
3628		dbg_print(0, MSG_ORIG(MSG_NOTE_NAMESZ),
3629		    EC_WORD(pnstate.pn_namesz));
3630		dbg_print(0, MSG_ORIG(MSG_NOTE_DESCSZ),
3631		    EC_WORD(pnstate.pn_descsz));
3632
3633		if (is_corenote)
3634			dbg_print(0, MSG_ORIG(MSG_NOTE_TYPE_STR),
3635			    conv_cnote_type(pnstate.pn_type, 0, &inv_buf));
3636		else
3637			dbg_print(0, MSG_ORIG(MSG_NOTE_TYPE),
3638			    EC_WORD(pnstate.pn_type));
3639		if (pnstate.pn_namesz) {
3640			dbg_print(0, MSG_ORIG(MSG_NOTE_NAME));
3641			/*
3642			 * The name string can contain embedded 'null'
3643			 * bytes and/or unprintable characters. Also,
3644			 * the final NULL is documented in the ELF ABI
3645			 * as being included in the namesz. So, display
3646			 * the name using C literal string notation, and
3647			 * include the terminating NULL in the output.
3648			 * We don't show surrounding double quotes, as
3649			 * that implies the termination that we are showing
3650			 * explicitly.
3651			 */
3652			(void) fwrite(MSG_ORIG(MSG_STR_8SP),
3653			    MSG_STR_8SP_SIZE, 1, stdout);
3654			conv_str_to_c_literal(pnstate.pn_name,
3655			    pnstate.pn_namesz, c_literal_cb, NULL);
3656			dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3657		}
3658
3659		if (pnstate.pn_descsz) {
3660			int		hexdump = 1;
3661
3662			/*
3663			 * If this is a core note, let the corenote()
3664			 * function handle it.
3665			 */
3666			if (is_corenote) {
3667				/* We only issue the bad arch error once */
3668				static int	badnote_done = 0;
3669				corenote_ret_t	corenote_ret;
3670
3671				corenote_ret = corenote(ehdr->e_machine,
3672				    do_swap, pnstate.pn_type, pnstate.pn_desc,
3673				    pnstate.pn_descsz);
3674				switch (corenote_ret) {
3675				case CORENOTE_R_OK:
3676					hexdump = 0;
3677					break;
3678				case CORENOTE_R_BADDATA:
3679					(void) fprintf(stderr,
3680					    MSG_INTL(MSG_NOTE_BADCOREDATA),
3681					    file);
3682					break;
3683				case CORENOTE_R_BADARCH:
3684					if (badnote_done)
3685						break;
3686					(void) fprintf(stderr,
3687					    MSG_INTL(MSG_NOTE_BADCOREARCH),
3688					    file,
3689					    conv_ehdr_mach(ehdr->e_machine,
3690					    0, &inv_buf));
3691					break;
3692				}
3693			}
3694
3695			/*
3696			 * The default thing when we don't understand
3697			 * the note data is to display it as hex bytes.
3698			 */
3699			if (hexdump) {
3700				dbg_print(0, MSG_ORIG(MSG_NOTE_DESC));
3701				dump_hex_bytes(pnstate.pn_desc,
3702				    pnstate.pn_descsz, 8, 4, 4);
3703			}
3704		}
3705	}
3706}
3707
3708/*
3709 * Search for and process .note sections.
3710 *
3711 * Returns the number of note sections seen.
3712 */
3713static Word
3714note(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
3715{
3716	Word	cnt, note_cnt = 0;
3717
3718	/*
3719	 * Otherwise look for any .note sections.
3720	 */
3721	for (cnt = 1; cnt < shnum; cnt++) {
3722		Cache	*_cache = &cache[cnt];
3723		Shdr	*shdr = _cache->c_shdr;
3724
3725		if (shdr->sh_type != SHT_NOTE)
3726			continue;
3727		note_cnt++;
3728		if (!match(MATCH_F_ALL, _cache->c_name, cnt, shdr->sh_type))
3729			continue;
3730
3731		/*
3732		 * As these sections are often hand rolled, make sure they're
3733		 * properly aligned before proceeding, and issue an error
3734		 * as necessary.
3735		 *
3736		 * Note that we will continue on to display the note even
3737		 * if it has bad alignment. We can do this safely, because
3738		 * libelf knows the alignment required for SHT_NOTE, and
3739		 * takes steps to deliver a properly aligned buffer to us
3740		 * even if the actual file is misaligned.
3741		 */
3742		if (shdr->sh_offset & (sizeof (Word) - 1))
3743			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADALIGN),
3744			    file, _cache->c_name);
3745
3746		if (_cache->c_data == NULL)
3747			continue;
3748
3749		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3750		dbg_print(0, MSG_INTL(MSG_ELF_SCN_NOTE), _cache->c_name);
3751		note_entry(_cache, (Word *)_cache->c_data->d_buf,
3752		/* LINTED */
3753		    (Word)_cache->c_data->d_size, ehdr, file);
3754	}
3755
3756	return (note_cnt);
3757}
3758
3759/*
3760 * The Linux Standard Base defines a special note named .note.ABI-tag
3761 * that is used to maintain Linux ABI information. Presence of this section
3762 * is a strong indication that the object should be considered to be
3763 * ELFOSABI_LINUX.
3764 *
3765 * This function returns True (1) if such a note is seen, and False (0)
3766 * otherwise.
3767 */
3768static int
3769has_linux_abi_note(Cache *cache, Word shnum, const char *file)
3770{
3771	Word	cnt;
3772
3773	for (cnt = 1; cnt < shnum; cnt++) {
3774		parse_note_t	pnstate;
3775		Cache		*_cache = &cache[cnt];
3776		Shdr		*shdr = _cache->c_shdr;
3777
3778		/*
3779		 * Section must be SHT_NOTE, must have the name
3780		 * .note.ABI-tag, and must have data.
3781		 */
3782		if ((shdr->sh_type != SHT_NOTE) ||
3783		    (strcmp(MSG_ORIG(MSG_STR_NOTEABITAG),
3784		    _cache->c_name) != 0) || (_cache->c_data == NULL))
3785			continue;
3786
3787		pnstate.pns_file = file;
3788		pnstate.pns_cache = _cache;
3789		pnstate.pns_size = _cache->c_data->d_size;
3790		pnstate.pns_data = (Word *)_cache->c_data->d_buf;
3791
3792		while (pnstate.pns_size > 0) {
3793			Word *w;
3794
3795			if (parse_note_entry(&pnstate) == 0)
3796				break;
3797
3798			/*
3799			 * The type must be 1, and the name must be "GNU".
3800			 * The descsz must be at least 16 bytes.
3801			 */
3802			if ((pnstate.pn_type != 1) ||
3803			    (pnstate.pn_namesz != (MSG_STR_GNU_SIZE + 1)) ||
3804			    (strncmp(MSG_ORIG(MSG_STR_GNU), pnstate.pn_name,
3805			    MSG_STR_CORE_SIZE + 1) != 0) ||
3806			    (pnstate.pn_descsz < 16))
3807				continue;
3808
3809			/*
3810			 * desc contains 4 32-bit fields. Field 0 must be 0,
3811			 * indicating Linux. The second, third, and fourth
3812			 * fields represent the earliest Linux kernel
3813			 * version compatible with this object.
3814			 */
3815			/*LINTED*/
3816			w = (Word *) pnstate.pn_desc;
3817			if (*w == 0)
3818				return (1);
3819		}
3820	}
3821
3822	return (0);
3823}
3824
3825/*
3826 * Determine an individual hash entry.  This may be the initial hash entry,
3827 * or an associated chain entry.
3828 */
3829static void
3830hash_entry(Cache *refsec, Cache *strsec, const char *hsecname, Word hashndx,
3831    Word symndx, Word symn, Sym *syms, const char *file, ulong_t bkts,
3832    uint_t flags, int chain)
3833{
3834	Sym		*sym;
3835	const char	*symname, *str;
3836	char		_bucket[MAXNDXSIZE], _symndx[MAXNDXSIZE];
3837	ulong_t		nbkt, nhash;
3838
3839	if (symndx > symn) {
3840		(void) fprintf(stderr, MSG_INTL(MSG_ERR_HSBADSYMNDX), file,
3841		    EC_WORD(symndx), EC_WORD(hashndx));
3842		symname = MSG_INTL(MSG_STR_UNKNOWN);
3843	} else {
3844		sym = (Sym *)(syms + symndx);
3845		symname = string(refsec, symndx, strsec, file, sym->st_name);
3846	}
3847
3848	if (chain == 0) {
3849		(void) snprintf(_bucket, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INTEGER),
3850		    hashndx);
3851		str = (const char *)_bucket;
3852	} else
3853		str = MSG_ORIG(MSG_STR_EMPTY);
3854
3855	(void) snprintf(_symndx, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INDEX2),
3856	    EC_WORD(symndx));
3857	dbg_print(0, MSG_ORIG(MSG_FMT_HASH_INFO), str, _symndx,
3858	    demangle(symname, flags));
3859
3860	/*
3861	 * Determine if this string is in the correct bucket.
3862	 */
3863	nhash = elf_hash(symname);
3864	nbkt = nhash % bkts;
3865
3866	if (nbkt != hashndx) {
3867		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADHASH), file,
3868		    hsecname, symname, EC_WORD(hashndx), nbkt);
3869	}
3870}
3871
3872#define	MAXCOUNT	500
3873
3874static void
3875hash(Cache *cache, Word shnum, const char *file, uint_t flags)
3876{
3877	static int	count[MAXCOUNT];
3878	Word		cnt;
3879	ulong_t		ndx, bkts;
3880	char		number[MAXNDXSIZE];
3881
3882	for (cnt = 1; cnt < shnum; cnt++) {
3883		uint_t		*hash, *chain;
3884		Cache		*_cache = &cache[cnt];
3885		Shdr		*sshdr, *hshdr = _cache->c_shdr;
3886		char		*ssecname, *hsecname = _cache->c_name;
3887		Sym		*syms;
3888		Word		symn;
3889
3890		if (hshdr->sh_type != SHT_HASH)
3891			continue;
3892
3893		/*
3894		 * Determine the hash table data and size.
3895		 */
3896		if ((hshdr->sh_entsize == 0) || (hshdr->sh_size == 0)) {
3897			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
3898			    file, hsecname);
3899			continue;
3900		}
3901		if (_cache->c_data == NULL)
3902			continue;
3903
3904		hash = (uint_t *)_cache->c_data->d_buf;
3905		bkts = *hash;
3906		chain = hash + 2 + bkts;
3907		hash += 2;
3908
3909		/*
3910		 * Get the data buffer for the associated symbol table.
3911		 */
3912		if ((hshdr->sh_link == 0) || (hshdr->sh_link >= shnum)) {
3913			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
3914			    file, hsecname, EC_WORD(hshdr->sh_link));
3915			continue;
3916		}
3917
3918		_cache = &cache[hshdr->sh_link];
3919		ssecname = _cache->c_name;
3920
3921		if (_cache->c_data == NULL)
3922			continue;
3923
3924		if ((syms = (Sym *)_cache->c_data->d_buf) == NULL) {
3925			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
3926			    file, ssecname);
3927			continue;
3928		}
3929
3930		sshdr = _cache->c_shdr;
3931		/* LINTED */
3932		symn = (Word)(sshdr->sh_size / sshdr->sh_entsize);
3933
3934		/*
3935		 * Get the associated string table section.
3936		 */
3937		if ((sshdr->sh_link == 0) || (sshdr->sh_link >= shnum)) {
3938			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHLINK),
3939			    file, ssecname, EC_WORD(sshdr->sh_link));
3940			continue;
3941		}
3942
3943		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3944		dbg_print(0, MSG_INTL(MSG_ELF_SCN_HASH), hsecname);
3945		dbg_print(0, MSG_INTL(MSG_ELF_HASH_INFO));
3946
3947		/*
3948		 * Loop through the hash buckets, printing the appropriate
3949		 * symbols.
3950		 */
3951		for (ndx = 0; ndx < bkts; ndx++, hash++) {
3952			Word	_ndx, _cnt;
3953
3954			if (*hash == 0) {
3955				count[0]++;
3956				continue;
3957			}
3958
3959			hash_entry(_cache, &cache[sshdr->sh_link], hsecname,
3960			    ndx, *hash, symn, syms, file, bkts, flags, 0);
3961
3962			/*
3963			 * Determine if any other symbols are chained to this
3964			 * bucket.
3965			 */
3966			_ndx = chain[*hash];
3967			_cnt = 1;
3968			while (_ndx) {
3969				hash_entry(_cache, &cache[sshdr->sh_link],
3970				    hsecname, ndx, _ndx, symn, syms, file,
3971				    bkts, flags, 1);
3972				_ndx = chain[_ndx];
3973				_cnt++;
3974			}
3975
3976			if (_cnt >= MAXCOUNT) {
3977				(void) fprintf(stderr,
3978				    MSG_INTL(MSG_HASH_OVERFLW), file,
3979				    _cache->c_name, EC_WORD(ndx),
3980				    EC_WORD(_cnt));
3981			} else
3982				count[_cnt]++;
3983		}
3984		break;
3985	}
3986
3987	/*
3988	 * Print out the count information.
3989	 */
3990	bkts = cnt = 0;
3991	dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
3992
3993	for (ndx = 0; ndx < MAXCOUNT; ndx++) {
3994		Word	_cnt;
3995
3996		if ((_cnt = count[ndx]) == 0)
3997			continue;
3998
3999		(void) snprintf(number, MAXNDXSIZE,
4000		    MSG_ORIG(MSG_FMT_INTEGER), _cnt);
4001		dbg_print(0, MSG_INTL(MSG_ELF_HASH_BKTS1), number,
4002		    EC_WORD(ndx));
4003		bkts += _cnt;
4004		cnt += (Word)(ndx * _cnt);
4005	}
4006	if (cnt) {
4007		(void) snprintf(number, MAXNDXSIZE, MSG_ORIG(MSG_FMT_INTEGER),
4008		    bkts);
4009		dbg_print(0, MSG_INTL(MSG_ELF_HASH_BKTS2), number,
4010		    EC_WORD(cnt));
4011	}
4012}
4013
4014static void
4015group(Cache *cache, Word shnum, const char *file, uint_t flags)
4016{
4017	Word	scnt;
4018
4019	for (scnt = 1; scnt < shnum; scnt++) {
4020		Cache		*_cache = &cache[scnt];
4021		Shdr		*shdr = _cache->c_shdr;
4022		Word		*grpdata, gcnt, grpcnt, symnum, unknown;
4023		Cache		*symsec, *strsec;
4024		Sym		*syms, *sym;
4025		char		flgstrbuf[MSG_GRP_COMDAT_SIZE + 10];
4026		const char	*grpnam;
4027
4028		if (shdr->sh_type != SHT_GROUP)
4029			continue;
4030		if (!match(MATCH_F_ALL, _cache->c_name, scnt, shdr->sh_type))
4031			continue;
4032		if ((_cache->c_data == NULL) ||
4033		    ((grpdata = (Word *)_cache->c_data->d_buf) == NULL))
4034			continue;
4035		grpcnt = shdr->sh_size / sizeof (Word);
4036
4037		/*
4038		 * Get the data buffer for the associated symbol table and
4039		 * string table.
4040		 */
4041		if (stringtbl(cache, 1, scnt, shnum, file,
4042		    &symnum, &symsec, &strsec) == 0)
4043			return;
4044
4045		syms = symsec->c_data->d_buf;
4046
4047		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4048		dbg_print(0, MSG_INTL(MSG_ELF_SCN_GRP), _cache->c_name);
4049		dbg_print(0, MSG_INTL(MSG_GRP_TITLE));
4050
4051		/*
4052		 * The first element of the group defines the group.  The
4053		 * associated symbol is defined by the sh_link field.
4054		 */
4055		if ((shdr->sh_info == SHN_UNDEF) || (shdr->sh_info > symnum)) {
4056			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHINFO),
4057			    file, _cache->c_name, EC_WORD(shdr->sh_info));
4058			return;
4059		}
4060
4061		(void) strcpy(flgstrbuf, MSG_ORIG(MSG_STR_OSQBRKT));
4062		if (grpdata[0] & GRP_COMDAT) {
4063			(void) strcat(flgstrbuf, MSG_ORIG(MSG_GRP_COMDAT));
4064		}
4065		if ((unknown = (grpdata[0] & ~GRP_COMDAT)) != 0) {
4066			size_t	len = strlen(flgstrbuf);
4067
4068			(void) snprintf(&flgstrbuf[len],
4069			    (MSG_GRP_COMDAT_SIZE + 10 - len),
4070			    MSG_ORIG(MSG_GRP_UNKNOWN), unknown);
4071		}
4072		(void) strcat(flgstrbuf, MSG_ORIG(MSG_STR_CSQBRKT));
4073		sym = (Sym *)(syms + shdr->sh_info);
4074
4075		/*
4076		 * The GNU assembler can use section symbols as the signature
4077		 * symbol as described by this comment in the gold linker
4078		 * (found via google):
4079		 *
4080		 *	It seems that some versions of gas will create a
4081		 *	section group associated with a section symbol, and
4082		 *	then fail to give a name to the section symbol.  In
4083		 *	such a case, use the name of the section.
4084		 *
4085		 * In order to support such objects, we do the same.
4086		 */
4087		grpnam = string(_cache, 0, strsec, file, sym->st_name);
4088		if (((sym->st_name == 0) || (*grpnam == '\0')) &&
4089		    (ELF_ST_TYPE(sym->st_info) == STT_SECTION))
4090			grpnam = cache[sym->st_shndx].c_name;
4091
4092		dbg_print(0, MSG_INTL(MSG_GRP_SIGNATURE), flgstrbuf,
4093		    demangle(grpnam, flags));
4094
4095		for (gcnt = 1; gcnt < grpcnt; gcnt++) {
4096			char		index[MAXNDXSIZE];
4097			const char	*name;
4098
4099			(void) snprintf(index, MAXNDXSIZE,
4100			    MSG_ORIG(MSG_FMT_INDEX), EC_XWORD(gcnt));
4101
4102			if (grpdata[gcnt] >= shnum)
4103				name = MSG_INTL(MSG_GRP_INVALSCN);
4104			else
4105				name = cache[grpdata[gcnt]].c_name;
4106
4107			(void) printf(MSG_ORIG(MSG_GRP_ENTRY), index, name,
4108			    EC_XWORD(grpdata[gcnt]));
4109		}
4110	}
4111}
4112
4113static void
4114got(Cache *cache, Word shnum, Ehdr *ehdr, const char *file)
4115{
4116	Cache		*gotcache = NULL, *symtab = NULL;
4117	Addr		gotbgn, gotend;
4118	Shdr		*gotshdr;
4119	Word		cnt, gotents, gotndx;
4120	size_t		gentsize;
4121	Got_info	*gottable;
4122	char		*gotdata;
4123	Sym		*gotsym;
4124	Xword		gotsymaddr;
4125	uint_t		sys_encoding;
4126
4127	/*
4128	 * First, find the got.
4129	 */
4130	for (cnt = 1; cnt < shnum; cnt++) {
4131		if (strncmp(cache[cnt].c_name, MSG_ORIG(MSG_ELF_GOT),
4132		    MSG_ELF_GOT_SIZE) == 0) {
4133			gotcache = &cache[cnt];
4134			break;
4135		}
4136	}
4137	if (gotcache == NULL)
4138		return;
4139
4140	/*
4141	 * A got section within a relocatable object is suspicious.
4142	 */
4143	if (ehdr->e_type == ET_REL) {
4144		(void) fprintf(stderr, MSG_INTL(MSG_GOT_UNEXPECTED), file,
4145		    gotcache->c_name);
4146	}
4147
4148	gotshdr = gotcache->c_shdr;
4149	if (gotshdr->sh_size == 0) {
4150		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
4151		    file, gotcache->c_name);
4152		return;
4153	}
4154
4155	gotbgn = gotshdr->sh_addr;
4156	gotend = gotbgn + gotshdr->sh_size;
4157
4158	/*
4159	 * Some architectures don't properly set the sh_entsize for the GOT
4160	 * table.  If it's not set, default to a size of a pointer.
4161	 */
4162	if ((gentsize = gotshdr->sh_entsize) == 0)
4163		gentsize = sizeof (Xword);
4164
4165	if (gotcache->c_data == NULL)
4166		return;
4167
4168	/* LINTED */
4169	gotents = (Word)(gotshdr->sh_size / gentsize);
4170	gotdata = gotcache->c_data->d_buf;
4171
4172	if ((gottable = calloc(gotents, sizeof (Got_info))) == 0) {
4173		int err = errno;
4174		(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC), file,
4175		    strerror(err));
4176		return;
4177	}
4178
4179	/*
4180	 * Now we scan through all the sections looking for any relocations
4181	 * that may be against the GOT.  Since these may not be isolated to a
4182	 * .rel[a].got section we check them all.
4183	 * While scanning sections save the symbol table entry (a symtab
4184	 * overriding a dynsym) so that we can lookup _GLOBAL_OFFSET_TABLE_.
4185	 */
4186	for (cnt = 1; cnt < shnum; cnt++) {
4187		Word		type, symnum;
4188		Xword		relndx, relnum, relsize;
4189		void		*rels;
4190		Sym		*syms;
4191		Cache		*symsec, *strsec;
4192		Cache		*_cache = &cache[cnt];
4193		Shdr		*shdr;
4194
4195		shdr = _cache->c_shdr;
4196		type = shdr->sh_type;
4197
4198		if ((symtab == 0) && (type == SHT_DYNSYM)) {
4199			symtab = _cache;
4200			continue;
4201		}
4202		if (type == SHT_SYMTAB) {
4203			symtab = _cache;
4204			continue;
4205		}
4206		if ((type != SHT_RELA) && (type != SHT_REL))
4207			continue;
4208
4209		/*
4210		 * Decide entry size.
4211		 */
4212		if (((relsize = shdr->sh_entsize) == 0) ||
4213		    (relsize > shdr->sh_size)) {
4214			if (type == SHT_RELA)
4215				relsize = sizeof (Rela);
4216			else
4217				relsize = sizeof (Rel);
4218		}
4219
4220		/*
4221		 * Determine the number of relocations available.
4222		 */
4223		if (shdr->sh_size == 0) {
4224			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
4225			    file, _cache->c_name);
4226			continue;
4227		}
4228		if (_cache->c_data == NULL)
4229			continue;
4230
4231		rels = _cache->c_data->d_buf;
4232		relnum = shdr->sh_size / relsize;
4233
4234		/*
4235		 * Get the data buffer for the associated symbol table and
4236		 * string table.
4237		 */
4238		if (stringtbl(cache, 1, cnt, shnum, file,
4239		    &symnum, &symsec, &strsec) == 0)
4240			continue;
4241
4242		syms = symsec->c_data->d_buf;
4243
4244		/*
4245		 * Loop through the relocation entries.
4246		 */
4247		for (relndx = 0; relndx < relnum; relndx++,
4248		    rels = (void *)((char *)rels + relsize)) {
4249			char		section[BUFSIZ];
4250			Addr		offset;
4251			Got_info	*gip;
4252			Word		symndx, reltype;
4253			Rela		*rela;
4254			Rel		*rel;
4255
4256			/*
4257			 * Unravel the relocation.
4258			 */
4259			if (type == SHT_RELA) {
4260				rela = (Rela *)rels;
4261				symndx = ELF_R_SYM(rela->r_info);
4262				reltype = ELF_R_TYPE(rela->r_info,
4263				    ehdr->e_machine);
4264				offset = rela->r_offset;
4265			} else {
4266				rel = (Rel *)rels;
4267				symndx = ELF_R_SYM(rel->r_info);
4268				reltype = ELF_R_TYPE(rel->r_info,
4269				    ehdr->e_machine);
4270				offset = rel->r_offset;
4271			}
4272
4273			/*
4274			 * Only pay attention to relocations against the GOT.
4275			 */
4276			if ((offset < gotbgn) || (offset >= gotend))
4277				continue;
4278
4279			/* LINTED */
4280			gotndx = (Word)((offset - gotbgn) /
4281			    gotshdr->sh_entsize);
4282			gip = &gottable[gotndx];
4283
4284			if (gip->g_reltype != 0) {
4285				(void) fprintf(stderr,
4286				    MSG_INTL(MSG_GOT_MULTIPLE), file,
4287				    EC_WORD(gotndx), EC_ADDR(offset));
4288				continue;
4289			}
4290
4291			if (symndx)
4292				gip->g_symname = relsymname(cache, _cache,
4293				    strsec, symndx, symnum, relndx, syms,
4294				    section, BUFSIZ, file);
4295			gip->g_reltype = reltype;
4296			gip->g_rel = rels;
4297		}
4298	}
4299
4300	if (symlookup(MSG_ORIG(MSG_SYM_GOT), cache, shnum, &gotsym, NULL,
4301	    symtab, file))
4302		gotsymaddr = gotsym->st_value;
4303	else
4304		gotsymaddr = gotbgn;
4305
4306	dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4307	dbg_print(0, MSG_INTL(MSG_ELF_SCN_GOT), gotcache->c_name);
4308	Elf_got_title(0);
4309
4310	sys_encoding = _elf_sys_encoding();
4311	for (gotndx = 0; gotndx < gotents; gotndx++) {
4312		Got_info	*gip;
4313		Sword		gindex;
4314		Addr		gaddr;
4315		Xword		gotentry;
4316
4317		gip = &gottable[gotndx];
4318
4319		gaddr = gotbgn + (gotndx * gentsize);
4320		gindex = (Sword)(gaddr - gotsymaddr) / (Sword)gentsize;
4321
4322		if (gentsize == sizeof (Word))
4323			/* LINTED */
4324			gotentry = (Xword)(*((Word *)(gotdata) + gotndx));
4325		else
4326			/* LINTED */
4327			gotentry = *((Xword *)(gotdata) + gotndx);
4328
4329		Elf_got_entry(0, gindex, gaddr, gotentry, ehdr->e_machine,
4330		    ehdr->e_ident[EI_DATA], sys_encoding,
4331		    gip->g_reltype, gip->g_rel, gip->g_symname);
4332	}
4333	free(gottable);
4334}
4335
4336void
4337checksum(Elf *elf)
4338{
4339	dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4340	dbg_print(0, MSG_INTL(MSG_STR_CHECKSUM), elf_checksum(elf));
4341}
4342
4343/*
4344 * This variable is used by regular() to communicate the address of
4345 * the section header cache to sort_shdr_ndx_arr(). Unfortunately,
4346 * the qsort() interface does not include a userdata argument by which
4347 * such arbitrary data can be passed, so we are stuck using global data.
4348 */
4349static Cache *sort_shdr_ndx_arr_cache;
4350
4351
4352/*
4353 * Used with qsort() to sort the section indices so that they can be
4354 * used to access the section headers in order of increasing data offset.
4355 *
4356 * entry:
4357 *	sort_shdr_ndx_arr_cache - Contains address of
4358 *		section header cache.
4359 *	v1, v2 - Point at elements of sort_shdr_bits array to be compared.
4360 *
4361 * exit:
4362 *	Returns -1 (less than), 0 (equal) or 1 (greater than).
4363 */
4364static int
4365sort_shdr_ndx_arr(const void *v1, const void *v2)
4366{
4367	Cache	*cache1 = sort_shdr_ndx_arr_cache + *((size_t *)v1);
4368	Cache	*cache2 = sort_shdr_ndx_arr_cache + *((size_t *)v2);
4369
4370	if (cache1->c_shdr->sh_offset < cache2->c_shdr->sh_offset)
4371		return (-1);
4372
4373	if (cache1->c_shdr->sh_offset > cache2->c_shdr->sh_offset)
4374		return (1);
4375
4376	return (0);
4377}
4378
4379
4380static int
4381shdr_cache(const char *file, Elf *elf, Ehdr *ehdr, size_t shstrndx,
4382    size_t shnum, Cache **cache_ret, Word flags)
4383{
4384	Elf_Scn		*scn;
4385	Elf_Data	*data;
4386	size_t		ndx;
4387	Shdr		*nameshdr;
4388	char		*names = NULL;
4389	Cache		*cache, *_cache;
4390	size_t		*shdr_ndx_arr, shdr_ndx_arr_cnt;
4391
4392
4393	/*
4394	 * Obtain the .shstrtab data buffer to provide the required section
4395	 * name strings.
4396	 */
4397	if (shstrndx == SHN_UNDEF) {
4398		/*
4399		 * It is rare, but legal, for an object to lack a
4400		 * header string table section.
4401		 */
4402		names = NULL;
4403		(void) fprintf(stderr, MSG_INTL(MSG_ERR_NOSHSTRSEC), file);
4404	} else if ((scn = elf_getscn(elf, shstrndx)) == NULL) {
4405		failure(file, MSG_ORIG(MSG_ELF_GETSCN));
4406		(void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SHDR),
4407		    EC_XWORD(shstrndx));
4408
4409	} else if ((data = elf_getdata(scn, NULL)) == NULL) {
4410		failure(file, MSG_ORIG(MSG_ELF_GETDATA));
4411		(void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_DATA),
4412		    EC_XWORD(shstrndx));
4413
4414	} else if ((nameshdr = elf_getshdr(scn)) == NULL) {
4415		failure(file, MSG_ORIG(MSG_ELF_GETSHDR));
4416		(void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN),
4417		    EC_WORD(elf_ndxscn(scn)));
4418
4419	} else if ((names = data->d_buf) == NULL)
4420		(void) fprintf(stderr, MSG_INTL(MSG_ERR_SHSTRNULL), file);
4421
4422	/*
4423	 * Allocate a cache to maintain a descriptor for each section.
4424	 */
4425	if ((*cache_ret = cache = malloc(shnum * sizeof (Cache))) == NULL) {
4426		int err = errno;
4427		(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
4428		    file, strerror(err));
4429		return (0);
4430	}
4431
4432	*cache = cache_init;
4433	_cache = cache;
4434	_cache++;
4435
4436	/*
4437	 * Allocate an array that will hold the section index for
4438	 * each section that has data in the ELF file:
4439	 *
4440	 *	- Is not a NOBITS section
4441	 *	- Data has non-zero length
4442	 *
4443	 * Note that shnum is an upper bound on the size required. It
4444	 * is likely that we won't use a few of these array elements.
4445	 * Allocating a modest amount of extra memory in this case means
4446	 * that we can avoid an extra loop to count the number of needed
4447	 * items, and can fill this array immediately in the first loop
4448	 * below.
4449	 */
4450	if ((shdr_ndx_arr = malloc(shnum * sizeof (*shdr_ndx_arr))) == NULL) {
4451		int err = errno;
4452		(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
4453		    file, strerror(err));
4454		return (0);
4455	}
4456	shdr_ndx_arr_cnt = 0;
4457
4458	/*
4459	 * Traverse the sections of the file.  This gathering of data is
4460	 * carried out in two passes.  First, the section headers are captured
4461	 * and the section header names are evaluated.  A verification pass is
4462	 * then carried out over the section information.  Files have been
4463	 * known to exhibit overlapping (and hence erroneous) section header
4464	 * information.
4465	 *
4466	 * Finally, the data for each section is obtained.  This processing is
4467	 * carried out after section verification because should any section
4468	 * header overlap occur, and a file needs translating (ie. xlate'ing
4469	 * information from a non-native architecture file), then the process
4470	 * of translation can corrupt the section header information.  Of
4471	 * course, if there is any section overlap, the data related to the
4472	 * sections is going to be compromised.  However, it is the translation
4473	 * of this data that has caused problems with elfdump()'s ability to
4474	 * extract the data.
4475	 */
4476	for (ndx = 1, scn = NULL; scn = elf_nextscn(elf, scn);
4477	    ndx++, _cache++) {
4478		char	scnndxnm[100];
4479
4480		_cache->c_ndx = ndx;
4481		_cache->c_scn = scn;
4482
4483		if ((_cache->c_shdr = elf_getshdr(scn)) == NULL) {
4484			failure(file, MSG_ORIG(MSG_ELF_GETSHDR));
4485			(void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN),
4486			    EC_WORD(elf_ndxscn(scn)));
4487		}
4488
4489		/*
4490		 * If this section has data in the file, include it in
4491		 * the array of sections to check for address overlap.
4492		 */
4493		if ((_cache->c_shdr->sh_size != 0) &&
4494		    (_cache->c_shdr->sh_type != SHT_NOBITS))
4495			shdr_ndx_arr[shdr_ndx_arr_cnt++] = ndx;
4496
4497		/*
4498		 * If a shstrtab exists, assign the section name.
4499		 */
4500		if (names && _cache->c_shdr) {
4501			if (_cache->c_shdr->sh_name &&
4502			    /* LINTED */
4503			    (nameshdr->sh_size > _cache->c_shdr->sh_name)) {
4504				const char	*symname;
4505				char		*secname;
4506
4507				secname = names + _cache->c_shdr->sh_name;
4508
4509				/*
4510				 * A SUN naming convention employs a "%" within
4511				 * a section name to indicate a section/symbol
4512				 * name.  This originated from the compilers
4513				 * -xF option, that places functions into their
4514				 * own sections.  This convention (which has no
4515				 * formal standard) has also been followed for
4516				 * COMDAT sections.  To demangle the symbol
4517				 * name, the name must be separated from the
4518				 * section name.
4519				 */
4520				if (((flags & FLG_CTL_DEMANGLE) == 0) ||
4521				    ((symname = strchr(secname, '%')) == NULL))
4522					_cache->c_name = secname;
4523				else {
4524					size_t	secsz = ++symname - secname;
4525					size_t	strsz;
4526
4527					symname = demangle(symname, flags);
4528					strsz = secsz + strlen(symname) + 1;
4529
4530					if ((_cache->c_name =
4531					    malloc(strsz)) == NULL) {
4532						int err = errno;
4533						(void) fprintf(stderr,
4534						    MSG_INTL(MSG_ERR_MALLOC),
4535						    file, strerror(err));
4536						return (0);
4537					}
4538					(void) snprintf(_cache->c_name, strsz,
4539					    MSG_ORIG(MSG_FMT_SECSYM),
4540					    EC_WORD(secsz), secname, symname);
4541				}
4542
4543				continue;
4544			}
4545
4546			/*
4547			 * Generate an error if the section name index is zero
4548			 * or exceeds the shstrtab data.  Fall through to
4549			 * fabricate a section name.
4550			 */
4551			if ((_cache->c_shdr->sh_name == 0) ||
4552			    /* LINTED */
4553			    (nameshdr->sh_size <= _cache->c_shdr->sh_name)) {
4554				(void) fprintf(stderr,
4555				    MSG_INTL(MSG_ERR_BADSHNAME), file,
4556				    EC_WORD(ndx),
4557				    EC_XWORD(_cache->c_shdr->sh_name));
4558			}
4559		}
4560
4561		/*
4562		 * If there exists no shstrtab data, or a section header has no
4563		 * name (an invalid index of 0), then compose a name for the
4564		 * section.
4565		 */
4566		(void) snprintf(scnndxnm, sizeof (scnndxnm),
4567		    MSG_INTL(MSG_FMT_SCNNDX), ndx);
4568
4569		if ((_cache->c_name = malloc(strlen(scnndxnm) + 1)) == NULL) {
4570			int err = errno;
4571			(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
4572			    file, strerror(err));
4573			return (0);
4574		}
4575		(void) strcpy(_cache->c_name, scnndxnm);
4576	}
4577
4578	/*
4579	 * Having collected all the sections, validate their address range.
4580	 * Cases have existed where the section information has been invalid.
4581	 * This can lead to all sorts of other, hard to diagnose errors, as
4582	 * each section is processed individually (ie. with elf_getdata()).
4583	 * Here, we carry out some address comparisons to catch a family of
4584	 * overlapping memory issues we have observed (likely, there are others
4585	 * that we have yet to discover).
4586	 *
4587	 * Note, should any memory overlap occur, obtaining any additional
4588	 * data from the file is questionable.  However, it might still be
4589	 * possible to inspect the ELF header, Programs headers, or individual
4590	 * sections, so rather than bailing on an error condition, continue
4591	 * processing to see if any data can be salvaged.
4592	 */
4593	if (shdr_ndx_arr_cnt > 1) {
4594		sort_shdr_ndx_arr_cache = cache;
4595		qsort(shdr_ndx_arr, shdr_ndx_arr_cnt,
4596		    sizeof (*shdr_ndx_arr), sort_shdr_ndx_arr);
4597	}
4598	for (ndx = 0; ndx < shdr_ndx_arr_cnt; ndx++) {
4599		Cache	*_cache = cache + shdr_ndx_arr[ndx];
4600		Shdr	*shdr = _cache->c_shdr;
4601		Off	bgn1, bgn = shdr->sh_offset;
4602		Off	end1, end = shdr->sh_offset + shdr->sh_size;
4603		size_t	ndx1;
4604
4605		/*
4606		 * Check the section against all following ones, reporting
4607		 * any overlaps. Since we've sorted the sections by offset,
4608		 * we can stop after the first comparison that fails. There
4609		 * are no overlaps in a properly formed ELF file, in which
4610		 * case this algorithm runs in O(n) time. This will degenerate
4611		 * to O(n^2) for a completely broken file. Such a file is
4612		 * (1) highly unlikely, and (2) unusable, so it is reasonable
4613		 * for the analysis to take longer.
4614		 */
4615		for (ndx1 = ndx + 1; ndx1 < shdr_ndx_arr_cnt; ndx1++) {
4616			Cache	*_cache1 = cache + shdr_ndx_arr[ndx1];
4617			Shdr	*shdr1 = _cache1->c_shdr;
4618
4619			bgn1 = shdr1->sh_offset;
4620			end1 = shdr1->sh_offset + shdr1->sh_size;
4621
4622			if (((bgn1 <= bgn) && (end1 > bgn)) ||
4623			    ((bgn1 < end) && (end1 >= end))) {
4624				(void) fprintf(stderr,
4625				    MSG_INTL(MSG_ERR_SECMEMOVER), file,
4626				    EC_WORD(elf_ndxscn(_cache->c_scn)),
4627				    _cache->c_name, EC_OFF(bgn), EC_OFF(end),
4628				    EC_WORD(elf_ndxscn(_cache1->c_scn)),
4629				    _cache1->c_name, EC_OFF(bgn1),
4630				    EC_OFF(end1));
4631			} else {	/* No overlap, so can stop */
4632				break;
4633			}
4634		}
4635
4636		/*
4637		 * In addition to checking for sections overlapping
4638		 * each other (done above), we should also make sure
4639		 * the section doesn't overlap the section header array.
4640		 */
4641		bgn1 = ehdr->e_shoff;
4642		end1 = ehdr->e_shoff + (ehdr->e_shentsize * ehdr->e_shnum);
4643
4644		if (((bgn1 <= bgn) && (end1 > bgn)) ||
4645		    ((bgn1 < end) && (end1 >= end))) {
4646			(void) fprintf(stderr,
4647			    MSG_INTL(MSG_ERR_SHDRMEMOVER), file, EC_OFF(bgn1),
4648			    EC_OFF(end1),
4649			    EC_WORD(elf_ndxscn(_cache->c_scn)),
4650			    _cache->c_name, EC_OFF(bgn), EC_OFF(end));
4651		}
4652	}
4653
4654	/*
4655	 * Obtain the data for each section.
4656	 */
4657	for (ndx = 1; ndx < shnum; ndx++) {
4658		Cache	*_cache = &cache[ndx];
4659		Elf_Scn	*scn = _cache->c_scn;
4660
4661		if ((_cache->c_data = elf_getdata(scn, NULL)) == NULL) {
4662			failure(file, MSG_ORIG(MSG_ELF_GETDATA));
4663			(void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCNDATA),
4664			    EC_WORD(elf_ndxscn(scn)));
4665		}
4666
4667		/*
4668		 * If a string table, verify that it has NULL first and
4669		 * final bytes.
4670		 */
4671		if ((_cache->c_shdr->sh_type == SHT_STRTAB) &&
4672		    (_cache->c_data->d_buf != NULL) &&
4673		    (_cache->c_data->d_size > 0)) {
4674			const char *s = _cache->c_data->d_buf;
4675
4676			if ((*s != '\0') ||
4677			    (*(s + _cache->c_data->d_size - 1) != '\0'))
4678				(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALSTR),
4679				    file, _cache->c_name);
4680		}
4681	}
4682
4683	return (1);
4684}
4685
4686
4687
4688/*
4689 * Generate a cache of section headers and related information
4690 * for use by the rest of elfdump. If requested (or the file
4691 * contains no section headers), we generate a fake set of
4692 * headers from the information accessible from the program headers.
4693 * Otherwise, we use the real section headers contained in the file.
4694 */
4695static int
4696create_cache(const char *file, int fd, Elf *elf, Ehdr *ehdr, Cache **cache,
4697    size_t shstrndx, size_t *shnum, uint_t *flags)
4698{
4699	/*
4700	 * If there are no section headers, then resort to synthesizing
4701	 * section headers from the program headers. This is normally
4702	 * only done by explicit request, but in this case there's no
4703	 * reason not to go ahead, since the alternative is simply to quit.
4704	 */
4705	if ((*shnum <= 1) && ((*flags & FLG_CTL_FAKESHDR) == 0)) {
4706		(void) fprintf(stderr, MSG_INTL(MSG_ERR_NOSHDR), file);
4707		*flags |= FLG_CTL_FAKESHDR;
4708	}
4709
4710	if (*flags & FLG_CTL_FAKESHDR) {
4711		if (fake_shdr_cache(file, fd, elf, ehdr, cache, shnum) == 0)
4712			return (0);
4713	} else {
4714		if (shdr_cache(file, elf, ehdr, shstrndx, *shnum,
4715		    cache, *flags) == 0)
4716			return (0);
4717	}
4718
4719	return (1);
4720}
4721
4722int
4723regular(const char *file, int fd, Elf *elf, uint_t flags,
4724    const char *wname, int wfd, uchar_t osabi)
4725{
4726	enum { CACHE_NEEDED, CACHE_OK, CACHE_FAIL} cache_state = CACHE_NEEDED;
4727	Elf_Scn		*scn;
4728	Ehdr		*ehdr;
4729	size_t		ndx, shstrndx, shnum, phnum;
4730	Shdr		*shdr;
4731	Cache		*cache;
4732	VERSYM_STATE	versym;
4733	int		ret = 0;
4734	int		addr_align;
4735
4736	if ((ehdr = elf_getehdr(elf)) == NULL) {
4737		failure(file, MSG_ORIG(MSG_ELF_GETEHDR));
4738		return (ret);
4739	}
4740
4741	if (elf_getshdrnum(elf, &shnum) == -1) {
4742		failure(file, MSG_ORIG(MSG_ELF_GETSHDRNUM));
4743		return (ret);
4744	}
4745
4746	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
4747		failure(file, MSG_ORIG(MSG_ELF_GETSHDRSTRNDX));
4748		return (ret);
4749	}
4750
4751	if (elf_getphdrnum(elf, &phnum) == -1) {
4752		failure(file, MSG_ORIG(MSG_ELF_GETPHDRNUM));
4753		return (ret);
4754	}
4755	/*
4756	 * If the user requested section headers derived from the
4757	 * program headers (-P option) and this file doesn't have
4758	 * any program headers (i.e. ET_REL), then we can't do it.
4759	 */
4760	if ((phnum == 0) && (flags & FLG_CTL_FAKESHDR)) {
4761		(void) fprintf(stderr, MSG_INTL(MSG_ERR_PNEEDSPH), file);
4762		return (ret);
4763	}
4764
4765
4766	if ((scn = elf_getscn(elf, 0)) != NULL) {
4767		if ((shdr = elf_getshdr(scn)) == NULL) {
4768			failure(file, MSG_ORIG(MSG_ELF_GETSHDR));
4769			(void) fprintf(stderr, MSG_INTL(MSG_ELF_ERR_SCN), 0);
4770			return (ret);
4771		}
4772	} else
4773		shdr = NULL;
4774
4775	/*
4776	 * Print the elf header.
4777	 */
4778	if (flags & FLG_SHOW_EHDR)
4779		Elf_ehdr(0, ehdr, shdr);
4780
4781	/*
4782	 * If the section headers or program headers have inadequate
4783	 * alignment for the class of object, print a warning. libelf
4784	 * can handle such files, but programs that use them can crash
4785	 * when they dereference unaligned items.
4786	 *
4787	 * Note that the AMD64 ABI, although it is a 64-bit architecture,
4788	 * allows access to data types smaller than 128-bits to be on
4789	 * word alignment.
4790	 */
4791	if (ehdr->e_machine == EM_AMD64)
4792		addr_align = sizeof (Word);
4793	else
4794		addr_align = sizeof (Addr);
4795
4796	if (ehdr->e_phoff & (addr_align - 1))
4797		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADPHDRALIGN), file);
4798	if (ehdr->e_shoff & (addr_align - 1))
4799		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSHDRALIGN), file);
4800
4801
4802	/*
4803	 * Determine the Operating System ABI (osabi) we will use to
4804	 * interpret the object.
4805	 */
4806	if (flags & FLG_CTL_OSABI) {
4807		/*
4808		 * If the user explicitly specifies '-O none', we need
4809		 * to display a completely generic view of the file.
4810		 * However, libconv is written to assume that ELFOSABI_NONE
4811		 * is equivalent to ELFOSABI_SOLARIS. To get the desired
4812		 * effect, we use an osabi that libconv has no knowledge of.
4813		 */
4814		if (osabi == ELFOSABI_NONE)
4815			osabi = ELFOSABI_UNKNOWN4;
4816	} else {
4817		/* Determine osabi from file */
4818		osabi = ehdr->e_ident[EI_OSABI];
4819		if (osabi == ELFOSABI_NONE) {
4820			/*
4821			 * Chicken/Egg scenario:
4822			 *
4823			 * Ideally, we wait to create the section header cache
4824			 * until after the program headers are printed. If we
4825			 * only output program headers, we can skip building
4826			 * the cache entirely.
4827			 *
4828			 * Proper interpretation of program headers requires
4829			 * the osabi, which is supposed to be in the ELF header.
4830			 * However, many systems (Solaris and Linux included)
4831			 * have a history of setting the osabi to the generic
4832			 * SysV ABI (ELFOSABI_NONE). We assume ELFOSABI_SOLARIS
4833			 * in such cases, but would like to check the object
4834			 * to see if it has a Linux .note.ABI-tag section,
4835			 * which implies ELFOSABI_LINUX. This requires a
4836			 * section header cache.
4837			 *
4838			 * To break the cycle, we create section headers now
4839			 * if osabi is ELFOSABI_NONE, and later otherwise.
4840			 * If it succeeds, we use them, if not, we defer
4841			 * exiting until after the program headers are out.
4842			 */
4843			if (create_cache(file, fd, elf, ehdr, &cache,
4844			    shstrndx, &shnum, &flags) == 0) {
4845				cache_state = CACHE_FAIL;
4846			} else {
4847				cache_state = CACHE_OK;
4848				if (has_linux_abi_note(cache, shnum, file)) {
4849					Conv_inv_buf_t	ibuf1, ibuf2;
4850
4851					(void) fprintf(stderr,
4852					    MSG_INTL(MSG_INFO_LINUXOSABI), file,
4853					    conv_ehdr_osabi(osabi, 0, &ibuf1),
4854					    conv_ehdr_osabi(ELFOSABI_LINUX,
4855					    0, &ibuf2));
4856					osabi = ELFOSABI_LINUX;
4857				}
4858			}
4859		}
4860		/*
4861		 * We treat ELFOSABI_NONE identically to ELFOSABI_SOLARIS.
4862		 * Mapping NONE to SOLARIS simplifies the required test.
4863		 */
4864		if (osabi == ELFOSABI_NONE)
4865			osabi = ELFOSABI_SOLARIS;
4866	}
4867
4868	/*
4869	 * Print the program headers.
4870	 */
4871	if ((flags & FLG_SHOW_PHDR) && (phnum != 0)) {
4872		Phdr	*phdr;
4873
4874		if ((phdr = elf_getphdr(elf)) == NULL) {
4875			failure(file, MSG_ORIG(MSG_ELF_GETPHDR));
4876			return (ret);
4877		}
4878
4879		for (ndx = 0; ndx < phnum; phdr++, ndx++) {
4880			if (!match(MATCH_F_PHDR| MATCH_F_NDX | MATCH_F_TYPE,
4881			    NULL, ndx, phdr->p_type))
4882				continue;
4883
4884			dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
4885			dbg_print(0, MSG_INTL(MSG_ELF_PHDR), EC_WORD(ndx));
4886			Elf_phdr(0, osabi, ehdr->e_machine, phdr);
4887		}
4888	}
4889
4890	/*
4891	 * If we have flag bits set that explicitly require a show or calc
4892	 * operation, but none of them require the section headers, then
4893	 * we are done and can return now.
4894	 */
4895	if (((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) != 0) &&
4896	    ((flags & (FLG_MASK_SHOW_SHDR | FLG_MASK_CALC_SHDR)) == 0))
4897		return (ret);
4898
4899	/*
4900	 * Everything from this point on requires section headers.
4901	 * If we have no section headers, there is no reason to continue.
4902	 *
4903	 * If we tried above to create the section header cache and failed,
4904	 * it is time to exit. Otherwise, create it if needed.
4905	 */
4906	switch (cache_state) {
4907	case CACHE_NEEDED:
4908		if (create_cache(file, fd, elf, ehdr, &cache, shstrndx,
4909		    &shnum, &flags) == 0)
4910			return (ret);
4911		break;
4912	case CACHE_FAIL:
4913		return (ret);
4914	}
4915	if (shnum <= 1)
4916		goto done;
4917
4918	/*
4919	 * If -w was specified, find and write out the section(s) data.
4920	 */
4921	if (wfd) {
4922		for (ndx = 1; ndx < shnum; ndx++) {
4923			Cache	*_cache = &cache[ndx];
4924
4925			if (match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name,
4926			    ndx, _cache->c_shdr->sh_type) &&
4927			    _cache->c_data && _cache->c_data->d_buf) {
4928				if (write(wfd, _cache->c_data->d_buf,
4929				    _cache->c_data->d_size) !=
4930				    _cache->c_data->d_size) {
4931					int err = errno;
4932					(void) fprintf(stderr,
4933					    MSG_INTL(MSG_ERR_WRITE), wname,
4934					    strerror(err));
4935					/*
4936					 * Return an exit status of 1, because
4937					 * the failure is not related to the
4938					 * ELF file, but by system resources.
4939					 */
4940					ret = 1;
4941					goto done;
4942				}
4943			}
4944		}
4945	}
4946
4947	/*
4948	 * If we have no flag bits set that explicitly require a show or calc
4949	 * operation, but match options (-I, -N, -T) were used, then run
4950	 * through the section headers and see if we can't deduce show flags
4951	 * from the match options given.
4952	 *
4953	 * We don't do this if -w was specified, because (-I, -N, -T) used
4954	 * with -w in lieu of some other option is supposed to be quiet.
4955	 */
4956	if ((wfd == 0) && (flags & FLG_CTL_MATCH) &&
4957	    ((flags & (FLG_MASK_SHOW | FLG_MASK_CALC)) == 0)) {
4958		for (ndx = 1; ndx < shnum; ndx++) {
4959			Cache	*_cache = &cache[ndx];
4960
4961			if (!match(MATCH_F_STRICT | MATCH_F_ALL, _cache->c_name,
4962			    ndx, _cache->c_shdr->sh_type))
4963				continue;
4964
4965			switch (_cache->c_shdr->sh_type) {
4966			case SHT_PROGBITS:
4967				/*
4968				 * Heuristic time: It is usually bad form
4969				 * to assume the meaning/format of a PROGBITS
4970				 * section based on its name. However, there
4971				 * are ABI mandated exceptions. Check for
4972				 * these special names.
4973				 */
4974
4975				/* The ELF ABI specifies .interp and .got */
4976				if (strcmp(_cache->c_name,
4977				    MSG_ORIG(MSG_ELF_INTERP)) == 0) {
4978					flags |= FLG_SHOW_INTERP;
4979					break;
4980				}
4981				if (strcmp(_cache->c_name,
4982				    MSG_ORIG(MSG_ELF_GOT)) == 0) {
4983					flags |= FLG_SHOW_GOT;
4984					break;
4985				}
4986				/*
4987				 * The GNU compilers, and amd64 ABI, define
4988				 * .eh_frame and .eh_frame_hdr. The Sun
4989				 * C++ ABI defines .exception_ranges.
4990				 */
4991				if ((strncmp(_cache->c_name,
4992				    MSG_ORIG(MSG_SCN_FRM),
4993				    MSG_SCN_FRM_SIZE) == 0) ||
4994				    (strncmp(_cache->c_name,
4995				    MSG_ORIG(MSG_SCN_EXRANGE),
4996				    MSG_SCN_EXRANGE_SIZE) == 0)) {
4997					flags |= FLG_SHOW_UNWIND;
4998					break;
4999				}
5000				break;
5001
5002			case SHT_SYMTAB:
5003			case SHT_DYNSYM:
5004			case SHT_SUNW_LDYNSYM:
5005			case SHT_SUNW_versym:
5006			case SHT_SYMTAB_SHNDX:
5007				flags |= FLG_SHOW_SYMBOLS;
5008				break;
5009
5010			case SHT_RELA:
5011			case SHT_REL:
5012				flags |= FLG_SHOW_RELOC;
5013				break;
5014
5015			case SHT_HASH:
5016				flags |= FLG_SHOW_HASH;
5017				break;
5018
5019			case SHT_DYNAMIC:
5020				flags |= FLG_SHOW_DYNAMIC;
5021				break;
5022
5023			case SHT_NOTE:
5024				flags |= FLG_SHOW_NOTE;
5025				break;
5026
5027			case SHT_GROUP:
5028				flags |= FLG_SHOW_GROUP;
5029				break;
5030
5031			case SHT_SUNW_symsort:
5032			case SHT_SUNW_tlssort:
5033				flags |= FLG_SHOW_SORT;
5034				break;
5035
5036			case SHT_SUNW_cap:
5037				flags |= FLG_SHOW_CAP;
5038				break;
5039
5040			case SHT_SUNW_move:
5041				flags |= FLG_SHOW_MOVE;
5042				break;
5043
5044			case SHT_SUNW_syminfo:
5045				flags |= FLG_SHOW_SYMINFO;
5046				break;
5047
5048			case SHT_SUNW_verdef:
5049			case SHT_SUNW_verneed:
5050				flags |= FLG_SHOW_VERSIONS;
5051				break;
5052
5053			case SHT_AMD64_UNWIND:
5054				flags |= FLG_SHOW_UNWIND;
5055				break;
5056			}
5057		}
5058	}
5059
5060
5061	if (flags & FLG_SHOW_SHDR)
5062		sections(file, cache, shnum, ehdr, osabi);
5063
5064	if (flags & FLG_SHOW_INTERP)
5065		interp(file, cache, shnum, phnum, elf);
5066
5067	if ((osabi == ELFOSABI_SOLARIS) || (osabi == ELFOSABI_LINUX))
5068		versions(cache, shnum, file, flags, &versym);
5069
5070	if (flags & FLG_SHOW_SYMBOLS)
5071		symbols(cache, shnum, ehdr, osabi, &versym, file, flags);
5072
5073	if ((flags & FLG_SHOW_SORT) && (osabi == ELFOSABI_SOLARIS))
5074		sunw_sort(cache, shnum, ehdr, osabi, &versym, file, flags);
5075
5076	if (flags & FLG_SHOW_HASH)
5077		hash(cache, shnum, file, flags);
5078
5079	if (flags & FLG_SHOW_GOT)
5080		got(cache, shnum, ehdr, file);
5081
5082	if (flags & FLG_SHOW_GROUP)
5083		group(cache, shnum, file, flags);
5084
5085	if (flags & FLG_SHOW_SYMINFO)
5086		syminfo(cache, shnum, ehdr, osabi, file);
5087
5088	if (flags & FLG_SHOW_RELOC)
5089		reloc(cache, shnum, ehdr, file);
5090
5091	if (flags & FLG_SHOW_DYNAMIC)
5092		dynamic(cache, shnum, ehdr, osabi, file);
5093
5094	if (flags & FLG_SHOW_NOTE) {
5095		Word	note_cnt;
5096		size_t	note_shnum;
5097		Cache	*note_cache;
5098
5099		note_cnt = note(cache, shnum, ehdr, file);
5100
5101		/*
5102		 * Solaris core files have section headers, but these
5103		 * headers do not include SHT_NOTE sections that reference
5104		 * the core note sections. This means that note() won't
5105		 * find the core notes. Fake section headers (-P option)
5106		 * recover these sections, but it is inconvenient to require
5107		 * users to specify -P in this situation. If the following
5108		 * are all true:
5109		 *
5110		 *	- No note sections were found
5111		 *	- This is a core file
5112		 *	- We are not already using fake section headers
5113		 *
5114		 * then we will automatically generate fake section headers
5115		 * and then process them in a second call to note().
5116		 */
5117		if ((note_cnt == 0) && (ehdr->e_type == ET_CORE) &&
5118		    !(flags & FLG_CTL_FAKESHDR) &&
5119		    (fake_shdr_cache(file, fd, elf, ehdr,
5120		    &note_cache, &note_shnum) != 0)) {
5121			(void) note(note_cache, note_shnum, ehdr, file);
5122			fake_shdr_cache_free(note_cache, note_shnum);
5123		}
5124	}
5125
5126	if ((flags & FLG_SHOW_MOVE) && (osabi == ELFOSABI_SOLARIS))
5127		move(cache, shnum, file, flags);
5128
5129	if (flags & FLG_CALC_CHECKSUM)
5130		checksum(elf);
5131
5132	if ((flags & FLG_SHOW_CAP) && (osabi == ELFOSABI_SOLARIS))
5133		cap(file, cache, shnum, phnum, ehdr, osabi, elf, flags);
5134
5135	if ((flags & FLG_SHOW_UNWIND) &&
5136	    ((osabi == ELFOSABI_SOLARIS) || (osabi == ELFOSABI_LINUX)))
5137		unwind(cache, shnum, phnum, ehdr, osabi, file, elf, flags);
5138
5139
5140	/* Release the memory used to cache section headers */
5141done:
5142	if (flags & FLG_CTL_FAKESHDR)
5143		fake_shdr_cache_free(cache, shnum);
5144	else
5145		free(cache);
5146
5147	return (ret);
5148}
5149