changeset 4168:7a68e9a5dc29

PSARC 2007/247 Add -I option to elfdump 6246083 elfdump should allow section index specification (numeric -N equivalent)
author ab196087
date Fri, 04 May 2007 09:22:04 -0700
parents c12aee7caf8a
children b5f65de76d0c
files usr/src/cmd/sgs/elfdump/common/_elfdump.h usr/src/cmd/sgs/elfdump/common/elfdump.c usr/src/cmd/sgs/elfdump/common/elfdump.msg usr/src/cmd/sgs/elfdump/common/lintsup.c usr/src/cmd/sgs/elfdump/common/main.c usr/src/cmd/sgs/packages/common/SUNWonld-README
diffstat 6 files changed, 266 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/elfdump/common/_elfdump.h	Fri May 04 00:56:46 2007 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/_elfdump.h	Fri May 04 09:22:04 2007 -0700
@@ -82,6 +82,7 @@
 
 extern	void		failure(const char *, const char *);
 extern	const char	*demangle(const char *, uint_t);
+extern int		match(int, const char *, int);
 
 /*
  * Define various elfdump() functions into their 32-bit and 64-bit variants.
@@ -132,8 +133,8 @@
 #define	version_need		version_need32
 #endif
 
-extern	void	regular32(const char *, Elf *, uint_t, char *, int);
-extern	void	regular64(const char *, Elf *, uint_t, char *, int);
+extern	void	regular32(const char *, Elf *, uint_t, int);
+extern	void	regular64(const char *, Elf *, uint_t, int);
 
 #ifdef	__cplusplus
 }
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.c	Fri May 04 00:56:46 2007 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c	Fri May 04 09:22:04 2007 -0700
@@ -323,8 +323,7 @@
  * Print section headers.
  */
 static void
-sections(const char *file, Cache *cache, Word shnum, Ehdr *ehdr,
-    const char *name)
+sections(const char *file, Cache *cache, Word shnum, Ehdr *ehdr)
 {
 	size_t	seccnt;
 
@@ -342,7 +341,7 @@
 			    file, secname, EC_WORD(shdr->sh_type));
 		}
 
-		if (name && strcmp(name, secname))
+		if (!match(0, secname, seccnt))
 			continue;
 
 		/*
@@ -417,8 +416,8 @@
 }
 
 static void
-unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *name,
-    const char *file, Elf *elf)
+unwind(Cache *cache, Word shnum, Word phnum, Ehdr *ehdr, const char *file,
+    Elf *elf)
 {
 	Word	cnt;
 	Phdr	*uphdr = 0;
@@ -451,7 +450,8 @@
 		    (strncmp(_cache->c_name, MSG_ORIG(MSG_SCN_FRMHDR),
 		    MSG_SCN_FRMHDR_SIZE) != 0))
 			continue;
-		if (name && strcmp(name, _cache->c_name))
+
+		if (!match(0, _cache->c_name, cnt))
 			continue;
 
 		if (_cache->c_data == NULL)
@@ -1442,8 +1442,8 @@
  * Search for and process any symbol tables.
  */
 void
-symbols(Cache *cache, Word shnum, Ehdr *ehdr, const char *name,
-    VERSYM_STATE *versym, const char *file, uint_t flags)
+symbols(Cache *cache, Word shnum, Ehdr *ehdr, VERSYM_STATE *versym,
+    const char *file, uint_t flags)
 {
 	SYMTBL_STATE state;
 	Cache *_cache;
@@ -1460,7 +1460,7 @@
 		    (shdr->sh_type != SHT_DYNSYM) &&
 		    (shdr->sh_type != SHT_SUNW_LDYNSYM))
 			continue;
-		if (name && strcmp(name, _cache->c_name))
+		if (!match(0, _cache->c_name, secndx))
 			continue;
 
 		if (!init_symtbl_state(&state, cache, shnum, secndx, ehdr,
@@ -1484,8 +1484,8 @@
  * These sections are always associated with the .SUNW_ldynsym./.dynsym pair.
  */
 static void
-sunw_sort(Cache *cache, Word shnum, Ehdr *ehdr, const char *name,
-    VERSYM_STATE *versym, const char *file, uint_t flags)
+sunw_sort(Cache *cache, Word shnum, Ehdr *ehdr, VERSYM_STATE *versym,
+    const char *file, uint_t flags)
 {
 	SYMTBL_STATE	ldynsym_state,	dynsym_state;
 	Cache		*sortcache,	*symcache;
@@ -1504,7 +1504,7 @@
 		if ((sortshdr->sh_type != SHT_SUNW_symsort) &&
 		    (sortshdr->sh_type != SHT_SUNW_tlssort))
 			continue;
-		if (name && strcmp(name, sortcache->c_name))
+		if (!match(0, sortcache->c_name, sortsecndx))
 			continue;
 
 		/*
@@ -1617,7 +1617,7 @@
  * Search for and process any relocation sections.
  */
 static void
-reloc(Cache *cache, Word shnum, Ehdr *ehdr, const char *name, const char *file,
+reloc(Cache *cache, Word shnum, Ehdr *ehdr, const char *file,
     uint_t flags)
 {
 	Word	cnt;
@@ -1635,7 +1635,7 @@
 		if (((type = shdr->sh_type) != SHT_RELA) &&
 		    (type != SHT_REL))
 			continue;
-		if (name && strcmp(name, relname))
+		if (!match(0, relname, cnt))
 			continue;
 
 		/*
@@ -1857,7 +1857,7 @@
  * Search for and process a MOVE section.
  */
 static void
-move(Cache *cache, Word shnum, const char *name, const char *file, uint_t flags)
+move(Cache *cache, Word shnum, const char *file, uint_t flags)
 {
 	Word		cnt;
 	const char	*fmt = 0;
@@ -1872,7 +1872,7 @@
 
 		if (shdr->sh_type != SHT_SUNW_move)
 			continue;
-		if (name && strcmp(name, _cache->c_name))
+		if (!match(0, _cache->c_name, cnt))
 			continue;
 
 		/*
@@ -2113,7 +2113,7 @@
  * Search for and process a .note section.
  */
 static void
-note(Cache *cache, Word shnum, const char *name, const char *file)
+note(Cache *cache, Word shnum, const char *file)
 {
 	Word	cnt;
 
@@ -2126,7 +2126,7 @@
 
 		if (shdr->sh_type != SHT_NOTE)
 			continue;
-		if (name && strcmp(name, _cache->c_name))
+		if (!match(0, _cache->c_name, cnt))
 			continue;
 
 		/*
@@ -2199,7 +2199,7 @@
 #define	MAXCOUNT	500
 
 static void
-hash(Cache *cache, Word shnum, const char *name, const char *file, uint_t flags)
+hash(Cache *cache, Word shnum, const char *file, uint_t flags)
 {
 	static int	count[MAXCOUNT];
 	Word		cnt;
@@ -2216,8 +2216,6 @@
 
 		if (hshdr->sh_type != SHT_HASH)
 			continue;
-		if (name && strcmp(name, hsecname))
-			continue;
 
 		/*
 		 * Determine the hash table data and size.
@@ -2341,8 +2339,7 @@
 }
 
 static void
-group(Cache *cache, Word shnum, const char *name, const char *file,
-    uint_t flags)
+group(Cache *cache, Word shnum, const char *file, uint_t flags)
 {
 	Word	scnt;
 
@@ -2356,7 +2353,7 @@
 
 		if (shdr->sh_type != SHT_GROUP)
 			continue;
-		if (name && strcmp(name, _cache->c_name))
+		if (!match(0, _cache->c_name, scnt))
 			continue;
 		if ((_cache->c_data == NULL) ||
 		    ((grpdata = (Word *)_cache->c_data->d_buf) == NULL))
@@ -2650,7 +2647,7 @@
 }
 
 void
-regular(const char *file, Elf *elf, uint_t flags, char *Nname, int wfd)
+regular(const char *file, Elf *elf, uint_t flags, int wfd)
 {
 	Elf_Scn		*scn;
 	Ehdr		*ehdr;
@@ -2719,10 +2716,8 @@
 		}
 
 		for (cnt = 0; cnt < phnum; phdr++, cnt++) {
-
-			if (Nname &&
-			    (strcmp(Nname, conv_phdr_type(ehdr->e_machine,
-			    phdr->p_type, CONV_FMT_ALTFILE)) != 0))
+			if (!match(0, conv_phdr_type(ehdr->e_machine,
+			    phdr->p_type, CONV_FMT_ALTFILE), cnt))
 				continue;
 
 			dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
@@ -2733,12 +2728,12 @@
 
 	/*
 	 * Return now if there are no section, if there's just one section to
-	 * act as an extension of the ELF header, or if on section information
-	 * was requested.
+	 * act as an extension of the ELF header, or if only program header
+	 * information was requested.
 	 */
 	if ((shnum <= 1) || (flags && (flags & ~(FLG_EHDR | FLG_PHDR)) == 0)) {
 		if ((ehdr->e_type == ET_CORE) && (flags & FLG_NOTE))
-			note(0, shnum, 0, file);
+			note(0, shnum, file);
 		return;
 	}
 
@@ -2940,15 +2935,14 @@
 		/*
 		 * Do we wish to write the section out?
 		 */
-		if (wfd && Nname && (strcmp(Nname, _cache->c_name) == 0) &&
-		    _cache->c_data) {
+		if (wfd && match(1, _cache->c_name, cnt) && _cache->c_data) {
 			(void) write(wfd, _cache->c_data->d_buf,
 			    _cache->c_data->d_size);
 		}
 	}
 
 	if (flags & FLG_SHDR)
-		sections(file, cache, shnum, ehdr, Nname);
+		sections(file, cache, shnum, ehdr);
 
 	if (flags & FLG_INTERP)
 		interp(file, cache, shnum, phnum, elf);
@@ -2956,34 +2950,34 @@
 	versions(cache, shnum, file, flags, &versym);
 
 	if (flags & FLG_SYMBOLS)
-		symbols(cache, shnum, ehdr, Nname, &versym, file, flags);
+		symbols(cache, shnum, ehdr, &versym, file, flags);
 
 	if (flags & FLG_SORT)
-		sunw_sort(cache, shnum, ehdr, Nname, &versym, file, flags);
+		sunw_sort(cache, shnum, ehdr, &versym, file, flags);
 
 	if (flags & FLG_HASH)
-		hash(cache, shnum, Nname, file, flags);
+		hash(cache, shnum, file, flags);
 
 	if (flags & FLG_GOT)
 		got(cache, shnum, ehdr, file, flags);
 
 	if (flags & FLG_GROUP)
-		group(cache, shnum, Nname, file, flags);
+		group(cache, shnum, file, flags);
 
 	if (flags & FLG_SYMINFO)
 		syminfo(cache, shnum, file);
 
 	if (flags & FLG_RELOC)
-		reloc(cache, shnum, ehdr, Nname, file, flags);
+		reloc(cache, shnum, ehdr, file, flags);
 
 	if (flags & FLG_DYNAMIC)
 		dynamic(cache, shnum, ehdr, file);
 
 	if (flags & FLG_NOTE)
-		note(cache, shnum, Nname, file);
+		note(cache, shnum, file);
 
 	if (flags & FLG_MOVE)
-		move(cache, shnum, Nname, file, flags);
+		move(cache, shnum, file, flags);
 
 	if (flags & FLG_CHECKSUM)
 		checksum(elf);
@@ -2992,7 +2986,7 @@
 		cap(file, cache, shnum, phnum, ehdr, elf);
 
 	if (flags & FLG_UNWIND)
-		unwind(cache, shnum, phnum, ehdr, Nname, file, elf);
+		unwind(cache, shnum, phnum, ehdr, file, elf);
 
 	free(cache);
 }
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg	Fri May 04 00:56:46 2007 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg	Fri May 04 09:22:04 2007 -0700
@@ -34,8 +34,8 @@
 
 # Usage Messages
 
-@ MSG_USAGE_BRIEF	"usage: %s [-cCdegGhHiklmnprSsuvy] [-N name] \
-			 [-w file] file(s)\n"
+@ MSG_USAGE_BRIEF	"usage: %s [-cCdegGhHiklmnprSsuvy] [-I index] \
+			 [-N name] [-w file] file(s)\n"
 @ MSG_USAGE_DETAIL1	"\t[-c]\t\tdump section header information\n"
 @ MSG_USAGE_DETAIL2	"\t[-C]\t\tdemangle C++ symbol names\n"
 @ MSG_USAGE_DETAIL3	"\t[-d]\t\tdump the contents of the .dynamic section\n"
@@ -46,25 +46,26 @@
 @ MSG_USAGE_DETAIL8	"\t[-H]\t\tdump the contents of the .SUNW_hwcap \
 			 section\n"
 @ MSG_USAGE_DETAIL9	"\t[-i]\t\tdump the contents of the .interp section\n"
-@ MSG_USAGE_DETAIL9_1	"\t[-l]\t\tdump with no truncated section names\n"
-@ MSG_USAGE_DETAIL10	"\t[-k]\t\tcalculate elf checksum\n"
-@ MSG_USAGE_DETAIL11	"\t[-m]\t\tdump the contents of the .SUNW_move \
+@ MSG_USAGE_DETAIL10	"\t[-I index]\tqualify an option with an index\n"
+@ MSG_USAGE_DETAIL11	"\t[-l]\t\tdump with no truncated section names\n"
+@ MSG_USAGE_DETAIL12	"\t[-k]\t\tcalculate elf checksum\n"
+@ MSG_USAGE_DETAIL13	"\t[-m]\t\tdump the contents of the .SUNW_move \
 			 section\n"
-@ MSG_USAGE_DETAIL12	"\t[-n]\t\tdump the contents of the .note section\n"
-@ MSG_USAGE_DETAIL13	"\t[-N name]\tqualify an option with a `name'\n"
-@ MSG_USAGE_DETAIL14	"\t[-p]\t\tdump the program headers\n"
-@ MSG_USAGE_DETAIL15	"\t[-r]\t\tdump the contents of the relocation \
+@ MSG_USAGE_DETAIL14	"\t[-n]\t\tdump the contents of the .note section\n"
+@ MSG_USAGE_DETAIL15	"\t[-N name]\tqualify an option with a `name'\n"
+@ MSG_USAGE_DETAIL16	"\t[-p]\t\tdump the program headers\n"
+@ MSG_USAGE_DETAIL17	"\t[-r]\t\tdump the contents of the relocation \
 			 sections\n"
-@ MSG_USAGE_DETAIL16	"\t[-S]\t\tdump the contents of the sort index \
+@ MSG_USAGE_DETAIL18	"\t[-S]\t\tdump the contents of the sort index \
 			 sections\n"
-@ MSG_USAGE_DETAIL17	"\t[-s]\t\tdump the contents of the symbol table \
+@ MSG_USAGE_DETAIL19	"\t[-s]\t\tdump the contents of the symbol table \
 			 sections\n"
-@ MSG_USAGE_DETAIL18	"\t[-u]\t\tdump the contents of a frame unwind \
+@ MSG_USAGE_DETAIL20	"\t[-u]\t\tdump the contents of a frame unwind \
 			 section\n"
-@ MSG_USAGE_DETAIL19	"\t[-v]\t\tdump the contents of the version sections\n"
-@ MSG_USAGE_DETAIL20	"\t[-w file]\twrite the contents of specified section \
+@ MSG_USAGE_DETAIL21	"\t[-v]\t\tdump the contents of the version sections\n"
+@ MSG_USAGE_DETAIL22	"\t[-w file]\twrite the contents of specified section \
 			 to `file'\n"
-@ MSG_USAGE_DETAIL21	"\t[-y]\t\tdump the contents of the .SUNW_syminfo \
+@ MSG_USAGE_DETAIL23	"\t[-y]\t\tdump the contents of the .SUNW_syminfo \
 			 section\n"
 
 # Errors
@@ -244,7 +245,7 @@
 
 @ MSG_GOT_SYM		"_GLOBAL_OFFSET_TABLE_"
 
-@ MSG_STR_OPTIONS	"CcdeGgHhiklmN:nprSsuvw:y"
+@ MSG_STR_OPTIONS	"CcdeGgHhiI:klmN:nprSsuvw:y"
 
 @ MSG_STR_EMPTY		""
 
--- a/usr/src/cmd/sgs/elfdump/common/lintsup.c	Fri May 04 00:56:46 2007 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/lintsup.c	Fri May 04 09:22:04 2007 -0700
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 /* LINTLIBRARY */
@@ -45,14 +45,14 @@
 
 #if	defined(_ELF64)
 void
-regular32(const char *file, Elf *elf, uint32_t flags, char *Nname, int wfd)
+regular32(const char *file, Elf *elf, uint32_t flags, int wfd)
 {
-	regular64(file, elf, flags, Nname, wfd);
+	regular64(file, elf, flags, wfd);
 }
 #else
 void
-regular64(const char *file, Elf *elf, uint32_t flags, char *Nname, int wfd)
+regular64(const char *file, Elf *elf, uint32_t flags, int wfd)
 {
-	regular32(file, elf, flags, Nname, wfd);
+	regular32(file, elf, flags, wfd);
 }
 #endif
--- a/usr/src/cmd/sgs/elfdump/common/main.c	Fri May 04 00:56:46 2007 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/main.c	Fri May 04 09:22:04 2007 -0700
@@ -31,6 +31,8 @@
 #include	<sys/param.h>
 #include	<fcntl.h>
 #include	<stdio.h>
+#include	<stdlib.h>
+#include	<ctype.h>
 #include	<libelf.h>
 #include	<link.h>
 #include	<stdarg.h>
@@ -47,6 +49,30 @@
 
 const Cache	cache_init = {NULL, NULL, NULL, NULL, 0};
 
+
+
+/* MATCH is  used to retain information about -N and -I options */
+typedef enum {
+	MATCH_T_NAME,		/* Record contains a name */
+	MATCH_T_NDX,		/* Record contains a single index */
+	MATCH_T_RANGE		/* Record contains an index range */
+} MATCH_T;
+
+typedef struct _match {
+	struct _match	*next;		/* Pointer to next item in list */
+	MATCH_T		type;
+	union {
+		const char	*name;	/* MATCH_T_NAME */
+		struct {		/* MATCH_T_NDX and MATCH_T_RANGE */
+			int	start;
+			int	end;	/* Only for MATCH_T_RANGE */
+		} ndx;
+	} value;
+} MATCH;
+
+/* List of MATCH records used by match() to implement -N and -I options */
+static MATCH *match_list = NULL;
+
 const char *
 _elfdump_msg(Msg mid)
 {
@@ -90,7 +116,6 @@
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL7));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL8));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL9));
-	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL9_1));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL10));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL11));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL12));
@@ -103,20 +128,165 @@
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL19));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL20));
 	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL21));
+	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL22));
+	(void) fprintf(stderr, MSG_INTL(MSG_USAGE_DETAIL23));
+}
+
+/*
+ * Convert the ASCII representation of an index, or index range, into
+ * binary form, and store it in rec:
+ *
+ *	index: An positive or 0 valued integer
+ *	range: Two indexes, separated by a ':' character, denoting
+ *		a range of allowed values. If the second value is omitted,
+ *		any values equal to or greater than the first will match.
+ *
+ * exit:
+ *	On success, *rec is filled in with a MATCH_T_NDX or MATCH_T_RANGE
+ *	value, and this function returns (1). On failure, the contents
+ *	of *rec are undefined, and (0) is returned.
+ */
+int
+process_index_opt(const char *str, MATCH *rec)
+{
+#define	SKIP_BLANK for (; *str && isspace(*str); str++)
+
+	char	*endptr;
+
+	rec->value.ndx.start = strtol(str, &endptr, 10);
+	/* Value must use some of the input, and be 0 or positive */
+	if ((str == endptr) || (rec->value.ndx.start < 0))
+		return (0);
+	str = endptr;
+
+	SKIP_BLANK;
+	if (*str != ':') {
+		rec->type = MATCH_T_NDX;
+	} else {
+		str++;					/* Skip the ':' */
+		rec->type = MATCH_T_RANGE;
+		SKIP_BLANK;
+		if (*str == '\0') {
+			rec->value.ndx.end = -1;	/* Indicates "to end" */
+		} else {
+			rec->value.ndx.end = strtol(str, &endptr, 10);
+			if ((str == endptr) || (rec->value.ndx.end < 0))
+				return (0);
+			str = endptr;
+			SKIP_BLANK;
+		}
+	}
+
+	/* Syntax error if anything is left over */
+	if (*str != '\0')
+		return (0);
+
+	return (1);
+
+#undef	SKIP_BLANK
+}
+
+/*
+ * Returns True (1) if the item with the given name or index should
+ * be displayed, and False (0) if it should not be.
+ *
+ * entry:
+ *	strict - A strict match requires an explicit match to
+ *		a user specified -I or -N option. A non-strict match
+ *		succeeds if the match list is empty.
+ *	name - Name of item under consideration, or NULL if the name
+ *		should not be considered.
+ *	ndx - if (ndx >= 0) index of item under consideration.
+ *		A negative value indicates that the item has no index.
+ *
+ * exit:
+ *	True will be returned if the given name/index matches those given
+ *	by one of the -N or -I command line options, or if no such option
+ *	was used in the command invocation.
+ */
+int
+match(int strict, const char *name, int ndx)
+{
+	MATCH *list;
+
+	/* If no match options were specified, allow everything */
+	if (!strict && (match_list == NULL))
+		return (1);
+
+	/* Run through the match records and check for a hit */
+	for (list = match_list; list; list = list->next) {
+		switch (list->type) {
+		case MATCH_T_NAME:
+			if ((name != NULL) &&
+			    (strcmp(list->value.name, name) == 0))
+				return (1);
+			break;
+		case MATCH_T_NDX:
+			if (ndx == list->value.ndx.start)
+				return (1);
+			break;
+		case MATCH_T_RANGE:
+			/*
+			 * A range end value less than 0 means that any value
+			 * above the start is acceptible.
+			 */
+			if ((ndx >= list->value.ndx.start) &&
+			    ((list->value.ndx.end < 0) ||
+			    (ndx <= list->value.ndx.end)))
+				return (1);
+			break;
+		}
+	}
+
+	/* Nothing matched */
+	return (0);
+}
+
+/*
+ * Add an entry to match_list for use by match().
+ *
+ * Return True (1) for success. On failure, an error is written
+ * to stderr, and False (0) is returned.
+ */
+static int
+add_match_record(char *argv0, MATCH *data)
+{
+	MATCH *rec;
+	MATCH *list;
+
+	if ((rec = malloc(sizeof (*rec))) == NULL) {
+		int err = errno;
+		(void) fprintf(stderr, MSG_INTL(MSG_ERR_MALLOC),
+		    basename(argv0), strerror(err));
+		return (0);
+	}
+
+	*rec = *data;
+
+	/* Insert at end of match_list */
+	if (match_list == NULL) {
+		match_list = rec;
+	} else {
+		for (list = match_list; list->next != NULL; list = list->next)
+			;
+		list->next = rec;
+	}
+
+	rec->next = NULL;
+	return (1);
 }
 
 static void
-decide(const char *file, Elf *elf, uint_t flags, char *Nname, int wfd)
+decide(const char *file, Elf *elf, uint_t flags, int wfd)
 {
 	if (gelf_getclass(elf) == ELFCLASS64)
-		regular64(file, elf, flags, Nname, wfd);
+		regular64(file, elf, flags, wfd);
 	else
-		regular32(file, elf, flags, Nname, wfd);
+		regular32(file, elf, flags, wfd);
 }
 
 static void
-archive(const char *file, int fd, Elf *elf, uint_t flags, char *Nname,
-    int wfd)
+archive(const char *file, int fd, Elf *elf, uint_t flags, int wfd)
 {
 	Elf_Cmd		cmd = ELF_C_READ;
 	Elf_Arhdr	*arhdr;
@@ -127,8 +297,7 @@
 	/*
 	 * Determine if the archive symbol table itself is required.
 	 */
-	if ((flags & FLG_SYMBOLS) && ((Nname == NULL) ||
-	    (strcmp(Nname, MSG_ORIG(MSG_ELF_ARSYM)) == 0))) {
+	if ((flags & FLG_SYMBOLS) && match(0, MSG_ORIG(MSG_ELF_ARSYM), -1)) {
 		/*
 		 * Get the archive symbol table.
 		 */
@@ -211,8 +380,8 @@
 		/*
 		 * If we only need the archive symbol table return.
 		 */
-		if ((flags & FLG_SYMBOLS) && Nname &&
-		    (strcmp(Nname, MSG_ORIG(MSG_ELF_ARSYM)) == 0))
+		if ((flags & FLG_SYMBOLS) &&
+		    match(1, MSG_ORIG(MSG_ELF_ARSYM), -1))
 			return;
 
 		/*
@@ -240,10 +409,10 @@
 
 			switch (elf_kind(_elf)) {
 			case ELF_K_AR:
-				archive(name, fd, _elf, flags, Nname, wfd);
+				archive(name, fd, _elf, flags, wfd);
 				break;
 			case ELF_K_ELF:
-				decide(name, _elf, flags, Nname, wfd);
+				decide(name, _elf, flags, wfd);
 				break;
 			default:
 				(void) fprintf(stderr,
@@ -262,8 +431,9 @@
 {
 	Elf		*elf;
 	int		var, fd, wfd = 0;
-	char		*Nname = NULL, *wname = 0;
+	char		*wname = 0;
 	uint_t		flags = 0;
+	MATCH		match_data;
 
 	/*
 	 * If we're on a 64-bit kernel, try to exec a full 64-bit version of
@@ -307,6 +477,16 @@
 		case 'h':
 			flags |= FLG_HASH;
 			break;
+		case 'I':
+			if (!process_index_opt(optarg, &match_data)) {
+				(void) fprintf(stderr,
+				    MSG_INTL(MSG_USAGE_BRIEF),
+				    basename(argv[0]));
+				return (1);
+			}
+			if (!add_match_record(argv[0], &match_data))
+				return (1);
+			break;
 		case 'i':
 			flags |= FLG_INTERP;
 			break;
@@ -320,7 +500,10 @@
 			flags |= FLG_MOVE;
 			break;
 		case 'N':
-			Nname = optarg;
+			match_data.type = MATCH_T_NAME;
+			match_data.value.name = optarg;
+			if (!add_match_record(argv[0], &match_data))
+				return (1);
 			break;
 		case 'n':
 			flags |= FLG_NOTE;
@@ -363,9 +546,9 @@
 	 * Validate any arguments.
 	 */
 	if ((flags & ~(FLG_DEMANGLE | FLG_LONGNAME)) == 0) {
-		if (!wname && !Nname) {
+		if (!wname && (match_list == NULL)) {
 			flags |= FLG_EVERYTHING;
-		} else if (!wname || !Nname) {
+		} else if (!wname || (match_list == NULL)) {
 			(void) fprintf(stderr, MSG_INTL(MSG_USAGE_BRIEF),
 			    basename(argv[0]));
 			return (1);
@@ -425,10 +608,10 @@
 
 		switch (elf_kind(elf)) {
 		case ELF_K_AR:
-			archive(file, fd, elf, flags, Nname, wfd);
+			archive(file, fd, elf, flags, wfd);
 			break;
 		case ELF_K_ELF:
-			decide(file, elf, flags, Nname, wfd);
+			decide(file, elf, flags, wfd);
 			break;
 		default:
 			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADFILE), file);
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Fri May 04 00:56:46 2007 -0700
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Fri May 04 09:22:04 2007 -0700
@@ -1232,3 +1232,6 @@
 6341667 elfdump should check alignments of ELF header elements
 6387860 elfdump cores, when processing linux built ELF file
 6198202 mcs -d dumps core
+6246083 elfdump should allow section index specification
+	(numeric -N equivalent) (D)
+	PSARC/2007/247 Add -I option to elfdump