PSARC/2006/714 ld(1) mapfile: symbol interpose definition
authorrie
Mon, 22 Jan 2007 19:26:57 -0800
changeset 3466 4cc6ca6917b5
parent 3465 d3ee62ddc096
child 3467 8cf06bcbb424
PSARC/2006/714 ld(1) mapfile: symbol interpose definition 6494214 Refinements to symbolic binding, symbol declarations and interposition 6500110 *file* could produce better error diagnostics
usr/src/Makefile.master
usr/src/cmd/file/Makefile
usr/src/cmd/file/file.c
usr/src/cmd/file/magicutils.c
usr/src/cmd/sgs/elfdump/common/elfdump.c
usr/src/cmd/sgs/include/libld.h
usr/src/cmd/sgs/include/rtld.h
usr/src/cmd/sgs/lari/lari.pl
usr/src/cmd/sgs/libconv/common/dynamic.c
usr/src/cmd/sgs/libconv/common/dynamic.msg
usr/src/cmd/sgs/libld/common/args.c
usr/src/cmd/sgs/libld/common/libld.msg
usr/src/cmd/sgs/libld/common/map.c
usr/src/cmd/sgs/libld/common/relocate.c
usr/src/cmd/sgs/libld/common/resolve.c
usr/src/cmd/sgs/libld/common/syms.c
usr/src/cmd/sgs/libld/common/update.c
usr/src/cmd/sgs/liblddbg/common/liblddbg.msg
usr/src/cmd/sgs/liblddbg/common/syminfo.c
usr/src/cmd/sgs/packages/common/SUNWonld-README
usr/src/cmd/sgs/rtld/Makefile.com
usr/src/cmd/sgs/rtld/amd64/mapfile-amd64-vers
usr/src/cmd/sgs/rtld/common/_rtld.h
usr/src/cmd/sgs/rtld/common/analyze.c
usr/src/cmd/sgs/rtld/common/elf.c
usr/src/cmd/sgs/rtld/common/mapfile-32-vers
usr/src/cmd/sgs/rtld/common/mapfile-64-vers
usr/src/cmd/sgs/rtld/common/mapfile-vers
usr/src/cmd/sgs/rtld/common/setup.c
usr/src/cmd/sgs/rtld/common/util.c
usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c
usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg
usr/src/uts/common/sys/link.h
--- a/usr/src/Makefile.master	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/Makefile.master	Mon Jan 22 19:26:57 2007 -0800
@@ -707,7 +707,6 @@
 BLOCAL=		-Blocal
 BREDUCE=	-Breduce
 BSTATIC=	-Bstatic
-BSYMBOLIC=	-Bsymbolic
 
 ZCOMBRELOC=	-zcombreloc
 ZDEFS=		-zdefs
--- a/usr/src/cmd/file/Makefile	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/file/Makefile	Mon Jan 22 19:26:57 2007 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -64,6 +64,9 @@
 	$(LINK.c) $(XPG4OBJS) -o $@ $(LDLIBS)
 	$(POST_PROCESS)
 
+%.o:	%.c
+	$(COMPILE.c) -o $@ $<
+
 xpg4_%.o:	%.c
 	$(COMPILE.c) -o $@ $<
 
--- a/usr/src/cmd/file/file.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/file/file.c	Mon Jan 22 19:26:57 2007 -0800
@@ -26,7 +26,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.
  */
 
@@ -135,7 +135,7 @@
 
 
 /* start for MB env */
-static wchar_t wchar;
+static wchar_t	wchar;
 static int	length;
 static int	IS_ascii;
 static int	Max;
@@ -165,7 +165,7 @@
 static Elf *is_elf_file(int elffd);
 static void ar_coff_or_aout(int ifd);
 static int type(char *file);
-static int def_position_tests(void);
+static int def_position_tests(char *file);
 static void def_context_tests(void);
 static int troffint(char *bp, int n);
 static int lookup(char **tab);
@@ -174,9 +174,9 @@
 static int sccs(void);
 static int english(char *bp, int n);
 static int old_core(Elf *elf, GElf_Ehdr *ehdr, int format);
-static int core(Elf *elf, GElf_Ehdr *ehdr, int format);
+static int core(Elf *elf, GElf_Ehdr *ehdr, int format, char *file);
 static int shellscript(char buf[], struct stat64 *sb);
-static int elf_check(Elf *elf);
+static int elf_check(Elf *elf, char *file);
 static int get_door_target(char *, char *, size_t);
 static int zipfile(char *, int);
 static int is_crash_dump(const char *, int);
@@ -198,6 +198,12 @@
 #define	prf(x)	(void) printf("%s:%s", x, (int)strlen(x) > 6 ? "\t" : "\t\t");
 #endif	/* XPG4 */
 
+/*
+ * Static program identifier - used to prevent localization of the name "file"
+ * within individual error messages.
+ */
+const char *File = "file";
+
 int
 main(int argc, char **argv)
 {
@@ -239,23 +245,28 @@
 
 		case 'f':
 			fflg++;
+			errno = 0;
 			if ((fl = fopen(optarg, "r")) == NULL) {
-				(void) fprintf(stderr,
-					gettext("cannot open %s\n"), optarg);
+				int err = errno;
+				(void) fprintf(stderr, gettext("%s: cannot "
+				    "open file %s: %s\n"), File, optarg,
+				    err ? strerror(err) : "");
 				usage();
 			}
 			pathlen = pathconf("/", _PC_PATH_MAX);
 			if (pathlen == -1) {
-				(void) fprintf(stderr,
-				    gettext("pathconf: cannot determine "
-					"maximum path length\n"));
+				int err = errno;
+				(void) fprintf(stderr, gettext("%s: cannot "
+				    "determine maximum path length: %s\n"),
+				    File, strerror(err));
 				exit(1);
 			}
 			pathlen += 2; /* for null and newline in fgets */
-			ap = malloc(pathlen * sizeof (char));
-			if (ap == NULL) {
-				perror("malloc");
-				exit(1);
+			if ((ap = malloc(pathlen * sizeof (char))) == NULL) {
+				int err = errno;
+				(void) fprintf(stderr, gettext("%s: malloc "
+				    "failed: %s\n"), File, strerror(err));
+				exit(2);
 			}
 			break;
 
@@ -366,24 +377,29 @@
 	}
 	if (maxmagicoffset < (intmax_t)FBSZ)
 		maxmagicoffset = (intmax_t)FBSZ;
-	if ((magicbuf = (char *)malloc(maxmagicoffset)) == NULL) {
-		(void) fprintf(stderr, gettext("malloc failed\n"));
+	if ((magicbuf = malloc(maxmagicoffset)) == NULL) {
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: malloc failed: %s\n"),
+		    File, strerror(err));
 		exit(2);
 	}
 
 	if (cflg) {
 		f_prtmtab();
 		if (ferror(stdout) != 0) {
-			(void) fprintf(stderr, gettext("file: error writing to "
-			    "stdout\n"));
+			(void) fprintf(stderr, gettext("%s: error writing to "
+			    "stdout\n"), File);
 			exit(1);
 		}
 		if (fclose(stdout) != 0) {
-			perror(gettext("file: fclose failed"));
+			int err = errno;
+			(void) fprintf(stderr, gettext("%s: fclose "
+			    "failed: %s\n"), File, strerror(err));
 			exit(1);
 		}
 		exit(0);
 	}
+
 	for (; fflg || optind < argc; optind += !fflg) {
 		register int	l;
 
@@ -405,16 +421,18 @@
 	}
 	if (ap != NULL)
 		free(ap);
-	if (tret != 0) {
+	if (tret != 0)
 		exit(tret);
-	}
+
 	if (ferror(stdout) != 0) {
-		(void) fprintf(stderr, gettext("file: error writing to "
-		    "stdout\n"));
+		(void) fprintf(stderr, gettext("%s: error writing to "
+		    "stdout\n"), File);
 		exit(1);
 	}
 	if (fclose(stdout) != 0) {
-		perror(gettext("file: fclose failed"));
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: fclose failed: %s\n"),
+		    File, strerror(err));
 		exit(1);
 	}
 	return (0);
@@ -431,8 +449,9 @@
 	ifd = -1;
 	if ((*statf)(file, &mbuf) < 0) {
 		if (statf == lstat64 || lstat64(file, &mbuf) < 0) {
+			int err = errno;
 			(void) printf(gettext("cannot open: %s\n"),
-			    strerror(errno));
+			    strerror(err));
 			return (0);		/* POSIX.2 */
 		}
 	}
@@ -457,8 +476,9 @@
 
 	case S_IFLNK:
 		if ((cc = readlink(file, buf, BUFSIZ)) < 0) {
+			int err = errno;
 			(void) printf(gettext("readlink error: %s\n"),
-				strerror(errno));
+			    strerror(err));
 			return (1);
 		}
 		buf[cc] = '\0';
@@ -494,20 +514,23 @@
 
 	ifd = open64(file, O_RDONLY);
 	if (ifd < 0) {
-		(void) printf(gettext("cannot open: %s\n"), strerror(errno));
+		int err = errno;
+		(void) printf(gettext("cannot open: %s\n"), strerror(err));
 		return (0);			/* POSIX.2 */
 	}
 
 	/* need another fd for elf, since we might want to read the file too */
 	elffd = open64(file, O_RDONLY);
 	if (elffd < 0) {
-		(void) printf(gettext("cannot open: %s\n"), strerror(errno));
+		int err = errno;
+		(void) printf(gettext("cannot open: %s\n"), strerror(err));
 		(void) close(ifd);
 		ifd = -1;
 		return (0);			/* POSIX.2 */
 	}
 	if ((fbsz = read(ifd, fbuf, FBSZ)) == -1) {
-		(void) printf(gettext("cannot read: %s\n"), strerror(errno));
+		int err = errno;
+		(void) printf(gettext("cannot read: %s\n"), strerror(err));
 		(void) close(ifd);
 		ifd = -1;
 		return (0);			/* POSIX.2 */
@@ -523,8 +546,9 @@
 	 * which need to execute before the default tests.
 	 */
 	if ((mread = pread(ifd, (void*)magicbuf, (size_t)maxmagicoffset,
-			(off_t)0)) == -1) {
-		(void) printf(gettext("cannot read: %s\n"), strerror(errno));
+	    (off_t)0)) == -1) {
+		int err = errno;
+		(void) printf(gettext("cannot read: %s\n"), strerror(err));
 		fd_cleanup();
 		return (0);
 	}
@@ -555,7 +579,7 @@
 		 * default position-dependent tests,
 		 * plus non-default magic tests, if any
 		 */
-		switch (def_position_tests()) {
+		switch (def_position_tests(file)) {
 			case -1:	/* error */
 				fd_cleanup();
 				return (1);
@@ -594,7 +618,7 @@
  */
 
 static int
-def_position_tests(void)
+def_position_tests(char *file)
 {
 	Elf	*elf;
 
@@ -605,7 +629,7 @@
 	if (fbuf[0] == '#' && fbuf[1] == '!' && shellscript(fbuf+2, &mbuf))
 		return (1);
 	if ((elf = is_elf_file(elffd)) != NULL) {
-		(void) elf_check(elf);
+		(void) elf_check(elf, file);
 		(void) elf_end(elf);
 		(void) putchar('\n');
 		return (1);
@@ -1165,7 +1189,7 @@
 }
 
 static int
-print_cap(Elf *elf, GElf_Ehdr *ehdr)
+print_cap(Elf *elf, GElf_Ehdr *ehdr, char *file)
 {
 	Elf_Scn	*scn = 0;
 
@@ -1179,8 +1203,9 @@
 		Elf_Data	*data;
 
 		if (gelf_getshdr(scn, &shdr) == 0) {
-			(void) fprintf(stderr,
-			    gettext("can't read ELF section header\n"));
+			(void) fprintf(stderr, gettext("%s: %s: can't read "
+			    "ELF section header - ELF capabilities ignored\n"),
+			    File, file);
 			return (1);
 		}
 		if (shdr.sh_type != SHT_SUNW_cap)
@@ -1190,19 +1215,28 @@
 		 * Get the data associated with the .cap section.
 		 */
 		if ((data = elf_getdata(scn, 0)) == 0) {
-			(void) fprintf(stderr,
-				gettext("can't read ELF section data\n"));
+			(void) fprintf(stderr, gettext("%s: %s: can't read "
+			    "ELF section data - ELF capabilities ignored\n"),
+			    File, file);
 			return (1);
 		}
 
+		if ((shdr.sh_size == 0) || (shdr.sh_entsize == 0)) {
+			(void) fprintf(stderr, gettext("%s: %s zero size or "
+			    "zero entry ELF section - ELF capabilities "
+			    "ignored\n"), File, file);
+			return (1);
+		}
 		capn = (GElf_Word)(shdr.sh_size / shdr.sh_entsize);
+
 		for (ndx = 0; ndx < capn; ndx++) {
 			char		str[100];
 			GElf_Cap	cap;
 
 			if (gelf_getcap(data, ndx, &cap) == NULL) {
-				(void) fprintf(stderr,
-				    gettext("can't read capabilities data\n"));
+				(void) fprintf(stderr, gettext("%s: %s: can't "
+				    "read ELF capabilities data - ELF "
+				    "capabilities ignored\n"), File, file);
 				return (1);
 			}
 			if (cap.c_tag != CA_SUNW_NULL) {
@@ -1216,7 +1250,7 @@
 }
 
 static int
-elf_check(Elf *elf)
+elf_check(Elf *elf, char *file)
 {
 	GElf_Ehdr	ehdr;
 	GElf_Phdr	phdr;
@@ -1225,10 +1259,11 @@
 	size_t	size;
 
 	/*
-	 * verify information in file header
+	 * Verify information in file header.
 	 */
 	if (gelf_getehdr(elf, &ehdr) == (GElf_Ehdr *)0) {
-		(void) fprintf(stderr, gettext("can't read ELF header\n"));
+		(void) fprintf(stderr, gettext("%s: %s: can't read ELF "
+		    "header\n"), File, file);
 		return (1);
 	}
 	ident = elf_getident(elf, &size);
@@ -1242,30 +1277,31 @@
 		    gettext("Version"), (int)ehdr.e_version);
 	print_elf_flags(ehdr.e_machine, ehdr.e_flags);
 
-	if (core(elf, &ehdr, ident[EI_DATA]))	/* check for core file */
+	if (core(elf, &ehdr, ident[EI_DATA], file)) /* check for core file */
 		return (0);
 
-	if (print_cap(elf, &ehdr))
+	if (print_cap(elf, &ehdr, file))
 		return (1);
 
 	/*
-	 * check type
+	 * Check type.
 	 */
 	if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
 		return (1);
 
 	/*
-	 * read program header and check for dynamic section
+	 * Read program header and check for dynamic section.
 	 */
 	if (ehdr.e_phnum == 0) {
-		(void) fprintf(stderr, gettext("can't read program header\n"));
+		(void) fprintf(stderr, gettext("%s: %s: no ELF program headers "
+		    "exist\n"), File, file);
 		return (1);
 	}
 
 	for (dynamic = 0, cnt = 0; cnt < (int)ehdr.e_phnum; cnt++) {
 		if (gelf_getphdr(elf, cnt, &phdr) == NULL) {
-			(void) fprintf(stderr,
-				gettext("can't read program header\n"));
+			(void) fprintf(stderr, gettext("%s: %s: can't read "
+			    "ELF program header\n"), File, file);
 			return (1);
 		}
 		if (phdr.p_type == PT_DYNAMIC) {
@@ -1618,7 +1654,7 @@
  * If it's a core file, print out the name of the file that dumped core.
  */
 static int
-core(Elf *elf, GElf_Ehdr *ehdr, int format)
+core(Elf *elf, GElf_Ehdr *ehdr, int format, char *file)
 {
 	register int inx;
 	char *psinfo;
@@ -1631,19 +1667,20 @@
 		return (0);
 	for (inx = 0; inx < (int)ehdr->e_phnum; inx++) {
 		if (gelf_getphdr(elf, inx, &phdr) == NULL) {
-			(void) fprintf(stderr,
-				gettext("can't read program header\n"));
+			(void) fprintf(stderr, gettext("%s: %s: can't read "
+			    "ELF program header\n"), File, file);
 			return (0);
 		}
 		if (phdr.p_type == PT_NOTE) {
 			char *fname;
 			size_t size;
+
 			/*
 			 * If the next segment is also a note, use it instead.
 			 */
 			if (gelf_getphdr(elf, inx+1, &nphdr) == NULL) {
-				(void) fprintf(stderr,
-				    gettext("can't read program header\n"));
+				(void) fprintf(stderr, gettext("%s: %s: can't "
+				    "read ELF program header\n"), File, file);
 				return (0);
 			}
 			if (nphdr.p_type == PT_NOTE)
@@ -1651,6 +1688,7 @@
 			offset = (off_t)phdr.p_offset;
 			(void) pread(ifd, &nhdr, sizeof (GElf_Nhdr), offset);
 			convert_gelf_nhdr(elf, &nhdr, ehdr->e_version, format);
+
 			/*
 			 * Note: the ABI states that n_namesz must
 			 * be rounded up to a 4 byte boundary.
@@ -1658,8 +1696,14 @@
 			offset += sizeof (GElf_Nhdr) +
 			    ((nhdr.n_namesz + 0x03) & ~0x3);
 			size = nhdr.n_descsz;
-			psinfo = malloc(size);
+			if ((psinfo = malloc(size)) == NULL) {
+				int err = errno;
+				(void) fprintf(stderr, gettext("%s: malloc "
+				    "failed: %s\n"), File, strerror(err));
+				exit(2);
+			}
 			(void) pread(ifd, psinfo, size, offset);
+
 			/*
 			 * We want to print the string contained
 			 * in psinfo->pr_fname[], where 'psinfo'
@@ -1952,8 +1996,10 @@
 	const char *msg_locale = setlocale(LC_MESSAGES, NULL);
 	struct stat	statbuf;
 
-	if ((dfile = (char *)malloc(strlen(msg_locale) + 35)) == NULL) {
-		perror("file");
+	if ((dfile = malloc(strlen(msg_locale) + 35)) == NULL) {
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: malloc failed: %s\n"),
+		    File, strerror(err));
 		exit(2);
 	}
 	(void) snprintf(dfile, strlen(msg_locale) + 35,
@@ -1993,9 +2039,10 @@
 	}
 
 	if (mlist == NULL) {	/* initial mlist allocation */
-		if ((mlist = (char **)calloc(MLIST_SZ, sizeof (char *)))
-		    == NULL) {
-			perror("file");
+		if ((mlist = calloc(MLIST_SZ, sizeof (char *))) == NULL) {
+			int err = errno;
+			(void) fprintf(stderr, gettext("%s: malloc "
+			    "failed: %s\n"), File, strerror(err));
 			exit(2);
 		}
 		mlist_sz = MLIST_SZ;
@@ -2004,9 +2051,11 @@
 	if ((mlistp - mlist) >= mlist_sz) {
 		mlistp_off = mlistp - mlist;
 		mlist_sz *= 2;
-		if ((mlist = (char **)realloc(mlist,
+		if ((mlist = realloc(mlist,
 		    mlist_sz * sizeof (char *))) == NULL) {
-			perror("file");
+			int err = errno;
+			(void) fprintf(stderr, gettext("%s: malloc "
+			    "failed: %s\n"), File, strerror(err));
 			exit(2);
 		}
 		mlistp = mlist + mlistp_off;
@@ -2016,7 +2065,9 @@
 	 * magic file name string
 	 */
 	if ((*mlistp = malloc(strlen(magic_file) + 1)) == NULL) {
-		perror("file");
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: malloc failed: %s\n"),
+		    File, strerror(err));
 		exit(2);
 	}
 	(void) strlcpy(*mlistp, magic_file, strlen(magic_file) + 1);
--- a/usr/src/cmd/file/magicutils.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/file/magicutils.c	Mon Jan 22 19:26:57 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.
  */
 
@@ -94,6 +93,9 @@
 	const char	*e_str;
 };
 
+/* Non-localized string giving name of command.  Defined in file.c */
+extern const char	*File;
+
 typedef	struct entry	Entry;
 
 static Entry	*mtab1;	/* 1st magic table, applied before default tests */
@@ -111,7 +113,7 @@
 static Entry	*ep2;	/* current entry in mtab2 */
 
 static char *
-getstr(char *p)
+getstr(char *p, char *file)
 {
 	char	*newstr;
 	char	*s;
@@ -120,7 +122,9 @@
 
 	newstr = (char *)malloc((strlen(p) + 1) * sizeof (char));
 	if (newstr == NULL) {
-		perror(gettext("magic table string allocation"));
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: malloc failed: %s\n"),
+		    File, strerror(err));
 		return (NULL);
 	}
 
@@ -143,8 +147,9 @@
 			errno = 0;
 			val = strtol(p, &p, base);
 			if (val > UCHAR_MAX || val < 0 || errno != 0) {
-				perror(gettext("magic table invalid "
-				    "string value"));
+				(void) fprintf(stderr, gettext("%s: %s: magic "
+				    "table invalid string value\n"), File,
+				    file);
 				return (NULL);
 			}
 			*s++ = (char)val;
@@ -238,10 +243,10 @@
 
 	/* mtab may have been allocated on a previous f_mkmtab call */
 	if (mtab == (Entry *)NULL) {
-		mtab = (Entry *) calloc(sizeof (Entry), NENT);
-		if (mtab == (Entry *)NULL) {
-			(void) fprintf(stderr,
-			gettext("no memory for magic table\n"));
+		if ((mtab = calloc(sizeof (Entry), NENT)) == NULL) {
+			int err = errno;
+			(void) fprintf(stderr, gettext("%s: malloc "
+			    "failed: %s\n"), File, strerror(err));
 			return (-1);
 		}
 
@@ -249,11 +254,11 @@
 		mend = &mtab[NENT];
 	}
 
-	fp = fopen(magfile, "r");
-	if (fp == NULL) {
-		(void) fprintf(stderr,
-		gettext("cannot open magic file <%s>.\n"),
-		magfile);
+	errno = 0;
+	if ((fp = fopen(magfile, "r")) == NULL) {
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: %s: cannot open magic "
+		    "file: %s\n"), File, magfile, err ? strerror(err) : "");
 		return (-1);
 	}
 	while (fgets(buf, BSZ, fp) != NULL) {
@@ -270,7 +275,9 @@
 			oldsize = mend - mtab;
 			tbsize = (NENT + oldsize) * sizeof (Entry);
 			if ((mtab = realloc(mtab, tbsize)) == NULL) {
-				perror(gettext("magic table overflow"));
+				int err = errno;
+				(void) fprintf(stderr, gettext("%s: malloc "
+				    "failed: %s\n"), File, strerror(err));
 				return (-1);
 			} else {
 				(void) memset(mtab + oldsize, 0,
@@ -294,9 +301,9 @@
 		p2 = strchr(p, '\t');
 		if (p2 == NULL) {
 			if (cflg)
-				(void) fprintf(stderr,
-				    gettext("fmt error, no tab after %s on "
-				    "line %d of %s\n"), p, lcnt, magfile);
+				(void) fprintf(stderr, gettext("%s: %s: format "
+				    "error, no tab after %s on line %d\n"),
+				    File, magfile, p, lcnt);
 			continue;
 		}
 		*p2++ = NULL;
@@ -308,9 +315,9 @@
 		p2 = strchr(p, '\t');
 		if (p2 == NULL) {
 			if (cflg)
-				(void) fprintf(stderr,
-				    gettext("fmt error, no tab after %s on "
-				    "line %d of %s\n"), p, lcnt, magfile);
+				(void) fprintf(stderr, gettext("%s: %s: format "
+				    "error, no tab after %s on line %d\n"),
+				    File, magfile, p, lcnt);
 			continue;
 		}
 		*p2++ = NULL;
@@ -440,9 +447,9 @@
 		p2 = strchr(p, '\t');
 		if (p2 == NULL) {
 			if (cflg)
-				(void) fprintf(stderr,
-				    gettext("fmt error, no tab after %s on "
-				    "line %d of %s\n"), p, lcnt, magfile);
+				(void) fprintf(stderr, gettext("%s: %s: format "
+				    "error, no tab after %s on line %d\n"),
+				    File, magfile, p, lcnt);
 			continue;
 		}
 		*p2++ = NULL;
@@ -480,14 +487,17 @@
 			if (ep->e_type != STR) {
 				ep->e_value.num = strtoull((const char *)p,
 				    (char **)NULL, 0);
-			} else if ((ep->e_value.str = getstr(p)) == NULL) {
+			} else if ((ep->e_value.str =
+			    getstr(p, magfile)) == NULL) {
 				return (-1);
 			}
 		}
 		p2 += strspn(p2, "\t");
 			/* STRING */
 		if ((ep->e_str = strdup(p2)) == NULL) {
-			perror(gettext("magic table message allocation"));
+			int err = errno;
+			(void) fprintf(stderr, gettext("%s: malloc "
+			    "failed: %s\n"), File, strerror(err));
 			return (-1);
 		} else {
 			if ((p = strchr(ep->e_str, '\n')) != NULL)
@@ -508,8 +518,10 @@
 		mend2 = mend;
 		ep2 = ep;
 	}
-	if (fclose(fp) == EOF) {
-		perror(magfile);
+	if (fclose(fp) != 0) {
+		int err = errno;
+		(void) fprintf(stderr, gettext("%s: fclose failed: %s\n"),
+		    File, strerror(err));
 		return (-1);
 	}
 	return (0);
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.c	Mon Jan 22 19:26:57 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.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -50,6 +50,9 @@
 	static Cache	*osec = 0;
 	static int	nostr;
 
+	if (strsec->c_data == NULL)
+		return (NULL);
+
 	const char	*strs = (char *)strsec->c_data->d_buf;
 	Word		strn = strsec->c_data->d_size;
 
@@ -149,11 +152,17 @@
 			    file, cache[ndx].c_name, EC_WORD(shdr->sh_link));
 			return (0);
 		}
+		if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
+			    file, cache[ndx].c_name);
+			return (0);
+		}
 
 		/*
 		 * Obtain, and verify the symbol table data.
 		 */
-		if (cache[ndx].c_data->d_buf == 0) {
+		if ((cache[ndx].c_data == NULL) ||
+		    (cache[ndx].c_data->d_buf == NULL)) {
 			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
 			    file, cache[ndx].c_name);
 			return (0);
@@ -213,6 +222,9 @@
 		    file, symtab->c_name);
 		return (0);
 	}
+	if (symtab->c_data == NULL)
+		return (0);
+
 	/* LINTED */
 	symn = (Word)(shdr->sh_size / shdr->sh_entsize);
 	syms = (Sym *)symtab->c_data->d_buf;
@@ -388,6 +400,9 @@
 		if (name && strcmp(name, _cache->c_name))
 			continue;
 
+		if (_cache->c_data == NULL)
+			continue;
+
 		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
 		dbg_print(0, MSG_INTL(MSG_ELF_SCN_UNWIND), _cache->c_name);
 
@@ -616,8 +631,8 @@
     Elf *elf)
 {
 	Word		cnt;
-	Shdr *		cshdr = 0;
-	Cache *		ccache;
+	Shdr		*cshdr = 0;
+	Cache		*ccache;
 	Off		cphdr_off = 0;
 	Xword		cphdr_sz;
 
@@ -655,6 +670,9 @@
 		    (cphdr_off + cphdr_sz) > (shdr->sh_offset + shdr->sh_size)))
 			continue;
 
+		if (_cache->c_data == NULL)
+			continue;
+
 		ccache = _cache;
 		cshdr = shdr;
 		break;
@@ -663,12 +681,18 @@
 	if ((cshdr == 0) && (cphdr_off == 0))
 		return;
 
+	if ((cshdr->sh_entsize == 0) || (cshdr->sh_size == 0)) {
+		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
+		    file, ccache->c_name);
+		return;
+	}
+
 	/*
 	 * Print the hardware/software capabilities section.
 	 */
 	if (cshdr) {
 		Word	ndx, capn;
-		Cap	*cap = (Cap *)ccache->c_data->d_buf;
+		Cap	*cap  = (Cap *)ccache->c_data->d_buf;
 
 		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
 		dbg_print(0, MSG_INTL(MSG_ELF_SCN_CAP), ccache->c_name);
@@ -752,7 +776,7 @@
 	 * Print the interpreter string based on the offset defined in the
 	 * program header, as this is the offset used by the kernel.
 	 */
-	if (ishdr) {
+	if (ishdr && icache->c_data) {
 		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
 		dbg_print(0, MSG_INTL(MSG_ELF_SCN_INTERP), icache->c_name);
 		dbg_print(0, MSG_ORIG(MSG_FMT_INDENT),
@@ -800,6 +824,9 @@
 		    file, infocache->c_name);
 		return;
 	}
+	if (infocache->c_data == NULL)
+		return;
+
 	infonum = (Word)(infoshdr->sh_size / infoshdr->sh_entsize);
 	info = (Syminfo *)infocache->c_data->d_buf;
 
@@ -811,6 +838,9 @@
 		    file, infocache->c_name, EC_WORD(infoshdr->sh_info));
 		return;
 	}
+	if (cache[infoshdr->sh_info].c_data == NULL)
+		return;
+
 	dyns = cache[infoshdr->sh_info].c_data->d_buf;
 	if (dyns == 0) {
 		(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
@@ -992,7 +1022,8 @@
 		/*
 		 * Determine the version section data and number.
 		 */
-		if ((ver = (void *)_cache->c_data->d_buf) == 0) {
+		if ((_cache->c_data == NULL) ||
+		    ((ver = (void *)_cache->c_data->d_buf) == NULL)) {
 			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
 			    file, secname);
 			continue;
@@ -1049,6 +1080,9 @@
 		    ((symn = (uint_t)(shdr->sh_size / shdr->sh_entsize)) == 0))
 			continue;
 
+		if (_cache->c_data == NULL)
+			continue;
+
 		*shxndx = _cache->c_data->d_buf;
 		*symnshxndx = symn;
 		return (0);
@@ -1108,6 +1142,9 @@
 			    file, secname);
 			continue;
 		}
+		if (_cache->c_data == NULL)
+			continue;
+
 		/* LINTED */
 		symn = (Word)(shdr->sh_size / shdr->sh_entsize);
 		sym = (Sym *)_cache->c_data->d_buf;
@@ -1125,7 +1162,8 @@
 		 * Determine if there is a associated Versym section
 		 * with this Symbol Table.
 		 */
-		if (versymcache && (versymcache->c_shdr->sh_link == seccnt))
+		if (versymcache && (versymcache->c_shdr->sh_link == seccnt) &&
+		    versymcache->c_data)
 			versym = versymcache->c_data->d_buf;
 		else
 			versym = 0;
@@ -1319,6 +1357,9 @@
 			    file, relname);
 			continue;
 		}
+		if (_cache->c_data == NULL)
+			continue;
+
 		rels = _cache->c_data->d_buf;
 		relnum = shdr->sh_size / relsize;
 
@@ -1428,6 +1469,14 @@
 		if (stringtbl(cache, 0, cnt, shnum, file, 0, 0, &strsec) == 0)
 			continue;
 
+		if ((shdr->sh_entsize == 0) || (shdr->sh_size == 0)) {
+			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
+			    file, _cache->c_name);
+			continue;
+		}
+		if (_cache->c_data == NULL)
+			continue;
+
 		numdyn = shdr->sh_size / shdr->sh_entsize;
 		dyn = (Dyn *)_cache->c_data->d_buf;
 
@@ -1505,6 +1554,9 @@
 			    file, _cache->c_name);
 			continue;
 		}
+		if (_cache->c_data == NULL)
+			continue;
+
 		move = (Move *)_cache->c_data->d_buf;
 		movenum = shdr->sh_size / shdr->sh_entsize;
 
@@ -1757,6 +1809,8 @@
 			    file, _cache->c_name);
 			continue;
 		}
+		if (_cache->c_data == NULL)
+			continue;
 
 		dbg_print(0, MSG_ORIG(MSG_STR_EMPTY));
 		dbg_print(0, MSG_INTL(MSG_ELF_SCN_NOTE), _cache->c_name);
@@ -1844,6 +1898,9 @@
 			    file, hsecname);
 			continue;
 		}
+		if (_cache->c_data == NULL)
+			continue;
+
 		hash = (uint_t *)_cache->c_data->d_buf;
 		bkts = *hash;
 		chain = hash + 2 + bkts;
@@ -1861,7 +1918,10 @@
 		_cache = &cache[hshdr->sh_link];
 		ssecname = _cache->c_name;
 
-		if ((syms = (Sym *)_cache->c_data->d_buf) == 0) {
+		if (_cache->c_data == NULL)
+			continue;
+
+		if ((syms = (Sym *)_cache->c_data->d_buf) == NULL) {
 			(void) fprintf(stderr, MSG_INTL(MSG_ERR_BADSZ),
 			    file, ssecname);
 			continue;
@@ -1969,8 +2029,8 @@
 			continue;
 		if (name && strcmp(name, _cache->c_name))
 			continue;
-		if ((_cache->c_data == 0) ||
-		    ((grpdata = (Word *)_cache->c_data->d_buf) == 0))
+		if ((_cache->c_data == NULL) ||
+		    ((grpdata = (Word *)_cache->c_data->d_buf) == NULL))
 			continue;
 		grpcnt = shdr->sh_size / sizeof (Word);
 
@@ -2086,6 +2146,9 @@
 	if ((gentsize = gotshdr->sh_entsize) == 0)
 		gentsize = sizeof (Xword);
 
+	if (gotcache->c_data == NULL)
+		return;
+
 	/* LINTED */
 	gotents = (Word)(gotshdr->sh_size / gentsize);
 	gotdata = gotcache->c_data->d_buf;
@@ -2146,6 +2209,9 @@
 			    file, _cache->c_name);
 			continue;
 		}
+		if (_cache->c_data == NULL)
+			continue;
+
 		rels = _cache->c_data->d_buf;
 		relnum = shdr->sh_size / relsize;
 
@@ -2427,7 +2493,8 @@
 		/*
 		 * Do we wish to write the section out?
 		 */
-		if (wfd && Nname && (strcmp(Nname, _cache->c_name) == 0)) {
+		if (wfd && Nname && (strcmp(Nname, _cache->c_name) == 0) &&
+		    _cache->c_data) {
 			(void) write(wfd, _cache->c_data->d_buf,
 			    _cache->c_data->d_size);
 		}
--- a/usr/src/cmd/sgs/include/libld.h	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/include/libld.h	Mon Jan 22 19:26:57 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.
  */
 
@@ -189,8 +189,8 @@
 	Word		ofl_regsymcnt;	/* no. of output register symbols */
 	Word		ofl_lregsymcnt;	/* no. of local register symbols */
 	Sym_desc	*ofl_dtracesym;	/* ld -zdtrace= */
-	Word		ofl_flags;	/* various state bits, args etc. */
-	Word		ofl_flags1;	/*	more flags */
+	Lword		ofl_flags;	/* various state bits, args etc. */
+	Lword		ofl_flags1;	/*	more flags */
 	Xword		ofl_segorigin;	/* segment origin (start) */
 	void		*ofl_entry;	/* entry point (-e and Sym_desc *) */
 	char		*ofl_filtees;	/* shared objects we are a filter for */
@@ -316,6 +316,9 @@
 #define	FLG_OF_WARN	0x40000000	/* warning during input processing. */
 #define	FLG_OF_VERBOSE	0x80000000	/* -z verbose flag set */
 
+#define	FLG_OF_MAPSYMB	0x000100000000	/* symbolic scope definition seen */
+#define	FLG_OF_MAPGLOB	0x000200000000	/* global scope definition seen */
+
 /*
  * In the flags1 arena, establish any options that are applicable to archive
  * extraction first, and associate a mask.  These values are recorded with any
@@ -781,7 +784,7 @@
 #define	FLG_SY_REFRSD	0x00000400	/* symbols sd_ref has been raised */
 					/* 	due to a copy-relocs */
 					/*	weak-strong pairing */
-
+#define	FLG_SY_INTPOSE	0x00000800	/* symbol defines an interposer */
 #define	FLG_SY_INVALID	0x00001000	/* unwanted/erroneous symbol */
 #define	FLG_SY_SMGOT	0x00002000	/* small got index assigned to symbol */
 					/*	sparc only */
--- a/usr/src/cmd/sgs/include/rtld.h	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/include/rtld.h	Mon Jan 22 19:26:57 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.
  */
 
@@ -655,9 +655,11 @@
 #define	FLG_RT_NOOPEN	0x00100000	/* dlopen() not allowed */
 #define	FLG_RT_FINICLCT	0x00200000	/* fini has been collected (tsort) */
 #define	FLG_RT_INITCALL	0x00400000	/* objects .init has been called */
-#define	FLG_RT_INTRPOSE	0x00800000	/* object is an INTERPOSER */
-#define	FLG_RT_DIRECT	0x01000000	/* object has DIRECT bindings enabled */
-#define	FLG_RT_SUNWBSS	0x02000000	/* object with PT_SUNWBSS, not mapped */
+#define	FLG_RT_SUNWBSS	0x00800000	/* object with PT_SUNWBSS, not mapped */
+#define	FLG_RT_OBJINTPO	0x01000000	/* object is a global interposer */
+#define	FLG_RT_SYMINTPO	0x02000000	/* object contains symbol interposer */
+#define	MSK_RT_INTPOSE	0x03000000	/* mask for all interposer */
+					/*	possibilities */
 #define	FLG_RT_MOVE	0x04000000	/* object needs move operation */
 #define	FLG_RT_DLSYM	0x08000000	/* dlsym in progress on object */
 #define	FLG_RT_REGSYMS	0x10000000	/* object has DT_REGISTER entries */
@@ -686,6 +688,7 @@
 
 #define	FL1_RT_TLSADD	0x00010000	/* objects TLS has been registered */
 #define	FL1_RT_TLSSTAT	0x00020000	/* object requires static TLS */
+#define	FL1_RT_DIRECT	0x00040000	/* object has DIRECT bindings enabled */
 
 /*
  * The following range of bits are reserved to hold LML_TFLG_AUD_ values
--- a/usr/src/cmd/sgs/lari/lari.pl	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/lari/lari.pl	Mon Jan 22 19:26:57 2007 -0800
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -90,7 +90,7 @@
 $Sfte = 0x00002;	# symbol is a filtee backing a standard filter
 $Afte = 0x00004;	# symbol is a filtee backing a auxiliary filter
 $Gfte = 0x00008;	# symbol bound as a filtee
-$Intp = 0x00010;	# symbol originates for explicit interposer
+$Intp = 0x00010;	# symbol originates from explicit interposer
 $Dirc = 0x00020;	# symbol bound to directly
 $Cpyr = 0x00040;	# symbol bound to copy-relocation reference
 $Prot = 0x00080;	# symbol is protected (symbolic)
@@ -1284,7 +1284,7 @@
 
 			# Determine whether this object is an interposer.
 			if (($Fields[1] eq 'FLAGS_1') &&
-			    ($Line =~ / INTERPOSE /)) {
+			    ($Line =~ / OBJECT-INTERPOSE /)) {
 				$Interpose = 1;
 				next;
 			}
@@ -1342,6 +1342,9 @@
 			if ($Fields[1] =~ /A/) {
 				$Flags |= $Saft;
 			}
+			if ($Fields[1] =~ /I/) {
+				$Flags |= $Intp;
+			}
 
 			# Determine the symbol name based upon the number of
 			# fields.
@@ -1354,7 +1357,7 @@
 			# If this is a filter, we need to tag the associated
 			# filtee symbol.  However, the filtee might not have
 			# been processed yet, so save this information for later.
-			$Flags &= ~$Nodi;
+			$Flags &= ~($Nodi | $Intp);
 			if ($Flags) {
 				my ($Filtee) = $Fields[$#Fields - 1];
 
--- a/usr/src/cmd/sgs/libconv/common/dynamic.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libconv/common/dynamic.c	Mon Jan 22 19:26:57 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.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -128,8 +128,9 @@
 		MSG_DF1_NODIRECT_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 		MSG_DF1_IGNMULDEF_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 		MSG_DF1_NOKSYMS_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+		MSG_DF1_NOHDR_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 		MSG_DF1_NORELOC_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
-		MSG_DF1_NOHDR_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
+		MSG_DF1_SYMINTPOSE_SIZE	+ CONV_EXPN_FIELD_DEF_SEP_SIZE + \
 		CONV_INV_STRSIZE + CONV_EXPN_FIELD_DEF_SUFFIX_SIZE
 
 const char *
@@ -157,8 +158,9 @@
 		{ DF_1_NODIRECT,	MSG_ORIG(MSG_DF1_NODIRECT) },
 		{ DF_1_IGNMULDEF,	MSG_ORIG(MSG_DF1_IGNMULDEF) },
 		{ DF_1_NOKSYMS,		MSG_ORIG(MSG_DF1_NOKSYMS) },
+		{ DF_1_NOHDR,		MSG_ORIG(MSG_DF1_NOHDR) },
 		{ DF_1_NORELOC,		MSG_ORIG(MSG_DF1_NORELOC) },
-		{ DF_1_NOHDR,		MSG_ORIG(MSG_DF1_NOHDR) },
+		{ DF_1_SYMINTPOSE,	MSG_ORIG(MSG_DF1_SYMINTPOSE) },
 		{ 0,			0 }
 	};
 	static CONV_EXPN_FIELD_ARG conv_arg = { string, sizeof (string), vda };
--- a/usr/src/cmd/sgs/libconv/common/dynamic.msg	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libconv/common/dynamic.msg	Mon Jan 22 19:26:57 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.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -108,7 +108,7 @@
 @ MSG_DF1_NODELETE		"NODELETE"
 @ MSG_DF1_LOADFLTR		"LOADFLTR"
 @ MSG_DF1_INITFIRST		"INITFIRST"
-@ MSG_DF1_INTERPOSE		"INTERPOSE"
+@ MSG_DF1_INTERPOSE		"OBJECT-INTERPOSE"
 @ MSG_DF1_NOOPEN		"NOOPEN"
 @ MSG_DF1_ORIGIN		"ORIGIN"
 @ MSG_DF1_DIRECT		"DIRECT"
@@ -122,8 +122,9 @@
 @ MSG_DF1_NODIRECT		"NODIRECT"
 @ MSG_DF1_IGNMULDEF		"IGNMULDEF"
 @ MSG_DF1_NOKSYMS		"NOKSYMS"
+@ MSG_DF1_NOHDR			"NOHDR"
 @ MSG_DF1_NORELOC		"NORELOC"
-@ MSG_DF1_NOHDR			"NOHDR"
+@ MSG_DF1_SYMINTPOSE		"SYMBOL-INTERPOSE"
 
 @ MSG_DFP_LAZYLOAD	"LAZY"
 @ MSG_DFP_LAZYLOAD_ALT	"LAZYLOAD"
--- a/usr/src/cmd/sgs/libld/common/args.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/args.c	Mon Jan 22 19:26:57 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"
@@ -383,13 +383,23 @@
 			ofl->ofl_flags |= FLG_OF_SHAROBJ;
 
 			/*
-			 * By default we print relocation errors for
-			 * executables but *not* for a shared object
+			 * By default, print text relocation errors for
+			 * executables but *not* for shared objects.
 			 */
 			if (ztflag == 0)
 				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
 
 			if (Bsflag) {
+				/*
+				 * -Bsymbolic, and -Bnodirect make no sense.
+				 */
+				if (Bdflag == SET_FALSE) {
+					eprintf(ofl->ofl_lml, ERR_FATAL,
+					    MSG_INTL(MSG_ARG_INCOMP),
+					    MSG_ORIG(MSG_ARG_BSYMBOLIC),
+					    MSG_ORIG(MSG_ARG_BNODIRECT));
+					ofl->ofl_flags |= FLG_OF_FATAL;
+				}
 				ofl->ofl_flags |= FLG_OF_SYMBOLIC;
 				ofl->ofl_dtflags |= DF_SYMBOLIC;
 			}
@@ -544,6 +554,19 @@
 	}
 
 	/*
+	 * If a mapfile has been used to define a single symbolic scope of
+	 * interfaces, -Bsymbolic is established.  This global setting goes
+	 * beyond individual symbol protection, and ensures all relocations
+	 * (even those that reference section symbols) are processed within
+	 * the object being built.
+	 */
+	if ((ofl->ofl_flags &
+	    (FLG_OF_MAPSYMB | FLG_OF_MAPGLOB)) == FLG_OF_MAPSYMB) {
+		ofl->ofl_flags |= FLG_OF_SYMBOLIC;
+		ofl->ofl_dtflags |= DF_SYMBOLIC;
+	}
+
+	/*
 	 * If -zloadfltr is set, verify that filtering is in effect.  Filters
 	 * are either established from the command line, and affect the whole
 	 * object, or are set on a per-symbol basis from a mapfile.
--- a/usr/src/cmd/sgs/libld/common/libld.msg	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/libld.msg	Mon Jan 22 19:26:57 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.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -858,8 +858,8 @@
 			 a non-existent segment `%s'"
 @ MSG_MAP_INCOMFLG	"%s: %lld: incompatible flags $SPECVERS and $ADDVERS \
 			 used on the same object `%s'"
-@ MSG_MAP_MULSONAME	"%s: %lld: multiple definition of SONAME field for %s\
-			 \n\tfirst `%s', second `%s'; first value used"
+@ MSG_MAP_MULSONAME	"%s: %lld: multiple definition of SONAME field for %s: \
+			 first `%s', second `%s'; first value used"
 @ MSG_MAP_UNEXDEP	"%s: %lld: dependency `%s' unexpected; ignored"
 @ MSG_MAP_UNEXTOK	"%s: %lld: unexpected occurrence of `%c' token"
 
@@ -907,6 +907,10 @@
 @ MSG_MAP_NOFILTER	"%s: %lld: filtee definition required"
 @ MSG_MAP_BADSF1	"%s: %lld: unknown software capabilities: 0x%llx; \
 			 ignored"
+@ MSG_MAP_NOINTPOSE	"%s: %lld: interposition symbols can only be defined \
+			 when building a dynamic executable"
+@ MSG_MAP_PROTNDIR	"%s: %lld: protected scope and no-direct declaration \
+			 are incompatible"
 
 @ MSG_MAP_SEGSAME	"segments `%s' and `%s' have the same assigned \
 			 virtual address"
@@ -928,8 +932,8 @@
 @ MSG_MAP_SYMVAL	"symbol value"
 @ MSG_MAP_SYMSIZE	"symbol size"
 
-@ MSG_MAP_SECORDER	"section ordering set but no matching section found;\
-			 \n\tsegment: %s section: %s"
+@ MSG_MAP_SECORDER	"section ordering requested, but no matching section \
+			 found: segment: %s section: %s"
 
 # Generic error diagnostic labels
 
@@ -1141,6 +1145,7 @@
 @ MSG_MAP_FILTER	"filter"
 @ MSG_MAP_AUXILIARY	"auxiliary"
 @ MSG_MAP_OVERRIDE	"override"
+@ MSG_MAP_INTERPOSE	"interpose"
 
 @ MSG_FMT_INDEX		"[%lld]"
 
--- a/usr/src/cmd/sgs/libld/common/map.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/map.c	Mon Jan 22 19:26:57 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"
@@ -1430,22 +1430,27 @@
 			/*
 			 * Establish a new scope.  All symbols added by this
 			 * mapfile are actually global entries. They will be
-			 * reduced to locals during sym_update().
+			 * reduced to locals during sym_update().  If a symbolic
+			 * scope is detected, remember this.  If a symbolic
+			 * scope is the only scope defined in this (or any other
+			 * mapfiles), then -Bsymbolic is established.
 			 */
 			if ((strcmp(MSG_ORIG(MSG_STR_LOCAL),
 			    _name) == 0) ||
-			    (strcmp(MSG_ORIG(MSG_MAP_HIDDEN), _name) == 0))
+			    (strcmp(MSG_ORIG(MSG_MAP_HIDDEN), _name) == 0)) {
 				scope = FLG_SCOPE_LOCL;
-			else if ((strcmp(MSG_ORIG(MSG_MAP_GLOBAL),
+			} else if ((strcmp(MSG_ORIG(MSG_MAP_GLOBAL),
 			    _name) == 0) ||
-			    (strcmp(MSG_ORIG(MSG_MAP_DEFAULT), _name) == 0))
+			    (strcmp(MSG_ORIG(MSG_MAP_DEFAULT), _name) == 0)) {
 				scope = FLG_SCOPE_GLOB;
-			else if ((strcmp(MSG_ORIG(MSG_STR_SYMBOLIC),
+				ofl->ofl_flags |= FLG_OF_MAPGLOB;
+			} else if ((strcmp(MSG_ORIG(MSG_STR_SYMBOLIC),
 			    _name) == 0) ||
-			    (strcmp(MSG_ORIG(MSG_MAP_PROTECTED), _name) == 0))
+			    (strcmp(MSG_ORIG(MSG_MAP_PROTECTED), _name) == 0)) {
 				scope = FLG_SCOPE_SYMB;
-			else if (strcmp(MSG_ORIG(MSG_STR_ELIMINATE), _name)
-			    == 0)
+				ofl->ofl_flags |= FLG_OF_MAPSYMB;
+			} else if (strcmp(MSG_ORIG(MSG_STR_ELIMINATE),
+			    _name) == 0)
 				scope = FLG_SCOPE_ELIM;
 			else {
 				eprintf(ofl->ofl_lml, ERR_FATAL,
@@ -1570,6 +1575,13 @@
 					ofl->ofl_flags |= FLG_OF_SYMINFO;
 				} else if (strcmp(Start_tok,
 				    MSG_ORIG(MSG_MAP_NODIRECT)) == 0) {
+					if (scope == FLG_SCOPE_SYMB) {
+						eprintf(ofl->ofl_lml, ERR_FATAL,
+						    MSG_INTL(MSG_MAP_PROTNDIR),
+						    mapfile,
+						    EC_XWORD(Line_num));
+						return (S_ERROR);
+					}
 					sym_flags1 |= FLG_SY1_NDIR;
 					ofl->ofl_flags |= FLG_OF_SYMINFO;
 					ofl->ofl_flags1 |= FLG_OF1_NDIRECT;
@@ -1586,6 +1598,19 @@
 					sym_flags |= FLG_SY_AUXFLTR;
 					ofl->ofl_flags |= FLG_OF_SYMINFO;
 					continue;
+				} else if (strcmp(Start_tok,
+				    MSG_ORIG(MSG_MAP_INTERPOSE)) == 0) {
+					if (!(ofl->ofl_flags & FLG_OF_EXEC)) {
+						eprintf(ofl->ofl_lml, ERR_FATAL,
+						    MSG_INTL(MSG_MAP_NOINTPOSE),
+						    mapfile,
+						    EC_XWORD(Line_num));
+						return (S_ERROR);
+					}
+					sym_flags |= FLG_SY_INTPOSE;
+					ofl->ofl_flags |= FLG_OF_SYMINFO;
+					ofl->ofl_dtflags_1 |= DF_1_SYMINTPOSE;
+					continue;
 				} else {
 					eprintf(ofl->ofl_lml, ERR_FATAL,
 					    MSG_INTL(MSG_MAP_UNKSYMDEF),
@@ -1602,7 +1627,7 @@
 			 * specified in local scope and indicates that all
 			 * symbols processed that are not explicitly defined to
 			 * be global are to be reduced to local scope in the
-			 * output image.  This also applies that a version
+			 * output image.  This also implies that a version
 			 * definition is created as the user has effectively
 			 * defined an interface.
 			 */
--- a/usr/src/cmd/sgs/libld/common/relocate.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/relocate.c	Mon Jan 22 19:26:57 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"
@@ -1115,30 +1115,30 @@
 
 	/*
 	 * Determine whether this symbol should be bound locally or not.
-	 * Symbols will be bound locally if one of the following is true:
+	 * Symbols are bound locally if one of the following is true:
 	 *
-	 *  o	the symbol is of type STB_LOCAL
+	 *  o	the symbol is of type STB_LOCAL.
 	 *
-	 *  o	the output image is not a relocatable object and the
-	 *	relocation is relative to the .got
+	 *  o	the output image is not a relocatable object and the relocation
+	 *	is relative to the .got.
 	 *
-	 *  o	the section being relocated is of type SHT_SUNW_dof;
-	 *	these sections are bound to the functions in the
-	 *	containing object and don't care about interpositioning
+	 *  o	the section being relocated is of type SHT_SUNW_dof.  These
+	 *	sections must be bound to the functions in the containing
+	 *	object and can not be interposed upon.
 	 *
-	 *  o	the symbol has been reduced (scoped to a local or
-	 *	symbolic) and reductions are being processed
+	 *  o	the symbol has been reduced (scoped to a local or symbolic) and
+	 *	reductions are being processed.
 	 *
-	 *  o	the -Bsymbolic flag is in use when building a shared
-	 *	object or an executable (fixed address) is being created
+	 *  o	the -Bsymbolic flag is in use when building a shared object,
+	 *	and the symbol hasn't explicitly been defined as nodirect.
 	 *
-	 *  o	Building an executable and the symbol is defined
-	 *	in the executable.
+	 *  o	an executable (fixed address) is being created, and the symbol
+	 *	is defined in the executable.
 	 *
-	 *  o	the relocation is against a segment which will not
-	 *	be loaded into memory.  If that is the case we need
-	 *	to resolve the relocation now because ld.so.1 won't
-	 *	be able to.
+	 *  o	the relocation is against a segment which will not be loaded
+	 *	into memory.  In this case, the relocation must be resolved
+	 *	now, as ld.so.1 can not process relocations against unmapped
+	 *	segments.
 	 */
 	local = FALSE;
 	if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
@@ -1153,9 +1153,20 @@
 		    (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) {
 			local = TRUE;
 		} else if (sdp->sd_ref == REF_REL_NEED) {
+			/*
+			 * Global symbols may have been individually reduced in
+			 * scope.  If the whole object is to be self contained,
+			 * such as when generating an executable or a symbolic
+			 * shared object, make sure all relocation symbol
+			 * references (sections too) are treated locally.  Note,
+			 * explicit no-direct symbols should not be bound to
+			 * locally.
+			 */
 			if ((sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_PROT)))
 				local = TRUE;
-			else if (flags & (FLG_OF_SYMBOLIC | FLG_OF_EXEC))
+			else if ((flags & FLG_OF_EXEC) ||
+			    ((flags & FLG_OF_SYMBOLIC) &&
+			    ((sdp->sd_flags1 & FLG_SY1_NDIR) == 0)))
 				local = TRUE;
 		}
 	}
@@ -1871,6 +1882,7 @@
 {
 	Listnode	*lnp;
 	Is_desc		*isp;
+	Sym_desc	*sdp;
 
 	/*
 	 * At this point we have finished processing all input symbols.  Make
@@ -1919,12 +1931,11 @@
 	 * check the validity of copy relocations.
 	 */
 	if (ofl->ofl_copyrels.head != 0) {
-		Copy_rel *	cpyrel;
+		Copy_rel	*cpyrel;
 
 		for (LIST_TRAVERSE(&ofl->ofl_copyrels, lnp, cpyrel)) {
-			Sym_desc *	sdp;
+			sdp = cpyrel->copyrel_symd;
 
-			sdp = cpyrel->copyrel_symd;
 			/*
 			 * If there were no displacement relocation
 			 * in this file, don't worry about it.
@@ -1942,10 +1953,10 @@
 	 */
 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
 	    ((ofl->ofl_flags & FLG_OF_BLDGOT) ||
-	    (ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL),
-	    SYM_NOHASH, 0, ofl) != 0) ||
-	    (ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
-	    SYM_NOHASH, 0, ofl) != 0))) {
+	    ((((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL),
+	    SYM_NOHASH, 0, ofl)) != 0) ||
+	    ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
+	    SYM_NOHASH, 0, ofl)) != 0)) && (sdp->sd_ref != REF_DYN_SEEN)))) {
 		if (ld_make_got(ofl) == S_ERROR)
 			return (S_ERROR);
 
--- a/usr/src/cmd/sgs/libld/common/resolve.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/resolve.c	Mon Jan 22 19:26:57 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"	/* SVR4 6.2/18.2 */
@@ -252,11 +252,13 @@
 			sdp->sd_aux->sa_rfile = ifl->ifl_name;
 		} else {
 			/*
-			 * Under -Bnodirect, all exported interfaces are tagged
-			 * to prevent direct binding to them.
+			 * Under -Bnodirect, all exported interfaces that have
+			 * not explicitly been defined protected or directly
+			 * bound to, are tagged to prevent direct binding.
 			 */
 			if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
-			    ((sdp->sd_flags1 & FLG_SY1_DIR) == 0))
+			    ((sdp->sd_flags1 &
+			    (FLG_SY1_PROT | FLG_SY1_DIR)) == 0))
 				sdp->sd_flags1 |= FLG_SY1_NDIR;
 		}
 
--- a/usr/src/cmd/sgs/libld/common/syms.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/syms.c	Mon Jan 22 19:26:57 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.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -131,7 +131,7 @@
  * referenced, mark it so that we don't directly bind to it.
  */
 uintptr_t
-ld_sym_nodirect(Is_desc * isp, Ifl_desc * ifl, Ofl_desc * ofl)
+ld_sym_nodirect(Is_desc *isp, Ifl_desc *ifl, Ofl_desc *ofl)
 {
 	Shdr		*sifshdr, *symshdr;
 	Syminfo		*sifdata;
@@ -370,13 +370,15 @@
 		sdp->sd_ref = REF_REL_NEED;
 
 		/*
-		 * Under -Bnodirect, all exported interfaces are tagged to
-		 * prevent direct binding to them.
+		 * Under -Bnodirect, all exported interfaces that have not
+		 * explicitly been defined protected or directly bound to, are
+		 * tagged to prevent direct binding.
 		 */
 		if ((ofl->ofl_flags1 & FLG_OF1_ALNODIR) &&
-		    (nsym->st_shndx != SHN_UNDEF))
+		    ((sdp->sd_flags1 & (FLG_SY1_PROT | FLG_SY1_DIR)) == 0) &&
+		    (nsym->st_shndx != SHN_UNDEF)) {
 			sdp->sd_flags1 |= FLG_SY1_NDIR;
-
+		}
 	} else {
 		sdp->sd_ref = REF_DYN_SEEN;
 
@@ -552,15 +554,23 @@
 			usdp->sd_aux->sa_symspec = (Half)sdaux_id;
 
 			/*
-			 * If a user hasn't specifically indicated the scope of
-			 * this symbol be made local then leave it as global
-			 * (ie. prevent automatic scoping).
+			 * If a user hasn't specifically indicated that the
+			 * scope of this symbol be made local, then leave it
+			 * as global (ie. prevent automatic scoping).  The GOT
+			 * should be defined protected, whereas all other
+			 * special symbols are tagged as no-direct.
 			 */
 			if (!(usdp->sd_flags1 & FLG_SY1_LOCL) &&
 			    (flags1 & FLG_SY1_GLOB)) {
-				usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
-				if ((usdp->sd_flags1 & FLG_SY1_DIR) == 0)
-					usdp->sd_flags1 |= FLG_SY1_NDIR;
+			    usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
+			    if (sdaux_id == SDAUX_ID_GOT) {
+				    usdp->sd_flags1 &= ~FLG_SY1_NDIR;
+				    usdp->sd_flags1 |= FLG_SY1_PROT;
+				    usdp->sd_sym->st_other = STV_PROTECTED;
+			    } else if (((usdp->sd_flags1 & FLG_SY1_DIR) == 0) &&
+				((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
+				    usdp->sd_flags1 |= FLG_SY1_NDIR;
+			    }
 			}
 			usdp->sd_flags1 |= flags1;
 
@@ -596,8 +606,14 @@
 		usdp->sd_aux->sa_symspec = (Half)sdaux_id;
 
 		usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
-		if (flags1 & FLG_SY1_GLOB)
+
+		if (sdaux_id == SDAUX_ID_GOT) {
+			usdp->sd_flags1 |= FLG_SY1_PROT;
+			usdp->sd_sym->st_other = STV_PROTECTED;
+		} else if ((flags1 & FLG_SY1_GLOB) &&
+		    ((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
 			usdp->sd_flags1 |= FLG_SY1_NDIR;
+		}
 		usdp->sd_flags1 |= flags1;
 	}
 
@@ -628,15 +644,22 @@
 		sdp->sd_sym->st_info = ELF_ST_INFO(bind, STT_OBJECT);
 
 		/*
-		 * If a user hasn't specifically indicated the scope of
-		 * this symbol be made local then leave it as global
-		 * (ie. prevent automatic scoping).
+		 * If a user hasn't specifically indicated the scope of this
+		 * symbol be made local then leave it as global (ie. prevent
+		 * automatic scoping).  The GOT should be defined protected,
+		 * whereas all other special symbols are tagged as no-direct.
 		 */
 		if (!(sdp->sd_flags1 & FLG_SY1_LOCL) &&
 		    (flags1 & FLG_SY1_GLOB)) {
 			sdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;
-			if ((sdp->sd_flags1 & FLG_SY1_DIR) == 0)
+			if (sdaux_id == SDAUX_ID_GOT) {
+				sdp->sd_flags1 &= ~FLG_SY1_NDIR;
+				sdp->sd_flags1 |= FLG_SY1_PROT;
+				sdp->sd_sym->st_other = STV_PROTECTED;
+			} else if (((sdp->sd_flags1 & FLG_SY1_DIR) == 0) &&
+			    ((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
 				sdp->sd_flags1 |= FLG_SY1_NDIR;
+			}
 		}
 		sdp->sd_flags1 |= flags1;
 
@@ -745,52 +768,56 @@
 uintptr_t
 ld_sym_spec(Ofl_desc *ofl)
 {
-	if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) {
+	Sym_desc	*sdp;
 
-		DBG_CALL(Dbg_syms_spec_title(ofl->ofl_lml));
+	if (ofl->ofl_flags & FLG_OF_RELOBJ)
+		return (1);
+
+	DBG_CALL(Dbg_syms_spec_title(ofl->ofl_lml));
 
-		if (sym_add_spec(MSG_ORIG(MSG_SYM_ETEXT),
-		    MSG_ORIG(MSG_SYM_ETEXT_U), SDAUX_ID_ETEXT,
-		    FLG_SY1_GLOB, ofl) == S_ERROR)
-			return (S_ERROR);
-		if (sym_add_spec(MSG_ORIG(MSG_SYM_EDATA),
-		    MSG_ORIG(MSG_SYM_EDATA_U), SDAUX_ID_EDATA,
-		    FLG_SY1_GLOB, ofl) == S_ERROR)
-			return (S_ERROR);
-		if (sym_add_spec(MSG_ORIG(MSG_SYM_END),
-		    MSG_ORIG(MSG_SYM_END_U), SDAUX_ID_END,
+	if (sym_add_spec(MSG_ORIG(MSG_SYM_ETEXT), MSG_ORIG(MSG_SYM_ETEXT_U),
+	    SDAUX_ID_ETEXT, FLG_SY1_GLOB, ofl) == S_ERROR)
+		return (S_ERROR);
+	if (sym_add_spec(MSG_ORIG(MSG_SYM_EDATA), MSG_ORIG(MSG_SYM_EDATA_U),
+	    SDAUX_ID_EDATA, FLG_SY1_GLOB, ofl) == S_ERROR)
+		return (S_ERROR);
+	if (sym_add_spec(MSG_ORIG(MSG_SYM_END), MSG_ORIG(MSG_SYM_END_U),
+	    SDAUX_ID_END, FLG_SY1_GLOB, ofl) == S_ERROR)
+		return (S_ERROR);
+	if (sym_add_spec(MSG_ORIG(MSG_SYM_L_END), MSG_ORIG(MSG_SYM_L_END_U),
+	    SDAUX_ID_END, FLG_SY1_LOCL, ofl) == S_ERROR)
+		return (S_ERROR);
+	if (sym_add_spec(MSG_ORIG(MSG_SYM_L_START), MSG_ORIG(MSG_SYM_L_START_U),
+	    SDAUX_ID_START, FLG_SY1_LOCL, ofl) == S_ERROR)
+		return (S_ERROR);
+
+	/*
+	 * Historically we've always produced a _DYNAMIC symbol, even for
+	 * static executables (in which case its value will be 0).
+	 */
+	if (sym_add_spec(MSG_ORIG(MSG_SYM_DYNAMIC), MSG_ORIG(MSG_SYM_DYNAMIC_U),
+	    SDAUX_ID_DYN, FLG_SY1_GLOB, ofl) == S_ERROR)
+		return (S_ERROR);
+
+	if (OFL_ALLOW_DYNSYM(ofl)) {
+		if (sym_add_spec(MSG_ORIG(MSG_SYM_PLKTBL),
+		    MSG_ORIG(MSG_SYM_PLKTBL_U), SDAUX_ID_PLT,
 		    FLG_SY1_GLOB, ofl) == S_ERROR)
 			return (S_ERROR);
-		if (sym_add_spec(MSG_ORIG(MSG_SYM_L_END),
-		    MSG_ORIG(MSG_SYM_L_END_U), SDAUX_ID_END,
-		    FLG_SY1_LOCL, ofl) == S_ERROR)
-			return (S_ERROR);
-		if (sym_add_spec(MSG_ORIG(MSG_SYM_L_START),
-		    MSG_ORIG(MSG_SYM_L_START_U), SDAUX_ID_START,
-		    FLG_SY1_LOCL, ofl) == S_ERROR)
-			return (S_ERROR);
+	}
 
-		/*
-		 * Historically we've always produced a _DYNAMIC symbol, even
-		 * for static executables (in which case its value will be 0).
-		 */
-		if (sym_add_spec(MSG_ORIG(MSG_SYM_DYNAMIC),
-		    MSG_ORIG(MSG_SYM_DYNAMIC_U), SDAUX_ID_DYN,
-		    FLG_SY1_GLOB, ofl) == S_ERROR)
+	/*
+	 * A GOT reference will be accompanied by the associated GOT symbol.
+	 * Make sure it gets assigned the appropriate special attributes.
+	 */
+	if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
+	    SYM_NOHASH, 0, ofl)) != 0) && (sdp->sd_ref != REF_DYN_SEEN)) {
+		if (sym_add_spec(MSG_ORIG(MSG_SYM_GOFTBL),
+		    MSG_ORIG(MSG_SYM_GOFTBL_U), SDAUX_ID_GOT, FLG_SY1_GLOB,
+		    ofl) == S_ERROR)
 			return (S_ERROR);
+	}
 
-		if (OFL_ALLOW_DYNSYM(ofl))
-			if (sym_add_spec(MSG_ORIG(MSG_SYM_PLKTBL),
-			    MSG_ORIG(MSG_SYM_PLKTBL_U), SDAUX_ID_PLT,
-			    FLG_SY1_GLOB, ofl) == S_ERROR)
-				return (S_ERROR);
-
-		if (ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl))
-			if (sym_add_spec(MSG_ORIG(MSG_SYM_GOFTBL),
-			    MSG_ORIG(MSG_SYM_GOFTBL_U), SDAUX_ID_GOT,
-			    FLG_SY1_GLOB, ofl) == S_ERROR)
-				return (S_ERROR);
-	}
 	return (1);
 }
 
@@ -831,12 +858,13 @@
 		}
 
 		/*
-		 * If '-Bsymbolic' is in effect - then bind all global symbols
-		 * 'symbolically' and assign the STV_PROTECTED visibility
+		 * If -Bsymbolic is in effect, and the symbol hasn't explicitly
+		 * been defined nodirect (via a mapfile), then bind the global
+		 * symbol symbolically and assign the STV_PROTECTED visibility
 		 * attribute.
 		 */
 		if ((oflags & FLG_OF_SYMBOLIC) &&
-		    ((sdp->sd_flags1 & FLG_SY1_LOCL) == 0)) {
+		    ((sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_NDIR)) == 0)) {
 
 			sdp->sd_flags1 |= FLG_SY1_PROT;
 			if (ELF_ST_VISIBILITY(sym->st_other) == STV_DEFAULT)
--- a/usr/src/cmd/sgs/libld/common/update.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/libld/common/update.c	Mon Jan 22 19:26:57 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"
@@ -1128,10 +1128,12 @@
 				 */
 				syminfo[ndx].si_boundto = SYMINFO_BT_EXTERN;
 
-			} else if (sdp->sd_flags & FLG_SY_PARENT) {
+			} else if ((sdp->sd_flags & FLG_SY_PARENT) &&
+			    (sdp->sd_sym->st_shndx == SHN_UNDEF)) {
 				/*
-				 * A reference to a parent object.  Indicate
-				 * whether a direct binding should be
+				 * If this symbol has been explicitly defined
+				 * to be a reference to a parent object,
+				 * indicate whether a direct binding should be
 				 * established.
 				 */
 				syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
@@ -1166,6 +1168,7 @@
 
 			} else if ((sdp->sd_ref == REF_REL_NEED) &&
 			    (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
+
 				/*
 				 * This definition exists within the object
 				 * being created.  Flag whether it is necessary
@@ -1179,6 +1182,15 @@
 				}
 
 				/*
+				 * Indicate that this symbol is acting as an
+				 * individual interposer.
+				 */
+				if (sdp->sd_flags & FLG_SY_INTPOSE) {
+					syminfo[ndx].si_flags |=
+					    SYMINFO_FLG_INTERPOSE;
+				}
+
+				/*
 				 * If external bindings are allowed, or this is
 				 * a translator symbol, indicate the binding,
 				 * and a direct binding if necessary.
@@ -1262,7 +1274,7 @@
 				if (_hashndx = hashbkt[hashval]) {
 				    while (hashchain[_hashndx])
 					_hashndx = hashchain[_hashndx];
-					hashchain[_hashndx] = sdp->sd_symndx;
+				    hashchain[_hashndx] = sdp->sd_symndx;
 				} else {
 					hashbkt[hashval] = sdp->sd_symndx;
 				}
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg	Mon Jan 22 19:26:57 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.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -840,9 +840,9 @@
 # TRANSLATION_NOTE - the following two entries provide for a series of one or
 # more symbol information table entries that align with the initial title.
 
-@ MSG_SYMINFO_TITLE	"     index  flags        \
+@ MSG_SYMINFO_TITLE	"     index  flags            \
 			 bound to                 symbol"
-@ MSG_SYMINFO_ENTRY	"%10.10s  %-4s %7s %-24s %s"
+@ MSG_SYMINFO_ENTRY	"%10.10s  %-8s %7s %-24s %s"
 
 @ MSG_SYMINFO_SELF	"<self>"
 @ MSG_SYMINFO_PARENT	"<parent>"
@@ -1248,7 +1248,7 @@
 
 # Syminfo formats
 
-@ MSG_SYMINFO_UNKFLAG	" 0x%x"
+@ MSG_SYMINFO_UNKFLAG	"[0x%x]"
 
 # Lc_interface interface tags.
 
--- a/usr/src/cmd/sgs/liblddbg/common/syminfo.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/liblddbg/common/syminfo.c	Mon Jan 22 19:26:57 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.
  */
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -89,12 +89,16 @@
 		flagstr[flgndx++] = 'N';
 		flags &= ~SYMINFO_FLG_NOEXTDIRECT;
 	}
+	if (flags & SYMINFO_FLG_INTERPOSE) {
+		flagstr[flgndx++] = 'I';
+		flags &= ~SYMINFO_FLG_INTERPOSE;
+	}
 
 	/*
 	 * Did we account for all of the flags?
 	 */
 	if (flags)
-		(void) snprintf(&flagstr[flgndx], FLAGSZ - ndx,
+		(void) snprintf(&flagstr[flgndx], FLAGSZ - flgndx,
 		    MSG_ORIG(MSG_SYMINFO_UNKFLAG), flags);
 	else
 		flagstr[flgndx] = '\0';
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Mon Jan 22 19:26:57 2007 -0800
@@ -1130,6 +1130,7 @@
 6423746 add an option to relax the resolution of COMDAT relocs (D)
 4934427 runtime linker should load up static symbol names visible to
 	dladdr() (D)
+	PSARC 2006/526 SHT_SUNW_LDYNSYM - default local symbol addition
 6448719 sys/elf.h could be updated with additional machine and ABI types
 6336605 link-editors need to support R_*_SIZE relocations
 	PSARC/2006/558 R_*_SIZE relocation support
@@ -1153,3 +1154,5 @@
 6501793 GOTOP relocation transition (optimization) fails with offsets > 2^32
 6515970 HWCAP processing doesn't clean up fmap structure - browser fails to
 	run java applet
+6494214 Refinements to symbolic binding, symbol declarations and interposition 
+	PSARC/2006/714 ld(1) mapfile: symbol interpose definition
--- a/usr/src/cmd/sgs/rtld/Makefile.com	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/Makefile.com	Mon Jan 22 19:26:57 2007 -0800
@@ -19,7 +19,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -95,8 +95,8 @@
 		$(RTLDLIB) -lrtld \
 		$(LDLIB) $(LD_LIB) 
 
-DYNFLAGS +=	-i -e _rt_boot $(VERSREF) -Bsymbolic -zlazyload -znodlopen \
-		-z interpose -zdtrace=dtrace_data '-R$$ORIGIN'
+DYNFLAGS +=	-i -e _rt_boot $(VERSREF) $(ZLAZYLOAD) $(ZNODLOPEN) \
+		$(ZINTERPOSE) -zdtrace=dtrace_data '-R$$ORIGIN'
 
 BUILD.s=	$(AS) $(ASFLAGS) $< -o $@
 
--- a/usr/src/cmd/sgs/rtld/amd64/mapfile-amd64-vers	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/amd64/mapfile-amd64-vers	Mon Jan 22 19:26:57 2007 -0800
@@ -1,13 +1,12 @@
 #
-# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # 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.
@@ -26,7 +25,7 @@
 #
 
 SUNWprivate_1.2 {
-	global:
+	protected:
 		_dlamd64getunwind;
 		dlamd64getunwind;
 };
--- a/usr/src/cmd/sgs/rtld/common/_rtld.h	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/_rtld.h	Mon Jan 22 19:26:57 2007 -0800
@@ -23,7 +23,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.
  */
 
@@ -562,15 +562,16 @@
 extern void		get_lcinterface(Rt_map *, Lc_interface *);
 extern Lmid_t		get_linkmap_id(Lm_list *);
 extern Pnode		*get_next_dir(Pnode **, Rt_map *, uint_t);
-int			hdl_add(Grp_hdl *, Rt_map *, uint_t);
-Grp_hdl			*hdl_create(Lm_list *, Rt_map *, Rt_map *, uint_t);
-int			hdl_initialize(Grp_hdl *, Rt_map *, Rt_map *, int, int);
+extern int		hdl_add(Grp_hdl *, Rt_map *, uint_t);
+extern Grp_hdl		*hdl_create(Lm_list *, Rt_map *, Rt_map *, uint_t);
+extern int		hdl_initialize(Grp_hdl *, Rt_map *, Rt_map *, int, int);
 extern int		hwcap_check(Rej_desc *, Ehdr *);
 extern Pnode 		*hwcap_filtees(Pnode **, Aliste, Dyninfo *, Rt_map *,
 			    const char *, int, uint_t);
-void			is_dep_ready(Rt_map *, Rt_map *, int);
-void			is_dep_init(Rt_map *, Rt_map *);
-void			ldso_plt_init(Rt_map *);
+extern void		is_dep_ready(Rt_map *, Rt_map *, int);
+extern void		is_dep_init(Rt_map *, Rt_map *);
+extern int		is_sym_interposer(Rt_map *, Sym *);
+extern void		ldso_plt_init(Rt_map *);
 extern Listnode		*list_append(List *, const void *);
 extern Listnode		*list_insert(List *, const void *, Listnode *);
 extern Listnode		*list_prepend(List *, const void *);
--- a/usr/src/cmd/sgs/rtld/common/analyze.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/analyze.c	Mon Jan 22 19:26:57 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"
@@ -1844,7 +1844,7 @@
 		 * If the object wasn't explicitly dlopen()'ed associate it with
 		 * the parent.
 		 */
-		if (flags != FLG_RT_HANDLE)
+		if ((flags & FLG_RT_HANDLE) == 0)
 			nmode |= RTLD_PARENT;
 	}
 
@@ -2234,15 +2234,35 @@
 }
 
 /*
+ * Determine whether a symbol is defined as an interposer.
+ */
+int
+is_sym_interposer(Rt_map *lmp, Sym *sym)
+{
+	Syminfo	*sip = SYMINFO(lmp);
+
+	if (sip) {
+		ulong_t	ndx;
+
+		ndx = (((ulong_t)sym - (ulong_t)SYMTAB(lmp)) / SYMENT(lmp));
+		/* LINTED */
+		sip = (Syminfo *)((char *)sip + (ndx * SYMINENT(lmp)));
+		if (sip->si_flags & SYMINFO_FLG_INTERPOSE)
+			return (1);
+	}
+	return (0);
+}
+
+/*
  * While processing direct or group bindings, determine whether the object to
  * which we've bound can be interposed upon.  In this context, copy relocations
  * are a form of interposition.
  */
 static Sym *
-lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list * lml,
-    Sym * sym)
+lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml,
+    Sym *sym)
 {
-	Rt_map *	lmp;
+	Rt_map		*lmp;
 	Slookup		sl;
 
 	/*
@@ -2278,7 +2298,7 @@
 	 */
 	lmp = lml->lm_head;
 	sl = *slp;
-	if (((FLAGS(lmp) & FLG_RT_INTRPOSE) == 0) || (sl.sl_flags & LKUP_COPY))
+	if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY))
 		lmp = (Rt_map *)NEXT(lmp);
 	else
 		sl.sl_flags &= ~LKUP_SPEC;
@@ -2286,13 +2306,29 @@
 	for (; lmp; lmp = (Rt_map *)NEXT(lmp)) {
 		if (FLAGS(lmp) & FLG_RT_DELETE)
 			continue;
-		if ((FLAGS(lmp) & FLG_RT_INTRPOSE) == 0)
+		if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0)
 			break;
 
 		if (callable(lmp, *dlmp, 0)) {
+			Rt_map	*ilmp;
+
 			sl.sl_imap = lmp;
-			if (sym = SYMINTP(lmp)(&sl, dlmp, binfo)) {
+			if (sym = SYMINTP(lmp)(&sl, &ilmp, binfo)) {
+				/*
+				 * If this object provides individual symbol
+				 * interposers, make sure that the symbol we
+				 * have found is tagged as an interposer.
+				 */
+				if ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
+				    (is_sym_interposer(ilmp, sym) == 0))
+					continue;
+
+				/*
+				 * Indicate this binding has occurred to an
+				 * interposer, and return the symbol.
+				 */
 				*binfo |= DBG_BINFO_INTERPOSE;
+				*dlmp = ilmp;
 				return (sym);
 			}
 		}
@@ -2511,7 +2547,7 @@
 			 */
 			if (((FLAGS(clmp) & FLG_RT_TRANS) ||
 			    (!(LIST(clmp)->lm_tflags & LML_TFLG_NODIRECT))) &&
-			    ((FLAGS(clmp) & FLG_RT_DIRECT) ||
+			    ((FLAGS1(clmp) & FL1_RT_DIRECT) ||
 			    (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) {
 				sym = lookup_sym_direct(slp, dlmp, binfo,
 				    sip, lmp);
@@ -2538,8 +2574,21 @@
 	 */
 	if (FLAGS1(clmp) & FL1_RT_SYMBOLIC) {
 		sl.sl_imap = clmp;
-		if (sym = SYMINTP(clmp)(&sl, dlmp, binfo))
-			return (sym);
+		if (sym = SYMINTP(clmp)(&sl, dlmp, binfo)) {
+			ulong_t	dsymndx = (((ulong_t)sym -
+				    (ulong_t)SYMTAB(*dlmp)) / SYMENT(*dlmp));
+
+			/*
+			 * Make sure this symbol hasn't explicitly been defined
+			 * as nodirect.
+			 */
+			if (((sip = SYMINFO(*dlmp)) == 0) ||
+			    /* LINTED */
+			    ((sip = (Syminfo *)((char *)sip +
+			    (dsymndx * SYMINENT(*dlmp)))) == 0) ||
+			    ((sip->si_flags & SYMINFO_FLG_NOEXTDIRECT) == 0))
+				return (sym);
+		}
 	}
 
 	/*
--- a/usr/src/cmd/sgs/rtld/common/elf.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/elf.c	Mon Jan 22 19:26:57 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"
@@ -1300,7 +1300,7 @@
  * Disable filtee use.
  */
 static void
-elf_disable_filtee(Rt_map * lmp, Dyninfo * dip)
+elf_disable_filtee(Rt_map *lmp, Dyninfo *dip)
 {
 	dip->di_info = 0;
 
@@ -1418,7 +1418,7 @@
 	 * using their group handle to lookup the symbol.
 	 */
 	for (any = 0, pnpp = (Pnode **)&(dip->di_info), pnp = *pnpp; pnp;
-	    pnpp = &pnp->p_next, pnp = * pnpp) {
+	    pnpp = &pnp->p_next, pnp = *pnpp) {
 		int	mode;
 		Grp_hdl	*ghp;
 		Rt_map	*nlmp = 0;
@@ -1893,7 +1893,9 @@
 		if (sym->st_shndx != SHN_UNDEF) {
 			*dlmp = ilmp;
 			*binfo |= DBG_BINFO_FOUND;
-			if (FLAGS(ilmp) & FLG_RT_INTRPOSE)
+			if ((FLAGS(ilmp) & FLG_RT_OBJINTPO) ||
+			    ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
+			    is_sym_interposer(ilmp, sym)))
 				*binfo |= DBG_BINFO_INTERPOSE;
 			break;
 
@@ -1910,7 +1912,9 @@
 		    (ELF_ST_TYPE(sym->st_info) == STT_FUNC)) {
 			*dlmp = ilmp;
 			*binfo |= (DBG_BINFO_FOUND | DBG_BINFO_PLTADDR);
-			if (FLAGS(ilmp) & FLG_RT_INTRPOSE)
+			if ((FLAGS(ilmp) & FLG_RT_OBJINTPO) ||
+			    ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
+			    is_sym_interposer(ilmp, sym)))
 				*binfo |= DBG_BINFO_INTERPOSE;
 			return (sym);
 		}
@@ -2293,7 +2297,7 @@
 				if (ld->d_un.d_val & DF_1_CONFALT)
 					crle = 1;
 				if (ld->d_un.d_val & DF_1_DIRECT)
-					FLAGS(lmp) |= FLG_RT_DIRECT;
+					FLAGS1(lmp) |= FL1_RT_DIRECT;
 				if (ld->d_un.d_val & DF_1_NODEFLIB)
 					FLAGS1(lmp) |= FL1_RT_NODEFLIB;
 				if (ld->d_un.d_val & DF_1_ENDFILTEE)
@@ -2310,16 +2314,18 @@
 				 * already started, then demote it.  It's too
 				 * late to guarantee complete interposition.
 				 */
-				if (ld->d_un.d_val & DF_1_INTERPOSE) {
-				    if ((lml->lm_flags & LML_FLG_STARTREL) == 0)
-					FLAGS(lmp) |= FLG_RT_INTRPOSE;
-				    else {
+				if (ld->d_un.d_val &
+				    (DF_1_INTERPOSE | DF_1_SYMINTPOSE)) {
+				    if (lml->lm_flags & LML_FLG_STARTREL) {
 					DBG_CALL(Dbg_util_intoolate(lmp));
 					if (lml->lm_flags & LML_FLG_TRC_ENABLE)
 					    (void) printf(
 						MSG_INTL(MSG_LDD_REL_ERR2),
 						NAME(lmp));
-				    }
+				    } else if (ld->d_un.d_val & DF_1_INTERPOSE)
+					FLAGS(lmp) |= FLG_RT_OBJINTPO;
+				    else
+					FLAGS(lmp) |= FLG_RT_SYMINTPO;
 				}
 				break;
 			case DT_SYMINFO:
@@ -3086,10 +3092,10 @@
 }
 
 static void
-elf_lazy_cleanup(Alist * alp)
+elf_lazy_cleanup(Alist *alp)
 {
-	Rt_map **	lmpp;
-	Aliste		off;
+	Rt_map	**lmpp;
+	Aliste	off;
 
 	/*
 	 * Cleanup any link-maps added to this dynamic list and free it.
--- a/usr/src/cmd/sgs/rtld/common/mapfile-32-vers	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-32-vers	Mon Jan 22 19:26:57 2007 -0800
@@ -20,14 +20,14 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
 
 SUNWprivate_1.2 {
-	global:
+	protected:
 		do32_reloc;		# Required to support librtld.so
 		reloc32_table;
 };
--- a/usr/src/cmd/sgs/rtld/common/mapfile-64-vers	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-64-vers	Mon Jan 22 19:26:57 2007 -0800
@@ -20,14 +20,14 @@
 #
 
 #
-# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
 #
 
 SUNWprivate_1.2 {
-	global:
+	protected:
 		do64_reloc;		# Required to support librtld.so
 		reloc64_table;
 };
--- a/usr/src/cmd/sgs/rtld/common/mapfile-vers	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-vers	Mon Jan 22 19:26:57 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.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -40,7 +40,7 @@
 # All symbols in ld.so.1 are private as no-one should bind to these directly.
 
 SUNWprivate_1.2 {
-	global:
+	protected:
 		_dladdr;		# Standard dlopen(3x) family	
 		 dladdr;
 		_dladdr1;
--- a/usr/src/cmd/sgs/rtld/common/setup.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/setup.c	Mon Jan 22 19:26:57 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"
@@ -97,7 +97,7 @@
 	if ((lmflags & LML_FLG_TRC_ENABLE) && (FLAGS1(lmp) & FL1_RT_LDDSTUB))
 		flags = FLG_RT_PRELOAD;
 	else
-		flags = (FLG_RT_PRELOAD | FLG_RT_INTRPOSE);
+		flags = (FLG_RT_PRELOAD | FLG_RT_OBJINTPO);
 
 	ptr = strtok_r(objs, MSG_ORIG(MSG_STR_DELIMIT), &next);
 	do {
@@ -127,7 +127,7 @@
 		 * error occurred with loading this object, indicate that this
 		 * link-map list contains an interposer.
 		 */
-		flags |= FLG_RT_INTRPOSE;
+		flags |= FLG_RT_OBJINTPO;
 		if (nlmp == 0) {
 			if ((lmflags & LML_FLG_TRC_ENABLE) ||
 			    (rtld_flags & RT_FL_SECURE))
--- a/usr/src/cmd/sgs/rtld/common/util.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/common/util.c	Mon Jan 22 19:26:57 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"
@@ -1124,7 +1124,7 @@
 		lmc->lc_head = lmc->lc_tail = lmp;
 		add = 0;
 
-	} else if (FLAGS(lmp) & FLG_RT_INTRPOSE) {
+	} else if (FLAGS(lmp) & FLG_RT_OBJINTPO) {
 		Rt_map	*tlmp;
 
 		/*
@@ -1152,7 +1152,7 @@
 		for (tlmp = (Rt_map *)NEXT(lmc->lc_head); tlmp;
 		    tlmp = (Rt_map *)NEXT(tlmp)) {
 
-			if (FLAGS(tlmp) & FLG_RT_INTRPOSE)
+			if (FLAGS(tlmp) & FLG_RT_OBJINTPO)
 				continue;
 
 			/*
@@ -1194,7 +1194,7 @@
 	 * link-map can be explicitly defined as an interposer so that it can
 	 * provide interposition over direct binding requests.
 	 */
-	if (FLAGS(lmp) & FLG_RT_INTRPOSE)
+	if (FLAGS(lmp) & MSK_RT_INTPOSE)
 		lml->lm_flags |= LML_FLG_INTRPOSE;
 
 	/*
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.c	Mon Jan 22 19:26:57 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.
  */
 
@@ -70,9 +70,9 @@
 	{ MSG_ORIG(MSG_FLG_NOOPEN), FLG_RT_NOOPEN, FLG_RT_NOOPEN},
 	{ MSG_ORIG(MSG_FLG_FINICLCT), FLG_RT_FINICLCT, FLG_RT_FINICLCT},
 	{ MSG_ORIG(MSG_FLG_INITCALL), FLG_RT_INITCALL, FLG_RT_INITCALL},
-	{ MSG_ORIG(MSG_FLG_INTRPOSE), FLG_RT_INTRPOSE, FLG_RT_INTRPOSE},
-	{ MSG_ORIG(MSG_FLG_DIRECT), FLG_RT_DIRECT, FLG_RT_DIRECT},
 	{ MSG_ORIG(MSG_FLG_SUNWBSS), FLG_RT_SUNWBSS, FLG_RT_SUNWBSS},
+	{ MSG_ORIG(MSG_FLG_OBJINTPO), FLG_RT_OBJINTPO, FLG_RT_OBJINTPO},
+	{ MSG_ORIG(MSG_FLG_SYMINTPO), FLG_RT_SYMINTPO, FLG_RT_SYMINTPO},
 	{ MSG_ORIG(MSG_FLG_MOVE), FLG_RT_MOVE, FLG_RT_MOVE},
 	{ MSG_ORIG(MSG_FLG_DLSYM), FLG_RT_DLSYM, FLG_RT_DLSYM},
 	{ MSG_ORIG(MSG_FLG_REGSYMS), FLG_RT_REGSYMS, FLG_RT_REGSYMS},
@@ -99,6 +99,9 @@
 	{ MSG_ORIG(MSG_FL1_OBJAFLTR), FL1_RT_OBJAFLTR, FL1_RT_OBJAFLTR },
 	{ MSG_ORIG(MSG_FL1_SYMSFLTR), FL1_RT_SYMSFLTR, FL1_RT_SYMSFLTR },
 	{ MSG_ORIG(MSG_FL1_SYMAFLTR), FL1_RT_SYMAFLTR, FL1_RT_SYMAFLTR },
+	{ MSG_ORIG(MSG_FL1_TLSADD), FL1_RT_TLSADD, FL1_RT_TLSADD },
+	{ MSG_ORIG(MSG_FL1_TLSSTAT), FL1_RT_TLSSTAT, FL1_RT_TLSSTAT },
+	{ MSG_ORIG(MSG_FL1_DIRECT), FL1_RT_DIRECT, FL1_RT_DIRECT},
 
 	{ MSG_ORIG(MSG_LTFL_AUD_PREINIT), LML_TFLG_AUD_PREINIT,
 	    LML_TFLG_AUD_PREINIT },
--- a/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/cmd/sgs/rtld/mdbmod/common/rtld.msg	Mon Jan 22 19:26:57 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.
 #
 # pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -63,54 +63,57 @@
 #
 # Flag Strings
 #
-@ MSG_FLG_ISMAIN	"ISMAIN"
-@ MSG_FLG_IMGALLOC	"IMGALLOC"
+@ MSG_FLG_ISMAIN	"IS-MAIN"
+@ MSG_FLG_IMGALLOC	"IMAGE-ALLOCATED"
 @ MSG_FLG_RELOCED	"RELOCED"
-@ MSG_FLG_SETGROUP	"SETGROUP"
+@ MSG_FLG_SETGROUP	"SET-GROUP"
 @ MSG_FLG_HWCAP		"HWCAP"
 @ MSG_FLG_OBJECT	"OBJECT"
 @ MSG_FLG_NODUMP	"NODUMP"
 @ MSG_FLG_DELETE	"DELETE"
 @ MSG_FLG_ANALYZED	"ANALYZED"
-@ MSG_FLG_INITDONE	"INITDONE"
+@ MSG_FLG_INITDONE	"INIT-DONE"
 @ MSG_FLG_TRANS		"TRANS"
 @ MSG_FLG_FIXED		"FIXED"
 @ MSG_FLG_PRELOAD	"PRELOAD"
-@ MSG_FLG_ALTER		"ALTER"
-@ MSG_FLG_LOADFLTR	"LOADFLTR"
+@ MSG_FLG_ALTER		"ALTERNATE"
+@ MSG_FLG_LOADFLTR	"LOAD-FILTERS"
 @ MSG_FLG_AUDIT		"AUDIT"
-@ MSG_FLG_MODESET	"MODESET"
+@ MSG_FLG_MODESET	"MODE-SET"
 @ MSG_FLG_ANALZING	"ANALYZING"
-@ MSG_FLG_INITFRST	"INITFRST"
-@ MSG_FLG_NOOPEN	"NOOPEN"
-@ MSG_FLG_FINICLCT	"FINICLCT"
-@ MSG_FLG_INITCALL	"INITCALL"
-@ MSG_FLG_INTRPOSE	"INTRPOSE"
-@ MSG_FLG_DIRECT	"DIRECT"
+@ MSG_FLG_INITFRST	"INIT-FIRST"
+@ MSG_FLG_NOOPEN	"NO-OPEN"
+@ MSG_FLG_FINICLCT	"FINI-COLLECTED"
+@ MSG_FLG_INITCALL	"INIT-CALLED"
 @ MSG_FLG_SUNWBSS	"SUNWBSS"
+@ MSG_FLG_OBJINTPO	"OBJECT-INTERPOSE"
+@ MSG_FLG_SYMINTPO	"SYMBOL-INTERPOSE"
 @ MSG_FLG_MOVE		"MOVE"
 @ MSG_FLG_DLSYM		"DLSYM"
-@ MSG_FLG_REGSYMS	"REGSYMS"
-@ MSG_FLG_INITCLCT	"INITCLCT"
+@ MSG_FLG_REGSYMS	"REGISTER-SYMS"
+@ MSG_FLG_INITCLCT	"INIT-COLLECTED"
 @ MSG_FLG_HANDLE	"HANDLE"
 @ MSG_FLG_RELOCING	"RELOCATING"
 
 @ MSG_FL1_COPYTOOK	"COPYTOOK"
 @ MSG_FL1_RELATIVE	"RELATIVE"
 @ MSG_FL1_CONFSET	"CONFSET"
-@ MSG_FL1_NODEFLIB	"NODEFLIB"
-@ MSG_FL1_ENDFILTE	"ENDFILTE"
-@ MSG_FL1_DISPREL	"DISPREL"
-@ MSG_FL1_TEXTREL	"TEXTREL"
-@ MSG_FL1_INITWAIT	"INITWAIT"
+@ MSG_FL1_NODEFLIB	"NO-DEFAULT-LIBPATH"
+@ MSG_FL1_ENDFILTE	"END-FILTEE"
+@ MSG_FL1_DISPREL	"DISPLACEMENT-RELOCATED"
+@ MSG_FL1_TEXTREL	"TEXT-RELOCATED"
+@ MSG_FL1_INITWAIT	"INIT-WAIT"
 @ MSG_FL1_LDDSTUB	"LDDSTUB"
-@ MSG_FL1_NOINIFIN	"NOINITFINI"
+@ MSG_FL1_NOINIFIN	"NO-INITFINI"
 @ MSG_FL1_USED		"USED"
 @ MSG_FL1_SYMBOLIC	"SYMBOLIC"
-@ MSG_FL1_OBJSFLTR	"OBJSFLTR"
-@ MSG_FL1_OBJAFLTR	"OBJAFLTR"
-@ MSG_FL1_SYMSFLTR	"SYMSFLTR"
-@ MSG_FL1_SYMAFLTR	"SYMAFLTR"
+@ MSG_FL1_OBJSFLTR	"OBJ-STD-FILTER"
+@ MSG_FL1_OBJAFLTR	"OBJ-AUX-FILTER"
+@ MSG_FL1_SYMSFLTR	"SYM-STD-FILTER"
+@ MSG_FL1_SYMAFLTR	"SYM-AUX-FILTER"
+@ MSG_FL1_TLSADD	"TLS-ADD"
+@ MSG_FL1_TLSSTAT	"TLS-STAT"
+@ MSG_FL1_DIRECT	"DIRECT"
 
 @ MSG_MODE_LAZY		"LAZY"
 @ MSG_MODE_NOW		"NOW"
--- a/usr/src/uts/common/sys/link.h	Mon Jan 22 17:10:39 2007 -0800
+++ b/usr/src/uts/common/sys/link.h	Mon Jan 22 19:26:57 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.
  */
 
@@ -120,7 +120,7 @@
 #define	DT_SUNW_SYMTAB		0x60000011	/* symtab with local fcn */
 						/*	symbols immediately */
 						/*	preceding DT_SYMTAB */
-#define	DT_SUNW_SYMSZ		0x60000012	/* Size of SUNW_SYMTAB table */
+#define	DT_SUNW_SYMSZ		0x60000012	/* size of SUNW_SYMTAB table */
 #define	DT_HIOS			0x6ffff000
 
 /*
@@ -218,7 +218,7 @@
 #define	DF_1_ORIGIN	0x00000080	/* ORIGIN processing required */
 #define	DF_1_DIRECT	0x00000100	/* direct binding enabled */
 #define	DF_1_TRANS	0x00000200
-#define	DF_1_INTERPOSE	0x00000400	/* object is an 'interposer' */
+#define	DF_1_INTERPOSE	0x00000400	/* object is an interposer */
 #define	DF_1_NODEFLIB	0x00000800	/* ignore default library search path */
 #define	DF_1_NODUMP	0x00001000	/* object can't be dldump(3x)'ed */
 #define	DF_1_CONFALT	0x00002000	/* configuration alternative created */
@@ -233,6 +233,8 @@
 #define	DF_1_NOHDR	0x00100000	/* mapfile ?N:1st segment mapping */
 					/*	omits ELF & program headers */
 #define	DF_1_NORELOC	0x00400000	/* internal: unrelocated object */
+#define	DF_1_SYMINTPOSE	0x00800000	/* individual symbol interposers */
+					/*	exist */
 
 /*
  * Values set to DT_FEATURE_1 tag's d_val.
@@ -393,7 +395,7 @@
 					/*	to object containing defn. */
 #define	SYMINFO_FLG_PASSTHRU	0x0002	/* ignored - see SYMINFO_FLG_FILTER */
 #define	SYMINFO_FLG_COPY	0x0004	/* symbol is a copy-reloc */
-#define	SYMINFO_FLG_LAZYLOAD	0x0008	/* object containing defn should be */
+#define	SYMINFO_FLG_LAZYLOAD	0x0008	/* object containing defn. should be */
 					/*	lazily-loaded */
 #define	SYMINFO_FLG_DIRECTBIND	0x0010	/* ref should be bound directly to */
 					/*	object containing defn. */
@@ -401,6 +403,7 @@
 					/*	directly bind to this symbol */
 #define	SYMINFO_FLG_FILTER	0x0002	/* symbol ref is associated to a */
 #define	SYMINFO_FLG_AUXILIARY	0x0040	/* 	standard or auxiliary filter */
+#define	SYMINFO_FLG_INTERPOSE	0x0080	/* symbol defines an interposer */
 
 /*
  * Syminfo.si_boundto values.