changeset 9900:1b86d65a4f9e

6851224 elf_getshnum() and elf_getshstrndx() incompatible with 2002 ELF gABI agreement PSARC/2009/363 replace elf_getphnum, elf_getshnum, and elf_getshstrndx
author Ali Bahrami <Ali.Bahrami@Sun.COM>
date Thu, 18 Jun 2009 13:16:39 -0600
parents 1e97d6212720
children 6a754d578423
files usr/src/cmd/dis/dis_target.c usr/src/cmd/mdb/common/mdb/mdb_gelf.c usr/src/cmd/mdb/common/mdb/mdb_target.c usr/src/cmd/sgs/dump/common/dump.c usr/src/cmd/sgs/elfdump/common/elfdump.c usr/src/cmd/sgs/elfdump/common/elfdump.msg usr/src/cmd/sgs/elfdump/common/fake_shdr.c usr/src/cmd/sgs/elfedit/common/elfedit.msg usr/src/cmd/sgs/elfedit/common/elfedit_machelf.c usr/src/cmd/sgs/libelf/common/gelf.c usr/src/cmd/sgs/libelf/common/getphnum.c usr/src/cmd/sgs/libelf/common/getshnum.c usr/src/cmd/sgs/libelf/common/getshstrndx.c usr/src/cmd/sgs/libelf/common/mapfile-common usr/src/cmd/sgs/libelf/demo/acom.c usr/src/cmd/sgs/libelf/demo/dcom.c usr/src/cmd/sgs/libelf/demo/dispsyms.c usr/src/cmd/sgs/libelf/demo/pcom.c usr/src/cmd/sgs/libelf/demo/tpcom.c usr/src/cmd/sgs/libld/common/globals.c usr/src/cmd/sgs/mcs/common/file.c usr/src/cmd/sgs/nm/common/nm.c usr/src/cmd/sgs/packages/common/SUNWonld-README usr/src/head/libelf.h usr/src/lib/libdtrace/common/dt_module.c usr/src/lib/libelfsign/common/elfsignlib.c usr/src/lib/libproc/common/Pcore.c usr/src/lib/libproc/common/Pidle.c usr/src/lib/libproc/common/Psymtab.c usr/src/uts/common/sys/elf.h
diffstat 30 files changed, 288 insertions(+), 255 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/dis/dis_target.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/dis/dis_target.c	Thu Jun 18 13:16:39 2009 -0600
@@ -20,12 +20,10 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -390,7 +388,7 @@
 		current->dt_elf = elf;
 		current->dt_arhdr = arhdr;
 
-		if (elf_getshstrndx(elf, &current->dt_shstrndx) == -1) {
+		if (elf_getshdrstrndx(elf, &current->dt_shstrndx) == -1) {
 			warn("%s: failed to get section string table for "
 			    "file", file);
 			dis_tgt_destroy(tgt);
--- a/usr/src/cmd/mdb/common/mdb/mdb_gelf.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/mdb/common/mdb/mdb_gelf.c	Thu Jun 18 13:16:39 2009 -0600
@@ -927,7 +927,7 @@
 static void
 gelf32_symtab_init(mdb_gelf_symtab_t *gst)
 {
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. update gelf32_symtab_init()"
 #endif
 
@@ -954,7 +954,7 @@
 		const char *name = base + sym->st_name;
 		uchar_t type = ELF32_ST_TYPE(sym->st_info);
 
-		if (type >= STT_IFUNC || type == STT_SECTION)
+		if (type >= STT_NUM || type == STT_SECTION)
 			continue; /* skip sections and unknown types */
 
 		if (sym->st_name >= ss_size || name[0] < '!' || name[0] > '~') {
@@ -1024,7 +1024,7 @@
 static void
 gelf64_symtab_init(mdb_gelf_symtab_t *gst)
 {
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. update gelf64_symtab_init()"
 #endif
 
@@ -1051,7 +1051,7 @@
 		const char *name = base + sym->st_name;
 		uchar_t type = ELF64_ST_TYPE(sym->st_info);
 
-		if (type >= STT_IFUNC || type == STT_SECTION)
+		if (type >= STT_NUM || type == STT_SECTION)
 			continue; /* skip sections and unknown types */
 
 		if (sym->st_name >= ss_size || name[0] < '!' || name[0] > '~') {
--- a/usr/src/cmd/mdb/common/mdb/mdb_target.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/mdb/common/mdb/mdb_target.c	Thu Jun 18 13:16:39 2009 -0600
@@ -1902,7 +1902,7 @@
 int
 mdb_tgt_sym_match(const GElf_Sym *sym, uint_t mask)
 {
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. update mdb_tgt_sym_match()"
 #endif
 
@@ -1916,7 +1916,7 @@
 	 * in <sys/elf.h>.  Changes to ELF must maintain binary
 	 * compatibility, so I think this is reasonably fair game.
 	 */
-	if (s_bind < STB_NUM && s_type < STT_IFUNC) {
+	if (s_bind < STB_NUM && s_type < STT_NUM) {
 		uint_t type = (1 << (s_type + 8)) | (1 << s_bind);
 		return ((type & ~mask) == 0);
 	}
--- a/usr/src/cmd/sgs/dump/common/dump.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/dump/common/dump.c	Thu Jun 18 13:16:39 2009 -0600
@@ -789,9 +789,9 @@
 
 	head_scns = p_head_scns;
 
-	if (elf_getshnum(elf_file, &shnum) == 0) {
+	if (elf_getshdrnum(elf_file, &shnum) == -1) {
 		(void) fprintf(stderr,
-		    "%s: %s: elf_getshnum failed: %s\n",
+		    "%s: %s: elf_getshdrnum failed: %s\n",
 		    prog_name, filename, elf_errmsg(-1));
 		return;
 	}
@@ -1658,15 +1658,15 @@
 	size_t		shnum;
 
 
-	if (elf_getshnum(elf_file, &shnum) == 0) {
+	if (elf_getshdrnum(elf_file, &shnum) == -1) {
 		(void) fprintf(stderr,
-		    "%s: %s: elf_getshnum failed: %s\n",
+		    "%s: %s: elf_getshdrnum failed: %s\n",
 		    prog_name, filename, elf_errmsg(-1));
 		return;
 	}
-	if (elf_getshstrndx(elf_file, &shstrndx) == 0) {
+	if (elf_getshdrstrndx(elf_file, &shstrndx) == -1) {
 		(void) fprintf(stderr,
-		    "%s: %s: elf_getshstrndx failed: %s\n",
+		    "%s: %s: elf_getshdrstrndx failed: %s\n",
 		    prog_name, filename, elf_errmsg(-1));
 		return;
 	}
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c	Thu Jun 18 13:16:39 2009 -0600
@@ -1637,7 +1637,7 @@
 		0,			/* STT_FILE */
 		1,			/* STT_COMMON */
 		0,			/* STT_TLS */
-		0,			/* STT_IFUNC */
+		0,			/* 7 */
 		0,			/* 8 */
 		0,			/* 9 */
 		0,			/* 10 */
@@ -1647,7 +1647,7 @@
 		0,			/* 14 */
 		0,			/* 15 */
 	};
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. Update addr_symtype[]"
 #endif
 
@@ -4218,18 +4218,18 @@
 		return (ret);
 	}
 
-	if (elf_getshnum(elf, &shnum) == 0) {
-		failure(file, MSG_ORIG(MSG_ELF_GETSHNUM));
+	if (elf_getshdrnum(elf, &shnum) == -1) {
+		failure(file, MSG_ORIG(MSG_ELF_GETSHDRNUM));
 		return (ret);
 	}
 
-	if (elf_getshstrndx(elf, &shstrndx) == 0) {
-		failure(file, MSG_ORIG(MSG_ELF_GETSHSTRNDX));
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+		failure(file, MSG_ORIG(MSG_ELF_GETSHDRSTRNDX));
 		return (ret);
 	}
 
-	if (elf_getphnum(elf, &phnum) == 0) {
-		failure(file, MSG_ORIG(MSG_ELF_GETPHNUM));
+	if (elf_getphdrnum(elf, &phnum) == -1) {
+		failure(file, MSG_ORIG(MSG_ELF_GETPHDRNUM));
 		return (ret);
 	}
 	/*
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg	Thu Jun 18 13:16:39 2009 -0600
@@ -304,9 +304,9 @@
 @ MSG_ELF_GETARSYM	"elf_getarsym"
 @ MSG_ELF_RAND		"elf_rand"
 @ MSG_ELF_BEGIN		"elf_begin"
-@ MSG_ELF_GETPHNUM	"elf_getphnum"
-@ MSG_ELF_GETSHNUM	"elf_getshnum"
-@ MSG_ELF_GETSHSTRNDX	"elf_getshstrndx"
+@ MSG_ELF_GETPHDRNUM	"elf_getphdrnum"
+@ MSG_ELF_GETSHDRNUM	"elf_getshdrnum"
+@ MSG_ELF_GETSHDRSTRNDX	"elf_getshdrstrndx"
 @ MSG_ELF_XLATETOM	"elf_xlatetom"
 @ MSG_ELF_ARSYM		"ARSYM"
 
--- a/usr/src/cmd/sgs/elfdump/common/fake_shdr.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/fake_shdr.c	Thu Jun 18 13:16:39 2009 -0600
@@ -1122,8 +1122,8 @@
 	fstate.file = file;
 	fstate.fd = fd;
 	fstate.ehdr = ehdr;
-	if (elf_getphnum(elf, &fstate.phnum) == 0) {
-		failure(file, MSG_ORIG(MSG_ELF_GETPHNUM));
+	if (elf_getphdrnum(elf, &fstate.phnum) == -1) {
+		failure(file, MSG_ORIG(MSG_ELF_GETPHDRNUM));
 		return (0);
 	}
 	if ((fstate.phdr = elf_getphdr(elf)) == NULL) {
--- a/usr/src/cmd/sgs/elfedit/common/elfedit.msg	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/elfedit/common/elfedit.msg	Thu Jun 18 13:16:39 2009 -0600
@@ -592,12 +592,12 @@
 @ MSG_ELF_BEGIN		"elf_begin"
 @ MSG_ELF_GETEHDR	"elf_getehdr"
 @ MSG_ELF_GETDATA	"elf_getdata"
-@ MSG_ELF_GETPHNUM	"elf_getphnum"
+@ MSG_ELF_GETPHDRNUM	"elf_getphdrnum"
 @ MSG_ELF_GETPHDR	"elf_getphdr"
 @ MSG_ELF_GETSCN	"elf_getscn"
 @ MSG_ELF_GETSHDR	"elf_getshdr"
-@ MSG_ELF_GETSHNUM	"elf_getshnum"
-@ MSG_ELF_GETSHSTRNDX	"elf_getshstrndx"
+@ MSG_ELF_GETSHDRNUM	"elf_getshdrnum"
+@ MSG_ELF_GETSHDRSTRNDX	"elf_getshdrstrndx"
 @ MSG_ELF_UPDATE	"elf_update"
 
 
--- a/usr/src/cmd/sgs/elfedit/common/elfedit_machelf.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/elfedit/common/elfedit_machelf.c	Thu Jun 18 13:16:39 2009 -0600
@@ -20,10 +20,9 @@
  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * ELFCLASS specific code for elfedit, built once for each class
@@ -109,17 +108,19 @@
 #define	INITIAL_SYMTABNDX_ALLOC	5
 
 	/*
-	 * This macro is used to call functions from libelf, all of which
-	 * return NULL for failure and something else for success. On error,
-	 * libelf_fail_name is set and execution jumps to the libelf_failure
-	 * label for handling. Otherwise, the results of the call are ready
-	 * for use by the caller.
+	 * These macros are used to call functions from libelf.
+	 *
+	 * LIBELF_FAIL encapsulates the common way in which we handle
+	 * all of these errors: libelf_fail_name is set and execution
+	 * jumps to the libelf_failure label for handling.
+	 *
+	 * LIBELF is used for the common case in which the function returns
+	 * NULL for failure and something else for success.
 	 */
+#define	LIBELF_FAIL(_name) { libelf_fail_name = _name; goto libelf_failure; }
 #define	LIBELF(_libelf_expr, _name) \
-	if ((_libelf_expr) == NULL) { \
-		libelf_fail_name = _name; \
-		goto libelf_failure; \
-	}
+	if ((_libelf_expr) == NULL) \
+		LIBELF_FAIL(_name)
 
 	const char *libelf_fail_name;	/* Used for LIBELF errors */
 
@@ -146,8 +147,8 @@
 	    MSG_ORIG(MSG_ELF_GETEHDR))
 
 	/* Program header array count and address */
-	LIBELF(elf_getphnum(tstate.os_elf, &tstate.os_phnum),
-	    MSG_ORIG(MSG_ELF_GETPHNUM))
+	if (elf_getphdrnum(tstate.os_elf, &tstate.os_phnum) == -1)
+		LIBELF_FAIL(MSG_ORIG(MSG_ELF_GETPHDRNUM))
 	if (tstate.os_phnum > 0) {
 		LIBELF((tstate.os_phdr = elf_getphdr(tstate.os_elf)),
 		    MSG_ORIG(MSG_ELF_GETPHDR))
@@ -155,17 +156,15 @@
 		tstate.os_phdr = NULL;
 	}
 
-
-	LIBELF(elf_getshnum(tstate.os_elf, &tstate.os_shnum),
-	    MSG_ORIG(MSG_ELF_GETSHNUM))
-
+	if (elf_getshdrnum(tstate.os_elf, &tstate.os_shnum) == -1)
+		LIBELF_FAIL(MSG_ORIG(MSG_ELF_GETSHDRNUM))
 
 	/*
 	 * Obtain the .shstrtab data buffer to provide the required section
 	 * name strings.
 	 */
-	LIBELF(elf_getshstrndx(tstate.os_elf, &tstate.os_shstrndx),
-	    MSG_ORIG(MSG_ELF_GETSHSTRNDX))
+	if (elf_getshdrstrndx(tstate.os_elf, &tstate.os_shstrndx) == -1)
+		LIBELF_FAIL(MSG_ORIG(MSG_ELF_GETSHDRSTRNDX))
 	LIBELF((scn = elf_getscn(tstate.os_elf, tstate.os_shstrndx)),
 	    MSG_ORIG(MSG_ELF_GETSCN))
 	LIBELF((data = elf_getdata(scn, NULL)), MSG_ORIG(MSG_ELF_GETDATA))
@@ -448,6 +447,7 @@
 		free(obj_state);
 	(void) close(tstate.os_fd);
 	elfedit_elferr(tstate.os_file, libelf_fail_name);
-#undef LIBELF_FAILURE
 #undef INITIAL_SYMTABNDX_ALLOC
+#undef LIBELF_FAIL
+#undef LIBELF
 }
--- a/usr/src/cmd/sgs/libelf/common/gelf.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/common/gelf.c	Thu Jun 18 13:16:39 2009 -0600
@@ -19,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <string.h>
 #include "_libelf.h"
 #include "decl.h"
@@ -223,7 +221,7 @@
 	if (elf == NULL)
 		return (NULL);
 
-	if (elf_getphnum(elf, &phnum) == 0)
+	if (elf_getphdrnum(elf, &phnum) == -1)
 		return (NULL);
 
 	if (phnum <= ndx) {
@@ -270,7 +268,7 @@
 	if (elf == NULL)
 		return (0);
 
-	if (elf_getphnum(elf, &phnum) == 0)
+	if (elf_getphdrnum(elf, &phnum) == -1)
 		return (NULL);
 
 	if (phnum < ndx) {
--- a/usr/src/cmd/sgs/libelf/common/getphnum.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/common/getphnum.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,40 +19,59 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <string.h>
 #include <gelf.h>
 #include <decl.h>
 #include <msg.h>
 
+/*
+ * Return number of entries in the program header array, taking
+ * extended headers into account.
+ *
+ * elf_getphnum() was defined based on the definition of the earlier
+ * elf_getshnum(). It returns 0 for failure, and 1 for success.
+ *
+ * elf_getphdrnum() supercedes elf_getphnum(), which is now considered
+ * obsolete. It returns -1 for failure and 0 for success, matching
+ * elf_getshdrnum(), and bringing us into alignment with the interface
+ * agreed to in the 2002 gABI meeting.
+ *
+ * See the comment in getshnum.c for additional information.
+ */
+
 int
-elf_getphnum(Elf *elf, size_t *phnum)
+elf_getphdrnum(Elf *elf, size_t *phnum)
 {
 	GElf_Ehdr	ehdr;
 	Elf_Scn		*scn;
 	GElf_Shdr	shdr0;
 
 	if (gelf_getehdr(elf, &ehdr) == NULL)
-		return (0);
+		return (-1);
 
 	if (ehdr.e_phnum != PN_XNUM) {
 		*phnum = ehdr.e_phnum;
-		return (1);
+		return (0);
 	}
 
 	if ((scn = elf_getscn(elf, 0)) == NULL ||
 	    gelf_getshdr(scn, &shdr0) == NULL)
-		return (0);
+		return (-1);
 
 	if (shdr0.sh_info == 0)
 		*phnum = ehdr.e_phnum;
 	else
 		*phnum = shdr0.sh_info;
 
-	return (1);
+	return (0);
 }
+
+int
+elf_getphnum(Elf *elf, size_t *phnum)
+{
+	return (elf_getphdrnum(elf, phnum) == 0);
+}
--- a/usr/src/cmd/sgs/libelf/common/getshnum.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/common/getshnum.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,39 +19,61 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <string.h>
 #include <gelf.h>
 #include <decl.h>
 #include <msg.h>
 
 
+/*
+ * Return number of entries in the section header array, taking
+ * extended headers into account.
+ *
+ * elf_getshnum() and elf_getshstrndx() were defined during the 2002 gABI
+ * meetings. They were supposed to return -1 for failure, and 0 for success.
+ * Our manpage documented them as such, but we then implemented them to
+ * return 0 for failure and 1 for success. This makes elf_getshnum() and
+ * elf_getshstrnum() non-portable to systems that implement the 2002 gABI
+ * definition.
+ *
+ * In 2005, the manpage was modified to match the code.
+ * In 2009, the discrepency was identified. elf_getshdrnum() and
+ * elf_getshdrstrndx() were created to provide a portable implementation.
+ * The older two functions are considered to be obsolete, and are retained
+ * for backward compatability.
+ */
+
 int
-elf_getshnum(Elf *elf, size_t *shnum)
+elf_getshdrnum(Elf *elf, size_t *shnum)
 {
 	GElf_Ehdr	ehdr;
 	Elf_Scn		*scn;
 	GElf_Shdr	shdr0;
 
 	if (gelf_getehdr(elf, &ehdr) == 0)
-		return (0);
+		return (-1);
 	if (ehdr.e_shnum > 0) {
 		*shnum = ehdr.e_shnum;
-		return (1);
+		return (0);
 	}
 	if ((ehdr.e_shnum == 0) && (ehdr.e_shoff == 0)) {
 		*shnum = 0;
-		return (1);
+		return (0);
 	}
 	if ((scn = elf_getscn(elf, 0)) == 0)
-		return (0);
+		return (-1);
 	if (gelf_getshdr(scn, &shdr0) == 0)
-		return (0);
+		return (-1);
 	*shnum = shdr0.sh_size;
-	return (1);
+	return (0);
 }
+
+int
+elf_getshnum(Elf *elf, size_t *shnum)
+{
+	return (elf_getshdrnum(elf, shnum) == 0);
+}
--- a/usr/src/cmd/sgs/libelf/common/getshstrndx.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/common/getshstrndx.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,34 +19,51 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <string.h>
 #include <gelf.h>
 #include <decl.h>
 #include <msg.h>
 
+/*
+ * Return section header array string table index, taking
+ * extended headers into account.
+ *
+ * elf_getshstrndx() returns 0 for failure, and 1 for success.
+ *
+ * elf_getshdrstrndx() supercedes elf_getshstrndx(), which is now considered
+ * obsolete. It returns -1 for failure and 0 for success, bringing us into
+ * alignment with the interface agreed to in the 2002 gABI meeting.
+ *
+ * See the comment in getshnum.c for additional information.
+ */
+
 int
-elf_getshstrndx(Elf *elf, size_t *shstrndx)
+elf_getshdrstrndx(Elf *elf, size_t *shstrndx)
 {
 	GElf_Ehdr	ehdr;
 	Elf_Scn		*scn;
 	GElf_Shdr	shdr0;
 
 	if (gelf_getehdr(elf, &ehdr) == 0)
-		return (0);
+		return (-1);
 	if (ehdr.e_shstrndx != SHN_XINDEX) {
 		*shstrndx = ehdr.e_shstrndx;
-		return (1);
+		return (0);
 	}
 	if ((scn = elf_getscn(elf, 0)) == 0)
-		return (0);
+		return (-1);
 	if (gelf_getshdr(scn, &shdr0) == 0)
-		return (0);
+		return (-1);
 	*shstrndx = shdr0.sh_link;
-	return (1);
+	return (0);
 }
+
+int
+elf_getshstrndx(Elf *elf, size_t *shstrndx)
+{
+	return (elf_getshdrstrndx(elf, shstrndx) == 0);
+}
--- a/usr/src/cmd/sgs/libelf/common/mapfile-common	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/common/mapfile-common	Thu Jun 18 13:16:39 2009 -0600
@@ -37,6 +37,13 @@
 # MAPFILE HEADER END
 #
 
+SUNW_1.7 {
+    global:
+	elf_getphdrnum;
+	elf_getshdrnum;
+	elf_getshdrstrndx;
+} SUNW_1.6;
+
 SUNW_1.6 {
     global:
 	elf_getphnum;
--- a/usr/src/cmd/sgs/libelf/demo/acom.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/demo/acom.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,9 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 /*
  * acom: Append Comment
@@ -53,9 +51,9 @@
 	Elf_Data	*data;
 	size_t		shstrndx;
 
-	if (elf_getshstrndx(elf, &shstrndx) == 0) {
-		(void) fprintf(stderr, "%s: gelf_getshstrdx() failed: %s\n",
-			file, elf_errmsg(0));
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+		(void) fprintf(stderr, "%s: gelf_getshdrstrdx() failed: %s\n",
+		    file, elf_errmsg(0));
 		return;
 	}
 
@@ -66,9 +64,8 @@
 		 * this is the section we want to process.
 		 */
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			return;
 		}
 		if (strcmp(CommentStr, elf_strptr(elf, shstrndx,
@@ -80,24 +77,24 @@
 		int	ndx;
 
 		(void) printf("%s has no .comment section.  "
-			"Creating one...\n", file);
+		    "Creating one...\n", file);
 		/*
 		 * First add the ".comment" string to the string table
 		 */
 		if ((scn = elf_getscn(elf, shstrndx)) == 0) {
 			(void) fprintf(stderr, "%s: elf_getscn() failed: %s\n",
-				file, elf_errmsg(0));
+			    file, elf_errmsg(0));
 			return;
 		}
 		if ((data = elf_getdata(scn, 0)) == 0) {
 			(void) fprintf(stderr, "%s: elf_getdata() failed: %s\n",
-				file, elf_errmsg(0));
+			    file, elf_errmsg(0));
 			return;
 		}
 		ndx = data->d_off + data->d_size;
 		if ((data = elf_newdata(scn)) == 0) {
 			(void) fprintf(stderr, "%s: elf_newdata() failed: %s\n",
-				file, elf_errmsg(0));
+			    file, elf_errmsg(0));
 			return;
 		}
 		data->d_buf = (void *)CommentStr;
@@ -111,13 +108,12 @@
 		 */
 		if ((scn = elf_newscn(elf)) == 0) {
 			(void) fprintf(stderr, "%s: elf_newscn() failed: %s\n",
-				file, elf_errmsg(0));
+			    file, elf_errmsg(0));
 			return;
 		}
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			return;
 		}
 		shdr.sh_name = ndx;
@@ -136,13 +132,13 @@
 
 	if (shdr.sh_addr != 0) {
 		(void) printf("%s: .comment section is part of a "
-			"loadable segment, it cannot be changed.\n", file);
+		    "loadable segment, it cannot be changed.\n", file);
 		return;
 	}
 
 	if ((data = elf_newdata(scn)) == 0) {
 		(void) fprintf(stderr, "%s: elf_getdata() failed: %s\n",
-			file, elf_errmsg(0));
+		    file, elf_errmsg(0));
 		return;
 	}
 	data->d_buf = (void *)comment;
@@ -151,7 +147,7 @@
 
 	if (elf_update(elf, ELF_C_WRITE) == -1)
 		(void) fprintf(stderr, "%s: elf_update() failed: %s\n", file,
-			elf_errmsg(0));
+		    elf_errmsg(0));
 }
 
 
@@ -164,7 +160,7 @@
 
 	if (argc < 3) {
 		(void) printf("usage: %s <new comment> elf_file ...\n",
-			argv[0]);
+		    argv[0]);
 		return (1);
 	}
 
@@ -174,7 +170,7 @@
 	 */
 	if (elf_version(EV_CURRENT) == EV_NONE) {
 		(void) fprintf(stderr, "elf_version() failed: %s\n",
-			elf_errmsg(0));
+		    elf_errmsg(0));
 		return (1);
 	}
 
@@ -212,8 +208,7 @@
 			update_comment(elf, elf_fname, new_comment);
 		else
 			(void) printf("%s not of type ELF_K_ELF.  "
-				"elf_kind == %d\n",
-				elf_fname, elf_kind(elf));
+			    "elf_kind == %d\n", elf_fname, elf_kind(elf));
 
 		(void) elf_end(elf);
 		(void) close(fd);
--- a/usr/src/cmd/sgs/libelf/demo/dcom.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/demo/dcom.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,10 +19,9 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 
 /*
@@ -109,25 +107,25 @@
 
 	if (gelf_getehdr(elf, &ehdr) == 0) {
 		(void) fprintf(stderr, "%s: elf_getehdr() failed: %s\n",
-			file, elf_errmsg(0));
+		    file, elf_errmsg(0));
 		return;
 	}
 
-	if (elf_getshnum(elf, &shnum) == 0) {
-		(void) fprintf(stderr, "%s: elf_getshnum() failed: %s\n",
-			file, elf_errmsg(0));
+	if (elf_getshdrnum(elf, &shnum) == -1) {
+		(void) fprintf(stderr, "%s: elf_getshdrnum() failed: %s\n",
+		    file, elf_errmsg(0));
 		return;
 	}
 
-	if (elf_getshstrndx(elf, &shstrndx) == 0) {
-		(void) fprintf(stderr, "%s: elf_getshstrndx() failed: %s\n",
-			file, elf_errmsg(0));
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+		(void) fprintf(stderr, "%s: elf_getshdrstrndx() failed: %s\n",
+		    file, elf_errmsg(0));
 		return;
 	}
 
-	if (elf_getphnum(elf, &phnum) == 0) {
-		(void) fprintf(stderr, "%s: elf_getphnum() failed: %s\n",
-			file, elf_errmsg(0));
+	if (elf_getphdrnum(elf, &phnum) == -1) {
+		(void) fprintf(stderr, "%s: elf_getphdrnum() failed: %s\n",
+		    file, elf_errmsg(0));
 		return;
 	}
 
@@ -146,9 +144,8 @@
 		 * this is the section we want to process.
 		 */
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
@@ -164,8 +161,8 @@
 			 */
 			if (shdr.sh_addr != 0) {
 				(void) printf("%s: .comment section is "
-					"part of a loadable segment, it "
-					"cannot be deleted.\n", file);
+				    "part of a loadable segment, it "
+				    "cannot be deleted.\n", file);
 				free(shndx);
 				return;
 			}
@@ -195,13 +192,13 @@
 
 	if (gelf_newehdr(telf, gelf_getclass(elf)) == 0) {
 		(void) fprintf(stderr, "%s: elf_newehdr() failed: %s\n",
-			file, elf_errmsg(0));
+		    file, elf_errmsg(0));
 		free(shndx);
 		return;
 	}
 	if (gelf_getehdr(telf, &tehdr) == 0) {
 		(void) fprintf(stderr, "%s: elf_getehdr() failed: %s\n",
-			file, elf_errmsg(0));
+		    file, elf_errmsg(0));
 		free(shndx);
 		return;
 	}
@@ -225,23 +222,20 @@
 		 * new file.
 		 */
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
 		if ((tscn = elf_newscn(telf)) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_newscn() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_newscn() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
 		if (gelf_getshdr(tscn, &tshdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
@@ -268,16 +262,14 @@
 		gelf_update_shdr(tscn, &tshdr);
 
 		if ((data = elf_getdata(scn, 0)) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getdata() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getdata() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
 		if ((tdata = elf_newdata(tscn)) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_newdata() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_newdata() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
@@ -296,16 +288,14 @@
 		 * store the shstrndx in Shdr[0].sh_link
 		 */
 		if ((_scn = elf_getscn(telf, 0)) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getscn() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getscn() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
 		if (gelf_getshdr(_scn, &shdr0) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			free(shndx);
 			return;
 		}
@@ -322,17 +312,16 @@
 	 */
 	if (phnum != 0) {
 		if (gelf_newphdr(telf, phnum) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_newphdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_newphdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			return;
 		}
 		for (ndx = 0; ndx < (int)phnum; ndx++) {
 			if (gelf_getphdr(elf, ndx, &phdr) == 0 ||
 			    gelf_getphdr(telf, ndx, &tphdr) == 0) {
 				(void) fprintf(stderr,
-					"%s: elf_getphdr() failed: %s\n",
-					file, elf_errmsg(0));
+				    "%s: elf_getphdr() failed: %s\n",
+				    file, elf_errmsg(0));
 				return;
 			}
 			tphdr = phdr;
@@ -347,7 +336,7 @@
 	 */
 	if (elf_update(telf, ELF_C_WRITE) == -1) {
 		(void) fprintf(stderr, "elf_update() failed: %s\n",
-			elf_errmsg(0));
+		    elf_errmsg(0));
 		(void) elf_end(telf);
 		(void) close(tfd);
 		return;
@@ -387,7 +376,7 @@
 	 */
 	if (elf_version(EV_CURRENT) == EV_NONE) {
 		(void) fprintf(stderr, "elf_version() failed: %s\n",
-			elf_errmsg(0));
+		    elf_errmsg(0));
 		return (1);
 	}
 
@@ -423,8 +412,7 @@
 			 * ELF files.
 			 */
 			(void) printf("%s not of type ELF_K_ELF.  "
-				"elf_kind == %d\n",
-				elf_fname, elf_kind(elf));
+			    "elf_kind == %d\n", elf_fname, elf_kind(elf));
 		} else
 			delete_comment(elf, fd, elf_fname);
 
--- a/usr/src/cmd/sgs/libelf/demo/dispsyms.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/demo/dispsyms.c	Thu Jun 18 13:16:39 2009 -0600
@@ -61,9 +61,8 @@
 /* STT_FILE */		"FILE",
 /* STT_COMMON */	"COMM",
 /* STT_TLS */		"TLS"
-/* STT_IFUNC */		"IFUNC"
 };
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. Update symtype[]."
 #endif
 
@@ -85,8 +84,8 @@
 		return;
 	}
 
-	if (elf_getshstrndx(elf, &shstrndx) == 0) {
-		(void) fprintf(stderr, "%s: elf_getshstrndx() failed: %s\n",
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+		(void) fprintf(stderr, "%s: elf_getshdrstrndx() failed: %s\n",
 		    file, elf_errmsg(0));
 		return;
 	}
--- a/usr/src/cmd/sgs/libelf/demo/pcom.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/demo/pcom.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -34,8 +33,6 @@
  * contents will be displayed on stdout.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdio.h>
 #include <libelf.h>
 #include <gelf.h>
@@ -58,9 +55,9 @@
 
 	(void) printf("%s .comment:\n", file);
 
-	if (elf_getshstrndx(elf, &shstrndx) == 0) {
-		(void) fprintf(stderr, "%s: elf_getshstrndx() failed: %s\n",
-			file, elf_errmsg(0));
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+		(void) fprintf(stderr, "%s: elf_getshdrstrndx() failed: %s\n",
+		    file, elf_errmsg(0));
 		return;
 	}
 
@@ -71,9 +68,8 @@
 		 * this is the section we want to process.
 		 */
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			return;
 		}
 		if (strcmp(CommentStr, elf_strptr(elf, shstrndx,
@@ -87,8 +83,8 @@
 			 */
 			if ((data = elf_getdata(scn, 0)) == 0) {
 				(void) fprintf(stderr,
-					"%s: elf_getdata() failed: %s\n",
-					file, elf_errmsg(0));
+				    "%s: elf_getdata() failed: %s\n",
+				    file, elf_errmsg(0));
 				return;
 			}
 			/*
@@ -155,8 +151,8 @@
 	default:
 		if (!member)
 			(void) fprintf(stderr,
-				"%s: unexpected elf_kind(): 0x%x\n",
-				file, elf_kind(elf));
+			    "%s: unexpected elf_kind(): 0x%x\n",
+			    file, elf_kind(elf));
 		return;
 	}
 }
@@ -178,7 +174,7 @@
 	 */
 	if (elf_version(EV_CURRENT) == EV_NONE) {
 		(void) fprintf(stderr,
-			"elf_version() failed: %s\n", elf_errmsg(0));
+		    "elf_version() failed: %s\n", elf_errmsg(0));
 		return (1);
 	}
 
--- a/usr/src/cmd/sgs/libelf/demo/tpcom.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libelf/demo/tpcom.c	Thu Jun 18 13:16:39 2009 -0600
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * tpcom: Threaded Print Comment
  *
@@ -77,9 +74,9 @@
 	size_t		shstrndx;
 
 
-	if (elf_getshstrndx(elf, &shstrndx) == 0) {
-		(void) fprintf(stderr, "%s: elf_getshstrndx() failed: %s\n",
-			file, elf_errmsg(0));
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
+		(void) fprintf(stderr, "%s: elf_getshdrstrndx() failed: %s\n",
+		    file, elf_errmsg(0));
 		return;
 	}
 	while ((scn = elf_nextscn(elf, scn)) != 0) {
@@ -89,9 +86,8 @@
 		 * this is the section we want to process.
 		 */
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-				"%s: elf_getshdr() failed: %s\n",
-				file, elf_errmsg(0));
+			(void) fprintf(stderr, "%s: elf_getshdr() failed: %s\n",
+			    file, elf_errmsg(0));
 			return;
 		}
 
@@ -109,8 +105,8 @@
 			 */
 			if ((data = elf_getdata(scn, 0)) == 0) {
 				(void) fprintf(stderr,
-					"%s: elf_getdata() failed: %s\n",
-					file, elf_errmsg(0));
+				    "%s: elf_getdata() failed: %s\n",
+				    file, elf_errmsg(0));
 				mutex_unlock(&printlock);
 				return;
 			}
@@ -153,23 +149,23 @@
 
 			if ((arhdr = elf_getarhdr(_elf)) == 0) {
 				(void) fprintf(stderr,
-					"%s: elf_getarhdr() failed: %s\n",
-					pep->pe_file, elf_errmsg(0));
+				    "%s: elf_getarhdr() failed: %s\n",
+				    pep->pe_file, elf_errmsg(0));
 			}
 			cmd = elf_next(_elf);
 			_pep = malloc(sizeof (pe_args));
 			_pep->pe_elf = _elf;
 			_pep->pe_file = malloc(strlen(pep->pe_file) +
-				strlen(arhdr->ar_name) + 5);
+			    strlen(arhdr->ar_name) + 5);
 			(void) sprintf(_pep->pe_file,
-				"%s(%s)", pep->pe_file, arhdr->ar_name);
+			    "%s(%s)", pep->pe_file, arhdr->ar_name);
 			_pep->pe_fd = pep->pe_fd;
 			_pep->pe_member = 1;
 			if ((rc = thr_create(NULL, 0,
 			    (void *(*)(void *))process_elf,
 			    (void *)_pep, THR_DETACHED, 0)) != 0) {
 				(void) fprintf(stderr,
-					"thr_create() failed, rc = %d\n", rc);
+				    "thr_create() failed, rc = %d\n", rc);
 			}
 		}
 		break;
@@ -177,8 +173,8 @@
 		if (!pep->pe_member) {
 			mutex_lock(&printlock);
 			(void) fprintf(stderr,
-				"%s: unexpected elf_kind(): 0x%x\n",
-				pep->pe_file, elf_kind(pep->pe_elf));
+			    "%s: unexpected elf_kind(): 0x%x\n",
+			    pep->pe_file, elf_kind(pep->pe_elf));
 			mutex_unlock(&printlock);
 		}
 	}
@@ -207,7 +203,7 @@
 	 */
 	if (elf_version(EV_CURRENT) == EV_NONE) {
 		(void) fprintf(stderr,
-			"elf_version() failed: %s\n", elf_errmsg(0));
+		    "elf_version() failed: %s\n", elf_errmsg(0));
 		return (1);
 	}
 
@@ -255,7 +251,7 @@
 		    (void *)pep, THR_DETACHED, 0)) != 0) {
 			mutex_lock(&printlock);
 			(void) fprintf(stderr,
-				"thr_create() failed with code: %d\n", rc);
+			    "thr_create() failed with code: %d\n", rc);
 			mutex_unlock(&printlock);
 			return (1);
 		}
--- a/usr/src/cmd/sgs/libld/common/globals.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/libld/common/globals.c	Thu Jun 18 13:16:39 2009 -0600
@@ -89,7 +89,7 @@
 		1,			/* STT_FILE */
 		0,			/* STT_COMMON */
 		0,			/* STT_TLS */
-		0,			/* STT_IFUNC */
+		0,			/* 7 */
 		0,			/* 8 */
 		0,			/* 9 */
 		0,			/* 10 */
@@ -99,7 +99,7 @@
 		0,			/* 14 */
 		0,			/* 15 */
 };
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. Update ldynsym_symtype[]."
 #endif
 
@@ -116,7 +116,7 @@
 		0,			/* STT_FILE */
 		1,			/* STT_COMMON */
 		0,			/* STT_TLS */
-		0,			/* STT_IFUNC */
+		0,			/* 7 */
 		0,			/* 8 */
 		0,			/* 9 */
 		0,			/* 10 */
@@ -126,6 +126,6 @@
 		0,			/* 14 */
 		0,			/* 15 */
 };
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. Update dynsymsort_symtype[]."
 #endif
--- a/usr/src/cmd/sgs/mcs/common/file.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/mcs/common/file.c	Thu Jun 18 13:16:39 2009 -0600
@@ -258,7 +258,7 @@
 		return (FAILURE);
 	}
 
-	if (elf_getshnum(elf, &shnum) == NULL) {
+	if (elf_getshdrnum(elf, &shnum) == -1) {
 		error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
 		return (FAILURE);
 	}
@@ -328,11 +328,11 @@
 
 	state->Sect_exists = 0;
 
-	if (elf_getshnum(elf, &shnum) == NULL) {
+	if (elf_getshdrnum(elf, &shnum) == -1) {
 		error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
 		return (FAILURE);
 	}
-	if (elf_getshstrndx(elf, &shstrndx) == NULL) {
+	if (elf_getshdrstrndx(elf, &shstrndx) == -1) {
 		error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
 		return (FAILURE);
 	}
@@ -693,11 +693,11 @@
 	size_t shnum, shstrndx;
 
 
-	if (elf_getshnum(src_elf, &shnum) == NULL) {
+	if (elf_getshdrnum(src_elf, &shnum) == -1) {
 		error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
 		return (FAILURE);
 	}
-	if (elf_getshstrndx(src_elf, &shstrndx) == NULL) {
+	if (elf_getshdrstrndx(src_elf, &shstrndx) == -1) {
 		error_message(LIBELF_ERROR, LIBelf_ERROR, elf_errmsg(-1), prog);
 		return (FAILURE);
 	}
--- a/usr/src/cmd/sgs/nm/common/nm.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/nm/common/nm.c	Thu Jun 18 13:16:39 2009 -0600
@@ -538,7 +538,7 @@
 	GElf_Word symtabtype;
 	size_t shstrndx;
 
-	if (elf_getshstrndx(elf_file, &shstrndx) == 0) {
+	if (elf_getshdrstrndx(elf_file, &shstrndx) == -1) {
 		(void) fprintf(stderr, gettext(
 		    "%s: %s: could not get e_shstrndx\n"),
 		    prog_name, filename);
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Thu Jun 18 13:16:39 2009 -0600
@@ -1485,3 +1485,6 @@
 6784790 ld should examine archives to determine output object class/machine
 	PSARC/2009/305 ld -32 option
 6849998 remove undocumented mapfile $SPECVERS and $NEED options
+6851224 elf_getshnum() and elf_getshstrndx() incompatible with 2002 ELF gABI
+	agreement
+	PSARC/2009/363 replace elf_getphnum, elf_getshnum, and elf_getshstrndx
--- a/usr/src/head/libelf.h	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/head/libelf.h	Thu Jun 18 13:16:39 2009 -0600
@@ -22,15 +22,13 @@
 /*	  All Rights Reserved  	*/
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
 #ifndef _LIBELF_H
 #define	_LIBELF_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 1.9	*/
-
 #include <sys/types.h>
 #include <sys/elf.h>
 
@@ -191,8 +189,11 @@
 Elf_Scn		*elf_getscn	_((Elf *elf, size_t));
 Elf32_Shdr	*elf32_getshdr	_((Elf_Scn *));
 int		elf_getphnum	_((Elf *, size_t *));
+int		elf_getphdrnum	_((Elf *, size_t *));
 int		elf_getshnum	_((Elf *, size_t *));
+int		elf_getshdrnum	_((Elf *, size_t *));
 int		elf_getshstrndx	_((Elf *, size_t *));
+int		elf_getshdrstrndx _((Elf *, size_t *));
 unsigned long	elf_hash	_((const char *));
 uint_t		elf_sys_encoding _((void));
 long		elf32_checksum	_((Elf *));
--- a/usr/src/lib/libdtrace/common/dt_module.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/lib/libdtrace/common/dt_module.c	Thu Jun 18 13:16:39 2009 -0600
@@ -64,7 +64,7 @@
 static uint_t
 dt_module_syminit32(dt_module_t *dmp)
 {
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. update dt_module_syminit32()"
 #endif
 
@@ -78,7 +78,7 @@
 		const char *name = base + sym->st_name;
 		uchar_t type = ELF32_ST_TYPE(sym->st_info);
 
-		if (type >= STT_IFUNC || type == STT_SECTION)
+		if (type >= STT_NUM || type == STT_SECTION)
 			continue; /* skip sections and unknown types */
 
 		if (sym->st_name == 0 || sym->st_name >= ss_size)
@@ -97,7 +97,7 @@
 static uint_t
 dt_module_syminit64(dt_module_t *dmp)
 {
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. update dt_module_syminit64()"
 #endif
 
@@ -111,7 +111,7 @@
 		const char *name = base + sym->st_name;
 		uchar_t type = ELF64_ST_TYPE(sym->st_info);
 
-		if (type >= STT_IFUNC || type == STT_SECTION)
+		if (type >= STT_NUM || type == STT_SECTION)
 			continue; /* skip sections and unknown types */
 
 		if (sym->st_name == 0 || sym->st_name >= ss_size)
@@ -474,7 +474,7 @@
 	Elf_Data *dp;
 	Elf_Scn *sp;
 
-	if (elf_getshstrndx(dmp->dm_elf, &shstrs) == 0)
+	if (elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1)
 		return (dt_set_errno(dtp, EDT_NOTLOADED));
 
 	for (sp = NULL; (sp = elf_nextscn(dmp->dm_elf, sp)) != NULL; ) {
@@ -823,7 +823,7 @@
 	(void) close(fd);
 
 	if (dmp->dm_elf == NULL || err == -1 ||
-	    elf_getshstrndx(dmp->dm_elf, &shstrs) == 0) {
+	    elf_getshdrstrndx(dmp->dm_elf, &shstrs) == -1) {
 		dt_dprintf("failed to load %s: %s\n",
 		    fname, elf_errmsg(elf_errno()));
 		dt_module_destroy(dtp, dmp);
--- a/usr/src/lib/libelfsign/common/elfsignlib.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/lib/libelfsign/common/elfsignlib.c	Thu Jun 18 13:16:39 2009 -0600
@@ -20,12 +20,10 @@
  */
 
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #define	ELF_TARGET_ALL	/* get definitions of all section flags */
 
 #include <sys/types.h>
@@ -356,7 +354,7 @@
 	 * Call elf_getshstrndx to be sure we have a real ELF object
 	 * this is required because elf_begin doesn't check that.
 	 */
-	if (elf_getshstrndx(ess->es_elf, &ess->es_shstrndx) == 0) {
+	if (elf_getshdrstrndx(ess->es_elf, &ess->es_shstrndx) == -1) {
 		elfsign_end(ess);
 		cryptodebug("elfsign_begin: elf_getshstrndx failed");
 		return (ELFSIGN_INVALID_ELFOBJ);
--- a/usr/src/lib/libproc/common/Pcore.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/lib/libproc/common/Pcore.c	Thu Jun 18 13:16:39 2009 -0600
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1288,7 +1288,7 @@
 	uint_t i;
 	size_t nphdrs;
 
-	if (elf_getphnum(elf, &nphdrs) == 0)
+	if (elf_getphdrnum(elf, &nphdrs) == -1)
 		return (NULL);
 
 	for (i = 0; i < nphdrs; i++) {
@@ -1323,7 +1323,7 @@
 	 * as the virtual address at which is was loaded.
 	 */
 	if (gelf_getehdr(elf, &ehdr) == NULL ||
-	    elf_getphnum(elf, &nphdrs) == 0)
+	    elf_getphdrnum(elf, &nphdrs) == -1)
 		return (NULL);
 
 	for (i = 0; i < nphdrs; i++) {
--- a/usr/src/lib/libproc/common/Pidle.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/lib/libproc/common/Pidle.c	Thu Jun 18 13:16:39 2009 -0600
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -201,7 +201,7 @@
 		goto err;
 	}
 
-	if (elf_getphnum(elf, &phnum) == 0) {
+	if (elf_getphdrnum(elf, &phnum) == -1) {
 		*perr = G_STRANGE;
 		goto err;
 	}
--- a/usr/src/lib/libproc/common/Psymtab.c	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/lib/libproc/common/Psymtab.c	Thu Jun 18 13:16:39 2009 -0600
@@ -1664,8 +1664,8 @@
 		if ((elf = fake_elf(P, fptr)) == NULL ||
 		    elf_kind(elf) != ELF_K_ELF ||
 		    gelf_getehdr(elf, &ehdr) == NULL ||
-		    elf_getshnum(elf, &nshdrs) == 0 ||
-		    elf_getshstrndx(elf, &shstrndx) == 0 ||
+		    elf_getshdrnum(elf, &nshdrs) == -1 ||
+		    elf_getshdrstrndx(elf, &shstrndx) == -1 ||
 		    (scn = elf_getscn(elf, shstrndx)) == NULL ||
 		    (shdata = elf_getdata(scn, NULL)) == NULL) {
 			dprintf("failed to fake up ELF file\n");
@@ -1675,8 +1675,8 @@
 	} else if ((elf = elf_begin(fptr->file_fd, ELF_C_READ, NULL)) == NULL ||
 	    elf_kind(elf) != ELF_K_ELF ||
 	    gelf_getehdr(elf, &ehdr) == NULL ||
-	    elf_getshnum(elf, &nshdrs) == 0 ||
-	    elf_getshstrndx(elf, &shstrndx) == 0 ||
+	    elf_getshdrnum(elf, &nshdrs) == -1 ||
+	    elf_getshdrstrndx(elf, &shstrndx) == -1 ||
 	    (scn = elf_getscn(elf, shstrndx)) == NULL ||
 	    (shdata = elf_getdata(scn, NULL)) == NULL) {
 		int err = elf_errno();
@@ -1687,8 +1687,8 @@
 		if ((elf = fake_elf(P, fptr)) == NULL ||
 		    elf_kind(elf) != ELF_K_ELF ||
 		    gelf_getehdr(elf, &ehdr) == NULL ||
-		    elf_getshnum(elf, &nshdrs) == 0 ||
-		    elf_getshstrndx(elf, &shstrndx) == 0 ||
+		    elf_getshdrnum(elf, &nshdrs) == -1 ||
+		    elf_getshdrstrndx(elf, &shstrndx) == -1 ||
 		    (scn = elf_getscn(elf, shstrndx)) == NULL ||
 		    (shdata = elf_getdata(scn, NULL)) == NULL) {
 			dprintf("failed to fake up ELF file\n");
@@ -1712,8 +1712,8 @@
 		if ((newelf = fake_elf(P, fptr)) == NULL ||
 		    elf_kind(newelf) != ELF_K_ELF ||
 		    gelf_getehdr(newelf, &ehdr) == NULL ||
-		    elf_getshnum(newelf, &nshdrs) == 0 ||
-		    elf_getshstrndx(newelf, &shstrndx) == 0 ||
+		    elf_getshdrnum(newelf, &nshdrs) == -1 ||
+		    elf_getshdrstrndx(newelf, &shstrndx) == -1 ||
 		    (scn = elf_getscn(newelf, shstrndx)) == NULL ||
 		    (shdata = elf_getdata(scn, NULL)) == NULL) {
 			dprintf("failed to fake up ELF file\n");
@@ -2757,7 +2757,7 @@
 Psymbol_iter_com(struct ps_prochandle *P, Lmid_t lmid, const char *object_name,
     int which, int mask, pr_order_t order, proc_xsym_f *func, void *cd)
 {
-#if STT_NUM != (STT_IFUNC + 1)
+#if STT_NUM != (STT_TLS + 1)
 #error "STT_NUM has grown. update Psymbol_iter_com()"
 #endif
 
@@ -2845,7 +2845,7 @@
 			 * maintain binary compatibility, so I think this is
 			 * reasonably fair game.
 			 */
-			if (s_bind < STB_NUM && s_type < STT_IFUNC) {
+			if (s_bind < STB_NUM && s_type < STT_NUM) {
 				type = (1 << (s_type + 8)) | (1 << s_bind);
 				if ((type & ~mask) != 0)
 					continue;
--- a/usr/src/uts/common/sys/elf.h	Thu Jun 18 09:26:55 2009 -0700
+++ b/usr/src/uts/common/sys/elf.h	Thu Jun 18 13:16:39 2009 -0600
@@ -550,8 +550,7 @@
 #define	STT_FILE	4		/* symbol's name is file name */
 #define	STT_COMMON	5		/* common data object */
 #define	STT_TLS		6		/* thread-local data object */
-#define	STT_IFUNC	7		/* indirect code object (unused) */
-#define	STT_NUM		8		/* # defined types in generic range */
+#define	STT_NUM		7		/* # defined types in generic range */
 #define	STT_LOOS	10		/* OS specific range */
 #define	STT_HIOS	12
 #define	STT_LOPROC	13		/* processor specific range */