changeset 13086:787bf65954d0

6972860 ld should provide user guidance to improve objects PSARC/2010/312 Link-editor guidance
author Ali Bahrami <Ali.Bahrami@Oracle.COM>
date Wed, 11 Aug 2010 13:39:17 -0600
parents 6b4a9cc90eaa
children 71556dfac9dc
files usr/src/cmd/sgs/include/debug.h usr/src/cmd/sgs/include/libld.h usr/src/cmd/sgs/include/sgs.h usr/src/cmd/sgs/ld/common/ld.c usr/src/cmd/sgs/ld/common/ld.msg usr/src/cmd/sgs/ld/common/mapfile-intf usr/src/cmd/sgs/libld/common/_libld.h usr/src/cmd/sgs/libld/common/_map.h usr/src/cmd/sgs/libld/common/args.c usr/src/cmd/sgs/libld/common/debug.c usr/src/cmd/sgs/libld/common/entry.c usr/src/cmd/sgs/libld/common/exit.c usr/src/cmd/sgs/libld/common/files.c usr/src/cmd/sgs/libld/common/groups.c usr/src/cmd/sgs/libld/common/ldentry.c usr/src/cmd/sgs/libld/common/ldlibs.c usr/src/cmd/sgs/libld/common/ldmain.c usr/src/cmd/sgs/libld/common/libld.msg usr/src/cmd/sgs/libld/common/libs.c 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/machsym.sparc.c usr/src/cmd/sgs/libld/common/map_core.c usr/src/cmd/sgs/libld/common/mapfile-vers usr/src/cmd/sgs/libld/common/order.c usr/src/cmd/sgs/libld/common/outfile.c usr/src/cmd/sgs/libld/common/place.c usr/src/cmd/sgs/libld/common/relocate.c usr/src/cmd/sgs/libld/common/resolve.c usr/src/cmd/sgs/libld/common/sections.c usr/src/cmd/sgs/libld/common/sunwmove.c usr/src/cmd/sgs/libld/common/support.c usr/src/cmd/sgs/libld/common/syms.c usr/src/cmd/sgs/libld/common/unwind.c usr/src/cmd/sgs/libld/common/update.c usr/src/cmd/sgs/libld/common/util.c usr/src/cmd/sgs/libld/common/version.c usr/src/cmd/sgs/liblddbg/common/args.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/packages/common/SUNWonld-README usr/src/cmd/sgs/rtld/common/mapfile-vers usr/src/cmd/sgs/rtld/common/rtld.msg usr/src/cmd/sgs/rtld/common/util.c
diffstat 46 files changed, 1200 insertions(+), 867 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/include/debug.h	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/include/debug.h	Wed Aug 11 13:39:17 2010 -0600
@@ -763,6 +763,7 @@
  * External Dbg_*() interface routines.
  */
 extern	void	Dbg_args_file(Lm_list *, int, char *);
+extern	void	Dbg_args_guidance_unknown(Lm_list *, const char *);
 extern	void	Dbg_args_option(Lm_list *, int, int, char *);
 extern	void	Dbg_args_str2chr(Lm_list *, int, const char *, int);
 extern	void	Dbg_args_Wldel(Lm_list *, int, const char *);
--- a/usr/src/cmd/sgs/include/libld.h	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/include/libld.h	Wed Aug 11 13:39:17 2010 -0600
@@ -241,7 +241,8 @@
 /*
  * Output file processing structure
  */
-typedef Lword ofl_flag_t;
+typedef Lword	ofl_flag_t;
+typedef Word	ofl_guideflag_t;
 struct ofl_desc {
 	char		*ofl_sgsid;	/* link-editor identification */
 	const char	*ofl_name;	/* full file name */
@@ -403,6 +404,7 @@
 	APlist		*ofl_maptext;	/* mapfile added text sections */
 	APlist		*ofl_mapdata;	/* mapfile added data sections */
 	avl_tree_t	*ofl_wrap;	/* -z wrap symbols */
+	ofl_guideflag_t	ofl_guideflags;	/* -z guide flags */
 };
 
 #define	FLG_OF_DYNAMIC	0x00000001	/* generate dynamic output module */
@@ -460,6 +462,7 @@
 #define	FLG_OF_PTCAP	0x080000000000	/* PT_SUNWCAP required */
 #define	FLG_OF_CAPSTRS	0x100000000000	/* capability strings are required */
 #define	FLG_OF_EHFRAME	0x200000000000	/* output contains .eh_frame section */
+#define	FLG_OF_FATWARN	0x400000000000	/* make warnings fatal */
 
 /*
  * In the flags1 arena, establish any options that are applicable to archive
@@ -488,8 +491,7 @@
 #define	FLG_OF1_LAZYLD	0x0000008000	/* lazy loading of objects enabled */
 #define	FLG_OF1_GRPPRM	0x0000010000	/* dependencies are to have */
 					/*	GROUPPERM enabled */
-#define	FLG_OF1_OVRFLW	0x0000020000	/* size exceeds 32-bit limitation */
-					/*	of 32-bit libld */
+
 #define	FLG_OF1_NOPARTI	0x0000040000	/* -znopartial set */
 #define	FLG_OF1_BSSOREL	0x0000080000	/* output relocation against bss */
 					/*	section */
@@ -517,6 +519,30 @@
 #define	FLG_OF1_OVIDCAP	0x2000000000	/* override CA_SUNW_ID capability */
 
 /*
+ * Guidance flags. The flags with the FLG_OFG_NO_ prefix are used to suppress
+ * messages for a given category, and use the lower 28 bits of the word,
+ * The upper nibble is reserved for other guidance status.
+ */
+#define	FLG_OFG_ENABLE		0x10000000	/* -z guidance option active */
+#define	FLG_OFG_ISSUED		0x20000000	/* -z guidance message issued */
+
+#define	FLG_OFG_NO_ALL		0x0fffffff	/* disable all guidance */
+#define	FLG_OFG_NO_DEFS		0x00000001	/* specify all dependencies */
+#define	FLG_OFG_NO_DB		0x00000002	/* use direct bindings */
+#define	FLG_OFG_NO_LAZY		0x00000004	/* be explicit about lazyload */
+#define	FLG_OFG_NO_MF		0x00000008	/* use v2 mapfile syntax */
+#define	FLG_OFG_NO_TEXT		0x00000010	/* verify pure text segment */
+#define	FLG_OFG_NO_UNUSED	0x00000020	/* remove unused dependency */
+
+/*
+ * Test to see if a guidance should be given for a given category
+ * or not. _no_flag is one of the FLG_OFG_NO_xxx flags. Returns TRUE
+ * if the guidance should be issued, and FALSE to remain silent.
+ */
+#define	OFL_GUIDANCE(_ofl, _no_flag) (((_ofl)->ofl_guideflags & \
+	(FLG_OFG_ENABLE | (_no_flag))) == FLG_OFG_ENABLE)
+
+/*
  * Test to see if the output file would allow the presence of
  * a .dynsym section.
  */
@@ -862,6 +888,7 @@
 #define	FLG_IF_OTOSCAP	0x00040000	/* convert object capabilities to */
 					/*	symbol capabilities */
 #define	FLG_IF_DEFERRED	0x00080000	/* dependency is deferred */
+#define	FLG_IF_RTLDINF	0x00100000	/* dependency has DT_SUNW_RTLTINF set */
 
 /*
  * Symbol states that require the generation of a DT_POSFLAG_1 .dynamic entry.
--- a/usr/src/cmd/sgs/include/sgs.h	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/include/sgs.h	Wed Aug 11 13:39:17 2010 -0600
@@ -47,6 +47,7 @@
 #include <sys/types.h>
 #include <sys/machelf.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <libelf.h>
 #include <assert.h>
 #include <alist.h>
@@ -118,15 +119,17 @@
 } Boolean;
 
 /*
- * Types of errors (used by eprintf()), together with a generic error return
+ * Types of errors (used by veprintf()), together with a generic error return
  * value.
  */
 typedef enum {
-	ERR_NONE,
-	ERR_WARNING,
-	ERR_FATAL,
-	ERR_ELF,
-	ERR_NUM				/* Must be last */
+	ERR_NONE,		/* plain message */
+	ERR_WARNING_NF,		/* warning that cannot be promoted to fatal */
+	ERR_WARNING,		/* warning that can be promoted to fatal */
+	ERR_GUIDANCE,		/* guidance warning that can be promoted */
+	ERR_FATAL,		/* fatal error */
+	ERR_ELF,		/* fatal libelf error */
+	ERR_NUM			/* # of Error codes. Must be last */
 } Error;
 
 /*
@@ -258,6 +261,7 @@
  */
 extern int	assfail(const char *, const char *, int);
 extern void	eprintf(Lm_list *, Error, const char *, ...);
+extern void	veprintf(Lm_list *, Error, const char *, va_list);
 extern uint_t	sgs_str_hash(const char *);
 extern uint_t	findprime(uint_t);
 
--- a/usr/src/cmd/sgs/ld/common/ld.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/ld/common/ld.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<stdio.h>
@@ -87,12 +86,10 @@
 /*
  * Print a message to stdout
  */
-/* VARARGS3 */
 void
-eprintf(Lm_list *lml, Error error, const char *format, ...)
+veprintf(Lm_list *lml, Error error, const char *format, va_list args)
 {
-	va_list			args;
-	static const char	*strings[ERR_NUM] = { MSG_ORIG(MSG_STR_EMPTY) };
+	static const char	*strings[ERR_NUM];
 
 #if	defined(lint)
 	/*
@@ -101,23 +98,38 @@
 	 */
 	lml = 0;
 #endif
-	if (error > ERR_NONE) {
-		if (error == ERR_WARNING) {
-			if (strings[ERR_WARNING] == 0)
-				strings[ERR_WARNING] =
-				    MSG_INTL(MSG_ERR_WARNING);
-		} else if (error == ERR_FATAL) {
-			if (strings[ERR_FATAL] == 0)
-				strings[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL);
-		} else if (error == ERR_ELF) {
-			if (strings[ERR_ELF] == 0)
-				strings[ERR_ELF] = MSG_INTL(MSG_ERR_ELF);
-		}
+	/*
+	 * For error types we issue a prefix for, make sure the necessary
+	 * string has been internationalized and is ready.
+	 */
+	switch (error) {
+	case ERR_WARNING_NF:
+		if (strings[ERR_WARNING_NF] == NULL)
+			strings[ERR_WARNING_NF] = MSG_INTL(MSG_ERR_WARNING);
+		break;
+	case ERR_WARNING:
+		if (strings[ERR_WARNING] == NULL)
+			strings[ERR_WARNING] = MSG_INTL(MSG_ERR_WARNING);
+		break;
+	case ERR_GUIDANCE:
+		if (strings[ERR_GUIDANCE] == NULL)
+			strings[ERR_GUIDANCE] = MSG_INTL(MSG_ERR_GUIDANCE);
+		break;
+	case ERR_FATAL:
+		if (strings[ERR_FATAL] == NULL)
+			strings[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL);
+		break;
+	case ERR_ELF:
+		if (strings[ERR_ELF] == NULL)
+			strings[ERR_ELF] = MSG_INTL(MSG_ERR_ELF);
+	}
+
+	/* If strings[] element for our error type is non-NULL, issue prefix */
+	if (strings[error] != NULL) {
 		(void) fputs(MSG_ORIG(MSG_STR_LDDIAG), stderr);
+		(void) fputs(strings[error], stderr);
 	}
-	(void) fputs(strings[error], stderr);
 
-	va_start(args, format);
 	(void) vfprintf(stderr, format, args);
 	if (error == ERR_ELF) {
 		int	elferr;
@@ -128,6 +140,20 @@
 	}
 	(void) fprintf(stderr, MSG_ORIG(MSG_STR_NL));
 	(void) fflush(stderr);
+}
+
+
+/*
+ * Print a message to stdout
+ */
+/* VARARGS3 */
+void
+eprintf(Lm_list *lml, Error error, const char *format, ...)
+{
+	va_list	args;
+
+	va_start(args, format);
+	veprintf(lml, error, format, args);
 	va_end(args);
 }
 
--- a/usr/src/cmd/sgs/ld/common/ld.msg	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/ld/common/ld.msg	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 @ _START_
@@ -43,6 +42,7 @@
 # Generic error diagnostic labels
 
 @ MSG_ERR_WARNING	"warning: "
+@ MSG_ERR_GUIDANCE	"guidance: "
 @ MSG_ERR_FATAL		"fatal: "
 @ MSG_ERR_ELF		"elf error: "
 
--- a/usr/src/cmd/sgs/ld/common/mapfile-intf	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/ld/common/mapfile-intf	Wed Aug 11 13:39:17 2010 -0600
@@ -43,4 +43,5 @@
 SYMBOL_SCOPE {
 	global:
 		eprintf;
+		veprintf;
 };
--- a/usr/src/cmd/sgs/libld/common/_libld.h	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/_libld.h	Wed Aug 11 13:39:17 2010 -0600
@@ -203,7 +203,8 @@
 	void		(* mr_mach_make_dynamic)(Ofl_desc *, size_t *);
 	void		(* mr_mach_update_odynamic)(Ofl_desc *, Dyn **);
 	Xword		(* mr_calc_plt_addr)(Sym_desc *, Ofl_desc *);
-	uintptr_t	(* mr_perform_outreloc)(Rel_desc *, Ofl_desc *);
+	uintptr_t	(* mr_perform_outreloc)(Rel_desc *, Ofl_desc *,
+			    Boolean *);
 	uintptr_t	(* mr_do_activerelocs)(Ofl_desc *);
 	uintptr_t	(* mr_add_outrel)(Word, Rel_desc *, Ofl_desc *);
 	uintptr_t	(* mr_reloc_register)(Rel_desc *, Is_desc *,
@@ -688,6 +689,7 @@
 #define	ld_disp_errmsg		ld64_disp_errmsg
 #define	ld_ent_check		ld64_ent_check
 #define	ld_ent_lookup		ld64_ent_lookup
+#define	ld_eprintf		ld64_eprintf
 #define	ld_exit			ld64_exit
 #define	ld_find_library		ld64_find_library
 #define	ld_finish_libs		ld64_finish_libs
@@ -784,6 +786,7 @@
 #define	ld_disp_errmsg		ld32_disp_errmsg
 #define	ld_ent_check		ld32_ent_check
 #define	ld_ent_lookup		ld32_ent_lookup
+#define	ld_eprintf		ld32_eprintf
 #define	ld_exit			ld32_exit
 #define	ld_find_library		ld32_find_library
 #define	ld_finish_libs		ld32_finish_libs
@@ -892,6 +895,7 @@
 extern void		ld_ent_check(Ofl_desc *);
 extern Ent_desc		*ld_ent_lookup(Ofl_desc *, const char *name,
 			    avl_index_t *where);
+extern void		ld_eprintf(Ofl_desc *, Error, const char *, ...);
 extern int		ld_exit(Ofl_desc *);
 
 extern uintptr_t	ld_find_library(const char *, Ofl_desc *);
@@ -944,7 +948,7 @@
 extern uintptr_t	ld_reloc_GOT_relative(Boolean, Rel_desc *, Ofl_desc *);
 extern uintptr_t	ld_reloc_plt(Rel_desc *, Ofl_desc *);
 extern void		ld_reloc_remain_entry(Rel_desc *, Os_desc *,
-			    Ofl_desc *);
+			    Ofl_desc *, Boolean *);
 extern Boolean		ld_reloc_set_aux_osdesc(Ofl_desc *, Rel_desc *,
 			    Os_desc *);
 extern Boolean		ld_reloc_set_aux_usym(Ofl_desc *, Rel_desc *,
@@ -1006,7 +1010,7 @@
 extern uintptr_t	ld_vers_need_process(Is_desc *, Ifl_desc *, Ofl_desc *);
 extern void		ld_vers_promote(Sym_desc *, Word, Ifl_desc *,
 			    Ofl_desc *);
-extern int		ld_vers_sym_process(Lm_list *, Is_desc *, Ifl_desc *);
+extern int		ld_vers_sym_process(Ofl_desc *, Is_desc *, Ifl_desc *);
 extern int		ld_vers_verify(Ofl_desc *);
 extern WrapSymNode	*ld_wrap_enter(Ofl_desc *, const char *);
 
--- a/usr/src/cmd/sgs/libld/common/_map.h	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/_map.h	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -115,8 +114,7 @@
 /*
  * A very large percentage of mapfile errors start with the
  * calling sequence:
- *	eprintf(ofl->ofl_lml, ERR_XXX, format, mf->mf_name,
- *		mf->mf_lineno...)
+ *	ld_eprintf(ofl, ERR_XXX, format, mf->mf_name, mf->mf_lineno...)
  * The mf_fatal() and mf_warn() varadic macros are used to supply all
  * of boilerplate, resulting in visually simpler code.
  *
@@ -126,17 +124,17 @@
  * supported by the Sun compilers yet.
  */
 #define	mf_fatal0(_mf, _fmt) \
-	eprintf((_mf)->mf_ofl->ofl_lml, ERR_FATAL, _fmt, (_mf)->mf_name, \
+	ld_eprintf((_mf)->mf_ofl, ERR_FATAL, _fmt, (_mf)->mf_name, \
 	    EC_LINENO((_mf)->mf_lineno))
 #define	mf_fatal(_mf, _fmt, ...) \
-	eprintf((_mf)->mf_ofl->ofl_lml, ERR_FATAL, _fmt, (_mf)->mf_name, \
+	ld_eprintf((_mf)->mf_ofl, ERR_FATAL, _fmt, (_mf)->mf_name, \
 	    EC_LINENO((_mf)->mf_lineno), __VA_ARGS__)
 
 #define	mf_warn0(_mf, _fmt) \
-	eprintf((_mf)->mf_ofl->ofl_lml, ERR_WARNING, _fmt, (_mf)->mf_name, \
+	ld_eprintf((_mf)->mf_ofl, ERR_WARNING, _fmt, (_mf)->mf_name, \
 	    EC_LINENO((_mf)->mf_lineno))
 #define	mf_warn(_mf, _fmt, ...) \
-	eprintf((_mf)->mf_ofl->ofl_lml, ERR_WARNING, _fmt, (_mf)->mf_name, \
+	ld_eprintf((_mf)->mf_ofl, ERR_WARNING, _fmt, (_mf)->mf_name, \
 	    EC_LINENO((_mf)->mf_lineno), __VA_ARGS__)
 
 /* Possible return values from ld_map_gettoken */
--- a/usr/src/cmd/sgs/libld/common/args.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/args.c	Wed Aug 11 13:39:17 2010 -0600
@@ -95,6 +95,7 @@
 static Setstate	zdflag	= SET_UNKNOWN;
 static Setstate	Qflag	= SET_UNKNOWN;
 static Setstate	Bdflag	= SET_UNKNOWN;
+static Setstate zfwflag	= SET_UNKNOWN;
 
 static Boolean	aflag	= FALSE;
 static Boolean	bflag	= FALSE;
@@ -114,7 +115,14 @@
  * ztflag's state is set by pointing it to the matching string:
  *	text | textoff | textwarn
  */
-static const char	*ztflag = 0;
+static const char	*ztflag = NULL;
+
+/*
+ * Remember the guidance flags that result from the initial -z guidance
+ * option, so that they can be compared to any that follow. We only want
+ * to issue a warning when they differ.
+ */
+static ofl_guideflag_t	initial_guidance_flags	= 0;
 
 static uintptr_t process_files_com(Ofl_desc *, int, char **);
 static uintptr_t process_flags_com(Ofl_desc *, int, char **, int *);
@@ -179,8 +187,10 @@
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDFS));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZDRS));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZE));
+	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFATW));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZFA));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGP));
+	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZGUIDE));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZH));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZIG));
 	(void) fprintf(stderr, MSG_INTL(MSG_ARG_DETAIL_ZINA));
@@ -283,38 +293,42 @@
 static uintptr_t
 check_flags(Ofl_desc * ofl, int argc)
 {
-	if (Plibpath && (Llibdir || Ulibdir)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_YP),
+	/*
+	 * If the user specified -zguidance=noall, then we can safely disable
+	 * the entire feature. The purpose of -zguidance=noall is to allow
+	 * the user to override guidance specified from a makefile via
+	 * the LD_OPTIONS environment variable, and so, we want to behave
+	 * in exactly the same manner we would have if no option were present.
+	 */
+	if ((ofl->ofl_guideflags & (FLG_OFG_ENABLE | FLG_OFG_NO_ALL)) ==
+	    (FLG_OFG_ENABLE | FLG_OFG_NO_ALL))
+		ofl->ofl_guideflags &= ~FLG_OFG_ENABLE;
+
+	if (Plibpath && (Llibdir || Ulibdir))
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_YP),
 		    Llibdir ? 'L' : 'U');
-		ofl->ofl_flags |= FLG_OF_FATAL;
-	}
 
 	if (rflag) {
 		if (dflag == SET_UNKNOWN)
 			dflag = SET_FALSE;
-		if (ofl->ofl_flags & FLG_OF_COMREL) {
-			/*
-			 * Combining relocations when building a relocatable
-			 * object isn't allowed.  Warn the user, but proceed.
-			 */
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_MARG_INCOMP), MSG_INTL(MSG_MARG_REL),
+		/*
+		 * Combining relocations when building a relocatable
+		 * object isn't allowed.  Warn the user, but proceed.
+		 */
+		if (ofl->ofl_flags & FLG_OF_COMREL)
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_MARG_INCOMP),
+			    MSG_INTL(MSG_MARG_REL),
 			    MSG_ORIG(MSG_ARG_ZCOMBRELOC));
-			ofl->ofl_flags &= ~FLG_OF_COMREL;
-		}
 		ofl->ofl_flags |= FLG_OF_RELOBJ;
 	} else {
 		/*
 		 * Translating object capabilities to symbol capabilities is
 		 * only meaningful when creating a relocatable object.
 		 */
-		if (ofl->ofl_flags & FLG_OF_OTOSCAP) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MARG_ONLY),
+		if (ofl->ofl_flags & FLG_OF_OTOSCAP)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ONLY),
 			    MSG_ORIG(MSG_ARG_ZSYMBOLCAP),
 			    MSG_INTL(MSG_MARG_REL));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
 
 		/*
 		 * If the user hasn't explicitly requested that relocations
@@ -342,38 +356,24 @@
 	if (Beflag)
 		ofl->ofl_flags |= FLG_OF_AUTOELM;
 
-	if (Blflag && Beflag) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
+	if (Blflag && Beflag)
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 		    MSG_ORIG(MSG_ARG_BELIMINATE), MSG_ORIG(MSG_ARG_BLOCAL));
-		ofl->ofl_flags |= FLG_OF_FATAL;
-	}
 
-	if (ofl->ofl_interp && (ofl->ofl_flags1 & FLG_OF1_NOINTRP)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
+	if (ofl->ofl_interp && (ofl->ofl_flags1 & FLG_OF1_NOINTRP))
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 		    MSG_ORIG(MSG_ARG_CI), MSG_ORIG(MSG_ARG_ZNOINTERP));
-		ofl->ofl_flags |= FLG_OF_FATAL;
-	}
 
 	if ((ofl->ofl_flags1 & (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) ==
-	    (FLG_OF1_NRLXREL | FLG_OF1_RLXREL)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
+	    (FLG_OF1_NRLXREL | FLG_OF1_RLXREL))
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
 		    MSG_ORIG(MSG_ARG_ZRELAXRELOC),
 		    MSG_ORIG(MSG_ARG_ZNORELAXRELOC));
-		ofl->ofl_flags |= FLG_OF_FATAL;
-	}
 
-	if (ofl->ofl_filtees && !Gflag) {
-		if (ofl->ofl_flags & FLG_OF_AUX) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MARG_ST_ONLYAVL),
-			    MSG_INTL(MSG_MARG_FILTER_AUX));
-		} else {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MARG_ST_ONLYAVL),
-			    MSG_INTL(MSG_MARG_FILTER));
-		}
-		ofl->ofl_flags |= FLG_OF_FATAL;
-	}
+	if (ofl->ofl_filtees && !Gflag)
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_ONLYAVL),
+		    ((ofl->ofl_flags & FLG_OF_AUX) ?
+		    MSG_INTL(MSG_MARG_FILTER_AUX) : MSG_INTL(MSG_MARG_FILTER)));
 
 	if (dflag != SET_FALSE) {
 		/*
@@ -383,24 +383,19 @@
 		ofl->ofl_flags |=
 		    (FLG_OF_DYNAMIC | FLG_OF_DYNLIBS | FLG_OF_PROCRED);
 
-		if (aflag) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_INCOMP), MSG_ORIG(MSG_ARG_DY),
-			    MSG_ORIG(MSG_ARG_A));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
+		if (aflag)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_INCOMP),
+			    MSG_ORIG(MSG_ARG_DY), MSG_ORIG(MSG_ARG_A));
 
 		if (bflag)
 			ofl->ofl_flags |= FLG_OF_BFLAG;
 
 		if (Bgflag == TRUE) {
-			if (zdflag == SET_FALSE) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			if (zdflag == SET_FALSE)
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_INCOMP),
 				    MSG_ORIG(MSG_ARG_BGROUP),
 				    MSG_ORIG(MSG_ARG_ZNODEF));
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 			ofl->ofl_dtflags_1 |= DF_1_GROUP;
 			ofl->ofl_flags |= FLG_OF_NOUNDEF;
 		}
@@ -411,8 +406,7 @@
 		 * job running this object.
 		 */
 		if ((ofl->ofl_dtflags_1 & DF_1_NODEFLIB) && !ofl->ofl_rpath)
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_ARG_NODEFLIB),
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ARG_NODEFLIB),
 			    MSG_INTL(MSG_MARG_RPATH));
 
 		/*
@@ -422,10 +416,13 @@
 		 * generated unless specifically asked for.
 		 */
 		if ((ztflag == MSG_ORIG(MSG_ARG_ZTEXTOFF)) ||
-		    ((ztflag == 0) && bflag))
+		    ((ztflag == NULL) && bflag)) {
 			ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
-		else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT))
+			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
+		} else if (ztflag == MSG_ORIG(MSG_ARG_ZTEXT)) {
 			ofl->ofl_flags |= FLG_OF_PURETXT;
+			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
+		}
 
 		if (Gflag || !rflag) {
 			/*
@@ -450,6 +447,7 @@
 			if (Bdflag == SET_TRUE) {
 				ofl->ofl_dtflags_1 |= DF_1_DIRECT;
 				ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
+				ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
 				ofl->ofl_flags |= FLG_OF_SYMINFO;
 			}
 
@@ -475,18 +473,21 @@
 			if (zdflag != SET_FALSE)
 				ofl->ofl_flags |= FLG_OF_NOUNDEF;
 
-			if (Bsflag) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			/*
+			 * -z textwarn is the default for executables, and
+			 * only an explicit -z text* option can change that,
+			 * so there's no need to provide additional guidance.
+			 */
+			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
+
+			if (Bsflag)
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_DY_INCOMP),
 				    MSG_ORIG(MSG_ARG_BSYMBOLIC));
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
-			if (ofl->ofl_soname) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			if (ofl->ofl_soname)
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_MARG_DY_INCOMP),
 				    MSG_INTL(MSG_MARG_SONAME));
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 		} else if (!rflag) {
 			/*
 			 * Shared library.
@@ -494,23 +495,32 @@
 			ofl->ofl_flags |= FLG_OF_SHAROBJ;
 
 			/*
-			 * By default, print text relocation errors for
-			 * executables but *not* for shared objects.
+			 * By default, print text relocation warnings for
+			 * executables but *not* for shared objects. However,
+			 * if -z guidance is on, issue warnings for shared
+			 * objects as well.
+			 *
+			 * If -z textwarn is explicitly specified, also issue
+			 * guidance messages if -z guidance is on, but not
+			 * for -z text or -z textoff.
 			 */
-			if (ztflag == 0)
-				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
+			if (ztflag == NULL) {
+				if (!OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
+					ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
+			} else if ((ofl->ofl_flags & FLG_OF_PURETXT) ||
+			    (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)) {
+				ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
+			}
 
 			if (Bsflag) {
 				/*
 				 * -Bsymbolic, and -Bnodirect make no sense.
 				 */
-				if (Bdflag == SET_FALSE) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+				if (Bdflag == SET_FALSE)
+					ld_eprintf(ofl, 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;
 			}
@@ -518,87 +528,64 @@
 			/*
 			 * Dynamic relocatable object.
 			 */
-			if (ztflag == 0)
+			if (ztflag == NULL)
 				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
+			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 
-			if (ofl->ofl_interp) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			if (ofl->ofl_interp)
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_MARG_INCOMP),
 				    MSG_INTL(MSG_MARG_REL),
 				    MSG_ORIG(MSG_ARG_CI));
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 		}
 	} else {
 		ofl->ofl_flags |= FLG_OF_STATIC;
 
-		if (bflag) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_B));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (ofl->ofl_soname) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MARG_ST_INCOMP),
+		if (bflag)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
+			    MSG_ORIG(MSG_ARG_B));
+		if (ofl->ofl_soname)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
 			    MSG_INTL(MSG_MARG_SONAME));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (ofl->ofl_depaudit) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_CP));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (ofl->ofl_audit) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_P));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (ofl->ofl_config) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_ST_INCOMP), MSG_ORIG(MSG_ARG_C));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (ztflag) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_ST_INCOMP),
+		if (ofl->ofl_depaudit)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
+			    MSG_ORIG(MSG_ARG_CP));
+		if (ofl->ofl_audit)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
+			    MSG_ORIG(MSG_ARG_P));
+		if (ofl->ofl_config)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
+			    MSG_ORIG(MSG_ARG_C));
+		if (ztflag)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_ST_INCOMP),
 			    MSG_ORIG(MSG_ARG_ZTEXTALL));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (Gflag) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MARG_ST_INCOMP),
+		if (Gflag)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_ST_INCOMP),
 			    MSG_INTL(MSG_MARG_SO));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-		if (aflag && rflag) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MARG_INCOMP), MSG_ORIG(MSG_ARG_A),
-			    MSG_INTL(MSG_MARG_REL));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
+		if (aflag && rflag)
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MARG_INCOMP),
+			    MSG_ORIG(MSG_ARG_A), MSG_INTL(MSG_MARG_REL));
 
 		if (rflag) {
 			/*
 			 * We can only strip the symbol table and string table
 			 * if no output relocations will refer to them.
 			 */
-			if (sflag) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+			if (sflag)
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_ARG_STRIP),
 				    MSG_INTL(MSG_MARG_REL),
 				    MSG_INTL(MSG_MARG_STRIP));
-			}
 
-			if (ztflag == 0)
+			if (ztflag == NULL)
 				ofl->ofl_flags1 |= FLG_OF1_TEXTOFF;
+			ofl->ofl_guideflags |= FLG_OFG_NO_TEXT;
 
-			if (ofl->ofl_interp) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			if (ofl->ofl_interp)
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_MARG_INCOMP),
 				    MSG_INTL(MSG_MARG_REL),
 				    MSG_ORIG(MSG_ARG_CI));
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 		} else {
 			/*
 			 * Static executable.
@@ -684,12 +671,9 @@
 	 * object, or are set on a per-symbol basis from a mapfile.
 	 */
 	if (zlflag) {
-		if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_NOFLTR),
+		if ((ofl->ofl_filtees == NULL) && (ofl->ofl_dtsfltrs == NULL))
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFLTR),
 			    MSG_ORIG(MSG_ARG_ZLOADFLTR));
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
 		ofl->ofl_dtflags_1 |= DF_1_LOADFLTR;
 	}
 
@@ -705,8 +689,7 @@
 		    (argc == 2)) {
 			ofl->ofl_flags1 |= FLG_OF1_DONE;
 		} else {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_NOFILES));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOFILES));
 			return (S_ERROR);
 		}
 	}
@@ -717,11 +700,11 @@
  * Decompose the string pointed by optarg into argv[][] so that argv[][] can be
  * used as an argument to getopt().
  *
- * If the second argument 'error' is not 0, then this is called from the first
- * pass. Else this is called from the second pass.
+ * If the second argument 'usage' is not NULL, then this is called from the
+ * first pass. Else this is called from the second pass.
  */
 static uintptr_t
-createargv(Ofl_desc *ofl, int *error)
+createargv(Ofl_desc *ofl, int *usage)
 {
 	int		argc = 0, idx = 0, ooptind;
 	uintptr_t	ret;
@@ -811,8 +794,8 @@
 	/*
 	 * Dispatch to pass1 or pass2
 	 */
-	if (error)
-		ret = process_flags_com(ofl, argc, argv, error);
+	if (usage)
+		ret = process_flags_com(ofl, argc, argv, usage);
 	else
 		ret = process_files_com(ofl, argc, argv);
 
@@ -820,12 +803,118 @@
 	return (ret);
 }
 
+/*
+ * Parse the items in a '-z guidance' value, and set the ofl_guideflags.
+ * A guidance option looks like this:
+ *
+ *	-z guidance[=item1,item2,...]
+ *
+ * Where each item specifies categories of guidance messages to suppress,
+ * each starting with the prefix 'no'. We allow arbitrary whitespace between
+ * the items, allow multiple ',' delimiters without an intervening item, and
+ * quietly ignore any items we don't recognize.
+ *
+ * -	Such items are likely to be known to newer versions of the linker,
+ *	and we do not want an older version of the linker to
+ *	complain about them.
+ *
+ * -	Times and standards can change, and so we wish to reserve the
+ *	right to make an old item that no longer makes sense go away.
+ *	Quietly ignoring unrecognized items facilitates this.
+ *
+ * However, we always display unrecognized items in debug output.
+ *
+ * entry:
+ *	ofl - Output descriptor
+ *	optarg - option string to be processed. This will either be a NULL
+ *		terminated 'guidance', or it will be 'guidance=' followed
+ *		by the item tokens as described above.
+ *
+ * exit:
+ *	Returns TRUE (1) on success, FALSE (0) on failure.
+ *
+ */
+static Boolean
+guidance_parse(Ofl_desc *ofl, char *optarg)
+{
+	typedef struct {
+		const char	*name;
+		ofl_guideflag_t	flag;
+	} item_desc;
+
+	static  item_desc items[] = {
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_ALL),	FLG_OFG_NO_ALL },
+
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_DEFS),	FLG_OFG_NO_DEFS },
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_DIRECT),	FLG_OFG_NO_DB },
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_LAZYLOAD),	FLG_OFG_NO_LAZY },
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_MAPFILE),	FLG_OFG_NO_MF },
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_TEXT),	FLG_OFG_NO_TEXT },
+		{ MSG_ORIG(MSG_ARG_GUIDE_NO_UNUSED),	FLG_OFG_NO_UNUSED },
+		{ NULL,					0 }
+	};
+
+	char		*lasts, *name;
+	item_desc	*item;
+	ofl_guideflag_t	ofl_guideflags = FLG_OFG_ENABLE;
+
+	/*
+	 * Skip the 'guidance' prefix. If NULL terminated, there are no
+	 * item values to parse. Otherwise, skip the '=' and parse the items.
+	 */
+	optarg += MSG_ARG_GUIDE_SIZE;
+	if (*optarg == '=') {
+		optarg++;
+
+		if ((name = libld_malloc(strlen(optarg) + 1)) == NULL)
+			return (FALSE);
+		(void) strcpy(name, optarg);
+
+		if ((name = strtok_r(name, MSG_ORIG(MSG_ARG_GUIDE_DELIM),
+		    &lasts)) != NULL) {
+			do {
+				for (item = items; item->name != NULL; item++)
+					if (strcasecmp(name, item->name) == 0)
+						break;
+				if (item->name == NULL) {
+					DBG_CALL(Dbg_args_guidance_unknown(
+					    ofl->ofl_lml, name));
+					continue;
+				}
+				ofl_guideflags |= item->flag;
+			} while ((name = strtok_r(NULL,
+			    MSG_ORIG(MSG_ARG_GUIDE_DELIM), &lasts)) != NULL);
+		}
+	}
+
+	/*
+	 * If -zguidance is used more than once, we take the first one. We
+	 * do this quietly if they have identical options, and with a warning
+	 * otherwise.
+	 */
+	if ((initial_guidance_flags & FLG_OFG_ENABLE) &&
+	    (ofl_guideflags != initial_guidance_flags)) {
+		ld_eprintf(ofl, ERR_WARNING_NF, MSG_INTL(MSG_ARG_MTONCE),
+		    MSG_ORIG(MSG_ARG_ZGUIDE));
+		return (TRUE);
+	}
+
+	/*
+	 * First time: Save the flags for comparison to any subsequent
+	 * -z guidance that comes along, and OR the resulting flags into
+	 * the flags kept in the output descriptor.
+	 */
+	initial_guidance_flags = ofl_guideflags;
+	ofl->ofl_guideflags |= ofl_guideflags;
+	return (TRUE);
+}
+
 static int	optitle = 0;
 /*
  * Parsing options pass1 for process_flags().
  */
 static uintptr_t
-parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *error)
+parseopt_pass1(Ofl_desc *ofl, int argc, char **argv, int *usage)
 {
 	int	c, ndx = optind;
 
@@ -850,12 +939,10 @@
 			 * Here we sanity check the option incase some other
 			 * -3* option is mistakenly passed to us.
 			 */
-			if (optarg[0] != '2') {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			if (optarg[0] != '2')
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_3), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 			continue;
 
 		case '6':
@@ -866,12 +953,10 @@
 			 * Here we sanity check the option incase some other
 			 * -6* option is mistakenly passed to us.
 			 */
-			if (optarg[0] != '4') {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			if (optarg[0] != '4')
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_6), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 			continue;
 
 		case 'a':
@@ -899,7 +984,7 @@
 		case 'c':
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_config)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING_NF,
 				    MSG_INTL(MSG_ARG_MTONCE),
 				    MSG_ORIG(MSG_ARG_C));
 			else
@@ -915,30 +1000,29 @@
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
 				if (dflag != SET_UNKNOWN)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_D));
 				else
 					dflag = SET_FALSE;
 			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
 				if (dflag != SET_UNKNOWN)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_D));
 				else
 					dflag = SET_TRUE;
 			} else {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_D), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			}
 			break;
 
 		case 'e':
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_entry)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING_NF,
 				    MSG_INTL(MSG_MARG_MTONCE),
 				    MSG_INTL(MSG_MARG_ENTRY));
 			else
@@ -949,11 +1033,10 @@
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_filtees &&
 			    (!(ofl->ofl_flags & FLG_OF_AUX))) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_MARG_INCOMP),
 				    MSG_INTL(MSG_MARG_FILTER_AUX),
 				    MSG_INTL(MSG_MARG_FILTER));
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			} else {
 				if ((ofl->ofl_filtees =
 				    add_string(ofl->ofl_filtees, optarg)) ==
@@ -967,11 +1050,10 @@
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_filtees &&
 			    (ofl->ofl_flags & FLG_OF_AUX)) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_MARG_INCOMP),
 				    MSG_INTL(MSG_MARG_FILTER),
 				    MSG_INTL(MSG_MARG_FILTER_AUX));
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			} else {
 				if ((ofl->ofl_filtees =
 				    add_string(ofl->ofl_filtees, optarg)) ==
@@ -983,7 +1065,7 @@
 		case 'h':
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_soname)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING_NF,
 				    MSG_INTL(MSG_MARG_MTONCE),
 				    MSG_INTL(MSG_MARG_SONAME));
 			else
@@ -998,7 +1080,7 @@
 		case 'I':
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_interp)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING_NF,
 				    MSG_INTL(MSG_ARG_MTONCE),
 				    MSG_ORIG(MSG_ARG_CI));
 			else
@@ -1024,7 +1106,7 @@
 		case 'o':
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (ofl->ofl_name)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING_NF,
 				    MSG_INTL(MSG_MARG_MTONCE),
 				    MSG_INTL(MSG_MARG_OUTFILE));
 			else
@@ -1107,7 +1189,7 @@
 			 */
 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_HELP),
 			    MSG_ARG_HELP_SIZE) == 0) {
-				usage_mesg(1);
+				usage_mesg(TRUE);
 				exit(0);
 			}
 
@@ -1119,57 +1201,53 @@
 			    MSG_ARG_LD32_SIZE) == 0) ||
 			    (strncmp(optarg, MSG_ORIG(MSG_ARG_LD64),
 			    MSG_ARG_LD64_SIZE) == 0)) {
-				if (createargv(ofl, error) == S_ERROR)
+				if (createargv(ofl, usage) == S_ERROR)
 					return (S_ERROR);
 
 			} else if (
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFS)) == 0) {
 				if (zdflag != SET_UNKNOWN)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
 				else
 					zdflag = SET_TRUE;
+				ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_ARG_NODEFS)) == 0) {
 				if (zdflag != SET_UNKNOWN)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_ZDEFNODEF));
 				else
 					zdflag = SET_FALSE;
+				ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_ARG_TEXT)) == 0) {
 				if (ztflag &&
-				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXT))) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXT)))
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_INCOMP),
 					    MSG_ORIG(MSG_ARG_ZTEXT),
 					    ztflag);
-					ofl->ofl_flags |= FLG_OF_FATAL;
-				}
 				ztflag = MSG_ORIG(MSG_ARG_ZTEXT);
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_ARG_TEXTOFF)) == 0) {
 				if (ztflag &&
-				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF))) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTOFF)))
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_INCOMP),
 					    MSG_ORIG(MSG_ARG_ZTEXTOFF),
 					    ztflag);
-					ofl->ofl_flags |= FLG_OF_FATAL;
-				}
 				ztflag = MSG_ORIG(MSG_ARG_ZTEXTOFF);
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_ARG_TEXTWARN)) == 0) {
 				if (ztflag &&
-				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN))) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+				    (ztflag != MSG_ORIG(MSG_ARG_ZTEXTWARN)))
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_INCOMP),
 					    MSG_ORIG(MSG_ARG_ZTEXTWARN),
 					    ztflag);
-					ofl->ofl_flags |= FLG_OF_FATAL;
-				}
 				ztflag = MSG_ORIG(MSG_ARG_ZTEXTWARN);
 
 			/*
@@ -1276,10 +1354,9 @@
 					ofl->ofl_ars_gsandx = ndx;
 				} else if (ofl->ofl_ars_gsandx > 0) {
 					/* Another group is still open */
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_AR_GRP_OLAP),
 					    MSG_INTL(MSG_MARG_AR_GRPS));
-					ofl->ofl_flags |= FLG_OF_FATAL;
 					/* Don't report cascading errors */
 					ofl->ofl_ars_gsandx = -1;
 				}
@@ -1289,11 +1366,10 @@
 					ofl->ofl_ars_gsandx = 0;
 				} else if (ofl->ofl_ars_gsandx == 0) {
 					/* There was no matching begin */
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_AR_GRP_BAD),
 					    MSG_INTL(MSG_MARG_AR_GRP_END),
 					    MSG_INTL(MSG_MARG_AR_GRP_START));
-					ofl->ofl_flags |= FLG_OF_FATAL;
 					/* Don't report cascading errors */
 					ofl->ofl_ars_gsandx = -1;
 				}
@@ -1307,6 +1383,30 @@
 				if (ld_wrap_enter(ofl,
 				    optarg + MSG_ARG_WRAP_SIZE) == NULL)
 					return (S_ERROR);
+			} else if ((strncmp(optarg, MSG_ORIG(MSG_ARG_GUIDE),
+			    MSG_ARG_GUIDE_SIZE) == 0) &&
+			    ((optarg[MSG_ARG_GUIDE_SIZE] == '=') ||
+			    (optarg[MSG_ARG_GUIDE_SIZE] == '\0'))) {
+				if (!guidance_parse(ofl, optarg))
+					return (S_ERROR);
+			} else if (strcmp(optarg,
+			    MSG_ORIG(MSG_ARG_FATWARN)) == 0) {
+				if (zfwflag  == SET_FALSE) {
+					ld_eprintf(ofl, ERR_WARNING_NF,
+					    MSG_INTL(MSG_ARG_MTONCE),
+					    MSG_ORIG(MSG_ARG_ZFATWNOFATW));
+				} else {
+					zfwflag = SET_TRUE;
+					ofl->ofl_flags |= FLG_OF_FATWARN;
+				}
+			} else if (strcmp(optarg,
+			    MSG_ORIG(MSG_ARG_NOFATWARN)) == 0) {
+				if (zfwflag  == SET_TRUE)
+					ld_eprintf(ofl, ERR_WARNING_NF,
+					    MSG_INTL(MSG_ARG_MTONCE),
+					    MSG_ORIG(MSG_ARG_ZFATWNOFATW));
+				else
+					zfwflag = SET_FALSE;
 
 			/*
 			 * The following options just need validation as they
@@ -1340,10 +1440,9 @@
 			    MSG_ARG_TARGET_SIZE) &&
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_RESCAN_NOW)) &&
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_DEFERRED))) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_Z), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			}
 
 			break;
@@ -1380,23 +1479,25 @@
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (strcmp(optarg, MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
 				if (Bdflag == SET_FALSE) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_INCOMP),
 					    MSG_ORIG(MSG_ARG_BNODIRECT),
 					    MSG_ORIG(MSG_ARG_BDIRECT));
-					ofl->ofl_flags |= FLG_OF_FATAL;
-				} else
+				} else {
 					Bdflag = SET_TRUE;
+					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
+				}
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
 				if (Bdflag == SET_TRUE) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_INCOMP),
 					    MSG_ORIG(MSG_ARG_BDIRECT),
 					    MSG_ORIG(MSG_ARG_BNODIRECT));
-					ofl->ofl_flags |= FLG_OF_FATAL;
-				} else
+				} else {
 					Bdflag = SET_FALSE;
+					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
+				}
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_STR_SYMBOLIC)) == 0)
 				Bsflag = TRUE;
@@ -1411,16 +1512,15 @@
 				Beflag = TRUE;
 			else if (strcmp(optarg,
 			    MSG_ORIG(MSG_ARG_TRANSLATOR)) == 0) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_ARG_UNSUPPORTED),
 				    MSG_ORIG(MSG_ARG_BTRANSLATOR));
 			} else if (strcmp(optarg,
 			    MSG_ORIG(MSG_STR_LD_DYNAMIC)) &&
 			    strcmp(optarg, MSG_ORIG(MSG_ARG_STATIC))) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_CB), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			}
 			break;
 
@@ -1448,23 +1548,22 @@
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if ((optarg[0] == 'n') && (optarg[1] == '\0')) {
 				if (Qflag != SET_UNKNOWN)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_CQ));
 				else
 					Qflag = SET_FALSE;
 			} else if ((optarg[0] == 'y') && (optarg[1] == '\0')) {
 				if (Qflag != SET_UNKNOWN)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_CQ));
 				else
 					Qflag = SET_TRUE;
 			} else {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_CQ), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			}
 			break;
 
@@ -1487,7 +1586,7 @@
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, optarg));
 			if (strncmp(optarg, MSG_ORIG(MSG_ARG_LCOM), 2) == 0) {
 				if (Llibdir)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_CYL));
 				else
@@ -1495,7 +1594,7 @@
 			} else if (strncmp(optarg,
 			    MSG_ORIG(MSG_ARG_UCOM), 2) == 0) {
 				if (Ulibdir)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_CYU));
 				else
@@ -1503,22 +1602,23 @@
 			} else if (strncmp(optarg,
 			    MSG_ORIG(MSG_ARG_PCOM), 2) == 0) {
 				if (Plibpath)
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING_NF,
 					    MSG_INTL(MSG_ARG_MTONCE),
 					    MSG_ORIG(MSG_ARG_CYP));
 				else
 					Plibpath = optarg + 2;
 			} else {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_ARG_ILLEGAL),
 				    MSG_ORIG(MSG_ARG_CY), optarg);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			}
 			break;
 
 		case '?':
 			DBG_CALL(Dbg_args_option(ofl->ofl_lml, ndx, c, NULL));
-			(*error)++;
+			eprintf(ofl->ofl_lml, ERR_FATAL,
+			    MSG_INTL(MSG_ARG_UNKNOWN), optopt);
+			(*usage)++;
 			break;
 
 		default:
@@ -1561,10 +1661,9 @@
 						ofl->ofl_flags |=
 						    FLG_OF_DYNLIBS;
 					else {
-						eprintf(ofl->ofl_lml, ERR_FATAL,
+						ld_eprintf(ofl, ERR_FATAL,
 						    MSG_INTL(MSG_ARG_ST_INCOMP),
 						    MSG_ORIG(MSG_ARG_BDYNAMIC));
-						ofl->ofl_flags |= FLG_OF_FATAL;
 					}
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_STATIC)) == 0)
@@ -1582,12 +1681,10 @@
 				/*
 				 * Record DT_NEEDED string
 				 */
-				if (!(ofl->ofl_flags & FLG_OF_DYNAMIC)) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+				if (!(ofl->ofl_flags & FLG_OF_DYNAMIC))
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_ARG_ST_INCOMP),
 					    MSG_ORIG(MSG_ARG_CN));
-					ofl->ofl_flags |= FLG_OF_FATAL;
-				}
 				if (((ifl = libld_calloc(1,
 				    sizeof (Ifl_desc))) == NULL) ||
 				    (aplist_append(&ofl->ofl_sos, ifl,
@@ -1637,9 +1734,11 @@
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_DIRECT)) == 0) {
 					ofl->ofl_flags1 |= FLG_OF1_ZDIRECT;
+					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_NODIRECT)) == 0) {
 					ofl->ofl_flags1 &= ~FLG_OF1_ZDIRECT;
+					ofl->ofl_guideflags |= FLG_OFG_NO_DB;
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_IGNORE)) == 0) {
 					ofl->ofl_flags1 |= FLG_OF1_IGNORE;
@@ -1649,9 +1748,11 @@
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_LAZYLOAD)) == 0) {
 					ofl->ofl_flags1 |= FLG_OF1_LAZYLD;
+					ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_NOLAZYLOAD)) == 0) {
 					ofl->ofl_flags1 &= ~ FLG_OF1_LAZYLD;
+					ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
 				} else if (strcmp(optarg,
 				    MSG_ORIG(MSG_ARG_GROUPPERM)) == 0) {
 					ofl->ofl_flags1 |= FLG_OF1_GRPPRM;
@@ -1745,7 +1846,7 @@
  * Pass 1 -- process_flags: collects all options and sets flags
  */
 static uintptr_t
-process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *e)
+process_flags_com(Ofl_desc *ofl, int argc, char **argv, int *usage)
 {
 	for (; optind < argc; optind++) {
 		/*
@@ -1755,8 +1856,8 @@
 		 */
 		while ((optind < argc) && (argv[optind][0] == '-')) {
 			if (argv[optind][1] != '\0') {
-				if (parseopt_pass1(ofl, argc, argv, e) ==
-				    S_ERROR)
+				if (parseopt_pass1(ofl, argc, argv,
+				    usage) == S_ERROR)
 					return (S_ERROR);
 			} else if (++optind < argc)
 				continue;
@@ -1768,10 +1869,9 @@
 
 	/* Did an unterminated archive group run off the end? */
 	if (ofl->ofl_ars_gsandx > 0) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_AR_GRP_BAD),
 		    MSG_INTL(MSG_MARG_AR_GRP_START),
 		    MSG_INTL(MSG_MARG_AR_GRP_END));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (S_ERROR);
 	}
 
@@ -1781,7 +1881,7 @@
 uintptr_t
 ld_process_flags(Ofl_desc *ofl, int argc, char **argv)
 {
-	int	error = 0;	/* Collect all argument errors before exit */
+	int	usage = 0;	/* Collect all argument errors before exit */
 
 	if (argc < 2) {
 		usage_mesg(FALSE);
@@ -1793,14 +1893,14 @@
 	 */
 	opterr = 0;
 	optind = 1;
-	if (process_flags_com(ofl, argc, argv, &error) == S_ERROR)
+	if (process_flags_com(ofl, argc, argv, &usage) == S_ERROR)
 		return (S_ERROR);
 
 	/*
-	 * Having parsed everything, did we have any errors.
+	 * Having parsed everything, did we have any usage errors.
 	 */
-	if (error) {
-		usage_mesg(TRUE);
+	if (usage) {
+		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_USEHELP));
 		return (S_ERROR);
 	}
 
@@ -1839,9 +1939,8 @@
 		if ((fd = open(path, O_RDONLY)) == -1) {
 			int err = errno;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_SYS_OPEN), path, strerror(err));
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			continue;
 		}
 
@@ -1860,13 +1959,12 @@
 		if (rej.rej_type) {
 			Conv_reject_desc_buf_t rej_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(reject[rej.rej_type]),
 			    rej.rej_name ? rej.rej_name :
 			    MSG_INTL(MSG_STR_UNKNOWN),
 			    conv_reject_desc(&rej, &rej_buf,
 			    ld_targ.t_m.m_mach));
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (1);
 		}
 	}
@@ -1890,6 +1988,20 @@
 		return (1);
 
 	/*
+	 * Guidance: Use -B direct/nodirect or -z direct/nodirect.
+	 *
+	 * This is a backstop for the case where the link had no dependencies.
+	 * Otherwise, it will get caught by ld_process_ifl(). We need both,
+	 * because -z direct is positional, and its value at the time where
+	 * the first dependency is seen might be different than it is now.
+	 */
+	if ((ofl->ofl_flags & FLG_OF_DYNAMIC) &&
+	    OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
+		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DIRECT));
+		ofl->ofl_guideflags |= FLG_OFG_NO_DB;
+	}
+
+	/*
 	 * Now that all command line files have been processed see if there are
 	 * any additional `needed' shared object dependencies.
 	 */
--- a/usr/src/cmd/sgs/libld/common/debug.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/debug.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<stdio.h>
@@ -32,6 +31,7 @@
 #include	<debug.h>
 #include	<conv.h>
 #include	"msg.h"
+#include	"_libld.h"
 
 /*
  * dbg_setup() can be called a number of times.  The typical use through
@@ -110,7 +110,7 @@
 			if (fptr == NULL) {
 				int	err = errno;
 
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_SYS_OPEN), ofile,
 				    strerror(err));
 				return (0);
--- a/usr/src/cmd/sgs/libld/common/entry.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/entry.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #define	ELF_TARGET_AMD64
@@ -362,7 +361,7 @@
 	 * Initialize the elf library.
 	 */
 	if (elf_version(EV_CURRENT) == EV_NONE) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ELF_LIBELF),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ELF_LIBELF),
 		    EV_CURRENT);
 		return (S_ERROR);
 	}
--- a/usr/src/cmd/sgs/libld/common/exit.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/exit.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -59,6 +58,10 @@
 	 */
 	dbg_cleanup();
 
+	/* If any ERR_GUIDANCE messages were issued, add a summary */
+	if (ofl->ofl_guideflags & FLG_OFG_ISSUED)
+		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_SUMMARY));
+
 	return (1);
 }
 
@@ -79,7 +82,7 @@
 	{ SIGTERM,	SIG_IGN },
 	{ 0,		0 } };
 
-static Ofl_desc	*Ofl = 0;
+static Ofl_desc	*Ofl = NULL;
 
 /*
  * Define our signal handler.
@@ -114,7 +117,7 @@
 	 * Thus we catch all bus errors and hope we can decode a better error.
 	 */
 	if ((sig == SIGBUS) && sip && Ofl->ofl_name) {
-		eprintf(Ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INTERRUPT),
+		ld_eprintf(Ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INTERRUPT),
 		    Ofl->ofl_name, strerror(sip->si_errno));
 	}
 	/*
--- a/usr/src/cmd/sgs/libld/common/files.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/files.c	Wed Aug 11 13:39:17 2010 -0600
@@ -116,15 +116,13 @@
 		Shdr	*shdr0;
 
 		if ((scn = elf_getscn(elf, 0)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETSCN), name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
+			    name);
 			return ((Ifl_desc *)S_ERROR);
 		}
 		if ((shdr0 = elf_getshdr(scn)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETSHDR), name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
+			    name);
 			return ((Ifl_desc *)S_ERROR);
 		}
 		ifl->ifl_shnum = (Word)shdr0->sh_size;
@@ -181,9 +179,8 @@
 	isp->is_keyident = ident;
 
 	if ((isp->is_indata = elf_getdata(scn, NULL)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA),
 		    ifl->ifl_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -261,7 +258,7 @@
 		 * building a 32-bit object.
 		 */
 		if (val & SF1_SUNW_ADDR32) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_FIL_INADDR32SF1), ifl->ifl_name,
 			    EC_WORD(cisp->is_scnndx), cisp->is_name);
 			val &= ~SF1_SUNW_ADDR32;
@@ -280,13 +277,13 @@
 	 * an F1_SUNW_FPUSED by itself is viewed as bad practice.
 	 */
 	if ((badval = (val & ~SF1_SUNW_MASK)) != 0) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_FIL_BADSF1),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_FIL_BADSF1),
 		    ifl->ifl_name, EC_WORD(cisp->is_scnndx), cisp->is_name,
 		    EC_XWORD(badval));
 		val &= SF1_SUNW_MASK;
 	}
 	if ((val & FP_FLAGS) == SF1_SUNW_FPUSED) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_FIL_BADSF1),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_FIL_BADSF1),
 		    ifl->ifl_name, EC_WORD(cisp->is_scnndx), cisp->is_name,
 		    EC_XWORD(val));
 		return;
@@ -310,7 +307,7 @@
 		if ((val & SF1_SUNW_ADDR32) && (ofl->ofl_flags & FLG_OF_EXEC) &&
 		    ((ofl->ofl_ocapset.oc_sf_1.cm_val &
 		    SF1_SUNW_ADDR32) == 0)) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_FIL_EXADDR32SF1), ifl->ifl_name,
 			    EC_WORD(cisp->is_scnndx), cisp->is_name);
 		}
@@ -774,12 +771,11 @@
 		 */
 		msdp = mcsp->cs_sdp;
 
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_CAP_MULDEF),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_CAP_MULDEF),
 		    demangle(lsdp->sd_name));
-		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_CAP_MULDEFSYMS),
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_CAP_MULDEFSYMS),
 		    msdp->sd_file->ifl_name, msdp->sd_name,
 		    csdp->sd_file->ifl_name, csdp->sd_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 	}
 
 	/*
@@ -893,10 +889,9 @@
 			break;
 
 		default:
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_FIL_UNKCAP), ifl->ifl_name,
-			    EC_WORD(cisp->is_scnndx), cisp->is_name,
-			    data->c_tag);
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_FIL_UNKCAP),
+			    ifl->ifl_name, EC_WORD(cisp->is_scnndx),
+			    cisp->is_name, data->c_tag);
 		}
 	}
 
@@ -908,11 +903,9 @@
 		Word	info = cisp->is_shdr->sh_info;
 
 		if ((info == 0) || (info > ifl->ifl_shnum)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_FIL_INVSHINFO), ifl->ifl_name,
-			    EC_WORD(cisp->is_scnndx), cisp->is_name,
-			    EC_XWORD(info));
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
+			    ifl->ifl_name, EC_WORD(cisp->is_scnndx),
+			    cisp->is_name, EC_XWORD(info));
 			return (S_ERROR);
 		}
 		strs = (char *)ifl->ifl_isdesc[info]->is_indata->d_buf;
@@ -1195,7 +1188,7 @@
 		 * compilation environment a little more freedom.
 		 */
 		if ((sdp = ifl->ifl_oldndx[cndx]) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_CAPINFO_INVALSYM), ifl->ifl_name,
 			    EC_WORD(isp->is_scnndx), isp->is_name, cndx,
 			    MSG_INTL(MSG_STR_UNKNOWN));
@@ -1204,7 +1197,7 @@
 		if ((lndx == 0) || (lndx >= ifl->ifl_symscnt) ||
 		    ((lsdp = ifl->ifl_oldndx[lndx]) == NULL) ||
 		    (ELF_ST_BIND(lsdp->sd_sym->st_info) != STB_GLOBAL)) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_CAPINFO_INVALLEAD), ifl->ifl_name,
 			    EC_WORD(isp->is_scnndx), isp->is_name, cndx, lsdp ?
 			    demangle(lsdp->sd_name) : MSG_INTL(MSG_STR_UNKNOWN),
@@ -1363,7 +1356,7 @@
 	if (size) {
 		data = isp->is_indata->d_buf;
 		if (data[0] != '\0' || data[size - 1] != '\0')
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_FIL_MALSTR), ifl->ifl_name,
 			    EC_WORD(isp->is_scnndx), name);
 	} else
@@ -1383,7 +1376,7 @@
 {
 	Conv_inv_buf_t inv_buf;
 
-	eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_FIL_INVALSEC),
+	ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_FIL_INVALSEC),
 	    ifl->ifl_name, EC_WORD(ndx), name,
 	    conv_sec_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
 	    ifl->ifl_ehdr->e_machine, shdr->sh_type, 0, &inv_buf));
@@ -1461,7 +1454,7 @@
 			 */
 			if (ld_targ.t_m.m_sht_unwind == SHT_PROGBITS)
 				break;
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_EXEHFRMTYP), ifl->ifl_name,
 			    EC_WORD(ndx), name,
 			    conv_sec_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
@@ -1470,7 +1463,6 @@
 			    conv_sec_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
 			    ifl->ifl_ehdr->e_machine, ld_targ.t_m.m_sht_unwind,
 			    CONV_FMT_ALT_CF, &inv_buf2));
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (FALSE);
 		case 'g':
 			if (is_name_cmp(name, MSG_ORIG(MSG_SCN_GOT),
@@ -1690,7 +1682,7 @@
 
 		if ((isp == NULL) || ((isp->is_shdr->sh_type != SHT_SYMTAB) &&
 		    (isp->is_shdr->sh_type != SHT_DYNSYM))) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_INVSHLINK), ifl->ifl_name,
 			    EC_WORD(ndx), name, EC_XWORD(shdr->sh_link));
 			return (S_ERROR);
@@ -1712,7 +1704,7 @@
 
 		if ((isp == NULL) || ((isp->is_shdr->sh_type != SHT_SYMTAB) &&
 		    (isp->is_shdr->sh_type != SHT_DYNSYM))) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_INVSHLINK), isc->is_file->ifl_name,
 			    EC_WORD(isc->is_scnndx), isc->is_name,
 			    EC_XWORD(isc->is_shdr->sh_link));
@@ -1750,9 +1742,8 @@
 	 * Find the string section associated with the .dynamic section.
 	 */
 	if ((strscn = elf_getscn(ifl->ifl_elf, shdr->sh_link)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
 		    ifl->ifl_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 	dp = elf_getdata(strscn, NULL);
@@ -2117,14 +2108,19 @@
 	Dyn		*data, *dyn;
 	char		*str, *rpath = NULL;
 	const char	*soname, *needed;
+	Boolean		no_undef;
 
 	data = (Dyn *)isc->is_indata->d_buf;
 	str = (char *)ifl->ifl_isdesc[isc->is_shdr->sh_link]->is_indata->d_buf;
 
+	/* Determine if we need to examine the runpaths and NEEDED entries */
+	no_undef = (ofl->ofl_flags & (FLG_OF_NOUNDEF | FLG_OF_SYMBOLIC)) ||
+	    OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS);
+
 	/*
 	 * First loop through the dynamic section looking for a run path.
 	 */
-	if (ofl->ofl_flags & (FLG_OF_NOUNDEF | FLG_OF_SYMBOLIC)) {
+	if (no_undef) {
 		for (dyn = data; dyn->d_tag != DT_NULL; dyn++) {
 			if ((dyn->d_tag != DT_RPATH) &&
 			    (dyn->d_tag != DT_RUNPATH))
@@ -2153,8 +2149,7 @@
 		    (dyn->d_tag == DT_USED)) {
 			Sdf_desc	*sdf;
 
-			if (!(ofl->ofl_flags &
-			    (FLG_OF_NOUNDEF | FLG_OF_SYMBOLIC)))
+			if (!no_undef)
 				continue;
 			if ((needed = str + (size_t)dyn->d_un.d_val) == NULL)
 				continue;
@@ -2191,6 +2186,22 @@
 			if (dyn->d_un.d_val & DF_1_NODIRECT)
 				ifl->ifl_flags |= FLG_IF_NODIRECT;
 
+			/*
+			 * If we are building an executable, and this
+			 * dependency is tagged as an interposer, then
+			 * assume that it is required even if symbol
+			 * resolution uncovers no evident use.
+			 *
+			 * If we are building a shared object, then an
+			 * interposer dependency has no special meaning, and we
+			 * treat it as a regular dependency. By definition, all
+			 * interposers must be visible to the runtime linker
+			 * at initialization time, and cannot be added later.
+			 */
+			if ((dyn->d_un.d_val & DF_1_INTERPOSE) &&
+			    (ofl->ofl_flags & FLG_OF_EXEC))
+				ifl->ifl_flags |= FLG_IF_DEPREQD;
+
 		} else if ((dyn->d_tag == DT_AUDIT) &&
 		    (ifl->ifl_flags & FLG_IF_NEEDED)) {
 			/*
@@ -2211,6 +2222,14 @@
 			 * be exercised as part of process initialization.
 			 */
 			ifl->ifl_flags &= ~MSK_IF_POSFLAG1;
+
+			/*
+			 * libc is not subject to the usual guidance checks
+			 * for lazy loading. It cannot be lazy loaded, libld
+			 * ignores the request, and rtld would ignore the
+			 * setting if it were present.
+			 */
+			ifl->ifl_flags |= FLG_IF_RTLDINF;
 		}
 	}
 
@@ -2258,10 +2277,9 @@
 				else
 					hint = MSG_ORIG(MSG_STR_EMPTY);
 
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_REC_OBJCNFLT), sifl->ifl_name,
 				    ifl->ifl_name, sifl->ifl_soname, hint);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 				return (0);
 			}
 		}
@@ -2273,10 +2291,9 @@
 		 */
 		if (ofl->ofl_soname &&
 		    (strcmp(ofl->ofl_soname, ifl->ifl_soname) == 0)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_REC_OPTCNFLT), ifl->ifl_name,
 			    MSG_INTL(MSG_MARG_SONAME), ifl->ifl_soname);
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (0);
 		}
 	}
@@ -2338,11 +2355,10 @@
 	 * Make sure this is a valid relocation we can handle.
 	 */
 	if (shdr->sh_type != ld_targ.t_m.m_rel_sht_type) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVALSEC),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVALSEC),
 		    ifl->ifl_name, EC_WORD(isc->is_scnndx), isc->is_name,
 		    conv_sec_type(ifl->ifl_ehdr->e_ident[EI_OSABI],
 		    ifl->ifl_ehdr->e_machine, shdr->sh_type, 0, &inv_buf));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -2358,10 +2374,9 @@
 		/*
 		 * Broken input file.
 		 */
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
 		    ifl->ifl_name, EC_WORD(isc->is_scnndx), isc->is_name,
 		    EC_XWORD(rndx));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 	if (rndx == 0) {
@@ -2388,7 +2403,7 @@
 					return (S_ERROR);
 				return (1);
 			}
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_INVRELOC1), ifl->ifl_name,
 			    EC_WORD(isc->is_scnndx), isc->is_name,
 			    EC_WORD(risc->is_scnndx), risc->is_name);
@@ -2424,7 +2439,7 @@
 		/*
 		 * A conflict, issue an warning message, and ignore the section.
 		 */
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_FIL_EXCLUDE),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_FIL_EXCLUDE),
 		    ifl->ifl_name, EC_WORD(ndx), name);
 		return (0);
 	}
@@ -2531,22 +2546,19 @@
 
 	sndx = ifl->ifl_shstrndx;
 	if ((scn = elf_getscn(elf, (size_t)sndx)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
 		    ifl->ifl_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 	if ((shdr = elf_getshdr(scn)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
 		    ifl->ifl_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 	if ((name = elf_strptr(elf, (size_t)sndx, (size_t)shdr->sh_name)) ==
 	    NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_STRPTR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_STRPTR),
 		    ifl->ifl_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -2560,9 +2572,8 @@
 	 */
 	if ((name = elf_strptr(elf, (size_t)sndx, (size_t)shdr->sh_name)) ==
 	    NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_STRPTR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_STRPTR),
 		    ifl->ifl_name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -2599,9 +2610,8 @@
 			continue;
 
 		if ((shdr = elf_getshdr(scn)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETSHDR), ifl->ifl_name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
+			    ifl->ifl_name);
 			return (0);
 		}
 		name = str + (size_t)(shdr->sh_name);
@@ -2650,7 +2660,7 @@
 			if (row < (Word)SHT_LOSUNW) {
 				Conv_inv_buf_t inv_buf;
 
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_FIL_INVALSEC), ifl->ifl_name,
 				    EC_WORD(ndx), name, conv_sec_type(
 				    ifl->ifl_ehdr->e_ident[EI_OSABI],
@@ -2898,7 +2908,8 @@
 	 * `needed' entries in the same manner as will be generated from the
 	 * .dynamic's NEEDED entries.
 	 */
-	if (vndisp && (ofl->ofl_flags & (FLG_OF_NOUNDEF | FLG_OF_SYMBOLIC)))
+	if (vndisp && ((ofl->ofl_flags & (FLG_OF_NOUNDEF | FLG_OF_SYMBOLIC)) ||
+	    OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS)))
 		if (ld_vers_need_process(vndisp, ifl, ofl) == S_ERROR)
 			return (S_ERROR);
 
@@ -2907,7 +2918,7 @@
 	 * version sections.
 	 */
 	if (vsyisp)
-		(void) ld_vers_sym_process(ofl->ofl_lml, vsyisp, ifl);
+		(void) ld_vers_sym_process(ofl, vsyisp, ifl);
 
 	if (ifl->ifl_versym &&
 	    (vdfisp || (sdf && (sdf->sdf_flags & FLG_SDF_SELECT))))
@@ -3126,9 +3137,8 @@
 		 * because of a -z rescan.
 		 */
 		if (elf_cntl(elf, ELF_C_FDREAD) == -1) {
-			eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_CNTL),
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_CNTL),
 			    name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (0);
 		}
 
@@ -3225,7 +3235,7 @@
 					    (strcmp(name, ifl->ifl_name) == 0) ?
 					    MSG_INTL(MSG_FIL_MULINC_1) :
 					    MSG_INTL(MSG_FIL_MULINC_2);
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    errmsg, name, ifl->ifl_name);
 				}
 				if (ifl_ret)
@@ -3260,9 +3270,8 @@
 		case ET_DYN:
 			if ((ofl->ofl_flags & FLG_OF_STATIC) ||
 			    !(ofl->ofl_flags & FLG_OF_DYNLIBS)) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_FIL_SOINSTAT), name);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 				return (0);
 			}
 
@@ -3302,6 +3311,28 @@
 			if (ifl->ifl_flags & MSK_IF_SYMINFO)
 				ofl->ofl_flags |= FLG_OF_SYMINFO;
 
+			/*
+			 * Guidance: Use -z lazyload/nolazyload.
+			 * libc is exempt from this advice, because it cannot
+			 * be lazy loaded, and requests to do so are ignored.
+			 */
+			if (OFL_GUIDANCE(ofl, FLG_OFG_NO_LAZY) &&
+			    ((ifl->ifl_flags & FLG_IF_RTLDINF) == 0)) {
+				ld_eprintf(ofl, ERR_GUIDANCE,
+				    MSG_INTL(MSG_GUIDE_LAZYLOAD));
+				ofl->ofl_guideflags |= FLG_OFG_NO_LAZY;
+			}
+
+			/*
+			 * Guidance: Use -B direct/nodirect or
+			 * -z direct/nodirect.
+			 */
+			if (OFL_GUIDANCE(ofl, FLG_OFG_NO_DB)) {
+				ld_eprintf(ofl, ERR_GUIDANCE,
+				    MSG_INTL(MSG_GUIDE_DIRECT));
+				ofl->ofl_guideflags |= FLG_OFG_NO_DB;
+			}
+
 			break;
 		default:
 			(void) elf_errno();
@@ -3351,8 +3382,7 @@
 	const char	*nfile = ofile;
 
 	if ((elf = elf_begin(*fd, ELF_C_READ, NULL)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_BEGIN), npath);
-		ofl->ofl_flags |= FLG_OF_FATAL;
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_BEGIN), npath);
 		return (0);
 	}
 
@@ -3393,8 +3423,7 @@
 	Ifl_desc	*ifl;
 
 	if ((elf = elf_memory(addr, size)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_MEMORY), path);
-		ofl->ofl_flags |= FLG_OF_FATAL;
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_MEMORY), path);
 		return (0);
 	}
 
@@ -3429,9 +3458,8 @@
 	dlen++;
 	plen = dlen + strlen(file) + 1;
 	if (plen > PATH_MAX) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_PTHTOLONG),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_PTHTOLONG),
 		    _dir, file);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -3528,15 +3556,15 @@
 			DBG_CALL(Dbg_libs_req(ofl->ofl_lml, sdf->sdf_name,
 			    sdf->sdf_rfile, file));
 			if ((fd = open(file, O_RDONLY)) == -1) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_FIL_NOTFOUND), file,
 				    sdf->sdf_rfile);
 			} else {
 				uintptr_t	open_ret;
 				Rej_desc	_rej = { 0 };
 
-				open_ret = ld_process_open(file, ++slash, &fd,
-				    ofl, 0, &_rej, &ifl);
+				open_ret = ld_process_open(file, ++slash,
+				    &fd, ofl, 0, &_rej, &ifl);
 				if (fd != -1)
 					(void) close(fd);
 				if (open_ret == S_ERROR)
@@ -3545,7 +3573,7 @@
 				if (_rej.rej_type) {
 					Conv_reject_desc_buf_t rej_buf;
 
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    MSG_INTL(reject[_rej.rej_type]),
 					    _rej.rej_name ? rej.rej_name :
 					    MSG_INTL(MSG_STR_UNKNOWN),
@@ -3657,14 +3685,14 @@
 		if (rej.rej_type) {
 			Conv_reject_desc_buf_t rej_buf;
 
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(reject[rej.rej_type]),
 			    rej.rej_name ? rej.rej_name :
 			    MSG_INTL(MSG_STR_UNKNOWN),
 			    conv_reject_desc(&rej, &rej_buf,
 			    ld_targ.t_m.m_mach));
 		} else {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_FIL_NOTFOUND), file, sdf->sdf_rfile);
 		}
 	}
--- a/usr/src/cmd/sgs/libld/common/groups.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/groups.c	Wed Aug 11 13:39:17 2010 -0600
@@ -113,9 +113,8 @@
 		}
 	}
 
-	eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ELF_NOGROUPSECT),
+	ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ELF_NOGROUPSECT),
 	    ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name);
-	ofl->ofl_flags |= FLG_OF_FATAL;
 	return (NULL);
 }
 
@@ -137,17 +136,15 @@
 	if ((gshdr->sh_link == SHN_UNDEF) ||
 	    (gshdr->sh_link >= gifl->ifl_shnum) ||
 	    ((isc = gifl->ifl_isdesc[gshdr->sh_link]) == NULL)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHLINK),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHLINK),
 		    gifl->ifl_name, EC_WORD(gisc->is_scnndx),
 		    gisc->is_name, EC_XWORD(gshdr->sh_link));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 	if (gshdr->sh_entsize == 0) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHENTSIZE),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHENTSIZE),
 		    gifl->ifl_name, EC_WORD(gisc->is_scnndx), gisc->is_name,
 		    EC_XWORD(gshdr->sh_entsize));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -162,10 +159,9 @@
 	if ((sshdr->sh_info == SHN_UNDEF) ||
 	    (gshdr->sh_info >= (Word)(sshdr->sh_size / sshdr->sh_entsize)) ||
 	    ((isc = gifl->ifl_isdesc[sshdr->sh_link]) == NULL)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
 		    gifl->ifl_name, EC_WORD(gisc->is_scnndx), gisc->is_name,
 		    EC_XWORD(gshdr->sh_info));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -218,10 +214,9 @@
 				str = gisc->is_sym_name;
 		}
 
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_GRP_INVALSYM),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_GRP_INVALSYM),
 		    gifl->ifl_name, EC_WORD(gisc->is_scnndx),
 		    gisc->is_name, str);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 
@@ -233,10 +228,9 @@
 		Word	gndx;
 
 		if ((gndx = gd.gd_data[ndx]) >= gifl->ifl_shnum) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_GRP_INVALNDX), gifl->ifl_name,
 			    EC_WORD(gisc->is_scnndx), gisc->is_name, ndx, gndx);
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (0);
 		}
 
--- a/usr/src/cmd/sgs/libld/common/ldentry.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/ldentry.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<stdio.h>
@@ -211,13 +210,11 @@
 
 
 		if (alist_nitems(enp->ec_files) > 0) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_ENT_NOSEC_1), enp->ec_segment->sg_name,
-			    enp->ec_is_name);
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ENT_NOSEC_1),
+			    enp->ec_segment->sg_name, enp->ec_is_name);
 		} else {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_ENT_NOSEC_2), enp->ec_segment->sg_name,
-			    enp->ec_is_name);
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ENT_NOSEC_2),
+			    enp->ec_segment->sg_name, enp->ec_is_name);
 		}
 	}
 }
--- a/usr/src/cmd/sgs/libld/common/ldlibs.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/ldlibs.c	Wed Aug 11 13:39:17 2010 -0600
@@ -312,15 +312,13 @@
 	if (rej.rej_type) {
 		Conv_reject_desc_buf_t rej_buf;
 
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(reject[rej.rej_type]),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(reject[rej.rej_type]),
 		    rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN),
 		    conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach));
 	} else {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_LIB_NOTFOUND),
-		    name);
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_LIB_NOTFOUND), name);
 	}
 
-	ofl->ofl_flags |= FLG_OF_FATAL;
 	return (0);
 }
 
@@ -385,7 +383,7 @@
 			if (cp == (char *)S_ERROR)
 				return (S_ERROR);
 			else if (cp)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_LIB_MALFORM));
 		}
 	}
@@ -398,7 +396,7 @@
 	if (cp == (char *)S_ERROR)
 		return (S_ERROR);
 	else if (cp) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_LIB_BADYP));
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_LIB_BADYP));
 		return (S_ERROR);
 	}
 	DBG_CALL(Dbg_libs_init(ofl->ofl_lml, ofl->ofl_ulibdirs,
--- a/usr/src/cmd/sgs/libld/common/ldmain.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/ldmain.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -72,6 +71,40 @@
 			    EV_CURRENT };
 
 /*
+ * ld-centric wrapper on top of veprintf():
+ * - Accepts output descriptor rather than linkmap list
+ * - Sets the FLG_OF_FATAL/FLG_OF_WARN flags as necessary
+ */
+void
+ld_eprintf(Ofl_desc *ofl, Error error, const char *format, ...)
+{
+	va_list	args;
+
+	/* Set flag indicating type of error being issued */
+	switch (error) {
+	case ERR_NONE:
+	case ERR_WARNING_NF:
+		break;
+	case ERR_WARNING:
+		ofl->ofl_flags |= FLG_OF_WARN;
+		break;
+	case ERR_GUIDANCE:
+		if ((ofl->ofl_guideflags & FLG_OFG_ENABLE) == 0)
+			return;
+		ofl->ofl_guideflags |= FLG_OFG_ISSUED;
+		ofl->ofl_flags |= FLG_OF_WARN;
+		break;
+	default:
+		ofl->ofl_flags |= FLG_OF_FATAL;
+	}
+
+	/* Issue the error */
+	va_start(args, format);
+	veprintf(ofl->ofl_lml, error, format, args);
+	va_end(args);
+}
+
+/*
  * Establish the global state necessary to link the desired machine
  * target, as reflected by the ld_targ global variable.
  */
@@ -113,6 +146,7 @@
 	char		*sgs_support;	/* SGS_SUPPORT environment string */
 	Half		etype;
 	Ofl_desc	*ofl;
+	ofl_flag_t	save_flg_of_warn;
 
 	/*
 	 * Establish a base time.  Total time diagnostics are relative to
@@ -153,10 +187,19 @@
 	 * end of mapfile processing.  The entrance criteria and segment
 	 * descriptors are complete and in their final form.
 	 */
-	if (ld_process_flags(ofl, argc, argv) == S_ERROR)
+	if (ld_process_flags(ofl, argc, argv) == S_ERROR) {
+		/* If any ERR_GUIDANCE messages were issued, add a summary */
+		if (ofl->ofl_guideflags & FLG_OFG_ISSUED)
+			ld_eprintf(ofl, ERR_GUIDANCE,
+			    MSG_INTL(MSG_GUIDE_SUMMARY));
 		return (1);
+	}
 	if (ofl->ofl_flags & FLG_OF_FATAL) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_FLAGS));
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_FLAGS));
+		/* If any ERR_GUIDANCE messages were issued, add a summary */
+		if (ofl->ofl_guideflags & FLG_OFG_ISSUED)
+			ld_eprintf(ofl, ERR_GUIDANCE,
+			    MSG_INTL(MSG_GUIDE_SUMMARY));
 		return (1);
 	}
 
@@ -272,7 +315,7 @@
 	if (ld_process_files(ofl, argc, argv) == S_ERROR)
 		return (ld_exit(ofl));
 	if (ofl->ofl_flags & FLG_OF_FATAL) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_FILES),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_FILES),
 		    ofl->ofl_name);
 		return (ld_exit(ofl));
 	}
@@ -299,6 +342,20 @@
 		return (ld_exit(ofl));
 
 	/*
+	 * We need to know if FLG_OF_WARN is currently set, in case
+	 * we need to honor a -z fatal-warnings request. However, we also
+	 * need to know if a warning due to symbol validation results from
+	 * the upcoming call to ld_sym_validate() in order to issue the
+	 * appropriate message for it. So we save the current value,
+	 * and clear the main flag.
+	 */
+	save_flg_of_warn = ofl->ofl_flags & FLG_OF_WARN;
+	ofl->ofl_flags &= ~FLG_OF_WARN;
+
+	if (ld_sym_validate(ofl) == S_ERROR)
+		return (ld_exit(ofl));
+
+	/*
 	 * Now that all symbol processing is complete see if any undefined
 	 * references still remain.  If we observed undefined symbols the
 	 * FLG_OF_FATAL bit will be set:  If creating a static executable, or a
@@ -306,19 +363,44 @@
 	 * condition is fatal.  If creating a shared object with the -Bsymbolic
 	 * flag set, this condition is simply a warning.
 	 */
-	if (ld_sym_validate(ofl) == S_ERROR)
-		return (ld_exit(ofl));
+	if (ofl->ofl_flags & FLG_OF_FATAL)
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_SYM_FATAL),
+		    ofl->ofl_name);
+	else if (ofl->ofl_flags & FLG_OF_WARN)
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ARG_SYM_WARN));
+
+	/*
+	 * Guidance: Use -z defs|nodefs when building shared objects.
+	 *
+	 * ld_sym_validate() will mask this guidance message out unless we are
+	 * intended to send it here, so all we need to do is use OFL_GUIDANCE()
+	 * to decide whether to issue it or not.
+	 */
+	if (OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS))
+		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_DEFS));
 
-	if (ofl->ofl_flags1 & FLG_OF1_OVRFLW) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_FILES),
-		    ofl->ofl_name);
+	/*
+	 * Symbol processing was the final step before we start producing the
+	 * output object. At this time, if we've seen warnings and the
+	 * -z fatal-warnings option is specified, promote them to fatal, which
+	 * will cause us to exit without creating an object.
+	 *
+	 * We didn't do this as the warnings were reported in order to
+	 * maximize the number of problems a given link-editor invocation
+	 * can diagnose. This is safe, since warnings are by definition events
+	 * one can choose to ignore.
+	 */
+	if (((ofl->ofl_flags | save_flg_of_warn) &
+	    (FLG_OF_WARN | FLG_OF_FATWARN)) ==
+	    (FLG_OF_WARN | FLG_OF_FATWARN))
+		ofl->ofl_flags |= FLG_OF_FATAL;
+
+	/*
+	 * If fatal errors occurred in symbol processing, or due to warnings
+	 * promoted by -z fatal-warnings, this is the end of the line.
+	 */
+	if (ofl->ofl_flags & FLG_OF_FATAL)
 		return (ld_exit(ofl));
-	} else if (ofl->ofl_flags & FLG_OF_FATAL) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_ARG_SYM_FATAL),
-		    ofl->ofl_name);
-		return (ld_exit(ofl));
-	} else if (ofl->ofl_flags & FLG_OF_WARN)
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_ARG_SYM_WARN));
 
 	/*
 	 * Generate any necessary sections.
@@ -373,7 +455,7 @@
 	 */
 	if (((ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) &&
 	    (_elf_swap_wrimage(ofl->ofl_elf) != 0)) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_SWAP_WRIMAGE),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_SWAP_WRIMAGE),
 		    ofl->ofl_name);
 		return (ld_exit(ofl));
 	}
@@ -382,7 +464,7 @@
 	 * We're done, so make sure the updates are flushed to the output file.
 	 */
 	if ((ofl->ofl_size = elf_update(ofl->ofl_welf, ELF_C_WRITE)) == 0) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_UPDATE),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_UPDATE),
 		    ofl->ofl_name);
 		return (ld_exit(ofl));
 	}
@@ -397,6 +479,10 @@
 	 */
 	dbg_cleanup();
 
+	/* If any ERR_GUIDANCE messages were issued, add a summary */
+	if (ofl->ofl_guideflags & FLG_OFG_ISSUED)
+		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_SUMMARY));
+
 	/*
 	 * For performance reasons we don't actually free up the memory we've
 	 * allocated, it will be freed when we exit.
--- a/usr/src/cmd/sgs/libld/common/libld.msg	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/libld.msg	Wed Aug 11 13:39:17 2010 -0600
@@ -154,12 +154,20 @@
 			 \t\t\tdependencies\n"
 @ MSG_ARG_DETAIL_ZE	"\t[-z endfiltee]\tmarks a filtee such that it will \
 			 terminate a filters\n\t\t\tsearch\n"
+@ MSG_ARG_DETAIL_ZFATW	"\t[-z fatal-warnings | nofatal-warnings],\n\
+			 \t[--fatal-warnings | --no-fatal-warnings]\n\
+			 \t\tenable|disable treatment of warnings as fatal\n"
 @ MSG_ARG_DETAIL_ZFA	"\t[-z finiarray=function]\n\
 			 \t\t\tname of function to be appended to the \
 			 .fini_array\n"
 @ MSG_ARG_DETAIL_ZGP	"\t[-z groupperm | nogroupperm]\n\
 			 \t\t\tenable|disable setting of group permissions\n\
 			 \t\t\ton dynamic dependencies\n"
+@ MSG_ARG_DETAIL_ZGUIDE	"\t[-z guidance | -z guidance=item1,item2,...]\n\
+			 \t\t\tenable guidance warnings. items: \
+			 noall, nodefs,\n\
+			 \t\t\tnodirect, nolazyload, nomapfile, notext, \
+			 nounused\n"
 @ MSG_ARG_DETAIL_ZH	"\t[-z help], [--help]\n\
 			 \t\t\tprint this usage message\n"
 @ MSG_ARG_DETAIL_ZIG	"\t[-z ignore | record]\n\
@@ -506,7 +514,7 @@
 			 initialization: start=0x%llx, length=0x%llx: \
 			 start=0x%llx, length=0x%llx"
 @ MSG_PSYM_EXPREASON1	"output file is static object"
-@ MSG_PSYM_EXPREASON2	"-znopartial option in effect"
+@ MSG_PSYM_EXPREASON2	"-z nopartial option in effect"
 @ MSG_PSYM_EXPREASON3	"move infrastructure size is greater than move data"
 
 #
@@ -672,6 +680,17 @@
 			 unsupported: %s"
 @ MSG_REJ_ARCHIVE	"file %s: invalid archive use"
 
+# Guidance messages
+@ MSG_GUIDE_SUMMARY	"see ld(1) -z guidance for more information"
+@ MSG_GUIDE_DEFS	"-z defs option recommended for shared objects"
+@ MSG_GUIDE_DIRECT	"-B direct or -z direct option recommended before \
+			 first dependency"
+@ MSG_GUIDE_LAZYLOAD	"-z lazyload option recommended before \
+			 first dependency"
+@ MSG_GUIDE_MAPFILE	"version 2 mapfile syntax recommended: %s"
+@ MSG_GUIDE_TEXT	"position independent (PIC) code recommended for \
+			 shared objects"
+@ MSG_GUIDE_UNUSED	"removal of unused dependency recommended: %s"
 
 @ _END_
 
@@ -899,6 +918,9 @@
 @ MSG_ARG_NOENTRY	"entry point symbol '%s' is undefined"
 @ MSG_ARG_UNSUPPORTED	"option %s is no longer supported; ignored"
 @ MSG_MARG_ONLY		"option %s can only be used with a %s"
+@ MSG_ARG_UNKNOWN	"unrecognized option '-%c'"
+@ MSG_ARG_USEHELP	"use the -z help option for usage information"
+
 
 @ MSG_ARG_FLAGS		"flags processing errors"
 @ MSG_ARG_FILES		"file processing errors. No output written to %s"
@@ -1312,6 +1334,7 @@
 @ MSG_ARG_CYU		"-YU"
 @ MSG_ARG_Z		"-z"
 @ MSG_ARG_ZDEFNODEF	"-z[defs|nodefs]"
+@ MSG_ARG_ZGUIDE	"-zguidance"
 @ MSG_ARG_ZNODEF	"-znodefs"
 @ MSG_ARG_ZNOINTERP	"-znointerp"
 @ MSG_ARG_ZRELAXRELOC	"-zrelaxreloc"
@@ -1323,6 +1346,7 @@
 @ MSG_ARG_ZLOADFLTR	"-zloadfltr"
 @ MSG_ARG_ZCOMBRELOC	"-zcombreloc"
 @ MSG_ARG_ZSYMBOLCAP	"-zsymbolcap"
+@ MSG_ARG_ZFATWNOFATW	"-z[fatal-warnings|nofatalwarnings]"
 
 @ MSG_ARG_ABSEXEC	"absexec"
 @ MSG_ARG_ALTEXEC64	"altexec64"
@@ -1361,7 +1385,7 @@
 @ MSG_ARG_REDLOCSYM	"redlocsym"
 @ MSG_ARG_VERBOSE	"verbose"
 @ MSG_ARG_WEAKEXT	"weakextract"
-@ MSG_ARG_LOADFLTR	"loadfltr""
+@ MSG_ARG_LOADFLTR	"loadfltr"
 @ MSG_ARG_ALLEXTRT	"allextract"
 @ MSG_ARG_DFLEXTRT	"defaultextract"
 @ MSG_ARG_COMBRELOC	"combreloc"
@@ -1374,6 +1398,7 @@
 @ MSG_ARG_RESCAN_NOW	"rescan-now"
 @ MSG_ARG_RESCAN_START	"rescan-start"
 @ MSG_ARG_RESCAN_END	"rescan-end"
+@ MSG_ARG_GUIDE		"guidance"
 @ MSG_ARG_NOLDYNSYM	"noldynsym"
 @ MSG_ARG_RELAXRELOC	"relaxreloc"
 @ MSG_ARG_NORELAXRELOC	"norelaxreloc"
@@ -1381,6 +1406,8 @@
 @ MSG_ARG_GLOBAUDIT	"globalaudit"
 @ MSG_ARG_TARGET	"target="
 @ MSG_ARG_WRAP		"wrap="
+@ MSG_ARG_FATWARN	"fatal-warnings"
+@ MSG_ARG_NOFATWARN	"nofatal-warnings"
 @ MSG_ARG_HELP		"help"
 @ MSG_ARG_GROUP		"group"
 @ MSG_ARG_REDUCE	"reduce"
@@ -1404,6 +1431,8 @@
 @ MSG_ARG_T_ENDGROUP	"-end-group"
 @ MSG_ARG_T_ENTRY	"-entry"
 @ MSG_ARG_T_STDFLTR	"-filter"
+@ MSG_ARG_T_FATWARN	"-fatal-warnings"
+@ MSG_ARG_T_NOFATWARN	"-no-fatal-warnings"
 @ MSG_ARG_T_HELP	"-help"
 @ MSG_ARG_T_LIBRARY	"-library"
 @ MSG_ARG_T_LIBPATH	"-library-path"
@@ -1420,6 +1449,16 @@
 @ MSG_ARG_T_OPAR	"("
 @ MSG_ARG_T_CPAR	")"
 
+# -z guidance=item strings
+@ MSG_ARG_GUIDE_DELIM		",: \t"
+@ MSG_ARG_GUIDE_NO_ALL		"noall"
+@ MSG_ARG_GUIDE_NO_DEFS		"nodefs"
+@ MSG_ARG_GUIDE_NO_DIRECT	"nodirect"
+@ MSG_ARG_GUIDE_NO_LAZYLOAD	"nolazyload"
+@ MSG_ARG_GUIDE_NO_MAPFILE	"nomapfile"
+@ MSG_ARG_GUIDE_NO_TEXT		"notext"
+@ MSG_ARG_GUIDE_NO_UNUSED	"nounused"
+
 # Environment variable strings
 
 @ MSG_LD_RUN_PATH	"LD_RUN_PATH"
--- a/usr/src/cmd/sgs/libld/common/libs.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/libs.c	Wed Aug 11 13:39:17 2010 -0600
@@ -81,9 +81,8 @@
 
 		while (scn = elf_nextscn(amp->am_elf, scn)) {
 			if ((shdr = elf_getshdr(scn)) == NULL) {
-				eprintf(ofl->ofl_lml, ERR_ELF,
+				ld_eprintf(ofl, ERR_ELF,
 				    MSG_INTL(MSG_ELF_GETSHDR), amp->am_path);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 				return (S_ERROR);
 			}
 			if ((shdr->sh_type == SHT_SYMTAB) ||
@@ -91,9 +90,8 @@
 				break;
 		}
 		if ((data = elf_getdata(scn, NULL)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETDATA), amp->am_path);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA),
+			    amp->am_path);
 			return (S_ERROR);
 		}
 		syms = (Sym *)data->d_buf;
@@ -106,15 +104,13 @@
 		 */
 		if ((scn = elf_getscn(amp->am_elf, (size_t)shdr->sh_link)) ==
 		    NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETSCN), amp->am_path);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
+			    amp->am_path);
 			return (S_ERROR);
 		}
 		if ((data = elf_getdata(scn, NULL)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETDATA), amp->am_path);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA),
+			    amp->am_path);
 			return (S_ERROR);
 		}
 		strs = data->d_buf;
@@ -200,14 +196,12 @@
 	if (ofl->ofl_flags1 & FLG_OF1_ALLEXRT) {
 		start = NULL;
 	} else  if ((start = elf_getarsym(elf, &number)) == NULL) {
-		if (elf_errno()) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETARSYM), name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		} else {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_ELF_ARSYM), name);
-		}
+		if (elf_errno())
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETARSYM),
+			    name);
+		else
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ELF_ARSYM),
+			    name);
 		return (0);
 	}
 
@@ -328,9 +322,7 @@
 	Elf_Arhdr	*arhdr;
 
 	if ((arhdr = elf_getarhdr(arelf)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETARHDR),
-		    name);
-		ofl->ofl_flags |= FLG_OF_FATAL;
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETARHDR), name);
 		return (NULL);
 	}
 	return (arhdr->ar_name);
@@ -588,19 +580,17 @@
 				 */
 				if (elf_rand(adp->ad_elf, arsym->as_off) !=
 				    arsym->as_off) {
-					eprintf(ofl->ofl_lml, ERR_ELF,
+					ld_eprintf(ofl, ERR_ELF,
 					    MSG_INTL(MSG_ELF_ARMEM), name,
 					    EC_WORD(arsym->as_off),
 					    demangle(arsym->as_name));
-					ofl->ofl_flags |= FLG_OF_FATAL;
 					return (FALSE);
 				}
 
 				if ((arelf = elf_begin(fd, ELF_C_READ,
 				    adp->ad_elf)) == NULL) {
-					eprintf(ofl->ofl_lml, ERR_ELF,
+					ld_eprintf(ofl, ERR_ELF,
 					    MSG_INTL(MSG_ELF_BEGIN), name);
-					ofl->ofl_flags |= FLG_OF_FATAL;
 					return (FALSE);
 				}
 
@@ -870,8 +860,7 @@
 	if ((found == 0) && rej.rej_type) {
 		Conv_reject_desc_buf_t rej_buf;
 
-		eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(reject[rej.rej_type]),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(reject[rej.rej_type]),
 		    rej.rej_name ? rej.rej_name : MSG_INTL(MSG_STR_UNKNOWN),
 		    conv_reject_desc(&rej, &rej_buf, ld_targ.t_m.m_mach));
 	}
--- a/usr/src/cmd/sgs/libld/common/machrel.amd.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/machrel.amd.c	Wed Aug 11 13:39:17 2010 -0600
@@ -236,7 +236,7 @@
 	if (do_reloc_ld(&rdesc_r_amd64_gotpcrel, &pltent[0x02], &val1,
 	    syn_rdesc_sym_name, MSG_ORIG(MSG_SPECFIL_PLTENT), bswap,
 	    ofl->ofl_lml) == 0) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL),
 		    sdp->sd_aux->sa_PLTndx, demangle(sdp->sd_name));
 		return (S_ERROR);
 	}
@@ -250,7 +250,7 @@
 	if (do_reloc_ld(&rdesc_r_amd64_32, &pltent[0x07], &val1,
 	    syn_rdesc_sym_name, MSG_ORIG(MSG_SPECFIL_PLTENT), bswap,
 	    ofl->ofl_lml) == 0) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL),
 		    sdp->sd_aux->sa_PLTndx, demangle(sdp->sd_name));
 		return (S_ERROR);
 	}
@@ -269,7 +269,7 @@
 	if (do_reloc_ld(&rdesc_r_amd64_pc32, &pltent[0x0c], &val1,
 	    syn_rdesc_sym_name, MSG_ORIG(MSG_SPECFIL_PLTENT), bswap,
 	    ofl->ofl_lml) == 0) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_PLT_PLTNFAIL),
 		    sdp->sd_aux->sa_PLTndx, demangle(sdp->sd_name));
 		return (S_ERROR);
 	}
@@ -278,7 +278,7 @@
 }
 
 static uintptr_t
-ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl)
+ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl, Boolean *remain_seen)
 {
 	Os_desc *	relosp, * osp = 0;
 	Word		ndx;
@@ -461,7 +461,7 @@
 	if (orsp->rel_rtype == R_AMD64_JUMP_SLOT)
 		osp = ofl->ofl_osgot;
 
-	ld_reloc_remain_entry(orsp, osp, ofl);
+	ld_reloc_remain_entry(orsp, osp, ofl, remain_seen);
 	return (1);
 }
 
@@ -975,8 +975,7 @@
 		if (arsp->rel_isdesc->is_indata->d_buf == 0) {
 			Conv_inv_buf_t inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_EMPTYSEC),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_EMPTYSEC),
 			    conv_reloc_amd64_type(arsp->rel_rtype, 0, &inv_buf),
 			    ifl_name, ld_reloc_sym_name(arsp),
 			    EC_WORD(arsp->rel_isdesc->is_scnndx),
@@ -1007,8 +1006,7 @@
 			else
 				class = ERR_WARNING;
 
-			eprintf(ofl->ofl_lml, class,
-			    MSG_INTL(MSG_REL_INVALOFFSET),
+			ld_eprintf(ofl, class, MSG_INTL(MSG_REL_INVALOFFSET),
 			    conv_reloc_amd64_type(arsp->rel_rtype, 0, &inv_buf),
 			    ifl_name, EC_WORD(arsp->rel_isdesc->is_scnndx),
 			    arsp->rel_isdesc->is_name, ld_reloc_sym_name(arsp),
@@ -1039,8 +1037,10 @@
 			 */
 			if (do_reloc_ld(arsp, addr, &value, ld_reloc_sym_name,
 			    ifl_name, OFL_SWAP_RELOC_DATA(ofl, arsp),
-			    ofl->ofl_lml) == 0)
+			    ofl->ofl_lml) == 0) {
+				ofl->ofl_flags |= FLG_OF_FATAL;
 				return_code = S_ERROR;
+			}
 		}
 	}
 	return (return_code);
@@ -1211,8 +1211,7 @@
 		 */
 		if (osp && (osp->os_shdr->sh_type == SHT_SUNW_ANNOTATE))
 			return (0);
-		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(MSG_REL_EXTERNSYM),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_EXTERNSYM),
 		    conv_reloc_amd64_type(rsp->rel_rtype, 0, &inv_buf),
 		    rsp->rel_isdesc->is_file->ifl_name,
 		    ld_reloc_sym_name(rsp), osp->os_name);
@@ -1446,8 +1445,7 @@
 		if (do_reloc_ld(&rdesc_r_amd64_gotpcrel, &pltent[0x02],
 		    &val1, syn_rdesc_sym_name, MSG_ORIG(MSG_SPECFIL_PLTENT),
 		    bswap, ofl->ofl_lml) == 0) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_PLT_PLT0FAIL));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_PLT_PLT0FAIL));
 			return (S_ERROR);
 		}
 
@@ -1462,8 +1460,7 @@
 		if (do_reloc_ld(&rdesc_r_amd64_gotpcrel, &pltent[0x08],
 		    &val1, syn_rdesc_sym_name, MSG_ORIG(MSG_SPECFIL_PLTENT),
 		    bswap, ofl->ofl_lml) == 0) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_PLT_PLT0FAIL));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_PLT_PLT0FAIL));
 			return (S_ERROR);
 		}
 	}
--- a/usr/src/cmd/sgs/libld/common/machrel.intel.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/machrel.intel.c	Wed Aug 11 13:39:17 2010 -0600
@@ -222,7 +222,7 @@
 }
 
 static uintptr_t
-ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl)
+ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl, Boolean *remain_seen)
 {
 	Os_desc *	relosp, * osp = 0;
 	Word		ndx, roffset, value;
@@ -380,7 +380,7 @@
 	if (orsp->rel_rtype == R_386_JMP_SLOT)
 		osp = ofl->ofl_osgot;
 
-	ld_reloc_remain_entry(orsp, osp, ofl);
+	ld_reloc_remain_entry(orsp, osp, ofl, remain_seen);
 	return (1);
 }
 
@@ -641,8 +641,7 @@
 		{
 			Conv_inv_buf_t	inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_BADTLSINS),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADTLSINS),
 			    conv_reloc_386_type(arsp->rel_rtype, 0, &inv_buf),
 			    arsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(arsp),
@@ -708,8 +707,7 @@
 		{
 			Conv_inv_buf_t	inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_BADTLSINS),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADTLSINS),
 			    conv_reloc_386_type(arsp->rel_rtype, 0, &inv_buf),
 			    arsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(arsp),
@@ -1028,8 +1026,7 @@
 		if (arsp->rel_isdesc->is_indata->d_buf == 0) {
 			Conv_inv_buf_t	inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_EMPTYSEC),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_EMPTYSEC),
 			    conv_reloc_386_type(arsp->rel_rtype, 0, &inv_buf),
 			    ifl_name, ld_reloc_sym_name(arsp),
 			    EC_WORD(arsp->rel_isdesc->is_scnndx),
@@ -1060,8 +1057,7 @@
 			else
 				class = ERR_WARNING;
 
-			eprintf(ofl->ofl_lml, class,
-			    MSG_INTL(MSG_REL_INVALOFFSET),
+			ld_eprintf(ofl, class, MSG_INTL(MSG_REL_INVALOFFSET),
 			    conv_reloc_386_type(arsp->rel_rtype, 0, &inv_buf),
 			    ifl_name, EC_WORD(arsp->rel_isdesc->is_scnndx),
 			    arsp->rel_isdesc->is_name, ld_reloc_sym_name(arsp),
@@ -1098,8 +1094,10 @@
 		if (OFL_DO_RELOC(ofl)) {
 			if (do_reloc_ld(arsp, addr, &value, ld_reloc_sym_name,
 			    ifl_name, OFL_SWAP_RELOC_DATA(ofl, arsp),
-			    ofl->ofl_lml) == 0)
+			    ofl->ofl_lml) == 0) {
+				ofl->ofl_flags |= FLG_OF_FATAL;
 				return_code = S_ERROR;
+			}
 		}
 	}
 	return (return_code);
@@ -1263,7 +1261,7 @@
 		 */
 		if (osp && (osp->os_shdr->sh_type == SHT_SUNW_ANNOTATE))
 			return (0);
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_EXTERNSYM),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_EXTERNSYM),
 		    conv_reloc_386_type(rsp->rel_rtype, 0, &inv_buf),
 		    rsp->rel_isdesc->is_file->ifl_name,
 		    ld_reloc_sym_name(rsp), osp->os_name);
--- a/usr/src/cmd/sgs/libld/common/machrel.sparc.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/machrel.sparc.c	Wed Aug 11 13:39:17 2010 -0600
@@ -581,7 +581,7 @@
 #endif /* _ELF64 */
 
 static uintptr_t
-ld_perform_outreloc(Rel_desc *orsp, Ofl_desc *ofl)
+ld_perform_outreloc(Rel_desc *orsp, Ofl_desc *ofl, Boolean *remain_seen)
 {
 	Os_desc		*relosp, *osp = NULL;
 	Xword		ndx, roffset, value;
@@ -732,8 +732,7 @@
 		    ((rep->re_fsize == 8) && (roffset & 0x7))) {
 			Conv_inv_buf_t inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_NONALIGN),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NONALIGN),
 			    conv_reloc_SPARC_type(orsp->rel_rtype, 0, &inv_buf),
 			    orsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(orsp), EC_XWORD(roffset));
@@ -802,7 +801,7 @@
 	 * Determine if this relocation is against a non-writable, allocatable
 	 * section.  If so we may need to provide a text relocation diagnostic.
 	 */
-	ld_reloc_remain_entry(orsp, osp, ofl);
+	ld_reloc_remain_entry(orsp, osp, ofl, remain_seen);
 	return (1);
 }
 
@@ -1036,7 +1035,7 @@
 	else
 		ifl_name = MSG_INTL(MSG_STR_NULL);
 
-	eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTFIX),
+	ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTFIX),
 	    conv_reloc_SPARC_type(arsp->rel_rtype, 0, &inv_buf),
 	    ifl_name, ld_reloc_sym_name(arsp));
 
@@ -1336,8 +1335,7 @@
 		if (arsp->rel_isdesc->is_indata->d_buf == 0) {
 			Conv_inv_buf_t	inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_EMPTYSEC),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_EMPTYSEC),
 			    conv_reloc_SPARC_type(arsp->rel_rtype, 0, &inv_buf),
 			    ifl_name, ld_reloc_sym_name(arsp),
 			    EC_WORD(arsp->rel_isdesc->is_scnndx),
@@ -1368,8 +1366,7 @@
 			else
 				class = ERR_WARNING;
 
-			eprintf(ofl->ofl_lml, class,
-			    MSG_INTL(MSG_REL_INVALOFFSET),
+			ld_eprintf(ofl, class, MSG_INTL(MSG_REL_INVALOFFSET),
 			    conv_reloc_SPARC_type(arsp->rel_rtype, 0, &inv_buf),
 			    ifl_name, EC_WORD(arsp->rel_isdesc->is_scnndx),
 			    arsp->rel_isdesc->is_name, ld_reloc_sym_name(arsp),
@@ -1388,8 +1385,10 @@
 		if (OFL_DO_RELOC(ofl)) {
 			if (do_reloc_ld(arsp, addr, &value, ld_reloc_sym_name,
 			    ifl_name, OFL_SWAP_RELOC_DATA(ofl, arsp),
-			    ofl->ofl_lml) == 0)
+			    ofl->ofl_lml) == 0) {
+				ofl->ofl_flags |= FLG_OF_FATAL;
 				return_code = S_ERROR;
+			}
 		}
 	}
 	return (return_code);
@@ -1424,8 +1423,7 @@
 		 * object - so emit the proper error message if that occurs.
 		 */
 		if ((rtype == R_SPARC_HIPLT22) || (rtype == R_SPARC_LOPLT10)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_UNRELREL),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNRELREL),
 			    conv_reloc_SPARC_type(rsp->rel_rtype, 0, &inv_buf),
 			    rsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(rsp));
@@ -1441,8 +1439,7 @@
 		 */
 		if ((rtype == R_SPARC_H44) || (rtype == R_SPARC_M44) ||
 		    (rtype == R_SPARC_L44)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_SHOBJABS44),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_SHOBJABS44),
 			    conv_reloc_SPARC_type(rsp->rel_rtype, 0, &inv_buf),
 			    rsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(rsp));
@@ -1652,8 +1649,7 @@
 		 */
 		if (osp && (osp->os_shdr->sh_type == SHT_SUNW_ANNOTATE))
 			return (0);
-		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(MSG_REL_EXTERNSYM),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_EXTERNSYM),
 		    conv_reloc_SPARC_type(rsp->rel_rtype, 0, &inv_buf),
 		    rsp->rel_isdesc->is_file->ifl_name,
 		    ld_reloc_sym_name(rsp), osp->os_name);
@@ -1885,8 +1881,7 @@
 			large_index += gotents;
 			break;
 		default:
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_ASSIGNGOT),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_ASSIGNGOT),
 			    EC_XWORD(gnp->gn_gotndx), demangle(sdp->sd_name));
 			return (S_ERROR);
 		}
@@ -2023,12 +2018,12 @@
 	 *		(M_GOT_MAXSMALL/2 - M_GOT_XNumber) mixed mode indices.
 	 */
 	if (smlgotcnt > M_GOT_MAXSMALL) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_SMALLGOT),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_SMALLGOT),
 		    EC_WORD(smlgotcnt), M_GOT_MAXSMALL);
 		return (S_ERROR);
 	}
 	if (mixgotcnt > (first_large_ndx - M_GOT_XNumber)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_MIXEDGOT),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_MIXEDGOT),
 		    EC_WORD(mixgotcnt), first_large_ndx - M_GOT_XNumber);
 		return (S_ERROR);
 	}
--- a/usr/src/cmd/sgs/libld/common/machsym.sparc.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/machsym.sparc.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 #define	ELF_TARGET_SPARC
 
@@ -76,12 +75,11 @@
 	    (ELF_ST_BIND(nsym->st_info) == STB_LOCAL)) {
 		if (osym->st_value == nsym->st_value) {
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_SYM_INCOMPREG3),
 			    conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1),
 			    sdp->sd_file->ifl_name, demangle(oname),
 			    ifl->ifl_name, demangle(nname));
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (1);
 		}
 		return (0);
@@ -94,12 +92,10 @@
 		 */
 		if (((osym->st_name == 0) || (nsym->st_name == 0)) ||
 		    (strcmp(oname, nname) != 0)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_INCOMPREG1),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG1),
 			    conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1),
 			    sdp->sd_file->ifl_name, demangle(oname),
 			    ifl->ifl_name, demangle(nname));
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (1);
 		}
 
@@ -108,22 +104,19 @@
 		 */
 		if ((osym->st_shndx == SHN_ABS) &&
 		    (nsym->st_shndx == SHN_ABS)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_MULTINIREG),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULTINIREG),
 			    conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1),
 			    demangle(nname), sdp->sd_file->ifl_name,
 			    ifl->ifl_name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (1);
 		}
 
 	} else if (strcmp(oname, nname) == 0) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG2),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_INCOMPREG2),
 		    demangle(sdp->sd_name), sdp->sd_file->ifl_name,
 		    conv_sym_SPARC_value(osym->st_value, 0, &inv_buf1),
 		    ifl->ifl_name,
 		    conv_sym_SPARC_value(nsym->st_value, 0, &inv_buf2));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (1);
 	}
 	return (0);
@@ -141,16 +134,14 @@
 	if (otype != ntype) {
 		if ((otype == STT_SPARC_REGISTER) ||
 		    (ntype == STT_SPARC_REGISTER)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name));
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_FILETYPES),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_DIFFTYPE),
+			    demangle(sdp->sd_name));
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
 			    sdp->sd_file->ifl_name, conv_sym_info_type(
 			    sdp->sd_file->ifl_ehdr->e_machine, otype,
 			    0, &inv_buf1), ifl->ifl_name,
 			    conv_sym_info_type(ifl->ifl_ehdr->e_machine,
 			    ntype, 0, &inv_buf2));
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			return (1);
 		}
 	} else if (otype == STT_SPARC_REGISTER)
@@ -183,7 +174,7 @@
 	 */
 	if ((sym->st_value < STO_SPARC_REGISTER_G1) ||
 	    (sym->st_value > STO_SPARC_REGISTER_G7)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG),
 		    ifl->ifl_name, symsecname, symndx, EC_XWORD(sym->st_value));
 		return ((const char *)S_ERROR);
 	}
@@ -192,7 +183,7 @@
 	 * A register symbol can only be undefined or defined (absolute).
 	 */
 	if ((shndx != SHN_ABS) && (shndx != SHN_UNDEF)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_BADREG),
 		    ifl->ifl_name, symsecname, symndx, EC_XWORD(sym->st_value));
 		return ((const char *)S_ERROR);
 	}
@@ -208,8 +199,7 @@
 		    (shndx != SHN_UNDEF)) {
 			Conv_inv_buf_t inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_BADSCRATCH),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_BADSCRATCH),
 			    ifl->ifl_name, symsecname, symndx,
 			    conv_sym_SPARC_value(sym->st_value, 0, &inv_buf));
 			return ((const char *)S_ERROR);
--- a/usr/src/cmd/sgs/libld/common/map_core.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/map_core.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -2280,8 +2279,8 @@
 	 */
 	if (stat(mapfile, &stat_buf) == -1) {
 		err = errno;
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_STAT),
-		    mapfile, strerror(err));
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_STAT), mapfile,
+		    strerror(err));
 		return (FALSE);
 	}
 	if (S_ISDIR(stat_buf.st_mode)) {
@@ -2312,16 +2311,15 @@
 		(void) closedir(dirp);
 		return (TRUE);
 	} else if (!S_ISREG(stat_buf.st_mode)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_NOTREG),
-		    mapfile);
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_NOTREG), mapfile);
 		return (FALSE);
 	}
 
 	/* Open file */
 	if ((mapfile_fd = open(mapfile, O_RDONLY)) == -1) {
 		err = errno;
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN),
-		    mapfile, strerror(err));
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), mapfile,
+		    strerror(err));
 		return (FALSE);
 	}
 
@@ -2341,8 +2339,8 @@
 	if (read(mapfile_fd, mf->mf_text, stat_buf.st_size) !=
 	    stat_buf.st_size) {
 		err = errno;
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_READ),
-		    mapfile, strerror(err));
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_READ), mapfile,
+		    strerror(err));
 		(void) close(mapfile_fd);
 		return (FALSE);
 	}
@@ -2371,6 +2369,11 @@
 
 	switch (mf->mf_version) {
 	case MFV_SYSV:
+		/* Guidance: Use newer mapfile syntax */
+		if (OFL_GUIDANCE(ofl, FLG_OFG_NO_MF))
+			ld_eprintf(ofl, ERR_GUIDANCE,
+			    MSG_INTL(MSG_GUIDE_MAPFILE), mapfile);
+
 		mf->mf_tokdisp = gettok_dispatch_v1;
 		if (!ld_map_parse_v1(mf))
 			return (FALSE);
@@ -2522,7 +2525,7 @@
 				    (sgp1->sg_flags & FLG_SG_EMPTY))) {
 					if (sgp1->sg_phdr.p_vaddr ==
 					    sgp2->sg_phdr.p_vaddr) {
-						eprintf(ofl->ofl_lml, ERR_FATAL,
+						ld_eprintf(ofl, ERR_FATAL,
 						    MSG_INTL(MSG_MAP_SEGSAME),
 						    sgp1->sg_name,
 						    sgp2->sg_name);
@@ -2800,7 +2803,7 @@
 		    (first_seg->sg_phdr.p_type != PT_LOAD)) {
 			Conv_inv_buf_t	inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_SEG_FIRNOTLOAD),
 			    conv_phdr_type(ELFOSABI_SOLARIS, ld_targ.t_m.m_mach,
 			    first_seg->sg_phdr.p_type, 0, &inv_buf),
--- a/usr/src/cmd/sgs/libld/common/mapfile-vers	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/mapfile-vers	Wed Aug 11 13:39:17 2010 -0600
@@ -87,4 +87,8 @@
 			TYPE = FUNCTION;
 			FLAGS = extern;
 		};
+		veprintf {
+			TYPE = FUNCTION;
+			FLAGS = extern;
+		};
 };
--- a/usr/src/cmd/sgs/libld/common/order.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/order.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -356,10 +355,10 @@
 
 		isp2 = ifl->ifl_isdesc[keyshndx];
 		if (isp2->is_flags & FLG_IS_DISCARD) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_FIL_BADORDREF), ifl->ifl_name,
-			    EC_WORD(isp->is_scnndx), isp->is_name,
-			    EC_WORD(isp2->is_scnndx), isp2->is_name);
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_BADORDREF),
+			    ifl->ifl_name, EC_WORD(isp->is_scnndx),
+			    isp->is_name, EC_WORD(isp2->is_scnndx),
+			    isp2->is_name);
 			return (S_ERROR);
 		}
 
@@ -400,7 +399,7 @@
 
 		for (ALIST_TRAVERSE(sgp->sg_os_order, idx2, scop)) {
 			if ((scop->sco_flags & FLG_SGO_USED) == 0) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_MAP_SECORDER),
 				    sgp->sg_name, scop->sco_secname);
 			}
--- a/usr/src/cmd/sgs/libld/common/outfile.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/outfile.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -127,7 +126,7 @@
 				int	err = errno;
 
 				if (err != ENOENT) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_SYS_OPEN),
 					    ofl->ofl_name, strerror(err));
 					return (S_ERROR);
@@ -140,7 +139,7 @@
 			    (errno != ENOENT)) {
 				int err = errno;
 
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_SYS_UNLINK),
 				    ofl->ofl_name, strerror(err));
 				return (S_ERROR);
@@ -157,7 +156,7 @@
 	    mode)) < 0) {
 		int	err = errno;
 
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN),
 		    ofl->ofl_name, strerror(err));
 		return (S_ERROR);
 	}
@@ -194,12 +193,12 @@
 	 * section headers and data buffers as they relate to the new image.
 	 */
 	if (elf_update(ofl->ofl_welf, ELF_C_NULL) == -1) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_UPDATE),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_UPDATE),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
 	if ((ehdr = elf_getehdr(ofl->ofl_welf)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETEHDR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETEHDR),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
@@ -233,7 +232,7 @@
 			    offset);
 
 			if ((data = elf_newdata(oscn)) == NULL) {
-				eprintf(ofl->ofl_lml, ERR_ELF,
+				ld_eprintf(ofl, ERR_ELF,
 				    MSG_INTL(MSG_ELF_NEWDATA), ofl->ofl_name);
 				return (S_ERROR);
 			}
@@ -293,7 +292,7 @@
 	 * Get a section descriptor for the section.
 	 */
 	if ((scn = elf_newscn(ofl->ofl_welf)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_NEWSCN),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_NEWSCN),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
@@ -304,7 +303,7 @@
 	 * information from the in-core descriptor.
 	 */
 	if ((shdr = elf_getshdr(scn)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
@@ -408,7 +407,7 @@
 	 * Tell the access library about our new temporary file.
 	 */
 	if ((ofl->ofl_welf = elf_begin(fd, cmd, 0)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_BEGIN),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_BEGIN),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
@@ -417,7 +416,7 @@
 	 * Obtain a new Elf header.
 	 */
 	if ((ofl->ofl_nehdr = elf_newehdr(ofl->ofl_welf)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_NEWEHDR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_NEWEHDR),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
@@ -598,7 +597,7 @@
 				 * the old data.
 				 */
 				if ((data = elf_newdata(osp->os_scn)) == NULL) {
-					eprintf(ofl->ofl_lml, ERR_ELF,
+					ld_eprintf(ofl, ERR_ELF,
 					    MSG_INTL(MSG_ELF_NEWDATA),
 					    ofl->ofl_name);
 					return (S_ERROR);
@@ -697,8 +696,8 @@
 	if (nseg) {
 		if ((ofl->ofl_phdr = elf_newphdr(ofl->ofl_welf,
 		    nseg)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_NEWPHDR), ofl->ofl_name);
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_NEWPHDR),
+			    ofl->ofl_name);
 			return (S_ERROR);
 		}
 	}
@@ -733,7 +732,7 @@
 	 */
 	if ((ofl->ofl_size = (size_t)elf_update(ofl->ofl_welf,
 	    ELF_C_WRIMAGE)) == (size_t)-1) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_UPDATE),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_UPDATE),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
@@ -747,19 +746,19 @@
 	 */
 	if ((ofl->ofl_elf = elf_begin(0, ELF_C_IMAGE,
 	    ofl->ofl_welf)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_BEGIN),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_BEGIN),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
 	if ((ofl->ofl_nehdr = elf_getehdr(ofl->ofl_elf)) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_ELF, MSG_INTL(MSG_ELF_GETEHDR),
+		ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETEHDR),
 		    ofl->ofl_name);
 		return (S_ERROR);
 	}
 	if (!(flags & FLG_OF_RELOBJ))
 		if ((ofl->ofl_phdr = elf_getphdr(ofl->ofl_elf)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETPHDR), ofl->ofl_name);
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETPHDR),
+			    ofl->ofl_name);
 			return (S_ERROR);
 		}
 
@@ -790,14 +789,14 @@
 			}
 			if ((osp->os_scn =
 			    elf_getscn(ofl->ofl_elf, ++ndx)) == NULL) {
-				eprintf(ofl->ofl_lml, ERR_ELF,
+				ld_eprintf(ofl, ERR_ELF,
 				    MSG_INTL(MSG_ELF_GETSCN), ofl->ofl_name,
 				    ndx);
 				return (S_ERROR);
 			}
 			if ((osp->os_shdr =
 			    elf_getshdr(osp->os_scn)) == NULL) {
-				eprintf(ofl->ofl_lml, ERR_ELF,
+				ld_eprintf(ofl, ERR_ELF,
 				    MSG_INTL(MSG_ELF_GETSHDR), ofl->ofl_name);
 				return (S_ERROR);
 			}
@@ -808,7 +807,7 @@
 
 				scn = sgp->sg_fscn;
 				if ((fndx = elf_ndxscn(scn)) == SHN_UNDEF) {
-					eprintf(ofl->ofl_lml, ERR_ELF,
+					ld_eprintf(ofl, ERR_ELF,
 					    MSG_INTL(MSG_ELF_NDXSCN),
 					    ofl->ofl_name);
 					return (S_ERROR);
@@ -821,7 +820,7 @@
 
 			if ((osp->os_outdata =
 			    elf_getdata(osp->os_scn, NULL)) == NULL) {
-				eprintf(ofl->ofl_lml, ERR_ELF,
+				ld_eprintf(ofl, ERR_ELF,
 				    MSG_INTL(MSG_ELF_GETDATA), ofl->ofl_name);
 				return (S_ERROR);
 			}
--- a/usr/src/cmd/sgs/libld/common/place.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/place.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -617,13 +616,12 @@
 					continue;
 
 				isp1 = lst->apl_data[0];
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_UPD_MULEHFRAME),
 				    isp1->is_file->ifl_name,
 				    EC_WORD(isp1->is_scnndx), isp1->is_name,
 				    isp->is_file->ifl_name,
 				    EC_WORD(isp->is_scnndx), isp->is_name);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 				return;
 			}
 		}
@@ -1208,7 +1206,7 @@
 	 */
 	if ((sgp->sg_phdr.p_type == PT_LOAD) &&
 	    ((osp->os_shdr->sh_flags & SHF_ALLOC) == 0)) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SCN_NONALLOC),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SCN_NONALLOC),
 		    ofl->ofl_name, osp->os_name, sgp->sg_name);
 		osp->os_shdr->sh_flags |= SHF_ALLOC;
 	}
--- a/usr/src/cmd/sgs/libld/common/relocate.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/relocate.c	Wed Aug 11 13:39:17 2010 -0600
@@ -104,7 +104,7 @@
 	 */
 	if ((ifl->ifl_flags & FLG_IF_DISPDONE) &&
 	    (ofl->ofl_flags & FLG_OF_VERBOSE))
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 		    ld_targ.t_m.m_r_copy, 0, &inv_buf),
 		    ifl->ifl_name, demangle(sdp->sd_name));
@@ -161,8 +161,8 @@
 					(void) strcpy(_str, str);
 					str = (const char *)_str;
 				}
-				eprintf(ofl->ofl_lml,
-				    ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
+				ld_eprintf(ofl, ERR_WARNING,
+				    MSG_INTL(MSG_REL_DISPREL1),
 				    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 				    (uint_t)ELF_R_TYPE(reloc->r_info,
 				    ld_targ.t_m.m_mach),
@@ -191,8 +191,7 @@
 				(void) strcpy(_str, str);
 				str = (const char *)_str;
 			}
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_REL_DISPREL1),
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 			    (uint_t)ELF_R_TYPE(reloc->r_info,
 			    ld_targ.t_m.m_mach), 0, &inv_buf),
@@ -346,7 +345,7 @@
 	else
 		str = MSG_INTL(MSG_STR_UNKNOWN);
 
-	eprintf(ofl->ofl_lml, ERR_WARNING, msg,
+	ld_eprintf(ofl, ERR_WARNING, msg,
 	    conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
 	    0, &inv_buf), ifl->ifl_name, ld_reloc_sym_name(rsp), str,
 	    EC_OFF(rsp->rel_roffset));
@@ -1079,7 +1078,7 @@
 	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) {
 		Conv_inv_buf_t inv_buf;
 
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM),
 		    conv_sym_info_type(sdp->sd_file->ifl_ehdr->e_machine,
 		    ELF_ST_TYPE(sym->st_info), 0, &inv_buf),
 		    rsp->rel_isdesc->is_file->ifl_name,
@@ -1272,8 +1271,7 @@
 		if (_sdp->sd_flags & FLG_SY_PROT) {
 			Conv_inv_buf_t inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_REL_COPY),
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_COPY),
 			    conv_reloc_type(_sdp->sd_file->ifl_ehdr->e_machine,
 			    ld_targ.t_m.m_r_copy, 0, &inv_buf),
 			    _sdp->sd_file->ifl_name, _sdp->sd_name);
@@ -1295,7 +1293,7 @@
 	Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
 	Conv_inv_buf_t	inv_buf;
 
-	eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL),
+	ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL),
 	    conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
 	    0, &inv_buf), ifl->ifl_name, ld_reloc_sym_name(rsp));
 
@@ -1354,8 +1352,7 @@
 			Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
 			Conv_inv_buf_t inv_buf;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_PICREDLOC),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_PICREDLOC),
 			    ld_reloc_sym_name(rsp), ifl->ifl_name,
 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 			    rsp->rel_rtype, 0, &inv_buf));
@@ -1411,7 +1408,7 @@
 	 * All TLS relocations are illegal in a static executable.
 	 */
 	if (OFL_IS_STATIC_EXEC(ofl)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
 		    conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
 		    ld_reloc_sym_name(rsp));
 		return (S_ERROR);
@@ -1422,7 +1419,7 @@
 	 * are illegal.
 	 */
 	if ((type = ELF_ST_TYPE(sdp->sd_sym->st_info)) != STT_TLS) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
 		    conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
 		    ld_reloc_sym_name(rsp),
 		    conv_sym_info_type(mach, type, 0, &inv_buf2));
@@ -1436,7 +1433,7 @@
 	 */
 	if (!local && (IS_TLS_LD(rtype) ||
 	    ((flags & FLG_OF_EXEC) && IS_TLS_LE(rtype)))) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
 		    conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
 		    ld_reloc_sym_name(rsp), sdp->sd_file->ifl_name);
 		return (S_ERROR);
@@ -1457,16 +1454,14 @@
 	 */
 	if ((flags & FLG_OF_EXEC) == 0) {
 		if (IS_TLS_LE(rtype)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_TLSLE),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSLE),
 			    conv_reloc_type(mach, rtype, 0, &inv_buf1),
 			    ifl->ifl_name, ld_reloc_sym_name(rsp));
 			return (S_ERROR);
 
 		} else if ((IS_TLS_IE(rtype)) &&
 		    (flags & FLG_OF_VERBOSE)) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_REL_TLSIE),
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_TLSIE),
 			    conv_reloc_type(mach, rtype, 0, &inv_buf1),
 			    ifl->ifl_name, ld_reloc_sym_name(rsp));
 		}
@@ -1613,7 +1608,7 @@
 	    IS_GOT_BASED(rtype)) {
 		Ifl_desc	*ifl = reld->rel_isdesc->is_file;
 
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
 		    0, &inv_buf), ifl->ifl_name, demangle(sdp->sd_name));
 		return (S_ERROR);
@@ -1631,8 +1626,7 @@
 		if (RELAUX_GET_OSDESC(reld)->os_shdr->sh_flags & SHF_ALLOC) {
 			Ifl_desc	*ifl = reld->rel_isdesc->is_file;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_BADTLS),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 			    rtype, 0, &inv_buf), ifl->ifl_name,
 			    demangle(sdp->sd_name));
@@ -1645,8 +1639,7 @@
 	 */
 	if (IS_REGISTER(rtype)) {
 		if (ld_targ.t_mr.mr_reloc_register == NULL) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_NOREG));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOREG));
 			return (S_ERROR);
 		}
 		return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
@@ -1853,7 +1846,7 @@
 
 		if (ofl->ofl_flags & FLG_OF_VERBOSE) {
 			if (sym->st_name != 0) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_REL_SLOPCDATNAM),
 				    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 				    reld->rel_rtype, 0, &inv_buf),
@@ -1864,7 +1857,7 @@
 				    EC_WORD(isp->is_scnndx), isp->is_name,
 				    rep_sdp->sd_file->ifl_name);
 			} else {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_REL_SLOPCDATNONAM),
 				    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 				    reld->rel_rtype, 0, &inv_buf),
@@ -1901,7 +1894,7 @@
 	 * Make sure the relocation is in the valid range.
 	 */
 	if (rtype >= ld_targ.t_m.m_r_num) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT),
 		    ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name,
 		    rtype);
 		return (S_ERROR);
@@ -1921,8 +1914,7 @@
 		    (void *)reloc, isp->is_name, isp->is_scnndx,
 		    ld_reloc_sym_name(reld)));
 		if (ld_targ.t_mr.mr_reloc_register == NULL) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_NOREG));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOREG));
 			return (S_ERROR);
 		}
 		return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
@@ -1957,14 +1949,14 @@
 		    ld_targ.t_m.m_mach, ld_targ.t_m.m_rel_sht_type,
 		    (void *)reloc, isp->is_name, isp->is_scnndx,
 		    ld_reloc_sym_name(reld)));
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_NULL),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_NULL),
 		    ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name);
 		return (1);
 	}
 
 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
 	    IS_NOTSUP(rtype)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
 		    0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
 		    isp->is_name);
@@ -1976,7 +1968,7 @@
 	 * symbol. If no symbol is assigned, this is a fatal error.
 	 */
 	if (sdp == NULL) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
 		    0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
 		    isp->is_name, EC_XWORD(reloc->r_offset));
@@ -2028,7 +2020,7 @@
 				if (((ofl->ofl_flags & FLG_OF_VERBOSE) != 0) ||
 				    ((is_shdr->sh_flags & SHF_ALLOC) &&
 				    (reject != RLXREL_REJ_TARGET)))
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    MSG_INTL(MSG_REL_SLOPCDATNOSYM),
 					    conv_reloc_type(
 					    ifl->ifl_ehdr->e_machine,
@@ -2045,8 +2037,7 @@
 			nsdp = ld_sym_find(sdp->sd_name, SYM_NOHASH, NULL, ofl);
 
 		if (nsdp == NULL) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_SYMDISC),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_SYMDISC),
 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
 			    reld->rel_rtype, 0, &inv_buf), ifl->ifl_name,
 			    EC_WORD(isp->is_scnndx), isp->is_name,
@@ -2084,7 +2075,7 @@
 	 */
 	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),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_RELINVSEC),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
 		    0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
 		    isp->is_name, EC_WORD(sdp->sd_isc->is_scnndx),
@@ -2100,7 +2091,7 @@
 	 */
 	if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) ||
 	    (rsndx >= ifl->ifl_symscnt)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
 		    0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
 		    isp->is_name, ld_reloc_sym_name(reld),
@@ -2116,7 +2107,7 @@
 	 */
 	if (IS_SIZE(rtype) &&
 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSIZE),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSIZE),
 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
 		    0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
 		    isp->is_name);
@@ -2575,6 +2566,7 @@
 	Word		index = 0;
 	int		debug = 0;
 	uintptr_t	error = 1;
+	Boolean		remain_seen = FALSE;
 
 	if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) *
 	    ofl->ofl_reloccnt))) == NULL)
@@ -2604,8 +2596,8 @@
 		 * order that it was originally processed.
 		 */
 		if (orsp->rel_flags & FLG_REL_PLT) {
-			if ((*ld_targ.t_mr.mr_perform_outreloc)(orsp, ofl) ==
-			    S_ERROR)
+			if ((*ld_targ.t_mr.mr_perform_outreloc)
+			    (orsp, ofl, &remain_seen) == S_ERROR)
 				error = S_ERROR;
 			continue;
 		}
@@ -2649,10 +2641,14 @@
 	 */
 	for (index = 0; index < ofl->ofl_reloccnt; index++) {
 		if ((*ld_targ.t_mr.mr_perform_outreloc)
-		    (sorted_list[index].rl_rsp, ofl) == S_ERROR)
+		    (sorted_list[index].rl_rsp, ofl, &remain_seen) == S_ERROR)
 			error = S_ERROR;
 	}
 
+	/* Guidance: Use -z text when building shared objects */
+	if (remain_seen && OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
+		ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_TEXT));
+
 	return (error);
 }
 
@@ -2761,7 +2757,7 @@
 	 */
 	if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) ==
 	    (FLG_OF_PURETXT | FLG_OF_TEXTREL)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3));
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3));
 		return (S_ERROR);
 	}
 
@@ -2803,25 +2799,10 @@
  * anything to fix the error - thus we've chosen not to give the user an error,
  * or warning, for this case.
  */
-static void
-reloc_remain_title(Ofl_desc *ofl, int warning)
+void
+ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl,
+    Boolean *remain_seen)
 {
-	const char	*str1;
-
-	if (warning)
-		str1 = MSG_INTL(MSG_REL_RMN_ITM_13);
-	else
-		str1 = MSG_INTL(MSG_REL_RMN_ITM_11);
-
-	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), str1,
-	    MSG_INTL(MSG_REL_RMN_ITM_31), MSG_INTL(MSG_REL_RMN_ITM_12),
-	    MSG_INTL(MSG_REL_RMN_ITM_2), MSG_INTL(MSG_REL_RMN_ITM_32));
-}
-
-void
-ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl)
-{
-	static Boolean	reloc_title = TRUE;
 
 	/*
 	 * -ztextoff
@@ -2847,19 +2828,22 @@
 	    (orsp->rel_sym->sd_sym->st_shndx == SHN_UNDEF))
 		return;
 
-	if (reloc_title) {
+	if (*remain_seen == FALSE) {
 		/*
 		 * If building with '-ztext' then emit a fatal error.  If
 		 * building a executable then only emit a 'warning'.
 		 */
-		if (ofl->ofl_flags & FLG_OF_PURETXT)
-			reloc_remain_title(ofl, 0);
-		else
-			reloc_remain_title(ofl, 1);
-		reloc_title = FALSE;
+		const char *str1 = (ofl->ofl_flags & FLG_OF_PURETXT) ?
+		    MSG_INTL(MSG_REL_RMN_ITM_11) : MSG_INTL(MSG_REL_RMN_ITM_13);
+
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), str1,
+		    MSG_INTL(MSG_REL_RMN_ITM_31), MSG_INTL(MSG_REL_RMN_ITM_12),
+		    MSG_INTL(MSG_REL_RMN_ITM_2), MSG_INTL(MSG_REL_RMN_ITM_32));
+
+		*remain_seen = TRUE;
 	}
 
-	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2),
+	ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2),
 	    ld_reloc_sym_name(orsp), EC_OFF(orsp->rel_roffset),
 	    orsp->rel_isdesc->is_file->ifl_name);
 }
@@ -3090,8 +3074,7 @@
 	default:
 		{
 			Conv_inv_buf_t inv_buf;
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_UNSUPSZ),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ),
 			    conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
 			    0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(rsp), (int)rep->re_fsize);
@@ -3154,8 +3137,7 @@
 	default:
 		{
 			Conv_inv_buf_t inv_buf;
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_REL_UNSUPSZ),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ),
 			    conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
 			    0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
 			    ld_reloc_sym_name(rsp), (int)rep->re_fsize);
--- a/usr/src/cmd/sgs/libld/common/resolve.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/resolve.c	Wed Aug 11 13:39:17 2010 -0600
@@ -23,8 +23,7 @@
  *	Copyright (c) 1988 AT&T
  *	  All Rights Reserved
  *
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -68,16 +67,13 @@
 	if (!(ofl->ofl_flags & FLG_OF_VERBOSE) && (err != ERR_FATAL))
 		return;
 
-	eprintf(ofl->ofl_lml, err, MSG_INTL(MSG_SYM_CONFVIS),
-	    demangle(sdp->sd_name));
-	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES),
+	ld_eprintf(ofl, err, MSG_INTL(MSG_SYM_CONFVIS), demangle(sdp->sd_name));
+	ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_VISTYPES),
 	    sdp->sd_file->ifl_name, conv_sym_other(osym->st_other, &inv_obuf),
 	    ifl->ifl_name, conv_sym_other(nsym->st_other, &inv_nbuf));
 
-	if (err == ERR_FATAL)
-		ofl->ofl_flags |= FLG_OF_FATAL;
-	else
-		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+	if (err != ERR_FATAL)
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
 		    ifl->ifl_name);
 }
 
@@ -290,9 +286,9 @@
 	if ((otype == ntype) || (otype == STT_NOTYPE) || (ntype == STT_NOTYPE))
 		return;
 
-	eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
+	ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
 	    demangle(sdp->sd_name));
-	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
+	ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
 	    sdp->sd_file->ifl_name,
 	    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype, 0, &inv_buf1),
 	    ifl->ifl_name,
@@ -511,14 +507,10 @@
 	 * Update the input section descriptor to that of the new input file
 	 */
 	if (((nsdflags & FLG_SY_SPECSEC) == 0) &&
-	    (nsym->st_shndx != SHN_UNDEF)) {
-		if ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == 0) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_NOSECDEF), demangle(sdp->sd_name),
-			    ifl->ifl_name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
-		}
-	}
+	    (nsym->st_shndx != SHN_UNDEF) &&
+	    ((sdp->sd_isc = ifl->ifl_isdesc[nshndx]) == NULL))
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_NOSECDEF),
+		    demangle(sdp->sd_name), ifl->ifl_name);
 }
 
 /*
@@ -574,15 +566,14 @@
 	 */
 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind != STB_WEAK) &&
 	    (nbind != STB_WEAK) && (!(ofl->ofl_flags & FLG_OF_MULDEFS))) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
 		    demangle(sdp->sd_name));
-		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
 		    sdp->sd_file->ifl_name,
 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
 		    0, &inv_buf1), ifl->ifl_name,
 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, ntype,
 		    0, &inv_buf2));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return;
 	}
 
@@ -597,9 +588,9 @@
 	 * Check the symbols type and size.
 	 */
 	if (otype != ntype) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
 		    demangle(sdp->sd_name));
-		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
 		    sdp->sd_file->ifl_name,
 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
 		    0, &inv_buf1), ifl->ifl_name,
@@ -608,7 +599,7 @@
 		warn++;
 	} else if ((otype == STT_OBJECT) && (osym->st_size != nsym->st_size)) {
 		if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
 			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
 			    EC_XWORD(osym->st_size), ifl->ifl_name,
@@ -635,20 +626,20 @@
 	 */
 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
 		if (warn)
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+			    sdp->sd_file->ifl_name);
 		return;
 	} else if ((nfile == ET_REL) && ((ofile == ET_DYN) ||
 	    ((obind == STB_WEAK) && (nbind != STB_WEAK)))) {
 		if (warn)
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+			    ifl->ifl_name);
 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
 		return;
 	} else {
 		if (warn)
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+			    sdp->sd_file->ifl_name);
 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
 		return;
 	}
@@ -690,16 +681,15 @@
 	if ((ofile == ET_REL) && (nfile == ET_REL) && (obind == nbind) &&
 	    ((otype == STT_FUNC) || (ntype == STT_FUNC))) {
 		if (ofl->ofl_flags & FLG_OF_MULDEFS) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_SYM_DIFFTYPE), demangle(sdp->sd_name));
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
+			    demangle(sdp->sd_name));
 			sym_promote(sdp, nsym, ifl, ofl, ndx,
 			    nshndx, nsdflags);
 		} else {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_MULDEF), demangle(sdp->sd_name));
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_MULDEF),
+			    demangle(sdp->sd_name));
 		}
-		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
 		    sdp->sd_file->ifl_name,
 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
 		    0, &inv_buf1), ifl->ifl_name,
@@ -738,9 +728,9 @@
 	 * Check the symbols type and size.
 	 */
 	if (otype != ntype) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFTYPE),
 		    demangle(sdp->sd_name));
-		eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FILETYPES),
 		    sdp->sd_file->ifl_name,
 		    conv_sym_info_type(ofl->ofl_dehdr->e_machine, otype,
 		    0, &inv_buf1), ifl->ifl_name,
@@ -759,17 +749,14 @@
 		    (obind == nbind)) &&
 		    ((otent && (osym->st_size > nsym->st_size)) ||
 		    (ntent && (osym->st_size < nsym->st_size)))) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
-			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
-			    EC_XWORD(osym->st_size), ifl->ifl_name,
-			    EC_XWORD(nsym->st_size));
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_TENTERR));
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_DIFFATTR),
+			    demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
+			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
+			    ifl->ifl_name, EC_XWORD(nsym->st_size));
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_TENTERR));
 		} else {
 			if (!(ofl->ofl_flags & FLG_OF_NOWARN)) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_SYM_DIFFATTR),
 				    demangle(sdp->sd_name),
 				    MSG_INTL(MSG_STR_SIZES),
@@ -815,22 +802,22 @@
 
 	if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
 		if (warn)
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+			    sdp->sd_file->ifl_name);
 		return;
 	}
 
 	if (((otent) && (!((obind != STB_WEAK) && (nbind == STB_WEAK)))) ||
 	    ((obind == STB_WEAK) && (nbind != STB_WEAK))) {
 		if (warn)
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_DEFTAKEN), ifl->ifl_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+			    ifl->ifl_name);
 		sym_override(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
 		return;
 	} else {
 		if (warn)
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_SYM_DEFTAKEN), sdp->sd_file->ifl_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_DEFTAKEN),
+			    sdp->sd_file->ifl_name);
 		sym_promote(sdp, nsym, ifl, ofl, ndx, nshndx, nsdflags);
 		return;
 	}
@@ -924,7 +911,7 @@
 			alignscompliment = 0;
 
 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
-			eprintf(ofl->ofl_lml, ERR_WARNING,
+			ld_eprintf(ofl, ERR_WARNING,
 			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
 			    MSG_INTL(MSG_STR_ALIGNMENTS),
 			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_value),
@@ -950,7 +937,7 @@
 			value = balign;
 		}
 		if (!(ofl->ofl_flags & FLG_OF_NOWARN) && !alignscompliment)
-			eprintf(ofl->ofl_lml, ERR_NONE, emsg, file);
+			ld_eprintf(ofl, ERR_NONE, emsg, file);
 	}
 
 	/*
@@ -961,11 +948,10 @@
 		const char	*file;
 
 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_SYM_DIFFATTR), demangle(sdp->sd_name),
-			    MSG_INTL(MSG_STR_SIZES), sdp->sd_file->ifl_name,
-			    EC_XWORD(osym->st_size), ifl->ifl_name,
-			    EC_XWORD(nsym->st_size));
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_DIFFATTR),
+			    demangle(sdp->sd_name), MSG_INTL(MSG_STR_SIZES),
+			    sdp->sd_file->ifl_name, EC_XWORD(osym->st_size),
+			    ifl->ifl_name, EC_XWORD(nsym->st_size));
 
 
 		/*
@@ -974,7 +960,7 @@
 		 */
 		if ((sdp->sd_flags & FLG_SY_SOFOUND) && (nfile == ET_DYN)) {
 			if (!(ofl->ofl_flags & FLG_OF_NOWARN))
-				eprintf(ofl->ofl_lml, ERR_NONE, emsg,
+				ld_eprintf(ofl, ERR_NONE, emsg,
 				    sdp->sd_file->ifl_name);
 			return;
 		}
@@ -1023,7 +1009,7 @@
 				file = sdp->sd_file->ifl_name;
 		}
 		if (!(ofl->ofl_flags & FLG_OF_NOWARN))
-			eprintf(ofl->ofl_lml, ERR_NONE, emsg, file);
+			ld_eprintf(ofl, ERR_NONE, emsg, file);
 		if (size)
 			sdp->sd_sym->st_size = (Xword)size;
 	} else {
--- a/usr/src/cmd/sgs/libld/common/sections.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/sections.c	Wed Aug 11 13:39:17 2010 -0600
@@ -1001,6 +1001,19 @@
 			DBG_CALL(Dbg_unused_file(ofl->ofl_lml, ifl->ifl_soname,
 			    (ifl->ifl_flags & FLG_IF_NEEDSTR), 0));
 
+			/*
+			 * Guidance: Remove unused dependency.
+			 *
+			 * If -z ignore is in effect, this warning is not
+			 * needed because we will quietly remove the unused
+			 * dependency.
+			 */
+			if (OFL_GUIDANCE(ofl, FLG_OFG_NO_UNUSED) &&
+			    ((ifl->ifl_flags & FLG_IF_IGNORE) == 0))
+				ld_eprintf(ofl, ERR_GUIDANCE,
+				    MSG_INTL(MSG_GUIDE_UNUSED),
+				    ifl->ifl_soname);
+
 			if (ifl->ifl_flags & FLG_IF_NEEDSTR)
 				ifl->ifl_flags |= FLG_IF_DEPREQD;
 			else if (ifl->ifl_flags & FLG_IF_IGNORE)
@@ -1599,10 +1612,8 @@
 	 * created, warn the user.  This scenario can occur if none of the
 	 * input relocatable objects defined any object capabilities.
 	 */
-	if ((ofl->ofl_flags & FLG_OF_OTOSCAP) && (ofl->ofl_capsymcnt == 0)) {
-		eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(MSG_CAP_NOSYMSFOUND));
-	}
+	if ((ofl->ofl_flags & FLG_OF_OTOSCAP) && (ofl->ofl_capsymcnt == 0))
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_CAP_NOSYMSFOUND));
 
 	/*
 	 * If symbol capabilities have been collected, but no symbols are left
@@ -1611,8 +1622,7 @@
 	 */
 	if ((ofl->ofl_flags & FLG_OF_OTOSCAP) && ofl->ofl_capsymcnt &&
 	    (ofl->ofl_capfamilies == NULL)) {
-		eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(MSG_CAP_NOSYMSFOUND));
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_CAP_NOSYMSFOUND));
 		ld_cap_move_symtoobj(ofl);
 		ofl->ofl_capsymcnt = 0;
 		ofl->ofl_capgroups = NULL;
@@ -1832,7 +1842,7 @@
 			 * capabilities.
 			 */
 			for (APLIST_TRAVERSE(cgp->cg_secs, idx2, isp)) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_CAP_REDUNDANT),
 				    isp->is_file->ifl_name,
 				    EC_WORD(isp->is_scnndx), isp->is_name);
--- a/usr/src/cmd/sgs/libld/common/sunwmove.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/sunwmove.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<string.h>
@@ -139,9 +138,8 @@
 			    ((smdp->md_start + smdp->md_len) <= lmdp->md_start))
 				continue;
 
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_MOVE_OVERLAP), sdp->sd_file->ifl_name,
-			    EC_WORD(isp->is_scnndx),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_MOVE_OVERLAP),
+			    sdp->sd_file->ifl_name, EC_WORD(isp->is_scnndx),
 			    isp->is_name, demangle(sdp->sd_name),
 			    EC_XWORD(nmd.md_start), EC_XWORD(nmd.md_len),
 			    EC_XWORD(omdp->md_start), EC_XWORD(omdp->md_len));
@@ -183,7 +181,7 @@
 		mvp = (Move *)isp->is_indata->d_buf;
 
 		if (isp->is_shdr->sh_entsize == 0) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_INVSHENTSIZE),
 			    isp->is_file->ifl_name, EC_WORD(isp->is_scnndx),
 			    isp->is_name, EC_XWORD(0));
@@ -198,7 +196,7 @@
 
 			if ((ndx >= (Xword) isp->is_file->ifl_symscnt) ||
 			    (ndx == 0)) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_PSYM_INVMINFO1),
 				    isp->is_file->ifl_name,
 				    EC_WORD(isp->is_scnndx), isp->is_name, i,
@@ -206,7 +204,7 @@
 				return (S_ERROR);
 			}
 			if (mvp->m_repeat == 0) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_PSYM_INVMREPEAT),
 				    isp->is_file->ifl_name,
 				    EC_WORD(isp->is_scnndx), isp->is_name, i,
@@ -225,7 +223,7 @@
 			case 1: case 2: case 4: case 8:
 				break;
 			default:
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_PSYM_INVMINFO2),
 				    isp->is_file->ifl_name,
 				    EC_WORD(isp->is_scnndx), isp->is_name, i,
@@ -338,7 +336,7 @@
 			if (OFL_IS_STATIC_EXEC(ofl)) {
 				if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) {
 					errcnt++;
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_PSYM_CANNOTEXPND),
 					    sdp->sd_file->ifl_name,
 					    EC_WORD(isp->is_scnndx),
@@ -349,7 +347,7 @@
 				}
 			} else if ((ofl->ofl_flags1 & FLG_OF1_NOPARTI) != 0) {
 				if (ELF_ST_TYPE(sym->st_info) == STT_SECTION) {
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    MSG_INTL(MSG_PSYM_CANNOTEXPND),
 					    sdp->sd_file->ifl_name,
 					    EC_WORD(isp->is_scnndx),
--- a/usr/src/cmd/sgs/libld/common/support.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/support.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<stdio.h>
@@ -73,7 +72,7 @@
 	 * with a fatal error.
 	 */
 	if ((handle = dlopen(obj, (RTLD_LAZY | RTLD_FIRST))) == NULL) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_SUP_NOLOAD),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SUP_NOLOAD),
 		    obj, dlerror());
 		return (S_ERROR);
 	}
@@ -119,7 +118,7 @@
 			 * than we support, we are unable to accept it.
 			 */
 			if (version > LD_SUP_VCURRENT) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_SUP_BADVERSION), obj,
 				    LD_SUP_VCURRENT, version);
 				(void) dlclose(handle);
@@ -273,9 +272,8 @@
 
 		if ((data == NULL) &&
 		    ((data = elf_getdata(scn, NULL)) == NULL)) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETDATA), ifl->ifl_name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETDATA),
+			    ifl->ifl_name);
 			return (S_ERROR);
 		}
 
--- a/usr/src/cmd/sgs/libld/common/syms.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/syms.c	Wed Aug 11 13:39:17 2010 -0600
@@ -82,14 +82,13 @@
 
 	if (name) {
 		if ((ifl->ifl_flags & FLG_IF_HSTRTAB) == 0) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_FIL_NOSTRTABLE), ifl->ifl_name,
-			    EC_WORD(symsecndx), symsecname, symndx,
-			    EC_XWORD(name));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_NOSTRTABLE),
+			    ifl->ifl_name, EC_WORD(symsecndx), symsecname,
+			    symndx, EC_XWORD(name));
 			return (NULL);
 		}
 		if (name >= (Word)strsize) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_EXCSTRTABLE), ifl->ifl_name,
 			    EC_WORD(symsecndx), symsecname, symndx,
 			    EC_XWORD(name), strsecname, EC_XWORD(strsize));
@@ -121,7 +120,7 @@
 	 * world and hasn't, as yet, been a problem.
 	 */
 	if ((name == 0) && (ELF_ST_BIND(sym->st_info) != STB_LOCAL)) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_FIL_NONAMESYM),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_FIL_NONAMESYM),
 		    ifl->ifl_name, EC_WORD(symsecndx), symsecname, symndx,
 		    EC_XWORD(name));
 	}
@@ -217,9 +216,8 @@
 		/*
 		 * Broken input file
 		 */
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_FIL_INVSHINFO),
 		    ifl->ifl_name, isp->is_name, EC_XWORD(sifshdr->sh_link));
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return (0);
 	}
 	symshdr = ifl->ifl_isdesc[sifshdr->sh_link]->is_shdr;
@@ -414,10 +412,8 @@
 		 * out as many error conditions as possible.
 		 */
 		if ((etype == ET_REL) && (sdp->sd_isc == NULL)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_INVSEC), name, ifl->ifl_name,
-			    EC_XWORD(shndx));
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_INVSEC),
+			    name, ifl->ifl_name, EC_XWORD(shndx));
 			return (sdp);
 		}
 	}
@@ -697,9 +693,8 @@
 
 			DBG_CALL(Dbg_syms_updated(ofl, usdp, uname));
 		} else
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_SYM_RESERVE), uname,
-			    usdp->sd_file->ifl_name);
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE),
+			    uname, usdp->sd_file->ifl_name);
 	} else {
 		/*
 		 * If the symbol does not exist create it.
@@ -791,23 +786,6 @@
 
 
 /*
- * Print undefined symbols.
- */
-static Boolean	undef_title = TRUE;
-
-static void
-sym_undef_title(Ofl_desc *ofl)
-{
-	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_SYM_FMT_UNDEF),
-	    MSG_INTL(MSG_SYM_UNDEF_ITM_11),
-	    MSG_INTL(MSG_SYM_UNDEF_ITM_21),
-	    MSG_INTL(MSG_SYM_UNDEF_ITM_12),
-	    MSG_INTL(MSG_SYM_UNDEF_ITM_22));
-
-	undef_title = FALSE;
-}
-
-/*
  * Undefined symbols can fall into one of four types:
  *
  *  -	the symbol is really undefined (SHN_UNDEF).
@@ -839,15 +817,47 @@
 	MSG_SYM_UND_BNDLOCAL		/* MSG_INTL(MSG_SYM_UND_BNDLOCAL) */
 };
 
+/*
+ * Issue an undefined symbol message for the given symbol.
+ *
+ * entry:
+ *	ofl - Output descriptor
+ *	sdp - Undefined symbol to report
+ *	type - Type of undefined symbol
+ *	ofl_flag - One of 0, FLG_OF_FATAL, or FLG_OF_WARN.
+ *	undef_state - Address of variable to be initialized to 0
+ *		before the first call to sym_undef_entry, and passed
+ *		to each subsequent call. A non-zero value for *undef_state
+ *		indicates that this is not the first call in the series.
+ *
+ * exit:
+ *	If *undef_state is 0, a title is issued.
+ *
+ *	A message for the undefined symbol is issued.
+ *
+ *	If ofl_flag is non-zero, its value is OR'd into *undef_state. Otherwise,
+ *	all bits other than FLG_OF_FATAL and FLG_OF_WARN are set, in order to
+ *	provide *undef_state with a non-zero value. These other bits have
+ *	no meaning beyond that, and serve to ensure that *undef_state is
+ *	non-zero if sym_undef_entry() has been called.
+ */
 static void
-sym_undef_entry(Ofl_desc *ofl, Sym_desc *sdp, Type type)
+sym_undef_entry(Ofl_desc *ofl, Sym_desc *sdp, Type type, ofl_flag_t ofl_flag,
+    ofl_flag_t *undef_state)
 {
 	const char	*name1, *name2, *name3;
 	Ifl_desc	*ifl = sdp->sd_file;
 	Sym_aux		*sap = sdp->sd_aux;
 
-	if (undef_title)
-		sym_undef_title(ofl);
+	if (*undef_state == 0)
+		ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_SYM_FMT_UNDEF),
+		    MSG_INTL(MSG_SYM_UNDEF_ITM_11),
+		    MSG_INTL(MSG_SYM_UNDEF_ITM_21),
+		    MSG_INTL(MSG_SYM_UNDEF_ITM_12),
+		    MSG_INTL(MSG_SYM_UNDEF_ITM_22));
+
+	ofl->ofl_flags |= ofl_flag;
+	*undef_state |= ofl_flag ? ofl_flag : ~(FLG_OF_FATAL | FLG_OF_WARN);
 
 	switch (type) {
 	case UNDEF:
@@ -870,7 +880,7 @@
 		return;
 	}
 
-	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(format[type]),
+	ld_eprintf(ofl, ERR_NONE, MSG_INTL(format[type]),
 	    demangle(sdp->sd_name), name1, name2, name3);
 }
 
@@ -1078,17 +1088,15 @@
 {
 	if (sdp->sd_sym->st_shndx == SHN_UNDEF) {
 		if (str) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_UNDEF), str,
-			    demangle((char *)sdp->sd_name));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_UNDEF),
+			    str, demangle((char *)sdp->sd_name));
 		}
 		return (1);
 	}
 	if (sdp->sd_ref != REF_REL_NEED) {
 		if (str) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_SYM_EXTERN), str,
-			    demangle((char *)sdp->sd_name),
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_SYM_EXTERN),
+			    str, demangle((char *)sdp->sd_name),
 			    sdp->sd_file->ifl_name);
 		}
 		return (1);
@@ -1153,6 +1161,7 @@
 #endif
 	int		ret, allow_ldynsym;
 	uchar_t		type;
+	ofl_flag_t	undef_state = 0;
 
 	DBG_CALL(Dbg_basic_validate(ofl->ofl_lml));
 
@@ -1170,21 +1179,29 @@
 #endif
 
 	/*
-	 * If a symbol is undefined and this link-edit calls for no undefined
-	 * symbols to remain (this is the default case when generating an
-	 * executable but can be enforced for any object using -z defs), the
-	 * symbol is classified as undefined and a fatal error condition will
-	 * be indicated.
+	 * Determine how undefined symbols are handled:
+	 *
+	 * fatal:
+	 *	If this link-edit calls for no undefined symbols to remain
+	 *	(this is the default case when generating an executable but
+	 *	can be enforced for any object using -z defs), a fatal error
+	 *	condition will be indicated.
 	 *
-	 * If the symbol is undefined and we're creating a shared object with
-	 * the -Bsymbolic flag, then the symbol is also classified as undefined
-	 * and a warning condition will be indicated.
+	 * warning:
+	 *	If we're creating a shared object, and either the -Bsymbolic
+	 *	flag is set, or the user has turned on the -z guidance feature,
+	 *	then a non-fatal warning is issued for each symbol.
+	 *
+	 * ignore:
+	 *	In all other cases, undefined symbols are quietly allowed.
 	 */
-	if ((oflags & (FLG_OF_SHAROBJ | FLG_OF_SYMBOLIC)) ==
-	    (FLG_OF_SHAROBJ | FLG_OF_SYMBOLIC))
-		undef = FLG_OF_WARN;
-	if (oflags & FLG_OF_NOUNDEF)
+	if (oflags & FLG_OF_NOUNDEF) {
 		undef = FLG_OF_FATAL;
+	} else if (oflags & FLG_OF_SHAROBJ) {
+		if ((oflags & FLG_OF_SYMBOLIC) ||
+		    OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS))
+			undef = FLG_OF_WARN;
+	}
 
 	/*
 	 * If the symbol is referenced from an implicitly included shared object
@@ -1193,6 +1210,9 @@
 	 */
 	if ((oflags & FLG_OF_NOUNDEF) || !(oflags & FLG_OF_SHAROBJ))
 		needed = FLG_OF_FATAL;
+	else if ((oflags & FLG_OF_SHAROBJ) &&
+	    OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS))
+		needed = FLG_OF_WARN;
 
 	/*
 	 * If the output image is being versioned, then all symbol definitions
@@ -1244,10 +1264,12 @@
 		sdp = sav->sav_sdp;
 
 		/*
-		 * If undefined symbols are allowed ignore any symbols that are
+		 * If undefined symbols are allowed, and we're not being
+		 * asked to supply guidance, ignore any symbols that are
 		 * not needed.
 		 */
 		if (!(oflags & FLG_OF_NOUNDEF) &&
+		    !OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS) &&
 		    (sdp->sd_ref == REF_DYN_SEEN))
 			continue;
 
@@ -1276,10 +1298,9 @@
 
 			if ((isp == NULL) || (isp->is_shdr == NULL) ||
 			    ((isp->is_shdr->sh_flags & SHF_TLS) == 0)) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_SYM_TLS),
 				    demangle(sdp->sd_name), ifl->ifl_name);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 				continue;
 			}
 		}
@@ -1308,8 +1329,8 @@
 		    (sym->st_shndx == SHN_UNDEF) &&
 		    (ELF_ST_BIND(sym->st_info) != STB_WEAK)) {
 			if (vis && (vis != STV_SINGLETON)) {
-				sym_undef_entry(ofl, sdp, BNDLOCAL);
-				ofl->ofl_flags |= FLG_OF_FATAL;
+				sym_undef_entry(ofl, sdp, BNDLOCAL,
+				    FLG_OF_FATAL, &undef_state);
 				continue;
 			}
 		}
@@ -1367,8 +1388,8 @@
 			    ((sdp->sd_flags &
 			    (FLG_SY_MAPREF | FLG_SY_MAPUSED | FLG_SY_HIDDEN |
 			    FLG_SY_PROTECT)) == FLG_SY_MAPREF))) {
-				sym_undef_entry(ofl, sdp, UNDEF);
-				ofl->ofl_flags |= undef;
+				sym_undef_entry(ofl, sdp, UNDEF, undef,
+				    &undef_state);
 				undeferr = 1;
 			}
 
@@ -1386,8 +1407,8 @@
 			if ((sdp->sd_flags &
 			    (FLG_SY_MAPREF | FLG_SY_MAPUSED)) ==
 			    FLG_SY_MAPREF) {
-				sym_undef_entry(ofl, sdp, UNDEF);
-				ofl->ofl_flags |= FLG_OF_WARN;
+				sym_undef_entry(ofl, sdp, UNDEF, FLG_OF_WARN,
+				    &undef_state);
 				undeferr = 1;
 			}
 		}
@@ -1420,8 +1441,8 @@
 				if (vip->vi_flags & FLG_VER_AVAIL) {
 					vip->vi_flags |= FLG_VER_REFER;
 				} else {
-					sym_undef_entry(ofl, sdp, NOTAVAIL);
-					ofl->ofl_flags |= FLG_OF_FATAL;
+					sym_undef_entry(ofl, sdp, NOTAVAIL,
+					    FLG_OF_FATAL, &undef_state);
 					continue;
 				}
 			}
@@ -1435,9 +1456,10 @@
 		if (needed && !undeferr && (sdp->sd_flags & FLG_SY_GLOBREF) &&
 		    (sdp->sd_ref == REF_DYN_NEED) &&
 		    (sdp->sd_flags & FLG_SY_NOTAVAIL)) {
-			sym_undef_entry(ofl, sdp, IMPLICIT);
-			ofl->ofl_flags |= needed;
-			continue;
+			sym_undef_entry(ofl, sdp, IMPLICIT, needed,
+			    &undef_state);
+			if (needed == FLG_OF_FATAL)
+				continue;
 		}
 
 		/*
@@ -1447,8 +1469,8 @@
 		 */
 		if ((sdp->sd_ref == REF_DYN_NEED) &&
 		    (sdp->sd_flags & (FLG_SY_HIDDEN | FLG_SY_PROTECT))) {
-			sym_undef_entry(ofl, sdp, BNDLOCAL);
-			ofl->ofl_flags |= FLG_OF_FATAL;
+			sym_undef_entry(ofl, sdp, BNDLOCAL, FLG_OF_FATAL,
+			    &undef_state);
 			continue;
 		}
 
@@ -1465,8 +1487,8 @@
 			} else {
 				if (!SYM_IS_HIDDEN(sdp) && sdp->sd_aux &&
 				    (sdp->sd_aux->sa_overndx == 0)) {
-					sym_undef_entry(ofl, sdp, NOVERSION);
-					ofl->ofl_flags |= verdesc;
+					sym_undef_entry(ofl, sdp, NOVERSION,
+					    verdesc, &undef_state);
 					continue;
 				}
 			}
@@ -1621,6 +1643,16 @@
 	}
 
 	/*
+	 * Guidance: Use -z defs|nodefs when building shared objects.
+	 *
+	 * Our caller issues this, unless we mask it out here. So we mask it
+	 * out unless we've issued at least one warnings or fatal error.
+	 */
+	if (!((oflags & FLG_OF_SHAROBJ) && OFL_GUIDANCE(ofl, FLG_OFG_NO_DEFS) &&
+	    (undef_state & (FLG_OF_FATAL | FLG_OF_WARN))))
+		ofl->ofl_guideflags |= FLG_OFG_NO_DEFS;
+
+	/*
 	 * If we've encountered a fatal error during symbol validation then
 	 * return now.
 	 */
@@ -1685,8 +1717,8 @@
 	if (ofl->ofl_entry) {
 		if ((sdp = ld_sym_find(ofl->ofl_entry, SYM_NOHASH,
 		    NULL, ofl)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_ARG_NOENTRY), ofl->ofl_entry);
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ARG_NOENTRY),
+			    ofl->ofl_entry);
 			ret++;
 		} else if (ensure_sym_local(ofl, sdp,
 		    MSG_INTL(MSG_SYM_ENTRY)) != 0) {
@@ -1822,26 +1854,22 @@
 issue_badaddr_msg(Ifl_desc *ifl, Ofl_desc *ofl, Sym_desc *sdp,
     Sym *sym, Word shndx)
 {
-	ofl_flag_t	flag;
 	Error		err;
 	const char	*msg;
 
 	if ((sdp->sd_isc->is_shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) ==
 	    SHF_ALLOC) {
 		msg = MSG_INTL(MSG_SYM_BADADDR_ROTXT);
-		flag = FLG_OF_WARN;
 		err = ERR_WARNING;
 	} else {
 		msg = MSG_INTL(MSG_SYM_BADADDR);
-		flag = FLG_OF_FATAL;
 		err = ERR_FATAL;
 	}
 
-	eprintf(ofl->ofl_lml, err, msg, demangle(sdp->sd_name),
+	ld_eprintf(ofl, err, msg, demangle(sdp->sd_name),
 	    ifl->ifl_name, shndx, sdp->sd_isc->is_name,
 	    EC_XWORD(sdp->sd_isc->is_shdr->sh_size),
 	    EC_XWORD(sym->st_value), EC_XWORD(sym->st_size));
-	ofl->ofl_flags |= flag;
 }
 
 /*
@@ -1948,7 +1976,7 @@
 	if (ifl->ifl_flags & FLG_IF_HSTRTAB) {
 		ndx = shdr->sh_link;
 		if ((ndx == 0) || (ndx >= ifl->ifl_shnum)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_FIL_INVSHLINK), ifl->ifl_name,
 			    EC_WORD(symsecndx), symsecname, EC_XWORD(ndx));
 			return (S_ERROR);
@@ -2035,17 +2063,15 @@
 			 */
 			if ((name = string(ofl, ifl, sym, strs, strsize, ndx,
 			    shndx, symsecndx, symsecname, strsecname,
-			    &sdflags)) == NULL) {
-				ofl->ofl_flags |= FLG_OF_FATAL;
+			    &sdflags)) == NULL)
 				continue;
-			}
 
 			/*
 			 * Now that we have the name, if the section index
 			 * was bad, report it.
 			 */
 			if (shndx_bad) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_SYM_INVSHNDX),
 				    demangle_symname(name, symsecname, ndx),
 				    ifl->ifl_name,
@@ -2171,7 +2197,7 @@
 			 */
 			if ((type = ELF_ST_TYPE(sym->st_info)) == STT_SECTION) {
 				if (sym->st_shndx == SHN_UNDEF) {
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    MSG_INTL(MSG_SYM_INVSHNDX),
 					    demangle_symname(name, symsecname,
 					    ndx), ifl->ifl_name,
@@ -2235,11 +2261,10 @@
 
 				if ((isp == NULL) || (isp->is_shdr == NULL) ||
 				    ((isp->is_shdr->sh_flags & SHF_TLS) == 0)) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_SYM_TLS),
 					    demangle(sdp->sd_name),
 					    ifl->ifl_name);
-					ofl->ofl_flags |= FLG_OF_FATAL;
 					continue;
 				}
 			}
@@ -2257,7 +2282,7 @@
 			    ((type == STT_FILE) &&
 			    (sym->st_shndx != SHN_ABS))) ||
 			    (sdp->sd_isc && (sdp->sd_isc->is_osdesc == NULL))) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_SYM_INVSHNDX),
 				    demangle_symname(name, symsecname, ndx),
 				    ifl->ifl_name,
@@ -2352,17 +2377,14 @@
 		 * Check if st_name has a valid value or not.
 		 */
 		if ((name = string(ofl, ifl, nsym, strs, strsize, ndx, shndx,
-		    symsecndx, symsecname, strsecname, &sdflags)) == NULL) {
-			ofl->ofl_flags |= FLG_OF_FATAL;
+		    symsecndx, symsecname, strsecname, &sdflags)) == NULL)
 			continue;
-		}
 
 		/*
 		 * Now that we have the name, report an erroneous section index.
 		 */
 		if (shndx_bad) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_SYM_INVSHNDX),
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_INVSHNDX),
 			    demangle_symname(name, symsecname, ndx),
 			    ifl->ifl_name,
 			    conv_sym_shndx(osabi, mach, nsym->st_shndx,
@@ -2446,8 +2468,7 @@
 		 */
 		bind = ELF_ST_BIND(nsym->st_info);
 		if ((bind != STB_GLOBAL) && (bind != STB_WEAK)) {
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_SYM_NONGLOB),
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NONGLOB),
 			    demangle_symname(name, symsecname, ndx),
 			    ifl->ifl_name,
 			    conv_sym_info_bind(bind, 0, &inv_buf));
@@ -2471,7 +2492,7 @@
 				 * the output file, which won't be a problem
 				 * unless a relocation is required against it.
 				 */
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_SYM_INVSHNDX),
 				    demangle_symname(name, symsecname, ndx),
 				    ifl->ifl_name,
--- a/usr/src/cmd/sgs/libld/common/unwind.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/unwind.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<string.h>
@@ -419,7 +418,7 @@
 					ndx += 1;
 					/* BEGIN CSTYLED */
 					if (cieversion != 1) {
-					    eprintf(ofl->ofl_lml, ERR_FATAL,
+					    ld_eprintf(ofl, ERR_FATAL,
 						MSG_INTL(MSG_UNW_BADCIEVERS),
 						isp->is_file->ifl_name,
 						isp->is_name, off);
--- a/usr/src/cmd/sgs/libld/common/update.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/update.c	Wed Aug 11 13:39:17 2010 -0600
@@ -113,7 +113,7 @@
 		addr = ldynsym[symsort[ndx]].st_value;
 		if (cmp_addr == addr) {
 			if (zverbose)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_SYM_DUPSORTADDR), secname,
 				    str + ldynsym[symsort[cmp_ndx]].st_name,
 				    str + ldynsym[symsort[ndx]].st_name,
@@ -513,7 +513,7 @@
 			etext_ndx = SHN_ABS;
 			etext_abs = 1;
 			if (flags & FLG_OF_VERBOSE)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_UPD_NOREADSEG));
 		}
 		if (dsgp) {
@@ -523,7 +523,7 @@
 			edata_ndx = SHN_ABS;
 			edata_abs = 1;
 			if (flags & FLG_OF_VERBOSE)
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_UPD_NORDWRSEG));
 		}
 
@@ -591,8 +591,7 @@
 			end = (Addr) 0;
 			end_ndx = SHN_ABS;
 			end_abs = 1;
-			eprintf(ofl->ofl_lml, ERR_WARNING,
-			    MSG_INTL(MSG_UPD_NOSEG));
+			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_UPD_NOSEG));
 		}
 	}
 
@@ -921,7 +920,7 @@
 		sdp->sd_sym->st_size = sdp->sd_isc->is_osdesc->os_shdr->sh_size;
 
 	} else if (iosp && !(flags & FLG_OF_RELOBJ)) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
 		    MSG_ORIG(MSG_SYM_INIT_U), MSG_ORIG(MSG_SCN_INIT));
 	}
 
@@ -933,7 +932,7 @@
 		sdp->sd_sym->st_size = sdp->sd_isc->is_osdesc->os_shdr->sh_size;
 
 	} else if (fosp && !(flags & FLG_OF_RELOBJ)) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
 		    MSG_ORIG(MSG_SYM_FINI_U), MSG_ORIG(MSG_SCN_FINI));
 	}
 
@@ -1616,7 +1615,7 @@
 		if (sectndx == SHN_UNDEF) {
 			if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) &&
 			    (sym->st_value != 0)) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_SYM_NOTNULL),
 				    demangle(name), sdp->sd_file->ifl_name);
 			}
@@ -3564,7 +3563,7 @@
 	 * is within range for the input file.
 	 */
 	if (link >= ifl->ifl_shnum) {
-		eprintf(ofl->ofl_lml, ERR_WARNING, msg, ifl->ifl_name,
+		ld_eprintf(ofl, ERR_WARNING, msg, ifl->ifl_name,
 		    EC_WORD(isp->is_scnndx), isp->is_name, EC_XWORD(link));
 		return (link);
 	}
@@ -3875,7 +3874,7 @@
 				p_e = p_s + (ofl->ofl_phdr[i]).p_memsz;
 				if (((p_s <= vaddr) && (p_e > vaddr)) ||
 				    ((vaddr <= p_s) && (v_e > p_s)))
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    MSG_INTL(MSG_UPD_SEGOVERLAP),
 					    ofl->ofl_name, EC_ADDR(p_e),
 					    sgp->sg_name, EC_ADDR(vaddr));
@@ -3920,7 +3919,7 @@
 
 			if (shdr->sh_type != SHT_NOBITS) {
 				if (nobits) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_UPD_NOBITS));
 					return (S_ERROR);
 				}
@@ -3973,7 +3972,7 @@
 			if ((sgp->sg_flags & FLG_SG_P_VADDR)) {
 				if (_phdr && (vaddr > phdr->p_vaddr) &&
 				    (phdr->p_type == PT_LOAD))
-					eprintf(ofl->ofl_lml, ERR_WARNING,
+					ld_eprintf(ofl, ERR_WARNING,
 					    MSG_INTL(MSG_UPD_SEGOVERLAP),
 					    ofl->ofl_name, EC_ADDR(vaddr),
 					    sgp->sg_name,
@@ -4095,10 +4094,9 @@
 		 * haven't exceeded any maximum segment length specification.
 		 */
 		if ((sgp->sg_length != 0) && (sgp->sg_length < phdr->p_memsz)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
-			    MSG_INTL(MSG_UPD_LARGSIZE), ofl->ofl_name,
-			    sgp->sg_name, EC_XWORD(phdr->p_memsz),
-			    EC_XWORD(sgp->sg_length));
+			ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_UPD_LARGSIZE),
+			    ofl->ofl_name, sgp->sg_name,
+			    EC_XWORD(phdr->p_memsz), EC_XWORD(sgp->sg_length));
 			return (S_ERROR);
 		}
 
@@ -4294,13 +4292,13 @@
 		Shdr	*shdr0;
 
 		if ((scn = elf_getscn(ofl->ofl_elf, 0)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETSCN), ofl->ofl_name);
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
+			    ofl->ofl_name);
 			return (S_ERROR);
 		}
 		if ((shdr0 = elf_getshdr(scn)) == NULL) {
-			eprintf(ofl->ofl_lml, ERR_ELF,
-			    MSG_INTL(MSG_ELF_GETSHDR), ofl->ofl_name);
+			ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
+			    ofl->ofl_name);
 			return (S_ERROR);
 		}
 		ofl->ofl_nehdr->e_shstrndx = SHN_XINDEX;
--- a/usr/src/cmd/sgs/libld/common/util.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/util.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -93,7 +92,7 @@
 	if ((addr = mmap(0, size, (PROT_READ | PROT_WRITE | PROT_EXEC),
 	    (MAP_PRIVATE | MAP_ANON), -1, 0)) == MAP_FAILED) {
 		int	err = errno;
-		eprintf(0, ERR_FATAL, MSG_INTL(MSG_SYS_MMAPANON),
+		eprintf(NULL, ERR_FATAL, MSG_INTL(MSG_SYS_MMAPANON),
 		    strerror(err));
 		return (MAP_FAILED);
 	}
@@ -502,6 +501,17 @@
 				}
 				break;
 			case 'f':
+				/*
+				 * Translate --fatal-warnings to
+				 * -z fatal-warnings.
+				 */
+				if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
+				    MSG_ORIG(MSG_ARG_T_FATWARN),
+				    0, NULL)) != 0) {
+					optarg = (char *)
+					    MSG_ORIG(MSG_ARG_FATWARN);
+					return (c);
+				}
 				/* Translate --filter <optarg> to -F <optarg> */
 				if ((c = str2chr(lml, ndx, argc, argv, arg, 'F',
 				    MSG_ORIG(MSG_ARG_T_STDFLTR),
@@ -538,6 +548,18 @@
 				}
 				break;
 			case 'n':
+				/*
+				 * Translate --no-fatal-warnings to
+				 * -z nofatal-warnings.
+				 */
+				if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
+				    MSG_ORIG(MSG_ARG_T_NOFATWARN),
+				    0, NULL)) != 0) {
+					optarg = (char *)
+					    MSG_ORIG(MSG_ARG_NOFATWARN);
+					return (c);
+				}
+
 				/* Translate --no-undefined to -zdefs */
 				if ((c = str2chr(lml, ndx, argc, argv, arg, 'z',
 				    MSG_ORIG(MSG_ARG_T_NOUNDEF), 0, NULL)) !=
--- a/usr/src/cmd/sgs/libld/common/version.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/libld/common/version.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<string.h>
@@ -119,7 +118,7 @@
 			 * cyclic dependency.
 			 */
 			if (err == 0) {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_VER_CYCLIC));
 				err = 1;
 			}
@@ -127,14 +126,14 @@
 				v = ver_stk.ver_stk[tmp_sp];
 				if ((v->vd_flags & FLG_VER_CYCLIC) == 0) {
 					v->vd_flags |= FLG_VER_CYCLIC;
-					eprintf(ofl->ofl_lml, ERR_NONE,
+					ld_eprintf(ofl, ERR_NONE,
 					    MSG_INTL(MSG_VER_ADDVER),
 					    v->vd_name);
 				}
 			}
 			if ((vp->vd_flags & FLG_VER_CYCLIC) == 0) {
 				vp->vd_flags |= FLG_VER_CYCLIC;
-				eprintf(ofl->ofl_lml, ERR_NONE,
+				ld_eprintf(ofl, ERR_NONE,
 				    MSG_INTL(MSG_VER_ADDVER), vp->vd_name);
 			}
 			return (err);
@@ -198,10 +197,9 @@
 		Aliste		idx2;
 
 		if (vdp->vd_ndx == 0) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_VER_UNDEF), name, vdp->vd_ref->vd_name,
 			    vdp->vd_ref->vd_file->ifl_name);
-			ofl->ofl_flags |= FLG_OF_FATAL;
 			continue;
 		}
 
@@ -275,7 +273,7 @@
 			} else if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
 			    (sdp->sd_sym->st_shndx != SHN_ABS) &&
 			    (sdp->sd_ref == REF_REL_NEED)) {
-				eprintf(ofl->ofl_lml, ERR_WARNING,
+				ld_eprintf(ofl, ERR_WARNING,
 				    MSG_INTL(MSG_VER_DEFINED), name,
 				    sdp->sd_file->ifl_name);
 			}
@@ -544,12 +542,12 @@
 				continue;
 
 			if (fail++ == 0) {
-				eprintf(ofl->ofl_lml, ERR_NONE,
+				ld_eprintf(ofl, ERR_NONE,
 				    MSG_INTL(MSG_VER_ADDVERS), sdf->sdf_rfile,
 				    sdf->sdf_name);
 			}
-			eprintf(ofl->ofl_lml, ERR_NONE,
-			    MSG_INTL(MSG_VER_ADDVER), sdv->sdv_name);
+			ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_VER_ADDVER),
+			    sdv->sdv_name);
 		}
 		if (fail)
 			return ((Ver_index *)S_ERROR);
@@ -562,7 +560,7 @@
  * Process a version symbol index section.
  */
 int
-ld_vers_sym_process(Lm_list *lml, Is_desc *isp, Ifl_desc *ifl)
+ld_vers_sym_process(Ofl_desc *ofl, Is_desc *isp, Ifl_desc *ifl)
 {
 	Shdr	*symshdr;
 	Shdr	*vershdr = isp->is_shdr;
@@ -576,7 +574,7 @@
 	    vershdr->sh_entsize)) {
 		Is_desc	*sym_isp = ifl->ifl_isdesc[vershdr->sh_link];
 
-		eprintf(lml, ERR_WARNING, MSG_INTL(MSG_ELF_VERSYM),
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_ELF_VERSYM),
 		    ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name,
 		    EC_WORD(vershdr->sh_size / vershdr->sh_entsize),
 		    EC_WORD(sym_isp->is_scnndx), sym_isp->is_name,
@@ -612,10 +610,9 @@
 		Aliste	idx;
 
 		for (ALIST_TRAVERSE(sdf->sdf_vers, idx, sdv)) {
-			eprintf(ofl->ofl_lml, ERR_FATAL,
+			ld_eprintf(ofl, ERR_FATAL,
 			    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
 			    sdv->sdv_name, sdv->sdv_ref);
-			ofl->ofl_flags |= FLG_OF_FATAL;
 		}
 		return (0);
 	}
@@ -628,9 +625,8 @@
 	 * data section will be of the same revision.
 	 */
 	if (vdf->vd_version > VER_DEF_CURRENT)
-		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vdf->vd_version,
-		    VER_DEF_CURRENT);
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_VER_HIGHER),
+		    ifl->ifl_name, vdf->vd_version, VER_DEF_CURRENT);
 
 
 	num = isp->is_shdr->sh_info;
@@ -788,12 +784,10 @@
 			}
 			if (found)
 				vers_select(ofl, ifl, vdp, sdv->sdv_ref);
-			else {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+			else
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
 				    sdv->sdv_name, sdv->sdv_ref);
-				ofl->ofl_flags |= FLG_OF_FATAL;
-			}
 		}
 	} else {
 		Ver_index	*vip;
@@ -835,9 +829,8 @@
 	 * data section will be of the same revision.
 	 */
 	if (vnd->vn_version > VER_DEF_CURRENT) {
-		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
-		    MSG_INTL(MSG_VER_HIGHER), ifl->ifl_name, vnd->vn_version,
-		    VER_DEF_CURRENT);
+		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_VER_HIGHER),
+		    ifl->ifl_name, vnd->vn_version, VER_DEF_CURRENT);
 	}
 
 	num = isp->is_shdr->sh_info;
@@ -931,9 +924,8 @@
 	 * version definition.
 	 */
 	if ((ifl->ifl_verndx == 0) || (vndx > ifl->ifl_vercnt)) {
-		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_VER_INVALNDX),
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_VER_INVALNDX),
 		    sdp->sd_name, ifl->ifl_name, vndx);
-		ofl->ofl_flags |= FLG_OF_FATAL;
 		return;
 	}
 
@@ -1066,17 +1058,15 @@
 
 				vip = &ifl->ifl_verndx[vdp->vd_ndx];
 				if (!(vip->vi_flags & FLG_VER_AVAIL)) {
-					eprintf(ofl->ofl_lml, ERR_FATAL,
+					ld_eprintf(ofl, ERR_FATAL,
 					    MSG_INTL(MSG_VER_UNAVAIL),
 					    ifl->ifl_name, sdv->sdv_name,
 					    sdv->sdv_ref);
-					ofl->ofl_flags |= FLG_OF_FATAL;
 				}
 			} else {
-				eprintf(ofl->ofl_lml, ERR_FATAL,
+				ld_eprintf(ofl, ERR_FATAL,
 				    MSG_INTL(MSG_VER_NOEXIST), ifl->ifl_name,
 				    sdv->sdv_name, sdv->sdv_ref);
-				ofl->ofl_flags |= FLG_OF_FATAL;
 			}
 		}
 	}
--- a/usr/src/cmd/sgs/liblddbg/common/args.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/liblddbg/common/args.c	Wed Aug 11 13:39:17 2010 -0600
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include	<debug.h>
@@ -66,3 +65,16 @@
 
 	dbg_print(lml, MSG_INTL(MSG_ARG_FILE), ndx, file);
 }
+
+
+/*
+ * Report unrecognized item provided to '-z guidance' option.
+ */
+void
+Dbg_args_guidance_unknown(Lm_list *lml, const char *item)
+{
+	if (DBG_NOTCLASS(DBG_C_ARGS))
+		return;
+
+	dbg_print(lml, MSG_INTL(MSG_ARG_NG_UNKNOWN), item);
+}
--- a/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/liblddbg/common/liblddbg.msg	Wed Aug 11 13:39:17 2010 -0600
@@ -562,6 +562,8 @@
 			 removed"
 @ MSG_ARG_FILE		"arg[%d]\tfile=%s"
 
+@ MSG_ARG_NG_UNKNOWN	"warning: unrecognized -z guidance item: %s"
+
 
 # Bindings messages
 # NOTE: these are used by appcert(1) and lari(1), use care when changing.
--- a/usr/src/cmd/sgs/liblddbg/common/llib-llddbg	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/liblddbg/common/llib-llddbg	Wed Aug 11 13:39:17 2010 -0600
@@ -36,6 +36,7 @@
 	Dbg_demangle_name(const char *);
 
 void	Dbg_args_file(Lm_list *, int, char *);
+void	Dbg_args_guidance_unknown(Lm_list *, const char *);
 void	Dbg_args_option(Lm_list *, int, int, char *);
 void	Dbg_args_str2chr(Lm_list *, int, const char *, int);
 void	Dbg_args_Wldel(Lm_list *, int, const char *);
--- a/usr/src/cmd/sgs/liblddbg/common/mapfile-vers	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/liblddbg/common/mapfile-vers	Wed Aug 11 13:39:17 2010 -0600
@@ -42,7 +42,7 @@
 
 $mapfile_version 2
 
-SYMBOL_VERSION SUNWprivate_4.82 {
+SYMBOL_VERSION SUNWprivate_4.83 {
 	global:
 		dbg_desc {	# interposed - ld.so.1(1)
 			FLAGS = NODIRECT;
@@ -52,6 +52,7 @@
 		};
 
 		Dbg_args_file;
+		Dbg_args_guidance_unknown;
 		Dbg_args_option;
 		Dbg_args_str2chr;
 		Dbg_args_Wldel;
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Wed Aug 11 13:39:17 2010 -0600
@@ -1620,3 +1620,5 @@
 6972234 sgs demo's could use some cleanup
 6935867 .dynamic could be readonly in sharable objects
 6975290 ld mishandles GOT relocation against local ABS symbol
+6972860 ld should provide user guidance to improve objects (D)
+	PSARC/2010/312 Link-editor guidance
--- a/usr/src/cmd/sgs/rtld/common/mapfile-vers	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/rtld/common/mapfile-vers	Wed Aug 11 13:39:17 2010 -0600
@@ -87,6 +87,7 @@
 		 dbg_desc;		# Diagnostic support
 		 dbg_print;
 		 eprintf;		# Error message printing
+		 veprintf;
 
 		 dgettext;		# Messaging support
 		 strerror;
--- a/usr/src/cmd/sgs/rtld/common/rtld.msg	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/rtld/common/rtld.msg	Wed Aug 11 13:39:17 2010 -0600
@@ -254,6 +254,7 @@
 # Error diagnostic standard prefixes.
 
 @ MSG_ERR_WARNING	"warning: "
+@ MSG_ERR_GUIDANCE	"guidance: "
 @ MSG_ERR_FATAL		"fatal: "
 @ MSG_ERR_ELF		"elf error: "
 
--- a/usr/src/cmd/sgs/rtld/common/util.c	Wed Aug 11 13:08:50 2010 -0600
+++ b/usr/src/cmd/sgs/rtld/common/util.c	Wed Aug 11 13:39:17 2010 -0600
@@ -2866,11 +2866,9 @@
  * The RT_FL_APPLIC flag serves to indicate the transition between process
  * initialization and when the applications code is running.
  */
-/*PRINTFLIKE3*/
 void
-eprintf(Lm_list *lml, Error error, const char *format, ...)
+veprintf(Lm_list *lml, Error error, const char *format, va_list args)
 {
-	va_list		args;
 	int		overflow = 0;
 	static int	lock = 0;
 	Prfbuf		prf;
@@ -2891,8 +2889,6 @@
 	 * still in the initialization stage, output the error directly and
 	 * add a newline.
 	 */
-	va_start(args, format);
-
 	prf.pr_buf = prf.pr_cur = nextptr;
 	prf.pr_len = ERRSIZE - (nextptr - errbuf);
 
@@ -2904,16 +2900,30 @@
 	if (error > ERR_NONE) {
 		if ((error == ERR_FATAL) && (rtld_flags2 & RT_FL2_FTL2WARN))
 			error = ERR_WARNING;
-		if (error == ERR_WARNING) {
+		switch (error) {
+		case ERR_WARNING_NF:
+			if (err_strs[ERR_WARNING_NF] == NULL)
+				err_strs[ERR_WARNING_NF] =
+				    MSG_INTL(MSG_ERR_WARNING);
+			break;
+		case ERR_WARNING:
 			if (err_strs[ERR_WARNING] == NULL)
 				err_strs[ERR_WARNING] =
 				    MSG_INTL(MSG_ERR_WARNING);
-		} else if (error == ERR_FATAL) {
+			break;
+		case ERR_GUIDANCE:
+			if (err_strs[ERR_GUIDANCE] == NULL)
+				err_strs[ERR_GUIDANCE] =
+				    MSG_INTL(MSG_ERR_GUIDANCE);
+			break;
+		case ERR_FATAL:
 			if (err_strs[ERR_FATAL] == NULL)
 				err_strs[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL);
-		} else if (error == ERR_ELF) {
+			break;
+		case ERR_ELF:
 			if (err_strs[ERR_ELF] == NULL)
 				err_strs[ERR_ELF] = MSG_INTL(MSG_ERR_ELF);
+			break;
 		}
 		if (procname) {
 			if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR1),
@@ -2980,7 +2990,6 @@
 		*(prf.pr_cur - 1) = '\0';
 
 	DBG_CALL(Dbg_util_str(lml, nextptr));
-	va_end(args);
 
 	/*
 	 * Determine if there was insufficient space left in the buffer to
@@ -3037,6 +3046,17 @@
 	lock = 0;
 }
 
+/*PRINTFLIKE3*/
+void
+eprintf(Lm_list *lml, Error error, const char *format, ...)
+{
+	va_list		args;
+
+	va_start(args, format);
+	veprintf(lml, error, format, args);
+	va_end(args);
+}
+
 #if	DEBUG
 /*
  * Provide assfail() for ASSERT() statements.  See <sys/debug.h> for further