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