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