changeset 2647:e440e3da2a6f

6464235 executing the 64-bit ld(1) should be easy
author rie
date Wed, 30 Aug 2006 10:15:44 -0700
parents 5c699a479a2a
children 6c17d29a3f67
files usr/src/cmd/sgs/crle/common/crle.c usr/src/cmd/sgs/dump/common/dump.c usr/src/cmd/sgs/elfdump/common/elfdump.msg usr/src/cmd/sgs/elfdump/common/main.c usr/src/cmd/sgs/include/conv.h usr/src/cmd/sgs/include/debug.h usr/src/cmd/sgs/include/i386/machdep.h usr/src/cmd/sgs/include/sparc/machdep.h usr/src/cmd/sgs/lari/lari.pl usr/src/cmd/sgs/ld/common/ld.c usr/src/cmd/sgs/ld/common/ld.msg usr/src/cmd/sgs/libconv/common/arch.c usr/src/cmd/sgs/libconv/common/llib-lconv usr/src/cmd/sgs/libconv/common/sections.c usr/src/cmd/sgs/libld/common/_libld.h usr/src/cmd/sgs/libld/common/args.c usr/src/cmd/sgs/libld/common/files.c usr/src/cmd/sgs/libld/common/libld.msg usr/src/cmd/sgs/libld/common/machrel.amd.c usr/src/cmd/sgs/libld/common/machrel.intel.c usr/src/cmd/sgs/libld/common/machrel.sparc.c usr/src/cmd/sgs/libld/common/order.c usr/src/cmd/sgs/libld/common/outfile.c usr/src/cmd/sgs/libld/common/relocate.c usr/src/cmd/sgs/libld/common/sections.c usr/src/cmd/sgs/libld/common/support.c usr/src/cmd/sgs/liblddbg/common/liblddbg.msg usr/src/cmd/sgs/liblddbg/common/llib-llddbg usr/src/cmd/sgs/liblddbg/common/mapfile-vers usr/src/cmd/sgs/liblddbg/common/sections.c usr/src/cmd/sgs/liblddbg/common/segments.c usr/src/cmd/sgs/liblddbg/common/shdr.c usr/src/cmd/sgs/mcs/common/main.c usr/src/cmd/sgs/moe/common/moe.c usr/src/cmd/sgs/nm/common/nm.c usr/src/cmd/sgs/packages/common/SUNWonld-README usr/src/cmd/sgs/pvs/common/pvs.c usr/src/tools/findunref/exception_list usr/src/uts/common/krtld/reloc.h
diffstat 39 files changed, 345 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/crle/common/crle.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/crle/common/crle.c	Wed Aug 30 10:15:44 2006 -0700
@@ -337,7 +337,7 @@
 	}
 #else
 	if (c_class == ELFCLASS64) {
-		conv_check_native(argv, envp);
+		(void) conv_check_native(argv, envp);
 
 		/*
 		 * conv_check_native() should not return, as we expect
@@ -346,7 +346,7 @@
 		 * available on this system.
 		 */
 		(void) fprintf(stderr, MSG_INTL(MSG_ISA32_NO64SUP),
-			crle.c_name);
+		    crle.c_name);
 		return (1);
 	}
 #endif
--- a/usr/src/cmd/sgs/dump/common/dump.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/dump/common/dump.c	Wed Aug 30 10:15:44 2006 -0700
@@ -1981,7 +1981,7 @@
 	/*
 	 * Check for a binary that better fits this architecture.
 	 */
-	conv_check_native(argv, envp);
+	(void) conv_check_native(argv, envp);
 
 	prog_name = argv[0];
 
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg	Wed Aug 30 10:15:44 2006 -0700
@@ -35,7 +35,7 @@
 # Usage Messages
 
 @ MSG_USAGE_BRIEF	"usage: %s [-cCdegGhHiklmnprsuvy] [-N name] \
-			 [-W file] file(s)\n"
+			 [-w file] file(s)\n"
 @ MSG_USAGE_DETAIL1	"\t[-c]\t\tdump section header information\n"
 @ MSG_USAGE_DETAIL2	"\t[-C]\t\tdemangle C++ symbol names\n"
 @ MSG_USAGE_DETAIL3	"\t[-d]\t\tdump the contents of the .dynamic section\n"
--- a/usr/src/cmd/sgs/elfdump/common/main.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/elfdump/common/main.c	Wed Aug 30 10:15:44 2006 -0700
@@ -268,7 +268,7 @@
 	 * If we're on a 64-bit kernel, try to exec a full 64-bit version of
 	 * the binary.  If successful, conv_check_native() won't return.
 	 */
-	conv_check_native(argv, envp);
+	(void) conv_check_native(argv, envp);
 
 	/*
 	 * Establish locale.
--- a/usr/src/cmd/sgs/include/conv.h	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/include/conv.h	Wed Aug 30 10:15:44 2006 -0700
@@ -150,7 +150,7 @@
 /*
  * Define all generic interfaces.
  */
-extern	void		conv_check_native(char **, char **);
+extern	uchar_t		conv_check_native(char **, char **);
 extern	const char	*conv_config_feat(int);
 extern	const char	*conv_config_obj(ushort_t);
 extern	const char	*conv_config_upm(const char *, const char *,
@@ -200,7 +200,7 @@
 #define	conv_reloc_amd64_type	conv64_reloc_amd64_type
 #define	conv_reloc_SPARC_type	conv64_reloc_SPARC_type
 #define	conv_sec_flags		conv64_sec_flags
-#define	conv_sec_info		conv64_sec_info
+#define	conv_sec_linkinfo	conv64_sec_linkinfo
 #define	conv_sec_type		conv64_sec_type
 #define	conv_sym_info_bind	conv64_sym_info_bind
 #define	conv_sym_info_type	conv64_sym_info_type
@@ -236,7 +236,7 @@
 #define	conv_reloc_amd64_type	conv32_reloc_amd64_type
 #define	conv_reloc_SPARC_type	conv32_reloc_SPARC_type
 #define	conv_sec_flags		conv32_sec_flags
-#define	conv_sec_info		conv32_sec_info
+#define	conv_sec_linkinfo	conv32_sec_linkinfo
 #define	conv_sec_type		conv32_sec_type
 #define	conv_sym_info_bind	conv32_sym_info_bind
 #define	conv_sym_info_type	conv32_sym_info_type
@@ -273,7 +273,7 @@
 extern	const char	*conv_reloc_amd64_type(Word, int);
 extern	const char	*conv_reloc_SPARC_type(Word, int);
 extern	const char	*conv_sec_flags(Xword);
-extern	const char	*conv_sec_info(Word, Xword);
+extern	const char	*conv_sec_linkinfo(Word, Xword);
 extern	const char	*conv_sec_type(Half, Word, int);
 extern	const char	*conv_sym_info_bind(uchar_t, int);
 extern	const char	*conv_sym_info_type(Half, uchar_t, int);
--- a/usr/src/cmd/sgs/include/debug.h	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/include/debug.h	Wed Aug 30 10:15:44 2006 -0700
@@ -308,6 +308,8 @@
 #define	Dbg_seg_os		Dbg64_seg_os
 #define	Dbg_seg_title		Dbg64_seg_title
 
+#define	Dbg_shdr_modified	Dbg64_shdr_modified
+
 #define	Dbg_statistics_ar	Dbg64_statistics_ar
 #define	Dbg_statistics_ld	Dbg64_statistics_ld
 
@@ -499,6 +501,8 @@
 #define	Dbg_seg_os		Dbg32_seg_os
 #define	Dbg_seg_title		Dbg32_seg_title
 
+#define	Dbg_shdr_modified	Dbg32_shdr_modified
+
 #define	Dbg_statistics_ar	Dbg32_statistics_ar
 #define	Dbg_statistics_ld	Dbg32_statistics_ld
 
@@ -721,6 +725,9 @@
 extern	void	Dbg_seg_os(Ofl_desc *, Os_desc *, int);
 extern	void	Dbg_seg_title(Lm_list *);
 
+extern	void	Dbg_shdr_modified(Lm_list *, Half, Shdr *, Shdr *,
+		    const char *);
+
 extern	void	Dbg_statistics_ar(Ofl_desc *);
 extern	void	Dbg_statistics_ld(Ofl_desc *);
 
--- a/usr/src/cmd/sgs/include/i386/machdep.h	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/include/i386/machdep.h	Wed Aug 30 10:15:44 2006 -0700
@@ -113,7 +113,7 @@
 #define	M_JMP_REG_DISP_IND	0xa3
 #define	M_NOP			0x90
 
-#define	M_BIND_ADJ		1	/* adjustment for end of */
+#define	M_BIND_ADJ	1		/* adjustment for end of */
 					/*	elf_rtbndr() address */
 #ifdef _ELF64
 #define	M_WORD_ALIGN	8
@@ -206,7 +206,6 @@
 #define	M_REL_SHT_TYPE	SHT_RELA	/* section header type */
 #define	M_REL_ELF_TYPE	ELF_T_RELA	/* data buffer type */
 
-#define	M_REL_CONTYPSTR	conv_reloc_amd64_type
 #else /* _ELF32 */
 #define	M_REL_DT_TYPE	DT_REL		/* .dynamic entry */
 #define	M_REL_DT_SIZE	DT_RELSZ	/* .dynamic entry */
@@ -215,7 +214,6 @@
 #define	M_REL_SHT_TYPE	SHT_REL		/* section header type */
 #define	M_REL_ELF_TYPE	ELF_T_REL	/* data buffer type */
 
-#define	M_REL_CONTYPSTR	conv_reloc_386_type
 #endif /* ELF32 */
 
 /*
--- a/usr/src/cmd/sgs/include/sparc/machdep.h	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/include/sparc/machdep.h	Wed Aug 30 10:15:44 2006 -0700
@@ -81,7 +81,7 @@
 #if	defined(_ELF64)
 #define	M_TLSSTATALIGN	0x10
 #else
-#define	M_TLSSTATALIGN	0x8
+#define	M_TLSSTATALIGN	0x08
 #endif
 
 
@@ -233,8 +233,6 @@
 #define	M_REL_SHT_TYPE	SHT_RELA	/* section header type */
 #define	M_REL_ELF_TYPE	ELF_T_RELA	/* data buffer type */
 
-#define	M_REL_CONTYPSTR	conv_reloc_SPARC_type
-
 /*
  * Make common relocation types transparent to the common code
  */
--- a/usr/src/cmd/sgs/lari/lari.pl	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/lari/lari.pl	Wed Aug 30 10:15:44 2006 -0700
@@ -42,14 +42,13 @@
 use File::Basename;
 
 # Pattern match to skip objects.
-$Rtld = qr{ ^(?:
+$Rtld = qr{
 	/lib/ld\.so\.1 |
 	/usr/lib/ld\.so\.1 |
 	/lib/sparcv9/ld\.so\.1 |
 	/usr/lib/sparcv9/ld\.so\.1 |
 	/lib/amd64/ld\.so\.1 |
 	/usr/lib/amd64/ld\.so\.1
-	)$
 }x;
 
 # Pattern matching required to determine a global symbol.
@@ -221,9 +220,15 @@
 			$opt{i} = 0;
 		}
 	}
-	if ($opt{o} && $opt{i}) {
-		inappropriate("-o", "-i", 1);
+	if ($opt{o}) {
+		if ($opt{i}) {
+			inappropriate("-o", "-i", 1);
 			$opt{i} = 0;
+		}
+		if ($opt{b}) {
+			inappropriate("-o", "-b", 1);
+			$opt{b} = 0;
+		}
 	}
 
 	# If -m is used, only one input file is applicable.
@@ -276,7 +281,7 @@
 		$opt{i} = 1;
 	}
 
-	# Determine whether we have a multiple input files.
+	# Determine whether we have multiple input files.
 	if ($#ARGV == 0) {
 		$Mult = 0;
 	} else {
@@ -398,6 +403,12 @@
 	my ($File, $Mult, $CmdLine) = @_;
 	my (@Ldd, $NoFound, $DbgFile, @DbgGlob, $Type);
 
+	# If we're scanning a directory (ie. /lib) and have picked up ld.so.1,
+	# ignore it.
+	if (($CmdLine eq 0) && ($File =~ $Rtld)) {
+		return 1;
+	}
+
 	$Type = `LC_ALL=C file '$File' 2>&1`;
 	if (($Type !~ /dynamically linked/) || ($Type =~ /Sun demand paged/)) {
 		if ($CmdLine) {
@@ -1025,8 +1036,14 @@
 		}
 	}
 
-	# If we want all symbols, return the count.
-	if (!$opt{i}) {
+	# If we want all overhead symbols, return the count.
+	if ($opt{o}) {
+		return $ObjCnt;
+	}
+
+	# If we want all symbols, return the count.  If we want all bound
+	# symbols, return the count provided it is non-zero.
+	if ($opt{a} && (!$opt{b} || ($BndCnt > 0))) {
 		return $ObjCnt;
 	}
 
@@ -1062,12 +1079,21 @@
 		return 0;
 	}
 
-	# If we're only interested in multiply-bound symbols.
-	if (($opt{b} || ($SymName =~ $MultSyms) || ($SymName =~ $CrtSyms)) &&
+	# Only display any reserved symbols if more than one binding has
+	# occurred.
+	if ((($SymName =~ $MultSyms) || ($SymName =~ $CrtSyms)) &&
 	    ($BndCnt < 2)) {
 		return (0);
 	}
 
+	# For all other symbols, determine whether a binding has occurred.
+	# Note: definitions within an executable are tagged as protected ("P")
+	# as they may have been bound to from within the executable - we can't
+	# tell.
+	if ($opt{b} && ($BndCnt == 0)) {
+		return (0);
+	}
+
 	# Multiple instances of a definition, where all but one are filter
 	# references and/or copy relocations, are also uninteresting.
 	# Effectively, only one symbol is providing the final binding.
@@ -1102,8 +1128,14 @@
 	# Determine whether we've already retrieved this object's symbols.
 	# Also, ignore the runtime linker, it's on a separate link-map, and
 	# except for the filtee symbols that might be bound via libdl, is
-	# uninteresting.
-	if (($Objects{$Obj}) || ($Obj =~ $Rtld)) {
+	# uninteresting.  Tag the runtime linker as versioned to simplify
+	# possible -v processing.
+	if ($Objects{$Obj}) {
+		return;
+	}
+
+	if ($Obj =~ $Rtld) {
+		$Versioned{$Obj} = 1;
 		return;
 	}
 
@@ -1177,12 +1209,12 @@
 				next;
 			}
 			@Fields = split(' ', $Rel);
-			if ($Fields[0] eq 'R_SPARC_COPY') {
-				$SymName = $Fields[4];
-			} elsif ($Fields[0] eq 'R_386_COPY') {
+			# Intel relocation records don't contain an addend,
+			# where as every other supported platform does.
+			if ($Fields[0] eq 'R_386_COPY') {
 				$SymName = $Fields[3];
 			} else {
-				next;
+				$SymName = $Fields[4];
 			}
 
 			$Symbols{$SymName}{$Obj}[$ObjFlag] |= $Cpyr;
--- a/usr/src/cmd/sgs/ld/common/ld.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/ld/common/ld.c	Wed Aug 30 10:15:44 2006 -0700
@@ -99,33 +99,50 @@
  * Determine whether we need the Elf32 or Elf64 libld.
  */
 static int
-determine_class(int argc, char ** argv)
+determine_class(int argc, char **argv, uchar_t *aoutclass, uchar_t *ldclass)
 {
-	unsigned char	class = 0;
-	int		c;
+#if	defined(__sparcv9) || defined(__amd64)
+	uchar_t aclass = 0, lclass = ELFCLASS64;
+#else
+	uchar_t	aclass = 0, lclass = 0;
+#endif
+	int	c;
 
 getmore:
 	/*
 	 * Skip options.
 	 *
-	 * The only option we're interested in is -64, which enforces a 64-bit
-	 * link-edit.  This option is used when the only input to ld() is a
-	 * mapfile and a 64-bit object is required.  If we've already processed
-	 * a 32-bit object and we find -64, we have an error condition, but let
-	 * this fall through to libld to obtain the default error message.
+	 * The only options we're interested in is -64 or -altzexec64.  The -64
+	 * option is used when the only input to ld() is a mapfile or archive,
+	 * and a 64-bit a.out is required.  The -zaltexec64 option requests the
+	 * 64-bit version of ld() is used regardless of the required a.out.
+	 *
+	 * If we've already processed a 32-bit object and we find -64, we have
+	 * an error condition, but let this fall through to libld to obtain the
+	 * default error message.
 	 */
 	opterr = 0;
 	while ((c = getopt(argc, argv, MSG_ORIG(MSG_STR_OPTIONS))) != -1) {
 		switch (c) {
 			case '6':
-				return (ELFCLASS64);
+				if (strncmp(optarg, MSG_ORIG(MSG_ARG_FOUR),
+				    MSG_ARG_FOUR_SIZE) == 0)
+					aclass = ELFCLASS64;
+				break;
+#if	!defined(__sparcv9) && !defined(__amd64)
+			case 'z':
+				if (strncmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64),
+				    MSG_ARG_ALTEXEC64_SIZE) == 0)
+					lclass = ELFCLASS64;
+				break;
+#endif
 			default:
 				break;
 		}
 	}
 
 	/*
-	 * Otherwise look for the first ELF object to determine the class of
+	 * Continue to look for the first ELF object to determine the class of
 	 * objects to operate on.
 	 */
 	for (; optind < argc; optind++) {
@@ -133,14 +150,6 @@
 		unsigned char	ident[EI_NIDENT];
 
 		/*
-		 * If we've already analyzed the initial object, continue.
-		 * We're only interested in skipping all files to check for
-		 * more options, and specifically if the -64 option is set.
-		 */
-		if (class)
-			continue;
-
-		/*
 		 * If we detect some more options return to getopt().
 		 * Checking argv[optind][1] against null prevents a forever
 		 * loop if an unadorned `-' argument is passed to us.
@@ -152,25 +161,33 @@
 				goto getmore;
 		}
 
+		/*
+		 * If we've already determined the object class, continue.
+		 * We're only interested in skipping all files to check for
+		 * more options, and specifically if the -64 option is set.
+		 */
+		if (aclass)
+			continue;
+
+		/*
+		 * Open the file and determine the files ELF class.
+		 */
 		if ((fd = open(argv[optind], O_RDONLY)) == -1) {
 			int err = errno;
 
 			eprintf(0, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN),
 			    argv[optind], strerror(err));
-			return (0);
+			return (1);
 		}
 
-		/*
-		 * Determine the files ELF class.
-		 */
 		if ((read(fd, ident, EI_NIDENT) == EI_NIDENT) &&
 		    (ident[EI_MAG0] == ELFMAG0) &&
 		    (ident[EI_MAG1] == ELFMAG1) &&
 		    (ident[EI_MAG2] == ELFMAG2) &&
 		    (ident[EI_MAG3] == ELFMAG3)) {
-			if (((class = ident[EI_CLASS]) != ELFCLASS32) &&
-			    (class != ELFCLASS64))
-				class = 0;
+			if (((aclass = ident[EI_CLASS]) != ELFCLASS32) &&
+			    (aclass != ELFCLASS64))
+				aclass = 0;
 		}
 		(void) close(fd);
 	}
@@ -178,10 +195,14 @@
 	/*
 	 * If we couldn't establish a class default to 32-bit.
 	 */
-	if (class)
-		return (class);
+	if (aclass == 0)
+		aclass = ELFCLASS32;
+	if (lclass == 0)
+		lclass = ELFCLASS32;
 
-	return (ELFCLASS32);
+	*aoutclass = aclass;
+	*ldclass = lclass;
+	return (0);
 }
 
 /*
@@ -277,31 +298,35 @@
  * arguments as the originating process.  This mechanism permits using
  * alternate link-editors (debugging/developer copies) even in complex build
  * environments.
- *
- * If LD_ALTEXEC= isn't set, or the exec() fails, silently return and allow the
- * current link-editor to execute.
  */
-void
+static int
 ld_altexec(char **argv, char **envp)
 {
 	char	*execstr;
 	char	**str;
+	int	err;
+
 	for (str = envp; *str; str++) {
 		if (strncmp(*str, MSG_ORIG(MSG_LD_ALTEXEC),
 		    MSG_LD_ALTEXEC_SIZE) == 0) {
 			break;
 		}
 	}
-	if (*str == 0)
-		return;
 
 	/*
-	 * get a pointer to the actual string - if it's
-	 * a null entry - we return.
+	 * If LD_ALTEXEC isn't set, return to continue executing the present
+	 * link-editor.
+	 */
+	if (*str == 0)
+		return (0);
+
+	/*
+	 * Get a pointer to the actual string.  If it's a null entry, return.
 	 */
 	execstr = strdup(*str + MSG_LD_ALTEXEC_SIZE);
 	if (*execstr == '\0')
-		return;
+		return (0);
+
 	/*
 	 * Null out the LD_ALTEXEC= environment entry.
 	 */
@@ -318,16 +343,19 @@
 	(void) execve(execstr, argv, envp);
 
 	/*
-	 * If the exec() fails, silently fall through and continue execution of
-	 * the current link-editor.
+	 * If the exec() fails, return a failure indication.
 	 */
+	err = errno;
+	eprintf(0, ERR_FATAL, MSG_INTL(MSG_SYS_EXEC), execstr,
+	    strerror(err));
+	return (1);
 }
 
 int
 main(int argc, char **argv, char **envp)
 {
 	char		*ld_options, **oargv = argv;
-	uchar_t 	class;
+	uchar_t 	aoutclass, ldclass, checkclass;
 
 	/*
 	 * XX64 -- Strip "-Wl," from the head of each argument.  This is to
@@ -352,9 +380,11 @@
 	(void) textdomain(MSG_ORIG(MSG_SUNW_OST_SGS));
 
 	/*
-	 * Execute alternate linker if LD_ALTEXEC environment variable is set.
+	 * Execute an alternate linker if the LD_ALTEXEC environment variable is
+	 * set.  If a specified alternative could not be found, bail.
 	 */
-	ld_altexec(argv, envp);
+	if (ld_altexec(argv, envp))
+		return (1);
 
 	/*
 	 * Check the LD_OPTIONS environment variable, and if present prepend
@@ -370,27 +400,31 @@
 	}
 
 	/*
-	 * Locate the first input file and from this file determine the class of
-	 * objects we're going to process.  If the class is ELFCLASS64 we'll
-	 * call the ELF64 class of interfaces, else the ELF32 class.  Note that
-	 * if the option -64 is encountered a 64-bit link is explicitly being
-	 * requested.
+	 * Determine the object class, and link-editor class required.
 	 */
-	if ((class = determine_class(argc, argv)) == 0)
+	if (determine_class(argc, argv, &aoutclass, &ldclass))
 		return (1);
 
 	/*
-	 * If we're on a 64-bit kernel, try to exec a full 64-bit version of ld.
+	 * If we're processing 64-bit objects, or the user specifically asked
+	 * for a 64-bit link-editor, determine if a 64-bit ld() can be executed.
+	 * Bail if a 64-bit ld() was explicitly asked for, but one could not be
+	 * found.
 	 */
-	if (class == ELFCLASS64)
-		conv_check_native(oargv, envp);
+	if ((aoutclass == ELFCLASS64) || (ldclass == ELFCLASS64))
+		checkclass = conv_check_native(oargv, envp);
+
+	if ((ldclass == ELFCLASS64) && (checkclass != ELFCLASS64)) {
+		eprintf(0, ERR_FATAL, MSG_INTL(MSG_SYS_64));
+		return (1);
+	}
 
 	/*
 	 * Reset the getopt(3c) error message flag, and call the generic entry
 	 * point using the appropriate class.
 	 */
 	optind = opterr = 1;
-	if (class == ELFCLASS64)
+	if (aoutclass == ELFCLASS64)
 		return (ld64_main(argc, argv));
 	else
 		return (ld32_main(argc, argv));
--- a/usr/src/cmd/sgs/ld/common/ld.msg	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/ld/common/ld.msg	Wed Aug 30 10:15:44 2006 -0700
@@ -34,8 +34,10 @@
 # System error messages
 
 @ MSG_SYS_OPEN		"file %s: open failed: %s"
+@ MSG_SYS_EXEC		"file %s: exec failed: %s"
 
 @ MSG_SYS_ALLOC		"alloc failed: %s"
+@ MSG_SYS_64		"unable to execute 64-bit version of ld"
 
 # Generic error diagnostic labels
 
@@ -58,6 +60,9 @@
 @ MSG_STR_OPTIONS	"6:abc:d:e:f:h:il:mo:p:rstu:z:B:CD:F:GI:L:M:N:P:Q:R:\
 			 S:VY:?"
 
+@ MSG_ARG_FOUR		"4"
+@ MSG_ARG_ALTEXEC64	"altexec64"
+
 @ MSG_LD_OPTIONS	"LD_OPTIONS"
 @ MSG_LD_ALTEXEC	"LD_ALTEXEC="
 
--- a/usr/src/cmd/sgs/libconv/common/arch.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libconv/common/arch.c	Wed Aug 30 10:15:44 2006 -0700
@@ -57,10 +57,11 @@
 
 #if	defined(_LP64)
 /* ARGSUSED */
-void
+uchar_t
 conv_check_native(char **argv, char **envp)
 {
 	/* 64-bit version does nothing */
+	return (ELFCLASS64);
 }
 
 #else
@@ -76,7 +77,7 @@
  * counterpart (ie. sparcv7, or sparc), but as none of the callers provide these
  * counterparts, we simply return to the caller.
  */
-void
+uchar_t
 conv_check_native(char **argv, char **envp)
 {
 	char	*str;
@@ -86,8 +87,9 @@
 	 * This is used by the test suite to test 32-bit support libraries.
 	 */
 	if (((str = getenv(MSG_ORIG(MSG_LD_NOEXEC64))) != NULL) && *str)
-		return;
+		return (ELFCLASS32);
 
 	(void) isaexec(getexecname(), argv, envp);
+	return (ELFCLASS32);
 }
 #endif
--- a/usr/src/cmd/sgs/libconv/common/llib-lconv	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libconv/common/llib-lconv	Wed Aug 30 10:15:44 2006 -0700
@@ -38,7 +38,7 @@
 /*
  * Define all generic interfaces.
  */
-void		conv_check_native(char **, char **);
+uchar_t		conv_check_native(char **, char **);
 const char      *conv_config_feat(int);
 const char	*conv_config_obj(ushort_t);
 const char	*conv_config_upm(const char *, const char *, const char *,
@@ -113,8 +113,8 @@
 const char	*conv64_reloc_SPARC_type(Word, int);
 const char	*conv32_sec_flags(Elf32_Word);
 const char	*conv64_sec_flags(Elf64_Xword);
-const char	*conv32_sec_info(Elf32_Word, Elf32_Word);
-const char	*conv64_sec_info(Elf64_Word, Elf64_Xword);
+const char	*conv32_sec_linkinfo(Elf32_Word, Elf32_Word);
+const char	*conv64_sec_linkinfo(Elf64_Word, Elf64_Xword);
 const char	*conv32_sec_type(Elf32_Half, Elf32_Word, int);
 const char	*conv64_sec_type(Elf64_Half, Elf64_Word, int);
 const char	*conv32_sym_info_bind(uchar_t, int);
--- a/usr/src/cmd/sgs/libconv/common/sections.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libconv/common/sections.c	Wed Aug 30 10:15:44 2006 -0700
@@ -168,11 +168,11 @@
 }
 
 const char *
-conv_sec_info(Word info, Xword flags)
+conv_sec_linkinfo(Word info, Xword flags)
 {
 	static	char	string[CONV_INV_STRSIZE];
 
-	if (flags & SHF_ORDERED) {
+	if (flags & ALL_SHF_ORDER) {
 		if (info == SHN_BEFORE)
 			return (MSG_ORIG(MSG_SHN_BEFORE));
 		else if (info == SHN_AFTER)
--- a/usr/src/cmd/sgs/libld/common/_libld.h	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/_libld.h	Wed Aug 30 10:15:44 2006 -0700
@@ -57,7 +57,7 @@
 #endif
 	LD_DYN,		LD_DTRACE,	 LD_NOTE,	LD_SUNWBSS,
 	LD_TLS,
-#if defined(__x86) && defined(_ELF64)
+#if	(defined(__i386) || defined(__amd64)) && defined(_ELF64)
 	LD_UNWIND,
 #endif
 	LD_EXTRA,
@@ -513,8 +513,8 @@
 extern void		ld_sup_input_done(Ofl_desc *);
 extern void		ld_sup_section(Ofl_desc *, const char *, Shdr *, Word,
 			    Elf_Data *, Elf *);
-extern uintptr_t	ld_sup_input_section(Ofl_desc*, const char *, Shdr **,
-			    Word, const char *, Elf_Scn *, Elf *);
+extern uintptr_t	ld_sup_input_section(Ofl_desc*, Ifl_desc *,
+			    const char *, Shdr **, Word, Elf_Scn *, Elf *);
 extern void		ld_sup_start(Ofl_desc *, const Half, const char *);
 extern Sym_desc		*ld_sym_add_u(const char *, Ofl_desc *);
 extern void		ld_sym_adjust_vis(Sym_desc *, Ofl_desc *);
@@ -548,9 +548,6 @@
 extern Xword		lcm(Xword, Xword);
 extern Listnode *	list_where(List *, Word);
 
-/*
- * AMD64 - 64-bit specific functions
- */
 #if	(defined(__i386) || defined(__amd64)) && defined(_ELF64)
 extern uintptr_t	append_amd64_unwind(Os_desc *, Ofl_desc *);
 extern uintptr_t	make_amd64_unwindhdr(Ofl_desc *);
--- a/usr/src/cmd/sgs/libld/common/args.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/args.c	Wed Aug 30 10:15:44 2006 -0700
@@ -149,6 +149,7 @@
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_CY));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZA));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAE));
+	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZAL));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZC));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZNC));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
@@ -889,7 +890,7 @@
 		case 'z':
 			/*
 			 * For specific help, print our usage message and exit
-			 * immediately to insure a 0 return code.
+			 * immediately to ensure a 0 return code.
 			 */
 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
 			    MSG_ARG_HELP_SIZE) == 0) {
@@ -1052,6 +1053,7 @@
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOGROUPPERM)) &&
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_NOLAZYLOAD)) &&
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_RECORD)) &&
+			    strcmp(optarg, MSG_ORIG(MSG_ARG_ALTEXEC64)) &&
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_WEAKEXT))) {
 				eprintf(ofl->ofl_lml, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
--- a/usr/src/cmd/sgs/libld/common/files.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/files.c	Wed Aug 30 10:15:44 2006 -0700
@@ -207,11 +207,11 @@
 		isp->is_ident = ident;
 
 		if ((ndx != 0) && (ndx == shdr->sh_link) &&
-		    (shdr->sh_flags & SHF_ORDERED))
+		    (shdr->sh_flags & SHF_ORDERED)) {
 			return ((uintptr_t)ld_place_section(ofl, isp,
 			    ident, 0));
+		}
 	}
-
 	return (1);
 }
 
@@ -1413,8 +1413,8 @@
 		return (0);
 	}
 
-	if (ld_sup_input_section(ofl, name, &shdr, sndx, ifl->ifl_name,
-	    scn, elf) == S_ERROR)
+	if (ld_sup_input_section(ofl, ifl, name, &shdr, sndx, scn,
+	    elf) == S_ERROR)
 		return (S_ERROR);
 
 	/*
@@ -1476,8 +1476,8 @@
 		}
 		name = str + (size_t)(shdr->sh_name);
 
-		if (ld_sup_input_section(ofl, name, &shdr, ndx, ifl->ifl_name,
-		    scn, elf) == S_ERROR)
+		if (ld_sup_input_section(ofl, ifl, name, &shdr, ndx, scn,
+		    elf) == S_ERROR)
 			return (S_ERROR);
 
 		/*
--- a/usr/src/cmd/sgs/libld/common/libld.msg	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/libld.msg	Wed Aug 30 10:15:44 2006 -0700
@@ -130,6 +130,7 @@
 			 allow extraction of\n\
 			 \t\t\tarchive members to resolvetweak references from \
 			 \n\t\t\t\archive files\n"
+@ MSG_ARG_DETAIL_ZAL	"\t[-z altexec64]\texecute the 64-bit link-editor\n"
 @ MSG_ARG_DETAIL_ZC	"\t[-z combreloc]\tcombine multiple relocation \
 			 sections\n"
 @ MSG_ARG_DETAIL_ZNC	"\t[-z nocompstrtab]\n\t\t\tdisable compression of \
@@ -1015,6 +1016,7 @@
 @ MSG_ARG_ZCOMBRELOC	"-zcombreloc"
 
 @ MSG_ARG_ABSEXEC	"absexec"
+@ MSG_ARG_ALTEXEC64	"altexec64"
 @ MSG_ARG_NOCOMPSTRTAB	"nocompstrtab"
 @ MSG_ARG_GROUPPERM	"groupperm"
 @ MSG_ARG_NOGROUPPERM	"nogroupperm"
--- a/usr/src/cmd/sgs/libld/common/machrel.amd.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/machrel.amd.c	Wed Aug 30 10:15:44 2006 -0700
@@ -356,9 +356,8 @@
 		raddend += value;
 
 	/*
-	 * addend field for R_AMD64_DTPMOD64 means nothing.  The addend
-	 * is propogated in the corresponding R_AMD64_DTPOFF64
-	 * relocation.
+	 * The addend field for R_AMD64_DTPMOD64 means nothing.  The addend
+	 * is propagated in the corresponding R_AMD64_DTPOFF64 relocation.
 	 */
 	if (orsp->rel_rtype == R_AMD64_DTPMOD64)
 		raddend = 0;
@@ -618,7 +617,9 @@
 	Word		flags = ofl->ofl_flags;
 	Word		dtflags1 = ofl->ofl_dtflags_1;
 
-	DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
+	if (ofl->ofl_actrels.head)
+		DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
+
 	/*
 	 * Process active relocations.
 	 */
@@ -728,7 +729,7 @@
 					value -= ofl->ofl_tlsphdr->p_vaddr;
 			} else {
 				/*
-				 * else the value is the symbols value
+				 * Else the value is the symbols value.
 				 */
 				value = sdp->sd_sym->st_value;
 			}
--- a/usr/src/cmd/sgs/libld/common/machrel.intel.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c	Wed Aug 30 10:15:44 2006 -0700
@@ -639,7 +639,9 @@
 	Word		flags = ofl->ofl_flags;
 	Word		dtflags1 = ofl->ofl_dtflags_1;
 
-	DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
+	if (ofl->ofl_actrels.head)
+		DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
+
 	/*
 	 * Process active relocations.
 	 */
@@ -748,7 +750,7 @@
 					value -= ofl->ofl_tlsphdr->p_vaddr;
 			} else {
 				/*
-				 * else the value is the symbols value
+				 * Else the value is the symbols value.
 				 */
 				value = sdp->sd_sym->st_value;
 			}
--- a/usr/src/cmd/sgs/libld/common/machrel.sparc.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/machrel.sparc.c	Wed Aug 30 10:15:44 2006 -0700
@@ -676,14 +676,12 @@
 		raddend += value;
 
 	/*
-	 * addend field for R_SPARC_TLS_DTPMOD32 &&
-	 * R_SPARC_TLS_DTPMOD64 mean nothing.  The addend
-	 * is propogated in the corresponding R_SPARC_TLS_DTPOFF*
-	 * relocations.
+	 * The addend field for R_SPARC_TLS_DTPMOD32 and R_SPARC_TLS_DTPMOD64
+	 * mean nothing.  The addend is propagated in the corresponding
+	 * R_SPARC_TLS_DTPOFF* relocations.
 	 */
-	if (orsp->rel_rtype == M_R_DTPMOD) {
+	if (orsp->rel_rtype == M_R_DTPMOD)
 		raddend = 0;
-	}
 
 	relbits = (char *)relosp->os_outdata->d_buf;
 
@@ -944,7 +942,9 @@
 	Word		flags = ofl->ofl_flags;
 	Word		dtflags1 = ofl->ofl_dtflags_1;
 
-	DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
+	if (ofl->ofl_actrels.head)
+		DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
+
 	/*
 	 * Process active relocations.
 	 */
@@ -1045,7 +1045,7 @@
 					value -= ofl->ofl_tlsphdr->p_vaddr;
 			} else {
 				/*
-				 * else the value is the symbols value
+				 * Else the value is the symbols value.
 				 */
 				value = sdp->sd_sym->st_value;
 			}
--- a/usr/src/cmd/sgs/libld/common/order.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/order.c	Wed Aug 30 10:15:44 2006 -0700
@@ -166,11 +166,12 @@
 	if ((isp->is_flags & FLG_IS_ORDERED) == 0)
 		return (0);
 
-	keylink = 0;
 	if (shflags & SHF_ORDERED)
 		keylink = isp->is_shdr->sh_info;
 	else if (shflags & SHF_LINK_ORDER)
 		keylink = isp->is_shdr->sh_link;
+	else
+		keylink = 0;
 
 	if ((error = is_keylink_ok(ifl, keylink, limit)) != 0) {
 		DBG_CALL(Dbg_sec_order_error(ofl->ofl_lml, ifl, ndx, error));
@@ -182,9 +183,9 @@
 	}
 
 	/*
-	 * If SHF_ORDERED is in effect - the we search for
-	 * our desitination section based off of sh_link else
-	 * we follow the default rules for the desitination section.
+	 * If SHF_ORDERED is in effect, search for our destination section based
+	 * off of sh_link, otherwise follow the default rules for the
+	 * destination section.
 	 */
 	if (shflags & SHF_ORDERED) {
 		if ((dest_ndx = get_shfordered_dest(ofl, ifl,
@@ -197,8 +198,8 @@
 		}
 	} else {
 		/*
-		 * SHF_LINK_ORDER coelsces into default sections - so
-		 * we set dest_ndx to NULL to trigger this.
+		 * SHF_LINK_ORDER coalesces into default sections, set dest_ndx
+		 * to NULL to trigger this.
 		 */
 		dest_ndx = 0;
 	}
@@ -219,13 +220,15 @@
 	 * list - place it on the list.
 	 */
 	osp2 = NULL;
-	for (LIST_TRAVERSE(&ofl->ofl_ordered, lnp, osp2))
+	for (LIST_TRAVERSE(&ofl->ofl_ordered, lnp, osp2)) {
 		if (osp2 == osp)
 			break;
+	}
 
-	if (osp != osp2)
+	if (osp != osp2) {
 		if (list_appendc(&(ofl->ofl_ordered), osp) == 0)
 			return ((uintptr_t)S_ERROR);
+	}
 
 	/*
 	 * Output section has been found - set up it's
--- a/usr/src/cmd/sgs/libld/common/outfile.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/outfile.c	Wed Aug 30 10:15:44 2006 -0700
@@ -371,7 +371,7 @@
 	}
 
 	/*
-	 * If there are any ordered section, handle them here.
+	 * If there are any ordered sections, handle them here.
 	 */
 	if ((ofl->ofl_ordered.head != NULL) &&
 	    (ld_sort_ordered(ofl) == S_ERROR))
--- a/usr/src/cmd/sgs/libld/common/relocate.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/relocate.c	Wed Aug 30 10:15:44 2006 -0700
@@ -954,7 +954,7 @@
 
 		/*
 		 * Indicate that this relocation should be processed the same
-		 * as a section symbol.  For SPARC and AMD (Rela), indicate
+		 * as a section symbol.  For SPARC and AMD64 (Rela), indicate
 		 * that the addend also needs to be applied to this relocation.
 		 */
 #if	(defined(__i386) || defined(__amd64)) && !defined(_ELF64)
@@ -1375,8 +1375,8 @@
 	if (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0) &&
 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_RELINVSEC),
-		    M_REL_CONTYPSTR(rtype, 0), ifl->ifl_name, isp->is_name,
-		    sdp->sd_isc->is_name);
+		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0),
+		    ifl->ifl_name, isp->is_name, sdp->sd_isc->is_name);
 		return (1);
 	}
 
@@ -1389,8 +1389,8 @@
 	if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) ||
 	    (rsndx >= ifl->ifl_symscnt)) {
 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
-		    M_REL_CONTYPSTR(rtype, 0), ifl->ifl_name, isp->is_name,
-		    demangle(reld->rel_sname),
+		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype, 0),
+		    ifl->ifl_name, isp->is_name, demangle(reld->rel_sname),
 		    EC_XWORD(reloc->r_offset), EC_WORD(rsndx));
 		return (S_ERROR);
 	}
--- a/usr/src/cmd/sgs/libld/common/sections.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/sections.c	Wed Aug 30 10:15:44 2006 -0700
@@ -1754,7 +1754,7 @@
 
 			/*
 			 * If the input relocation section had the SHF_GROUP
-			 * flag set - propogate it to the output relocation
+			 * flag set - propagate it to the output relocation
 			 * section.
 			 */
 			if (risp->is_shdr->sh_flags & SHF_GROUP) {
@@ -2413,22 +2413,41 @@
 	return (isec);
 }
 
-static const uchar_t ret_template[] = {
-#if	defined(i386)
+/*
+ * Define a set of templates for generating "void (*)(void)" function
+ * definitions.
+ */
+#if	defined(i386) || defined(__amd64)
+#if	defined(__lint)
+static const uchar_t ret_template[] = { 0 };
+#else	/* __lint */
+#if	defined(_ELF64)
+#define	ret_template	ret64_template
+#else
+#define	ret_template	ret32_template
+#endif
+
+static const uchar_t ret32_template[] = {
 /* 0x00 */	0xc3				/* ret */
-#elif	defined(__amd64)
+};
+
+static const uchar_t ret64_template[] = {
 /* 0x00 */	0x55,				/* pushq  %rbp */
 /* 0x01 */	0x48, 0x8b, 0xec,		/* movq   %rsp,%rbp */
 /* 0x04 */	0x48, 0x8b, 0xe5,		/* movq   %rbp,%rsp */
 /* 0x07 */	0x5d,				/* popq   %rbp */
 /* 0x08 */	0xc3				/* ret */
+};
+#endif	/* __lint */
+
 #elif	defined(sparc) || defined(__sparcv9)
+static const uchar_t ret_template[] = {
 /* 0x00 */	0x81, 0xc3, 0xe0, 0x08,		/* retl */
 /* 0x04 */	0x01, 0x00, 0x00, 0x00		/* nop */
+};
 #else
 #error	unsupported architecture!
 #endif
-};
 
 /*
  * Build an additional text section - used to back FUNC symbol definitions
--- a/usr/src/cmd/sgs/libld/common/support.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/libld/common/support.c	Wed Aug 30 10:15:44 2006 -0700
@@ -170,33 +170,44 @@
 }
 
 uintptr_t
-ld_sup_input_section(Ofl_desc * ofl, const char *scnname, Shdr **shdr, Word ndx,
-    const char *file, Elf_Scn *scn, Elf *elf)
+ld_sup_input_section(Ofl_desc *ofl, Ifl_desc *ifl, const char *sname,
+    Shdr **oshdr, Word ndx, Elf_Scn *scn, Elf *elf)
 {
 	Func_list	*flp;
 	Listnode	*lnp;
 	uint_t		flags = 0;
 	Elf_Data	*data = NULL;
+	Shdr		*nshdr = *oshdr;
 
 	for (LIST_TRAVERSE(&support[LDS_INP_SECTION].sup_funcs, lnp, flp)) {
 		/*
 		 * This interface was introduced in VERSION2 - so only call it
-		 * for libraries reporting support for * version 2 or above.
+		 * for libraries reporting support for version 2 or above.
 		 */
 		if (flp->fl_version < LD_SUP_VERSION2)
 			continue;
 		if ((data == NULL) &&
 		    ((data = elf_getdata(scn, NULL)) == NULL)) {
 			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETDATA), file);
+			    MSG_INTL(MSG_ELF_GETDATA), ifl->ifl_name);
 			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (S_ERROR);
 		}
 
 		DBG_CALL(Dbg_support_action(ofl->ofl_lml, flp->fl_obj,
-		    support[LDS_INP_SECTION].sup_name, LDS_INP_SECTION,
-		    scnname));
-		(*flp->fl_fptr)(scnname, shdr, ndx, data, elf, &flags);
+		    support[LDS_INP_SECTION].sup_name, LDS_INP_SECTION, sname));
+		(*flp->fl_fptr)(sname, &nshdr, ndx, data, elf, &flags);
+	}
+
+	/*
+	 * If the section header has been re-allocated (known to occur with
+	 * libCCexcept.so), then diagnose the section header difference and
+	 * return the new section header.
+	 */
+	if (nshdr != *oshdr) {
+		Dbg_shdr_modified(ofl->ofl_lml, ifl->ifl_ehdr->e_machine,
+		    *oshdr, nshdr, sname);
+		*oshdr = nshdr;
 	}
 	return (0);
 }
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg	Wed Aug 30 10:15:44 2006 -0700
@@ -517,6 +517,12 @@
 @ MSG_MOVE_OUTMOVE	"copying move entries for %s into .SUNW_move"
 @ MSG_MOVE_INPUT	"collecting move entries: file=%s"
 
+# Section header messages
+
+@ MSG_SHD_MODIFIED	"section=%s; section header modified by support library"
+@ MSG_SHD_ORIG		" original:"
+@ MSG_SHD_NEW		" new:"
+
 # Section messages
 
 @ MSG_SEC_INPUT		"section=%s; input from file=%s"
@@ -626,15 +632,14 @@
 
 # SHF_ORDERED related messages. Token used is sections.
 
-@ MSG_ORD_SORT_BEFORE	"Output section to be sorted=%s"
-@ MSG_ORD_SORT_AFTER	"Output section sorted=%s"
+@ MSG_ORD_SORT_BEFORE	"section=%s; requires output section reordering:"
+@ MSG_ORD_SORT_AFTER	"section=%s; output section reordered:"
 @ MSG_ORD_HDR_1		" number of SHN_BEGIN=%u, SHN_AFTER=%u, \
 			 sh_info/sh_link=%u"
 @ MSG_ORD_TITLE_0	" section=%s from %s is not an ordered section"
-@ MSG_ORD_TITLE_1	" section=%s from %s, sh_info=SHN_BEGIN"
-@ MSG_ORD_TITLE_2	" section=%s from %s, sh_info=SHN_AFTER"
-@ MSG_ORD_TITLE_3	" section=%s from %s, sh_info=%s, sort_val=%d"
-@ MSG_ORD_TITLE_4	" section=%s from %s, sh_link=%s, sort_val=%d"
+@ MSG_ORD_TITLE_1	" section=%s from %s, %s=SHN_BEGIN"
+@ MSG_ORD_TITLE_2	" section=%s from %s, %s=SHN_AFTER"
+@ MSG_ORD_TITLE_3	" section=%s from %s, %s=%s, sort_val=%d"
 
 @ MSG_ORD_ERR_TITLE	"the SHF_ORDERED section %s from %s has \
 			 an error;  flag ignored"
@@ -1070,6 +1075,9 @@
 @ MSG_SCN_FINIARRAY	".finiarray"
 @ MSG_SCN_PREINITARRAY	".preinitarray"
 
+@ MSG_SH_INFO		"sh_info"
+@ MSG_SH_LINK		"sh_link"
+
 @ MSG_UTL_SCC_ENTRY	"    [%d]  %s"
 
 @ MSG_FMT_INDEX		" [%d]"
@@ -1203,16 +1211,16 @@
 
 # Section header messages
 
-@ MSG_SHD_ADDR_32	"    sh_addr:      %#-10llx  sh_flags:   %s"
-@ MSG_SHD_SIZE_32	"    sh_size:      %#-10llx  sh_type:    %s"
-@ MSG_SHD_OFFSET_32	"    sh_offset:    %#-10llx  sh_entsize: %#llx"
-@ MSG_SHD_LINK_32	"    sh_link:      %-10d  sh_info:    %s"
+@ MSG_SHD_ADDR_32	"    sh_addr:      %#-10llx      sh_flags:   %s"
+@ MSG_SHD_SIZE_32	"    sh_size:      %#-10llx      sh_type:    %s"
+@ MSG_SHD_OFFSET_32	"    sh_offset:    %#-10llx      sh_entsize: %#llx"
+@ MSG_SHD_LINK_32	"    sh_link:      %-14s  sh_info:    %s"
 @ MSG_SHD_ALIGN_32	"    sh_addralign: %#-10llx"
 
 @ MSG_SHD_ADDR_64	"    sh_addr:      %#-18llx  sh_flags:   %s"
 @ MSG_SHD_SIZE_64	"    sh_size:      %#-18llx  sh_type:    %s"
 @ MSG_SHD_OFFSET_64	"    sh_offset:    %#-18llx  sh_entsize: %#llx"
-@ MSG_SHD_LINK_64	"    sh_link:      %-18d  sh_info:    %s"
+@ MSG_SHD_LINK_64	"    sh_link:      %-18s  sh_info:    %s"
 @ MSG_SHD_ALIGN_64	"    sh_addralign: %#-18llx"
 
 # Program header messages
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg	Wed Aug 30 10:15:44 2006 -0700
@@ -297,6 +297,9 @@
 void    Dbg32_seg_title(Lm_list *);
 void    Dbg64_seg_title(Lm_list *);
 
+void	Dbg32_shdr_modified(Lm_list *, Half, Shdr *, Shdr *, const char *);
+void	Dbg64_shdr_modified(Lm_list *, Half, Shdr *, Shdr *, const char *);
+
 void	Dbg32_statistics_ar(Ofl_desc *);
 void	Dbg64_statistics_ar(Ofl_desc *);
 void	Dbg32_statistics_ld(Ofl_desc *);
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers	Wed Aug 30 10:15:44 2006 -0700
@@ -38,7 +38,7 @@
 #	Policy for Shared Library Version Names and Interface Definitions
 
 
-SUNWprivate_4.52 {
+SUNWprivate_4.53 {
 	global:
 		dbg_desc = NODIRECT;	# interposed - ld.so.1(1)
 		dbg_print = NODIRECT;	# interposed - ld(1) and ld.so.1(1)
@@ -281,6 +281,9 @@
 		Dbg32_seg_title;
 		Dbg64_seg_title;
 
+		Dbg32_shdr_modified;
+		Dbg64_shdr_modified;
+
 		Dbg32_statistics_ar;
 		Dbg64_statistics_ar;
 		Dbg32_statistics_ld;
--- a/usr/src/cmd/sgs/liblddbg/common/sections.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/sections.c	Wed Aug 30 10:15:44 2006 -0700
@@ -52,7 +52,7 @@
 	if (!osp)
 		return;
 
-	dbg_print(lml, MSG_ORIG(MSG_STR_EMPTY));
+	Dbg_util_nl(lml, DBG_NL_STD);
 	if (stp->st_flags & FLG_STTAB_COMPRESS)
 		dbg_print(lml, MSG_INTL(MSG_SEC_STRTAB_COMP), osp->os_name,
 		    stp->st_fullstringsize, stp->st_stringsize);
@@ -182,6 +182,8 @@
 	if (DBG_NOTDETAIL())
 		return;
 
+	Dbg_util_nl(lml, DBG_NL_STD);
+
 	/*
 	 * If the flag == 0, then the routine is called before sorting.
 	 */
@@ -199,10 +201,10 @@
 		    EC_WORD(sort->st_ordercnt));
 
 		for (LIST_TRAVERSE(&osp->os_isdescs, lnp2, isp1)) {
-			Word			link;
-			Ifl_desc		*ifl = isp1->is_file;
-			Is_desc			*isp2;
-			static const char	*msg;
+			Word		link;
+			Ifl_desc	*ifl = isp1->is_file;
+			Is_desc		*isp2;
+			const char	*msg;
 
 			if ((isp1->is_flags & FLG_IS_ORDERED) == 0) {
 				dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_0),
@@ -212,30 +214,34 @@
 
 			if (isp1->is_shdr->sh_flags & SHF_ORDERED) {
 				link = isp1->is_shdr->sh_info;
-				msg = MSG_INTL(MSG_ORD_TITLE_3);
+				msg = MSG_ORIG(MSG_SH_INFO);
 			} else {
 				/* SHF_LINK_ORDER */
 				link = isp1->is_shdr->sh_link;
-				msg = MSG_INTL(MSG_ORD_TITLE_4);
+				msg = MSG_ORIG(MSG_SH_LINK);
 			}
 
 			if (link == SHN_BEFORE) {
 				dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_1),
-				    isp1->is_name, isp1->is_file->ifl_name);
+				    isp1->is_name, isp1->is_file->ifl_name,
+				    msg);
 				continue;
 			}
 
 			if (link == SHN_AFTER) {
 				dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_2),
-				    isp1->is_name, isp1->is_file->ifl_name);
+				    isp1->is_name, isp1->is_file->ifl_name,
+				    msg);
 				continue;
 			}
 
 			isp2 = ifl->ifl_isdesc[link];
-			dbg_print(lml, msg, isp1->is_name, ifl->ifl_name,
-			    isp2->is_name, isp2->is_key);
+			dbg_print(lml, MSG_INTL(MSG_ORD_TITLE_3),
+			    isp1->is_name, ifl->ifl_name, msg, isp2->is_name,
+			    isp2->is_key);
 		}
 	}
+	Dbg_util_nl(lml, DBG_NL_STD);
 }
 
 void
--- a/usr/src/cmd/sgs/liblddbg/common/segments.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/segments.c	Wed Aug 30 10:15:44 2006 -0700
@@ -68,6 +68,7 @@
 			    scop->sco_secname, EC_WORD(scop->sco_index));
 		}
 	}
+	Dbg_util_nl(lml, DBG_NL_STD);
 }
 
 void
--- a/usr/src/cmd/sgs/liblddbg/common/shdr.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/liblddbg/common/shdr.c	Wed Aug 30 10:15:44 2006 -0700
@@ -31,7 +31,7 @@
 #include	<msg.h>
 
 void
-Elf_shdr(Lm_list *lml, Half mach, Shdr * shdr)
+Elf_shdr(Lm_list *lml, Half mach, Shdr *shdr)
 {
 	dbg_print(lml, MSG_ORIG(MSG_SHD_ADDR), EC_ADDR(shdr->sh_addr),
 	    conv_sec_flags(shdr->sh_flags));
@@ -39,7 +39,29 @@
 	    conv_sec_type(mach, shdr->sh_type, 0));
 	dbg_print(lml, MSG_ORIG(MSG_SHD_OFFSET), EC_OFF(shdr->sh_offset),
 	    EC_XWORD(shdr->sh_entsize));
-	dbg_print(lml, MSG_ORIG(MSG_SHD_LINK), EC_WORD(shdr->sh_link),
-	    conv_sec_info(shdr->sh_info, shdr->sh_flags));
+	dbg_print(lml, MSG_ORIG(MSG_SHD_LINK),
+	    conv_sec_linkinfo(shdr->sh_link, shdr->sh_flags),
+	    conv_sec_linkinfo(shdr->sh_info, shdr->sh_flags));
 	dbg_print(lml, MSG_ORIG(MSG_SHD_ALIGN), EC_XWORD(shdr->sh_addralign));
 }
+
+void
+Dbg_shdr_modified(Lm_list *lml, Half mach, Shdr *oshdr, Shdr *nshdr,
+    const char *name)
+{
+	if (DBG_NOTCLASS(DBG_C_SECTIONS))
+		return;
+	if (DBG_NOTDETAIL())
+		return;
+
+	Dbg_util_nl(lml, DBG_NL_STD);
+	dbg_print(lml, MSG_INTL(MSG_SHD_MODIFIED), name);
+
+	dbg_print(lml, MSG_INTL(MSG_SHD_ORIG));
+	Elf_shdr(lml, mach, oshdr);
+
+	dbg_print(lml, MSG_INTL(MSG_SHD_NEW));
+	Elf_shdr(lml, mach, nshdr);
+
+	Dbg_util_nl(lml, DBG_NL_STD);
+}
--- a/usr/src/cmd/sgs/mcs/common/main.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/mcs/common/main.c	Wed Aug 30 10:15:44 2006 -0700
@@ -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.
@@ -19,13 +18,14 @@
  *
  * CDDL HEADER END
  */
+
 /*
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
  *
- *	Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
- *	Use is subject to license terms.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -60,7 +60,7 @@
 	/*
 	 * Check for a binary that better fits this architecture.
 	 */
-	conv_check_native(argv, envp);
+	(void) conv_check_native(argv, envp);
 
 	/*
 	 * mcs(1) and strip() are hard linked together, determine which command
--- a/usr/src/cmd/sgs/moe/common/moe.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/moe/common/moe.c	Wed Aug 30 10:15:44 2006 -0700
@@ -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.
@@ -19,8 +18,9 @@
  *
  * CDDL HEADER END
  */
+
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -228,7 +228,7 @@
 	 * Re-exec ourselves to process any 64-bit expansion.
 	 */
 #if	!defined(__sparcv9) && !defined(__amd64)
-	conv_check_native(argv, envp);
+	(void) conv_check_native(argv, envp);
 #endif
 	return (error);
 }
--- a/usr/src/cmd/sgs/nm/common/nm.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/nm/common/nm.c	Wed Aug 30 10:15:44 2006 -0700
@@ -174,7 +174,7 @@
 	/*
 	 * Check for a binary that better fits this architecture.
 	 */
-	conv_check_native(argv, envp);
+	(void) conv_check_native(argv, envp);
 #endif
 
 	/* table of keyletters for use with -p and -P options */
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Wed Aug 30 10:15:44 2006 -0700
@@ -1117,3 +1117,4 @@
 6449485 ld(1) creates misaligned TLS in binary compiled with -xpg
 6424550 Write to unallocated (wua) errors when libraries are built with
 	-z lazyload
+6464235 executing the 64-bit ld(1) should be easy (D)
--- a/usr/src/cmd/sgs/pvs/common/pvs.c	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/cmd/sgs/pvs/common/pvs.c	Wed Aug 30 10:15:44 2006 -0700
@@ -638,7 +638,7 @@
 	/*
 	 * Check for a binary that better fits this architecture.
 	 */
-	conv_check_native(argv, envp);
+	(void) conv_check_native(argv, envp);
 
 	/*
 	 * Establish locale.
--- a/usr/src/tools/findunref/exception_list	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/tools/findunref/exception_list	Wed Aug 30 10:15:44 2006 -0700
@@ -221,3 +221,8 @@
 ./src/uts/sparc/sata/Makefile
 ./src/uts/sparc/si3124/Makefile
 ./closed/uts/sparc/marvell88sx/Makefile
+
+#
+# Ignore any files that get used during a gcc build only.
+#
+./src/cmd/sgs/rtld/common/mapfile-order-gcc
--- a/usr/src/uts/common/krtld/reloc.h	Wed Aug 30 09:00:25 2006 -0700
+++ b/usr/src/uts/common/krtld/reloc.h	Wed Aug 30 10:15:44 2006 -0700
@@ -122,8 +122,6 @@
 					FLG_RE_ADDRELATIVE) != 0)
 #define	IS_REGISTER(X)		((reloc_table[(X)].re_flags & \
 					FLG_RE_REGISTER) != 0)
-#define	IS_FORMOFF(X)		((reloc_table[(X)].re_flags & \
-					FLG_RE_FRMOFF) != 0)
 #define	IS_NOTSUP(X)		((reloc_table[(X)].re_flags & \
 					FLG_RE_NOTSUP) != 0)
 #define	IS_SEG_RELATIVE(X)	((reloc_table[(X)].re_flags & \