changeset 14017:a8db07801f46

3616 SHF_GROUP sections should not be discarded via other COMDAT mechanisms 3709 need sloppy relocation for GNU .debug_macro Reviewed by: Joshua M. Clulow <josh@sysmgr.org> Reviewed by: Robert Mustacchi <rm@joyent.com> Reviewed by: Gordon Ross <gwr@nexenta.com> Approved by: Garrett D'Amore <garrett@damore.org>
author Richard Lowe <richlowe@richlowe.net>
date Thu, 21 Mar 2013 15:19:00 -0400
parents 9d68e7a6a0c3
children 9915df7eb304
files usr/src/cmd/sgs/libld/common/_libld.h usr/src/cmd/sgs/libld/common/files.c usr/src/cmd/sgs/libld/common/groups.c usr/src/cmd/sgs/libld/common/libld.msg usr/src/cmd/sgs/libld/common/place.c usr/src/cmd/sgs/libld/common/sections.c usr/src/cmd/sgs/packages/common/SUNWonld-README
diffstat 7 files changed, 128 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/sgs/libld/common/_libld.h	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/libld/common/_libld.h	Thu Mar 21 15:19:00 2013 -0400
@@ -688,6 +688,7 @@
 #define	ld_bswap_Xword		ld64_bswap_Xword
 #define	ld_cap_add_family	ld64_cap_add_family
 #define	ld_cap_move_symtoobj	ld64_cap_move_symtoobj
+#define	ld_comdat_validate	ld64_comdat_validate
 #define	ld_disp_errmsg		ld64_disp_errmsg
 #define	ld_ent_check		ld64_ent_check
 #define	ld_ent_lookup		ld64_ent_lookup
@@ -785,6 +786,7 @@
 #define	ld_bswap_Xword		ld32_bswap_Xword
 #define	ld_cap_add_family	ld32_cap_add_family
 #define	ld_cap_move_symtoobj	ld32_cap_move_symtoobj
+#define	ld_comdat_validate	ld32_comdat_validate
 #define	ld_disp_errmsg		ld32_disp_errmsg
 #define	ld_ent_check		ld32_ent_check
 #define	ld_ent_lookup		ld32_ent_lookup
@@ -892,6 +894,8 @@
 			    Cap_group *, APlist **);
 extern void		ld_cap_move_symtoobj(Ofl_desc *);
 
+extern void		ld_comdat_validate(Ofl_desc *, Ifl_desc *);
+
 extern void		ld_disp_errmsg(const char *, Rel_desc *, Ofl_desc *);
 
 extern void		ld_ent_check(Ofl_desc *);
--- a/usr/src/cmd/sgs/libld/common/files.c	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/libld/common/files.c	Thu Mar 21 15:19:00 2013 -0400
@@ -2821,6 +2821,14 @@
 	}
 
 	/*
+	 * Now group information has been processed, we can safely validate
+	 * that nothing is fishy about the section COMDAT description.  We
+	 * need to do this prior to placing the section (where any
+	 * SHT_SUNW_COMDAT sections will be restored to being PROGBITS)
+	 */
+	ld_comdat_validate(ofl, ifl);
+
+	/*
 	 * Now that all of the input sections have been processed, place
 	 * them in the appropriate output sections.
 	 */
--- a/usr/src/cmd/sgs/libld/common/groups.c	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/libld/common/groups.c	Thu Mar 21 15:19:00 2013 -0400
@@ -118,6 +118,47 @@
 	return (NULL);
 }
 
+/*
+ * When creating a .debug_macro section, in an attempt to make certain DWARF
+ * macro information shareable, the GNU compiler must construct group sections
+ * with a repeatable signature symbol while nevertheless having no actual
+ * symbol to refer to (because it relates to macros).
+ *
+ * We use this as yet another way to clue ourselves in that sloppy relocation
+ * will likely be required.
+ *
+ * The format of these gensym'd names is:
+ *    wm<offset size>.<encoded path name>.<lineno>.<32byte hash>
+ * Where the encoded file name may be absent.
+ */
+static boolean_t
+is_header_gensym(const char *name)
+{
+	const char	*c = NULL;
+	size_t		len = strlen(name);
+
+	/* No room for leader, hash, and periods */
+	if (len < 37)
+		return (B_FALSE);
+
+	if ((strncmp(name, "wm4.", 4) != 0) &&
+	    strncmp(name, "wm8.", 4) != 0)
+		return (B_FALSE);
+
+	c = &name[len - 33];
+	if (*c++ != '.')
+		return (B_FALSE);
+
+	for (; *c != '\0'; c++) {
+		if (!(((*c >= 'a') && (*c <= 'f')) ||
+		    ((*c >= '0') && (*c <= '9')))) {
+			return (B_FALSE);
+		}
+	}
+
+	return (B_TRUE);
+}
+
 uintptr_t
 ld_group_process(Is_desc *gisc, Ofl_desc *ofl)
 {
@@ -221,6 +262,17 @@
 	}
 
 	/*
+	 * If the signature symbol is a name generated by the GNU compiler to
+	 * refer to a header, we need sloppy relocation.
+	 */
+	if (is_header_gensym(str)) {
+		if ((ofl->ofl_flags1 & FLG_OF1_NRLXREL) == 0)
+			ofl->ofl_flags1 |= FLG_OF1_RLXREL;
+		DBG_CALL(Dbg_sec_gnu_comdat(ofl->ofl_lml, gisc, TRUE,
+		    (ofl->ofl_flags1 & FLG_OF1_RLXREL) != 0));
+	}
+
+	/*
 	 * Validate the section indices within the group.  If this is a COMDAT
 	 * group, mark each section as COMDAT.
 	 */
--- a/usr/src/cmd/sgs/libld/common/libld.msg	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/libld/common/libld.msg	Thu Mar 21 15:19:00 2013 -0400
@@ -471,6 +471,9 @@
 @ MSG_SCN_NONALLOC	"%s: non-allocatable section '%s' directed to a \
 			 loadable segment: %s"
 
+@ MSG_SCN_MULTICOMDAT	"file %s: section [%u]%s: cannot be susceptible to multiple \
+			 COMDAT mechanisms: %s"
+
 # Symbol processing errors
 
 @ MSG_SYM_NOSECDEF	"symbol '%s' in file %s has no section definition"
@@ -748,6 +751,8 @@
 @ MSG_STR_CDIR_ELSE	"$else"
 @ MSG_STR_CDIR_ENDIF	"$endif"
 
+@ MSG_STR_GROUP		"GROUP"
+@ MSG_STR_SUNW_COMDAT	"SUNW_COMDAT"
 
 @ MSG_FMT_ARMEM		"%s(%s)"
 @ MSG_FMT_COLPATH	"%s:%s"
--- a/usr/src/cmd/sgs/libld/common/place.c	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/libld/common/place.c	Thu Mar 21 15:19:00 2013 -0400
@@ -238,6 +238,17 @@
 	Isd_node	isd, *isdp;
 	avl_tree_t	*avlt;
 	avl_index_t	where;
+	Group_desc	*gr;
+
+	/*
+	 * Sections to which COMDAT groups apply are FLG_IS_COMDAT but are
+	 * discarded separately by the group logic so should never be
+	 * discarded here.
+	 */
+	if ((isp->is_shdr->sh_flags & SHF_GROUP) &&
+	    ((gr = ld_get_group(ofl, isp)) != NULL) &&
+	    (gr->gd_data[0] & GRP_COMDAT))
+		return (1);
 
 	/*
 	 * Create a COMDAT avl tree for this output section if required.
--- a/usr/src/cmd/sgs/libld/common/sections.c	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/libld/common/sections.c	Thu Mar 21 15:19:00 2013 -0400
@@ -3463,3 +3463,49 @@
 
 	return (isec);
 }
+
+void
+ld_comdat_validate(Ofl_desc *ofl, Ifl_desc *ifl)
+{
+	int i;
+
+	for (i = 0; i < ifl->ifl_shnum; i++) {
+		Is_desc *isp = ifl->ifl_isdesc[i];
+		int types = 0;
+		char buf[1024] = "";
+		Group_desc *gr = NULL;
+
+		if ((isp == NULL) || (isp->is_flags & FLG_IS_COMDAT) == 0)
+			continue;
+
+		if (isp->is_shdr->sh_type == SHT_SUNW_COMDAT) {
+			types++;
+			(void) strlcpy(buf, MSG_ORIG(MSG_STR_SUNW_COMDAT),
+			    sizeof (buf));
+		}
+
+		if (strncmp(MSG_ORIG(MSG_SCN_GNU_LINKONCE), isp->is_name,
+		    MSG_SCN_GNU_LINKONCE_SIZE) == 0) {
+			types++;
+			if (types > 1)
+				(void) strlcat(buf, ", ", sizeof (buf));
+			(void) strlcat(buf, MSG_ORIG(MSG_SCN_GNU_LINKONCE),
+			    sizeof (buf));
+		}
+
+		if ((isp->is_shdr->sh_flags & SHF_GROUP) &&
+		    ((gr = ld_get_group(ofl, isp)) != NULL) &&
+		    (gr->gd_data[0] & GRP_COMDAT)) {
+			types++;
+			if (types > 1)
+				(void) strlcat(buf, ", ", sizeof (buf));
+			(void) strlcat(buf, MSG_ORIG(MSG_STR_GROUP),
+			    sizeof (buf));
+		}
+
+		if (types > 1)
+			ld_eprintf(ofl, ERR_FATAL,
+			    MSG_INTL(MSG_SCN_MULTICOMDAT), ifl->ifl_name,
+			    EC_WORD(isp->is_scnndx), isp->is_name, buf);
+	}
+}
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README	Fri Apr 19 03:26:55 2013 -0500
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README	Thu Mar 21 15:19:00 2013 -0400
@@ -1644,3 +1644,5 @@
 3439	discarded sections shouldn't end up on output lists
 3436	relocatable objects also need sloppy relocation
 3451	archive libraries with no symbols shouldn't require a string table
+3616	SHF_GROUP sections should not be discarded via other COMDAT mechanisms
+3709	need sloppy relocation for GNU .debug_macro