elfdump.c revision 9273:9a0603d78ad3
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 */
101typedef 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 */
114typedef 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 */
140static const char *
141string(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 */
214static const char *
215relsymname(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 */
252static int
253stringtbl(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 */
316static int
317symlookup(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 */
373static void
374sections(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 */
417static Phdr *
418getphdr(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
437static void
438unwind(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 */
630static void
631cap(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 */
745static void
746interp(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 */
822static void
823syminfo(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 */
910static void
911version_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 */
994static void
995version_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 */
1089static void
1090update_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 */
1140static void
1141versions(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 */
1289static int
1290init_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 */
1352static void
1353symbols_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 */
1393static void
1394output_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 */
1632void
1633symbols(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 */
1675static void
1676sunw_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 */
1812static void
1813reloc(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 */
1945typedef 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 */
1962static void
1963dyn_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 */
2077static void
2078dyn_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 */
2114static void
2115dynamic(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 */
2612static void
2613move(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 */
2726typedef 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 */
2756static int
2757parse_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*/
2848static void
2849c_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 */
2859void
2860note_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 */
2979static Word
2980note(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 */
3034static int
3035has_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 */
3095static void
3096hash_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
3140static void
3141hash(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
3280static void
3281group(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
3362static void
3363got(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
3585void
3586checksum(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 */
3598static 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 */
3613static int
3614sort_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
3629static int
3630shdr_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 */
3944static int
3945create_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
3971int
3972regular(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 */
4379done:
4380	if (flags & FLG_CTL_FAKESHDR)
4381		fake_shdr_cache_free(cache, shnum);
4382	else
4383		free(cache);
4384
4385	return (ret);
4386}
4387