changeset 3621:2cbc0f92c696

PSARC 2007/074 -L option for nm(1) to display SHT_SUNW_LDYNSYM symbols 6518322 Some ELF utilities need updating for .SUNW_ldynsym section
author ab196087
date Thu, 08 Feb 2007 11:58:00 -0800
parents 3e35d13fa9ae
children eed77e5fc4ad
files usr/src/cmd/sgs/gprof/common/readelf.c usr/src/cmd/sgs/lari/lari.pl usr/src/cmd/sgs/libelf/common/checksum.c usr/src/cmd/sgs/libelf/common/decl.h usr/src/cmd/sgs/libelf/common/update.c usr/src/cmd/sgs/libelf/common/xlate.m4 usr/src/cmd/sgs/libelf/common/xlate64.m4 usr/src/cmd/sgs/libelf/demo/README usr/src/cmd/sgs/libelf/demo/dispsyms.c usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.h usr/src/cmd/sgs/librtld_db/rdb_demo/common/syms.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/cmd/sgs/prof/common/prof.c usr/src/cmd/sgs/prof/common/rdelf.c usr/src/cmd/sgs/prof/common/symintHdr.h usr/src/cmd/sgs/prof/common/symintLoad.c usr/src/cmd/sgs/prof/common/symintOpen.c
diffstat 20 files changed, 439 insertions(+), 245 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/gprof/common/readelf.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/gprof/common/readelf.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -454,48 +453,75 @@
 static void
 get_symtab(Elf *elf, mod_info_t *module)
 {
-	Elf_Scn		*scn = NULL, *sym = NULL;
+	Elf_Scn		*scn = NULL, *sym_pri = NULL, *sym_aux = NULL;
 	GElf_Word	strndx = 0;
 	sztype		nsyms, i;
-	Elf_Data	*symdata;
+	Elf_Data	*symdata_pri;
+	Elf_Data	*symdata_aux;
+	GElf_Xword	nsyms_pri, nsyms_aux = 0;
 	nltype		*etext = NULL;
+	nltype		*l_nl, *l_npe;
+	sztype		l_nname;
+	extern sztype	total_names;
+	int		symtab_found = 0;
+
 
-	nltype			*l_nl, *l_npe;
-	sztype			l_nname;
-	extern sztype		total_names;
-
-	while ((scn = elf_nextscn(elf, scn)) != NULL) {
+	/*
+	 * Scan the section headers looking for a symbol table. Our
+	 * preference is to use .symtab, because it contains the full
+	 * set of symbols. If we find it, we stop looking immediately
+	 * and use it. In the absence of a .symtab section, we are
+	 * willing to use the dynamic symbol table (.dynsym), possibly
+	 * augmented by the .SUNW_ldynsym, which contains local symbols.
+	 */
+	while ((symtab_found == 0) && ((scn = elf_nextscn(elf, scn)) != NULL)) {
 		GElf_Shdr shdr;
 
 		if (gelf_getshdr(scn, &shdr) == NULL)
 			continue;
 
-		if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
-			GElf_Xword chk = shdr.sh_size / shdr.sh_entsize;
-
-			nsyms = (sztype)(shdr.sh_size / shdr.sh_entsize);
-
-			if (chk != (GElf_Xword)nsyms)
-				fatal_error("32-bit gprof cannot handle"
-				    "more than 2^32 symbols");
+		switch (shdr.sh_type) {
+		case SHT_SYMTAB:
+			nsyms_pri = shdr.sh_size / shdr.sh_entsize;
+			strndx = shdr.sh_link;
+			sym_pri = scn;
+			/* Throw away .SUNW_ldynsym. It is for .dynsym only */
+			nsyms_aux = 0;
+			sym_aux = NULL;
+			/* We have found the best symbol table. Stop looking */
+			symtab_found = 1;
+			break;
 
+		case SHT_DYNSYM:
+			/* We will use .dynsym if no .symtab is found */
+			nsyms_pri = shdr.sh_size / shdr.sh_entsize;
 			strndx = shdr.sh_link;
-			sym = scn;
-		}
+			sym_pri = scn;
+			break;
 
-		/*
-		 * If we've found a real symbol table, we're done.
-		 */
-		if (shdr.sh_type == SHT_SYMTAB)
+		case SHT_SUNW_LDYNSYM:
+			/* Auxiliary table, used with .dynsym */
+			nsyms_aux = shdr.sh_size / shdr.sh_entsize;
+			sym_aux = scn;
 			break;
+		}
 	}
 
-	if (sym == NULL || strndx == 0)
+	if (sym_pri == NULL || strndx == 0)
 		fatal_error("can't find symbol table.\n");
 
-	if ((symdata = elf_getdata(scn, NULL)) == NULL)
+	nsyms = (sztype)(nsyms_pri + nsyms_aux);
+	if ((nsyms_pri + nsyms_aux) != (GElf_Xword)nsyms)
+		fatal_error(
+		    "32-bit gprof cannot handle more than 2^32 symbols");
+
+	if ((symdata_pri = elf_getdata(sym_pri, NULL)) == NULL)
 		fatal_error("can't read symbol data.\n");
 
+	if ((sym_aux != NULL) &&
+	    ((symdata_aux = elf_getdata(sym_aux, NULL)) == NULL))
+		fatal_error("can't read .SUNW_ldynsym symbol data.\n");
+
 	if ((l_nl = l_npe = (nltype *)calloc(nsyms + PRF_SYMCNT,
 	    sizeof (nltype))) == NULL)
 		fatal_error("cannot allocate symbol data.\n");
@@ -511,7 +537,16 @@
 		GElf_Sym gsym;
 		char *name;
 
-		(void) gelf_getsym(symdata, i, &gsym);
+		/*
+		 * Look up the symbol. In the case where we have a
+		 * .SUNW_ldynsym/.dynsym pair, we treat them as a single
+		 * logical table, with the data from .SUNW_ldynsym coming
+		 * before the data in .dynsym.
+		 */
+		if (i >= nsyms_aux)
+			(void) gelf_getsym(symdata_pri, i - nsyms_aux, &gsym);
+		else
+			(void) gelf_getsym(symdata_aux, i, &gsym);
 
 		name = elf_strptr(elf, strndx, gsym.st_name);
 
--- a/usr/src/cmd/sgs/lari/lari.pl	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/lari/lari.pl	Thu Feb 08 11:58:00 2007 -0800
@@ -1385,7 +1385,8 @@
 		return;
 	}
 
-	# Process elfdump(1) once more to obtain the .dynsym symbol table.
+	# Process elfdump(1) once more to obtain the .dynsym symbol table. We
+	# are only interested in global symbols, so .SUNW_ldynsym is not needed.
 	open($FileHandle, "LC_ALL=C elfdump -sN.dynsym '$Obj' 2> /dev/null |");
 
 	while (defined(my $Line = <$FileHandle>)) {
--- a/usr/src/cmd/sgs/libelf/common/checksum.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/common/checksum.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -141,9 +140,17 @@
 		if ((shdr = elf64_getshdr(scn)) == 0)
 			return (0);
 
+		/* Exclude strippable sections */
 		if (!(shdr->sh_flags & SHF_ALLOC))
 			continue;
 
+		/*
+		 * Exclude allocable sections that can change:
+		 *	- The .dynsym section can contain section symbols
+		 *		that strip might remove.
+		 *	- The .dynamic section is modified by the setting of
+		 *		this checksum value.
+		 */
 		if ((shdr->sh_type == SHT_DYNSYM) ||
 		    (shdr->sh_type == SHT_DYNAMIC))
 			continue;
--- a/usr/src/cmd/sgs/libelf/common/decl.h	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/common/decl.h	Thu Feb 08 11:58:00 2007 -0800
@@ -23,7 +23,7 @@
 
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -455,8 +455,8 @@
 extern Okay		_elf64_cookscn(Elf_Scn * s);
 extern Dnode		*_elf_dnode(void);
 extern Elf_Data		*_elf_locked_getdata(Elf_Scn *, Elf_Data *);
-extern size_t		_elf32_entsz(Elf32_Word, unsigned);
-extern size_t		_elf64_entsz(Elf64_Word, unsigned);
+extern size_t		_elf32_entsz(Elf *elf, Elf32_Word, unsigned);
+extern size_t		_elf64_entsz(Elf *elf, Elf64_Word, unsigned);
 extern Okay		_elf_inmap(Elf *);
 extern char		*_elf_outmap(int, size_t, unsigned *);
 extern size_t		_elf_outsync(int, char *, size_t, unsigned);
--- a/usr/src/cmd/sgs/libelf/common/update.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/common/update.c	Thu Feb 08 11:58:00 2007 -0800
@@ -24,7 +24,7 @@
  *	  All Rights Reserved
  *
  *
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -173,7 +173,7 @@
 			(void) _elfxx_cookscn(s);
 
 		sh->sh_addralign = 1;
-		if ((sz = (Xword)_elf_entsz(sh->sh_type, ver)) != 0)
+		if ((sz = (Xword)_elf_entsz(elf, sh->sh_type, ver)) != 0)
 			/* LINTED */
 			sh->sh_entsize = (Half)sz;
 		sz = 0;
--- a/usr/src/cmd/sgs/libelf/common/xlate.m4	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/common/xlate.m4	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
  */
 
@@ -689,18 +689,6 @@
 
 
 size_t
-_elf32_entsz(Elf32_Word shtype, unsigned ver)
-{
-	Elf_Type	ttype;
-
-	if (shtype >= sizeof (mtype[0]) / sizeof (mtype[0][0]) ||
-	    (ttype = mtype[ver - 1][shtype]) == ELF_T_BYTE)
-		return (0);
-	return (fmsize[ver - 1][ttype].s_filesz);
-}
-
-
-size_t
 elf32_fsize(Elf_Type type, size_t count, unsigned ver)
 {
 	if (--ver >= EV_CURRENT) {
@@ -731,6 +719,11 @@
 		return (mtype[ver - 1][shtype]);
 
 	switch (shtype) {
+	case SHT_SUNW_symsort:
+	case SHT_SUNW_tlssort:
+		return (ELF_T_WORD);
+	case SHT_SUNW_LDYNSYM:
+		return (ELF_T_SYM);
 	case SHT_SUNW_dof:
 		return (ELF_T_BYTE);
 	case SHT_SUNW_cap:
@@ -794,6 +787,16 @@
 }
 
 
+size_t
+_elf32_entsz(Elf *elf, Elf32_Word shtype, unsigned ver)
+{
+	Elf_Type	ttype;
+
+	ttype = _elf32_mtype(elf, shtype, ver);
+	return ((ttype == ELF_T_BYTE) ? 0 : fmsize[ver - 1][ttype].s_filesz); 
+}
+
+
 /*
  * XX64	This routine is also used to 'version' interactions with Elf64
  *	applications, but there's no way to figure out if the caller is
--- a/usr/src/cmd/sgs/libelf/common/xlate64.m4	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/common/xlate64.m4	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
  */
 
@@ -740,18 +740,6 @@
 
 
 size_t
-_elf64_entsz(Elf64_Word shtype, unsigned ver)
-{
-	Elf_Type	ttype;
-
-	if (shtype >= sizeof (mtype[0]) / sizeof (mtype[0][0]) ||
-	    (ttype = mtype[ver - 1][shtype]) == ELF_T_BYTE)
-		return (0);
-	return (fmsize[ver - 1][ttype].s_filesz);
-}
-
-
-size_t
 elf64_fsize(Elf_Type type, size_t count, unsigned ver)
 {
 	if (--ver >= EV_CURRENT) {
@@ -783,6 +771,11 @@
 		return (mtype[ver - 1][shtype]);
 
 	switch (shtype) {
+	case SHT_SUNW_symsort:
+	case SHT_SUNW_tlssort:
+		return (ELF_T_WORD);
+	case SHT_SUNW_LDYNSYM:
+		return (ELF_T_SYM);
 	case SHT_SUNW_dof:
 		return (ELF_T_BYTE);
 	case SHT_SUNW_cap:
@@ -841,6 +834,16 @@
 }
 
 
+size_t
+_elf64_entsz(Elf *elf, Elf64_Word shtype, unsigned ver)
+{
+	Elf_Type	ttype;
+
+	ttype = _elf64_mtype(elf, shtype, ver);
+	return ((ttype == ELF_T_BYTE) ? 0 : fmsize[ver - 1][ttype].s_filesz); 
+}
+
+
 static Elf_Data *
 xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof)
 						/* !0 -> xlatetof */
--- a/usr/src/cmd/sgs/libelf/demo/README	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/demo/README	Thu Feb 08 11:58:00 2007 -0800
@@ -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 2002 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -54,9 +53,9 @@
 		Demonstrates that libelf is MT-Hot and can be used
 		in a threaded program.
 
-dispsyms.c	print symbols:  scans a ELF file for either
-		a symbol table (either SHT_DYNSYM or SHT_SYMTAB)
-		and displays the symbol tables contents.
+dispsyms.c	print symbols:  scans a ELF file for any symbol tables
+		(SHT_SYMTAB, SHT_DYNSYM, or SHT_SUNW_LDYNSYM) and
+		displays the symbol tables contents.
 
 Makefile	make file to build the above programs.
 
--- a/usr/src/cmd/sgs/libelf/demo/dispsyms.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/libelf/demo/dispsyms.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -31,9 +30,8 @@
  * This program demonstrates the use of the libelf interface to
  * read an ELF file.  dispsyms will open an ELF file using
  * elf_begin(ELF_C_READ) and examine search the ELF file
- * for either a SHT_SYMTAB or SHT_DYNSYM symbol table.
- * If it finds either - it will display the contents of
- * the symbol tables it finds.
+ * for a symbol table (SHT_SYMTAB, SHT_DYNSYM, or SHT_SUNW_LDYNSYM).
+ * It will display the contents of any symbol tables it finds.
  *
  * Note:  This program also understands about the use
  *	  of 'Extended ELF Section indexes' and will
@@ -106,7 +104,8 @@
 			return;
 		}
 		if ((shdr.sh_type != SHT_SYMTAB) &&
-		    (shdr.sh_type != SHT_DYNSYM))
+		    (shdr.sh_type != SHT_DYNSYM) &&
+		    (shdr.sh_type != SHT_SUNW_LDYNSYM))
 			continue;
 
 		/*
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/maps.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -297,6 +296,7 @@
 	mp->mi_pltbase = 0;
 	mp->mi_pltsize = 0;
 	mp->mi_pltentsz = 0;
+	mp->mi_dynsym.st_symn = 0;
 	while ((scn = elf_nextscn(mp->mi_elf, scn)) != 0) {
 		GElf_Shdr 	shdr;
 		Elf_Data *	dp;
@@ -311,16 +311,23 @@
 		switch (shdr.sh_type) {
 		case SHT_DYNSYM:
 			dp = elf_getdata(scn, 0);
-			mp->mi_dynsym.st_syms = dp;
+			mp->mi_dynsym.st_syms_pri = dp;
 			tscn = elf_getscn(mp->mi_elf, shdr.sh_link);
-			mp->mi_dynsym.st_symn =
+			mp->mi_dynsym.st_symn +=
 				shdr.sh_size / shdr.sh_entsize;
 			dp = elf_getdata(tscn, 0);
 			mp->mi_dynsym.st_strs = (char *)dp->d_buf;
 			break;
+		case SHT_SUNW_LDYNSYM:
+			dp = elf_getdata(scn, 0);
+			mp->mi_dynsym.st_syms_aux = dp;
+			mp->mi_dynsym.st_symn_aux =
+				shdr.sh_size / shdr.sh_entsize;
+			mp->mi_dynsym.st_symn += mp->mi_dynsym.st_symn_aux;
+			break;
 		case SHT_SYMTAB:
 			dp = elf_getdata(scn, 0);
-			mp->mi_symtab.st_syms = dp;
+			mp->mi_symtab.st_syms_pri = dp;
 			tscn = elf_getscn(mp->mi_elf, shdr.sh_link);
 			mp->mi_symtab.st_symn =
 				shdr.sh_size / shdr.sh_entsize;
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.h	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/rdb.h	Thu Feb 08 11:58:00 2007 -0800
@@ -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 2000 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -72,28 +71,46 @@
 	RET_OK = 0
 } retc_t;
 
+/*
+ * sym_tbl_t contains a primary and an (optional) auxiliary symbol table, which
+ * we wish to treat as a single logical symbol table. In this logical table,
+ * the data from the auxiliary table preceeds that from the primary. Symbol
+ * indices start at [0], which is the first item in the auxiliary table
+ * if there is one. The sole purpose for this is so that we can treat the
+ * combination of .SUNW_ldynsym and .dynsym sections as a logically single
+ * entity without having to violate the public interface to libelf.
+ *
+ * Both tables must share the same string table section.
+ *
+ * The symtab_getsym() function serves as a gelf_getsym() replacement
+ * that is aware of the two tables and makes them look like a single table
+ * to the caller.
+ *
+ */
 typedef struct sym_tbl {
-	Elf_Data *	st_syms;	/* start of table */
-	char *		st_strs;	/* ptr to strings */
-	size_t		st_symn;	/* number of entries */
+	Elf_Data *	st_syms_pri;	/* start of primary table */
+	Elf_Data *	st_syms_aux;	/* start of auxiliary table */
+	char		*st_strs;	/* ptr to strings */
+	size_t		st_symn;	/* Total # of entries in both tables */
+	size_t		st_symn_aux;	/* # of entries in auxiliary table */
 } sym_tbl_t;
 
 
 typedef struct	map_info {
-	char *			mi_name;	/* file info */
-	char *			mi_refname;	/* filter reference name */
+	char			*mi_name;	/* file info */
+	char			*mi_refname;	/* filter reference name */
 	ulong_t			mi_addr;	/* start address */
 	ulong_t			mi_end;		/* end address */
 	int			mi_mapfd;	/* file desc. for mapping */
 	unsigned		mi_pltentsz;	/* size of PLT entries */
-	Elf *			mi_elf;		/* elf handle so we can close */
+	Elf			*mi_elf;	/* elf handle so we can close */
 	GElf_Ehdr		mi_ehdr;
 	sym_tbl_t		mi_symtab;	/* symbol table */
 	sym_tbl_t		mi_dynsym;	/* dynamic symbol table */
 	Lmid_t			mi_lmident;	/* Link Map Ident */
 	ulong_t			mi_pltbase;	/* PLT base address */
 	ulong_t			mi_pltsize;	/* size of PLT table */
-	struct map_info *	mi_next;
+	struct map_info		*mi_next;
 	ulong_t			mi_flags;	/* misc flags */
 	rd_loadobj_t		mi_loadobj;	/* keep the old loadobj for */
 						/* 	good luck */
@@ -109,8 +126,8 @@
 
 
 typedef struct map_list {
-	map_info_t *		ml_head;
-	map_info_t *		ml_tail;
+	map_info_t		*ml_head;
+	map_info_t		*ml_tail;
 } map_list_t;
 
 
@@ -121,7 +138,7 @@
 	ulong_t			bl_addr;	/* address of breakpoint */
 	bptinstr_t 		bl_instr;	/* original instruction */
 	unsigned		bl_flags;	/* break point flags */
-	struct bpt_struct *	bl_next;
+	struct bpt_struct	*bl_next;
 } bptlist_t;
 
 #define	FLG_BP_USERDEF		0x0001		/* user defined BP */
@@ -143,7 +160,7 @@
 
 struct ps_prochandle {
 	pid_t		pp_pid;		/* debug process pid */
-	rd_agent_t *	pp_rap;		/* rtld_db handle */
+	rd_agent_t	*pp_rap;	/* rtld_db handle */
 	int		pp_ctlfd;	/* open ctl proc fd */
 	int		pp_statusfd;	/* open status proc fd */
 	int		pp_asfd;	/* open as proc fd */
@@ -153,8 +170,8 @@
 	map_info_t	pp_ldsomap;	/* ld.so.1 map info */
 	map_info_t	pp_execmap;	/* exec map info */
 	map_list_t	pp_lmaplist;	/* list of link map infos */
-	bptlist_t *	pp_breakpoints;	/* break point list */
-	void *		pp_auxvp;	/* pointer to AUX vectors */
+	bptlist_t	*pp_breakpoints; /* break point list */
+	void		*pp_auxvp;	/* pointer to AUX vectors */
 	int		pp_flags;	/* misc flags */
 	int		pp_dmodel;	/* data model */
 };
@@ -196,10 +213,10 @@
 /*
  * Functions
  */
-extern map_info_t *	addr_to_map(struct ps_prochandle *, ulong_t);
+extern map_info_t	*addr_to_map(struct ps_prochandle *, ulong_t);
 extern retc_t		addr_to_sym(struct ps_prochandle *, ulong_t,
 				GElf_Sym *, char **);
-extern void		CallStack(struct ps_prochandle * ph);
+extern void		CallStack(struct ps_prochandle *ph);
 extern unsigned		continue_to_break(struct ps_prochandle *);
 extern retc_t		delete_all_breakpoints(struct ps_prochandle *);
 extern retc_t		delete_breakpoint(struct ps_prochandle *, ulong_t,
@@ -210,15 +227,15 @@
 extern retc_t		display_maps(struct ps_prochandle *);
 extern retc_t		display_linkmaps(struct ps_prochandle *);
 extern void		free_linkmaps(struct ps_prochandle *);
-extern bptlist_t *	find_bp(struct ps_prochandle * ph, ulong_t addr);
+extern bptlist_t	*find_bp(struct ps_prochandle *ph, ulong_t addr);
 extern retc_t		get_linkmaps(struct ps_prochandle *);
 extern ulong_t		hexstr_to_num(const char *);
 extern ulong_t		is_plt(struct ps_prochandle *, ulong_t);
 extern void		list_breakpoints(struct ps_prochandle *);
 extern retc_t		load_map(struct ps_prochandle *, caddr_t,
-				map_info_t * mp);
-extern char *		print_address(unsigned long);
-extern char *		print_address_ps(struct ps_prochandle *,
+				map_info_t *mp);
+extern char		*print_address(unsigned long);
+extern char		*print_address_ps(struct ps_prochandle *,
 				unsigned long, unsigned);
 extern void		print_mem(struct ps_prochandle *, ulong_t, int,
 				char *);
@@ -239,7 +256,7 @@
 extern void		step_to_addr(struct ps_prochandle *, ulong_t);
 extern retc_t		str_map_sym(const char *, map_info_t *, GElf_Sym *,
 				char **);
-extern map_info_t *	str_to_map(struct ps_prochandle *, const char *);
+extern map_info_t	*str_to_map(struct ps_prochandle *, const char *);
 extern retc_t		str_to_sym(struct ps_prochandle *, const char *,
 				GElf_Sym *);
 extern int		yyparse(void);
--- a/usr/src/cmd/sgs/librtld_db/rdb_demo/common/syms.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/librtld_db/rdb_demo/common/syms.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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 1996 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -31,17 +30,38 @@
 #include "rdb.h"
 
 
+/*
+ * Given a symbol index, look up the corresponding symbol from the
+ * given symbol table.
+ *
+ * This function allows the caller to treat the symbol table as a single
+ * logical entity even though there may be 2 actual ELF symbol tables
+ * involved. See the comments in Pcontrol.h for details.
+ */
+static GElf_Sym *
+symtab_getsym(sym_tbl_t *symtab, int ndx, GElf_Sym *dst)
+{
+	/* If index is in range of primary symtab, look it up there */
+	if (ndx >= symtab->st_symn_aux) {
+		return (gelf_getsym(symtab->st_syms_pri,
+		    ndx - symtab->st_symn_aux, dst));
+	}
+
+	/* Not in primary: Look it up in the auxiliary symtab */
+	return (gelf_getsym(symtab->st_syms_aux, ndx, dst));
+}
+
 retc_t
-str_map_sym(const char * symname, map_info_t * mp, GElf_Sym * symptr,
-	char ** str)
+str_map_sym(const char *symname, map_info_t *mp, GElf_Sym *symptr,
+	char **str)
 {
-	sym_tbl_t *	symp;
-	char *		strs;
+	sym_tbl_t	*symp;
+	char		*strs;
 	int		i;
 
-	if (mp->mi_symtab.st_syms)
+	if (mp->mi_symtab.st_syms_pri)
 		symp = &(mp->mi_symtab);
-	else if (mp->mi_dynsym.st_syms)
+	else if (mp->mi_dynsym.st_syms_pri)
 		symp = &(mp->mi_dynsym);
 	else
 		return (RET_FAILED);
@@ -51,8 +71,8 @@
 	for (i = 0; i < (int)symp->st_symn; i++) {
 		GElf_Sym sym;
 
-		if (gelf_getsym(symp->st_syms, i, &sym) == 0) {
-			printf("gelf_getsym(): %s\n", elf_errmsg(-1));
+		if (symtab_getsym(symp, i, &sym) == 0) {
+			printf("symtab_getsym(): %s\n", elf_errmsg(-1));
 			return (RET_FAILED);
 		}
 
@@ -105,13 +125,13 @@
 
 
 retc_t
-addr_map_sym(map_info_t * mp, ulong_t addr, GElf_Sym * symptr,
-	char ** str)
+addr_map_sym(map_info_t *mp, ulong_t addr, GElf_Sym *symptr,
+	char **str)
 {
-	sym_tbl_t *	symp;
+	sym_tbl_t	*symp;
 	GElf_Sym	sym;
-	GElf_Sym *	symr = 0;
-	GElf_Sym *	lsymr = 0;
+	GElf_Sym	*symr = 0;
+	GElf_Sym	*lsymr = 0;
 	GElf_Sym	rsym;
 	GElf_Sym	lsym;
 	ulong_t		baseaddr = 0;
@@ -120,9 +140,9 @@
 	if ((mp->mi_flags & FLG_MI_EXEC) == 0)
 		baseaddr = (ulong_t)mp->mi_addr;
 
-	if (mp->mi_symtab.st_syms)
+	if (mp->mi_symtab.st_syms_pri)
 		symp = &(mp->mi_symtab);
-	else if (mp->mi_dynsym.st_syms)
+	else if (mp->mi_dynsym.st_syms_pri)
 		symp = &(mp->mi_dynsym);
 	else
 		return (RET_FAILED);
@@ -134,8 +154,8 @@
 	for (i = 0; i < (int)symp->st_symn; i++) {
 		ulong_t	svalue;
 
-		if (gelf_getsym(symp->st_syms, i, &sym) == 0) {
-			printf("gelf_getsym(): %s\n", elf_errmsg(-1));
+		if (symtab_getsym(symp, i, &sym) == 0) {
+			printf("symtab_getsym(): %s\n", elf_errmsg(-1));
 			return (RET_FAILED);
 		}
 		if ((sym.st_name == 0) || (sym.st_shndx == SHN_UNDEF))
@@ -191,10 +211,10 @@
 
 
 retc_t
-addr_to_sym(struct ps_prochandle * ph, ulong_t addr,
-	GElf_Sym * symp, char ** str)
+addr_to_sym(struct ps_prochandle *ph, ulong_t addr,
+	GElf_Sym *symp, char **str)
 {
-	map_info_t *	mip;
+	map_info_t	*mip;
 
 	if ((mip = addr_to_map(ph, addr)) == 0)
 		return (RET_FAILED);
@@ -204,10 +224,9 @@
 
 
 retc_t
-str_to_sym(struct ps_prochandle * ph, const char * name,
-	GElf_Sym * symp)
+str_to_sym(struct ps_prochandle *ph, const char *name, GElf_Sym *symp)
 {
-	map_info_t *	mip;
+	map_info_t	*mip;
 
 	if (ph->pp_lmaplist.ml_head == 0) {
 		if (str_map_sym(name, &(ph->pp_ldsomap), symp, NULL) == RET_OK)
--- a/usr/src/cmd/sgs/mcs/common/file.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/mcs/common/file.c	Thu Feb 08 11:58:00 2007 -0800
@@ -23,7 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -786,7 +786,13 @@
 			}
 			*elf_data = *data;
 
-			/* SHT_{DYNSYM, SYMTAB} might need some change */
+			/*
+			 * SHT_{DYNSYM, SYMTAB} might need some change, as
+			 * they may contain section symbols that reference
+			 * removed sections. SHT_SUNW_LDYNSYM does not
+			 * contain section symbols, and therefore does not
+			 * have this issue.
+			 */
 			if (((src_shdr.sh_type == SHT_SYMTAB) ||
 			    (src_shdr.sh_type == SHT_DYNSYM)) &&
 			    src_shdr.sh_entsize != 0 &&
--- a/usr/src/cmd/sgs/nm/common/nm.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/nm/common/nm.c	Thu Feb 08 11:58:00 2007 -0800
@@ -24,7 +24,7 @@
  * Copyright (c) 1989 AT&T
  * All Rights Reserved
  *
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -78,7 +78,7 @@
 #define	REG_WEAK  "R*"
 #define	REG_LOCL  "r"
 
-#define	OPTSTR	":APDoxhvnursplCVefgRTt:" /* option string for getopt() */
+#define	OPTSTR	":APDoxhvnursplLCVefgRTt:" /* option string for getopt() */
 
 #define	DATESIZE 60
 
@@ -127,6 +127,7 @@
 	p_flag = 0,	/* produce terse output */
 	P_flag = 0,	/* Portable format output */
 	l_flag = 0,	/* produce long listing of output */
+	L_flag = 0,	/* print SUNW_LDYNSYM instead of SYMTAB */
 	D_flag = 0,	/* print DYNSYM instead of SYMTAB */
 	C_flag = 0,	/* print decoded C++ names */
 	A_flag = 0,	/* File name */
@@ -285,7 +286,17 @@
 				break;
 		case 'l':	l_flag = 1;
 				break;
-		case 'D':	D_flag = 1;
+		case 'L':	if (D_flag == 1) {
+					(void) fprintf(stderr, gettext(
+					"nm: -D set. -L ignored\n"));
+				} else
+					L_flag = 1;
+				break;
+		case 'D':	if (L_flag == 1) {
+					(void) fprintf(stderr, gettext(
+					"nm: -L set. -D ignored\n"));
+				} else
+					D_flag = 1;
 				break;
 		case 'C':
 				C_flag = 1;
@@ -565,6 +576,8 @@
 
 	if (D_flag)
 		symtabtype = SHT_DYNSYM;
+	else if (L_flag)
+		symtabtype = SHT_SUNW_LDYNSYM;
 	else
 		symtabtype = SHT_SYMTAB;
 
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Thu Feb 08 11:58:00 2007 -0800
@@ -1160,8 +1160,12 @@
 6475344 DTrace needs ELF function and data symbols sorted by address (D)
 	PSARC/2007/026 ELF symbol sort sections
 6494228 pclose() error when an audit library calls popen() and the main target
-	is being run under ldd
+	is being run under ldd (D)
 6518480 ld -melf_i386 doesn't complain (D)
+6519951 bfu is just another word for exit today (RPATH -> RUNPATH conversion
+	bites us)  (D) 
 6521504 ld: hardware capabilities processing from relocatables objects needs
 	hardening.
 6521608	assertion failure in runtime linker related to auditing
+6518322 Some ELF utilities need updating for .SUNW_ldynsym section (D)
+	PSARC/2007/074 -L option for nm(1) to display SHT_SUNW_LDYNSYM symbols
--- a/usr/src/cmd/sgs/prof/common/prof.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/prof/common/prof.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -1310,10 +1309,10 @@
 	int lth;			/* space needed for name */
 	int get;			/* amount of space to get */
 
-	name = &(ldpter->pf_symstr_p)[symbol.ps_sym.st_name];
-	if (name == NULL)  {
+	name = elf_strptr(ldpter->pf_elf_p, ldpter->pf_symstr_ndx,
+	    symbol.ps_sym.st_name);
+	if (name == NULL)
 		return ("<<bad symbol name>>");
-	}
 
 	if (Cflag)
 		name = demangled_name(name);
--- a/usr/src/cmd/sgs/prof/common/rdelf.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/prof/common/rdelf.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -211,51 +210,81 @@
 static void
 fetch_symtab(Elf *elf, char *filename, mod_info_t *module)
 {
-	Elf_Scn		*scn = NULL, *sym = NULL;
+	Elf_Scn		*scn = NULL, *sym_pri = NULL, *sym_aux = NULL;
 	GElf_Word	strndx = 0;
 	size_t		i, nsyms, nfuncs;
-	Elf_Data	*symdata;
+	GElf_Xword	nsyms_pri, nsyms_aux = 0;
+	Elf_Data	*symdata_pri, *symdata_aux;
 	nltype		*nl, *npe;
+	int		symtab_found = 0;
 
-	while ((scn = elf_nextscn(elf, scn)) != NULL) {
+
+	/*
+	 * Scan the section headers looking for a symbol table. Our
+	 * preference is to use .symtab, because it contains the full
+	 * set of symbols. If we find it, we stop looking immediately
+	 * and use it. In the absence of a .symtab section, we are
+	 * willing to use the dynamic symbol table (.dynsym), possibly
+	 * augmented by the .SUNW_ldynsym, which contains local symbols.
+	 */
+	while ((symtab_found == 0) && ((scn = elf_nextscn(elf, scn)) != NULL)) {
 
 		GElf_Shdr shdr;
 
 		if (gelf_getshdr(scn, &shdr) == NULL)
 			continue;
 
-		if (shdr.sh_type == SHT_SYMTAB ||
-					shdr.sh_type == SHT_DYNSYM) {
-			GElf_Xword chk = shdr.sh_size / shdr.sh_entsize;
-
-			nsyms = (size_t)(shdr.sh_size / shdr.sh_entsize);
+		switch (shdr.sh_type) {
+		case SHT_SYMTAB:
+			nsyms_pri = shdr.sh_size / shdr.sh_entsize;
+			strndx = shdr.sh_link;
+			sym_pri = scn;
+			/* Throw away .SUNW_ldynsym. It is for .dynsym only */
+			nsyms_aux = 0;
+			sym_aux = NULL;
+			/* We have found the best symbol table. Stop looking */
+			symtab_found = 1;
+			break;
 
-			if (chk != (GElf_Xword) nsyms) {
-				(void) fprintf(stderr, "%s: can't handle"
-					"more than 2^32 symbols", cmdname);
-				exit(ERR_INPUT);
-			}
-
+		case SHT_DYNSYM:
+			/* We will use .dynsym if no .symtab is found */
+			nsyms_pri = shdr.sh_size / shdr.sh_entsize;
 			strndx = shdr.sh_link;
-			sym = scn;
-		}
+			sym_pri = scn;
+			break;
 
-		/*
-		 * If we've found a real symbol table, we're done.
-		 */
-		if (shdr.sh_type == SHT_SYMTAB)
+		case SHT_SUNW_LDYNSYM:
+			/* Auxiliary table, used with .dynsym */
+			nsyms_aux = shdr.sh_size / shdr.sh_entsize;
+			sym_aux = scn;
 			break;
+		}
 	}
 
-	if (sym == NULL || strndx == 0) {
+	if (sym_pri == NULL || strndx == 0) {
 		(void) fprintf(stderr, "%s: missing symbol table in %s\n",
 						    cmdname, filename);
 		exit(ERR_ELF);
 	}
 
-	if ((symdata = elf_getdata(scn, NULL)) == NULL) {
+	nsyms = (size_t)(nsyms_pri + nsyms_aux);
+	if ((nsyms_pri + nsyms_aux) != (GElf_Xword)nsyms) {
+		(void) fprintf(stderr,
+		    "%s: can't handle more than 2^32 symbols", cmdname);
+		exit(ERR_INPUT);
+	}
+
+	if ((symdata_pri = elf_getdata(sym_pri, NULL)) == NULL) {
 		(void) fprintf(stderr, "%s: can't read symbol data from %s\n",
-						    cmdname, filename);
+		    cmdname, filename);
+		exit(ERR_ELF);
+	}
+
+	if ((sym_aux != NULL) &&
+	    ((symdata_aux = elf_getdata(sym_aux, NULL)) == NULL)) {
+		(void) fprintf(stderr,
+		    "%s: can't read .SUNW_ldynsym symbol data from %s\n",
+		    cmdname, filename);
 		exit(ERR_ELF);
 	}
 
@@ -276,7 +305,16 @@
 		GElf_Sym	gsym;
 		char		*name;
 
-		(void) gelf_getsym(symdata, i, &gsym);
+		/*
+		 * Look up the symbol. In the case where we have a
+		 * .SUNW_ldynsym/.dynsym pair, we treat them as a single
+		 * logical table, with the data in .SUNW_ldynsym coming
+		 * before the data in .dynsym.
+		 */
+		if (i >= nsyms_aux)
+			(void) gelf_getsym(symdata_pri, i - nsyms_aux, &gsym);
+		else
+			(void) gelf_getsym(symdata_aux, i, &gsym);
 
 		name = elf_strptr(elf, strndx, gsym.st_name);
 
--- a/usr/src/cmd/sgs/prof/common/symintHdr.h	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/prof/common/symintHdr.h	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
@@ -23,7 +22,7 @@
 /*	  All Rights Reserved  	*/
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -159,22 +158,28 @@
 typedef struct symint_prof_file
 	PROF_FILE;
 
+
+/*
+ * symint_prof_file contains a primary and an (optional) auxiliary
+ * symbol table, which we wish to treat as a single logical symbol table.
+ * In this logical table, the data from the auxiliary table preceeds that
+ * from the primary. Symbol indices start at [0], which is the first item
+ * in the auxiliary table if there is one. The sole purpose for this is so
+ * that we can treat the combination of .SUNW_ldynsym and .dynsym sections
+ * as a logically single entity.
+ *
+ * Both tables must share the same string table section.
+ */
 struct symint_prof_file {
 	int		pf_fildes;	/* file descriptor */
 	Elf		*pf_elf_p;	/* elf descriptor */
 	Elf32_Ehdr	*pf_elfhd_p;	/* elf header */
-	Elf32_Shdr	*pf_snmshd_p;	/* section names header */
 	Elf_Data	*pf_snmdat_p;	/* section names data */
-	Elf32_Shdr	*pf_symshd_p;	/* symbol table header */
-	Elf_Data	*pf_symdat_p;	/* symbol table data */
-	Elf32_Shdr	*pf_strshd_p;	/* symbol strings header */
-	Elf_Data	*pf_strdat_p;	/* symbol strings data */
-	char		*pf_symstr_p;	/* symbol table strings */
-	int		pf_nstsyms;	/* number of symbols in symbol table */
-	Elf32_Shdr	*pf_debugshd_p;	/* debug header */
-	Elf_Data	*pf_debugdat_p;	/* debug data */
-	Elf32_Shdr	*pf_lineshd_p;	/* line header */
-	Elf_Data	*pf_linedat_p;	/* line data */
+	Elf_Data	*pf_symdat_pri_p; /* primary symbol table data */
+	Elf_Data	*pf_symdat_aux_p; /* auxiliary symbol table data */
+	Elf32_Word	pf_symstr_ndx;	 /* Section index of string table */
+	int		pf_nstsyms;	/* total # symbols in both tables */
+	int		pf_nstsyms_aux;	/* # symbols in auxiliary table */
 
 	Elf32_Shdr	*pf_shdarr_p;	/* complete array of section hdrs */
 
--- a/usr/src/cmd/sgs/prof/common/symintLoad.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/prof/common/symintLoad.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -119,7 +118,10 @@
 PROF_SYMBOL *
 _symintLoad(PROF_FILE *proffilePtr)
 {
-	Elf_Data	*symdat_p;
+	Elf_Data	*symdat_pri_p;
+	Elf_Data	*symdat_aux_p;
+	size_t		nsyms_pri;
+	PROF_SYMBOL	*symlist;
 
 	DEBUG_LOC("_symintLoad: top");
 
@@ -129,17 +131,20 @@
 	 * sanity checks.
 	 */
 	DEBUG_EXP(printf("profPtr = %x\n", profPtr));
-	DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n", profPtr->pf_symdat_p));
+	DEBUG_EXP(printf("profPtr->pf_symdat_p = %x\n",
+	    profPtr->pf_symdat_pri_p));
 	DEBUG_EXP(printf("profPtr->pf_nstsyms = %x\n", profPtr->pf_nstsyms));
 
 	assert(profPtr != 0);
-	assert(profPtr->pf_symdat_p != 0);
+	assert(profPtr->pf_symdat_pri_p != 0);
 	assert(profPtr->pf_nstsyms != 0);
 
-	symdat_p = profPtr->pf_symdat_p;
-	DEBUG_EXP(printf("symdat_p->d_size = %x\n", symdat_p->d_size));
+	symdat_pri_p = profPtr->pf_symdat_pri_p;
+	symdat_aux_p = profPtr->pf_symdat_aux_p;
+	nsyms_pri = profPtr->pf_nstsyms - profPtr->pf_nstsyms_aux;
+	DEBUG_EXP(printf("symdat_pri_p->d_size = %x\n", symdat_pri_p->d_size));
 
-	prstsym_size = (symdat_p->d_size / profPtr->pf_nstsyms);
+	prstsym_size = (symdat_pri_p->d_size / profPtr->pf_nstsyms);
 	DEBUG_EXP(printf("_symintLoad: prstsym_size = %d\n",
 	    prstsym_size));
 
@@ -149,22 +154,34 @@
 	 *  ARE THE SAME SIZE & (effectively) HAVE THE SAME FIELDS!
 	 *  Set the descriptive `parameters' accordingly.
 	 *
-	 * (We'll take a copy, to simplify the 'Drop'
-	 *  logic.)
+	 * If there is an auxiliary symbol table (.SUNW_ldynsym) augmenting
+	 * the dynamic symbol table (.dynsym), then we copy both tables
+	 * into our copy, with the auxiliary coming first.
+	 *
+	 * (We'll take a copy, to simplify the 'Drop' logic.)
 	 */
 
 	{
-	int st_size;	/* size of symbol table data */
+	size_t st_size;	/* size of symbol table data */
 
-	st_size = symdat_p->d_size;
+	st_size = symdat_pri_p->d_size;
+	if (profPtr->pf_nstsyms_aux != 0)
+		st_size += symdat_aux_p->d_size;
 
 	NO_DEBUG_LOC("_symintLoad: before malloc for symbol list (PROF)");
-	prsym_list_p = (PROF_SYMBOL *)_Malloc(st_size, 1);
+	prsym_list_p = symlist = (PROF_SYMBOL *)_Malloc(st_size, 1);
 	NO_DEBUG_LOC("_symintLoad: after malloc for symbol list (PROF)");
 
+	if (profPtr->pf_nstsyms_aux > 0) {
+		NO_DEBUG_LOC("_symintLoad: before memcpy for "
+		    "auxiliary symbol list (PROF)");
+		(void) memcpy(symlist, symdat_aux_p->d_buf,
+		    symdat_aux_p->d_size);
+		symlist += profPtr->pf_nstsyms_aux;
+	}
+
 	NO_DEBUG_LOC("_symintLoad: before memcpy for symbol list (PROF)");
-	(void) memcpy((char *)&(prsym_list_p->ps_sym), symdat_p->d_buf,
-	    st_size);
+	(void) memcpy(symlist, symdat_pri_p->d_buf, symdat_pri_p->d_size);
 
 	profPtr->pf_nsyms = profPtr->pf_nstsyms;
 	}
--- a/usr/src/cmd/sgs/prof/common/symintOpen.c	Thu Feb 08 10:43:29 2007 -0800
+++ b/usr/src/cmd/sgs/prof/common/symintOpen.c	Thu Feb 08 11:58:00 2007 -0800
@@ -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.
@@ -21,7 +20,7 @@
  */
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -85,14 +84,9 @@
  */
 
 /*
- * #defines and globals.
+ * globals
  */
 
-#define	SCN_NAME_DEBUG	".debug"	/* debug information section */
-#define	SCN_NAME_LINE	".line"		/* line number section */
-#define	SCN_NAME_SYM	".symtab"	/* symbol table entry section */
-#define	SCN_NAME_SST	".strtab"	/* symbol table string table */
-
 
 static char
 	*fail_open_s =	"Unable to open file",
@@ -103,7 +97,8 @@
 	*fail_dat_s =	"Unable to get data for section",
 	*fail_sym_s =	"Cannot find symbol table section in",
 	*fail_pfsym_s =	"Unable to process symbols in",
-	*fail_buf_s =	"Data buffer is null for section"
+	*fail_buf_s =	"Data buffer is null for section",
+	*fail_sym32_s =	"Cannot handle more than 2^32 symbols"
 	;
 
 
@@ -157,6 +152,7 @@
 	Elf_Scn		*tscn_p;
 	Elf32_Shdr	*tshd_p;
 	int		k;
+	Elf64_Xword	nsyms_pri = 0, nsyms_aux = 0;
 
 	executableName = aout_name;
 
@@ -186,7 +182,7 @@
 	if (tscn_p == NULL)
 		_err_exit("%s %d in %s.", fail_sec_s, k, aout_name);
 
-	if ((pfile_p->pf_snmshd_p = elf32_getshdr(tscn_p)) == NULL)
+	if (elf32_getshdr(tscn_p) == NULL)
 		_err_exit("%s %s in %s.", fail_shd_s, "header names",
 		aout_name);
 	if ((pfile_p->pf_snmdat_p = elf_getdata(tscn_p, NULL)) == NULL)
@@ -224,11 +220,20 @@
 	int	shdsize = pfile_p->pf_elfhd_p->e_shentsize;
 	int	i;
 	char	*s;
+	int		symtab_found = 0;
 
-	i = 0;
 	tscn_p = 0;
 	DEBUG_EXP(printf("Section header entry size = %d\n", shdsize));
 	DEBUG_EXP(printf("First section header name = %s\n", &shdnms_p[1]));
+	pfile_p->pf_symdat_aux_p = NULL;
+	/*
+	 * Scan the section headers looking for a symbol table. Our
+	 * preference is to use .symtab, because it contains the full
+	 * set of symbols. If we find it, we stop looking immediately
+	 * and use it. In the absence of a .symtab section, we are
+	 * willing to use the dynamic symbol table (.dynsym), possibly
+	 * augmented by the .SUNW_ldynsym, which contains local symbols.
+	 */
 	while ((tscn_p = elf_nextscn(telf_p, tscn_p)) != NULL) {
 		if ((tshd_p = elf32_getshdr(tscn_p)) == NULL)
 			_err_exit("%s %d in %s.", fail_shd_s, i, aout_name);
@@ -240,35 +245,52 @@
 		DEBUG_EXP(printf("index of section name = %d\n",
 		    tshd_p->sh_name));
 		DEBUG_EXP(printf("_symintOpen: reading section %s\n", s));
-		if (strcmp(s, SCN_NAME_DEBUG) == 0) {
-			DEBUG_LOC("_symintOpen: found debug section");
-			pfile_p->pf_debugshd_p = tshd_p;
-			pfile_p->pf_debugdat_p = section_data_p(tscn_p,
-			    "debug");
-		} else if (strcmp(s, SCN_NAME_LINE) == 0) {
-			DEBUG_LOC("_symintOpen: found line section");
-			pfile_p->pf_lineshd_p = tshd_p;
-			pfile_p->pf_linedat_p = section_data_p(tscn_p, "line");
-		} else if (strcmp(s, SCN_NAME_SYM) == 0) {
+
+		if (symtab_found)
+			continue;
+		switch (tshd_p->sh_type) {
+		case SHT_SYMTAB:
 			DEBUG_LOC("_symintOpen: found symbol section");
-			pfile_p->pf_symshd_p = tshd_p;
-			pfile_p->pf_symdat_p = section_data_p(tscn_p, "symtab");
-			pfile_p->pf_nstsyms =
-				tshd_p->sh_size / tshd_p->sh_entsize;
-		} else if (strcmp(s, SCN_NAME_SST) == 0) {
-			DEBUG_LOC("_symintOpen: found symbol table strings");
-			pfile_p->pf_strshd_p = tshd_p;
-			pfile_p->pf_strdat_p = section_data_p(tscn_p, "strtab");
-			pfile_p->pf_symstr_p = pfile_p->pf_strdat_p->d_buf;
+			pfile_p->pf_symstr_ndx = tshd_p->sh_link;
+			pfile_p->pf_symdat_pri_p =
+			    section_data_p(tscn_p, "symtab");
+			nsyms_pri = tshd_p->sh_size / tshd_p->sh_entsize;
+			/* Throw away .SUNW_ldynsym. It is for .dynsym only */
+			nsyms_aux = 0;
+			pfile_p->pf_symdat_aux_p = NULL;
+			/* We have found the best symbol table. Stop looking */
+			symtab_found = 1;
+			break;
+
+		case SHT_DYNSYM:
+			/* We will use .dynsym if no .symtab is found */
+			DEBUG_LOC("_symintOpen: found dynamic symbol section");
+			pfile_p->pf_symstr_ndx = tshd_p->sh_link;
+			pfile_p->pf_symdat_pri_p =
+			    section_data_p(tscn_p, "dynsym");
+			nsyms_pri = tshd_p->sh_size / tshd_p->sh_entsize;
+			break;
+
+		case SHT_SUNW_LDYNSYM:
+			/* Auxiliary table, used with .dynsym */
+			DEBUG_LOC("_symintOpen: found dynamic symbol section");
+			pfile_p->pf_symdat_aux_p =
+			    section_data_p(tscn_p, "SUNW_ldynsym");
+			nsyms_aux = tshd_p->sh_size / tshd_p->sh_entsize;
+			break;
 		}
 
-		i++;
 	}
 	}
 
-	if (!pfile_p->pf_symdat_p) {
+	if (pfile_p->pf_symdat_pri_p == NULL || pfile_p->pf_symstr_ndx == 0)
 		_err_exit("%s %s.", fail_sym_s, executableName);
-	}
+
+	pfile_p->pf_nstsyms = (int)(nsyms_pri + nsyms_aux);
+	pfile_p->pf_nstsyms_aux = (int)nsyms_aux;
+	if ((nsyms_pri + nsyms_aux) != (Elf64_Xword)pfile_p->pf_nstsyms)
+		_err_exit("%s %s.", fail_sym32_s, executableName);
+
 
 	DEBUG_LOC("_symintOpen: after for loop that reads the sections");