summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRichard Lowe <richlowe@richlowe.net>2013-03-21 15:19:00 -0400
committerRichard Lowe <richlowe@richlowe.net>2013-04-19 22:38:17 -0400
commitef16f6b5e980be84e2248939502c5aa269ef026d (patch)
treeef1826a97a6899af795b13362982e3fe5ac0b7c6 /usr/src
parent9e647765f079a9527bc9430bd6805745b590091b (diff)
downloadillumos-joyent-ef16f6b5e980be84e2248939502c5aa269ef026d.tar.gz
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>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/sgs/libld/common/_libld.h4
-rw-r--r--usr/src/cmd/sgs/libld/common/files.c8
-rw-r--r--usr/src/cmd/sgs/libld/common/groups.c52
-rw-r--r--usr/src/cmd/sgs/libld/common/libld.msg5
-rw-r--r--usr/src/cmd/sgs/libld/common/place.c11
-rw-r--r--usr/src/cmd/sgs/libld/common/sections.c46
-rw-r--r--usr/src/cmd/sgs/packages/common/SUNWonld-README2
7 files changed, 128 insertions, 0 deletions
diff --git a/usr/src/cmd/sgs/libld/common/_libld.h b/usr/src/cmd/sgs/libld/common/_libld.h
index 87b05ec13e..146dd54b8c 100644
--- a/usr/src/cmd/sgs/libld/common/_libld.h
+++ b/usr/src/cmd/sgs/libld/common/_libld.h
@@ -688,6 +688,7 @@ extern Sdf_desc *sdf_find(const char *, APlist *);
#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 @@ extern Sdf_desc *sdf_find(const char *, APlist *);
#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 @@ extern uintptr_t ld_cap_add_family(Ofl_desc *, Sym_desc *, Sym_desc *,
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 *);
diff --git a/usr/src/cmd/sgs/libld/common/files.c b/usr/src/cmd/sgs/libld/common/files.c
index 99e6e89f9d..d731e935d4 100644
--- a/usr/src/cmd/sgs/libld/common/files.c
+++ b/usr/src/cmd/sgs/libld/common/files.c
@@ -2821,6 +2821,14 @@ process_elf(Ifl_desc *ifl, Elf *elf, Ofl_desc *ofl)
}
/*
+ * 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.
*/
diff --git a/usr/src/cmd/sgs/libld/common/groups.c b/usr/src/cmd/sgs/libld/common/groups.c
index faedb90934..e4853ba823 100644
--- a/usr/src/cmd/sgs/libld/common/groups.c
+++ b/usr/src/cmd/sgs/libld/common/groups.c
@@ -118,6 +118,47 @@ ld_get_group(Ofl_desc *ofl, Is_desc *isp)
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 @@ ld_group_process(Is_desc *gisc, Ofl_desc *ofl)
}
/*
+ * 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.
*/
diff --git a/usr/src/cmd/sgs/libld/common/libld.msg b/usr/src/cmd/sgs/libld/common/libld.msg
index f0c5266aec..761a293aed 100644
--- a/usr/src/cmd/sgs/libld/common/libld.msg
+++ b/usr/src/cmd/sgs/libld/common/libld.msg
@@ -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"
diff --git a/usr/src/cmd/sgs/libld/common/place.c b/usr/src/cmd/sgs/libld/common/place.c
index d56e205717..cadc43f977 100644
--- a/usr/src/cmd/sgs/libld/common/place.c
+++ b/usr/src/cmd/sgs/libld/common/place.c
@@ -238,6 +238,17 @@ add_comdat(Ofl_desc *ofl, Os_desc *osp, Is_desc *isp)
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.
diff --git a/usr/src/cmd/sgs/libld/common/sections.c b/usr/src/cmd/sgs/libld/common/sections.c
index 8601c40362..01ee18aab3 100644
--- a/usr/src/cmd/sgs/libld/common/sections.c
+++ b/usr/src/cmd/sgs/libld/common/sections.c
@@ -3463,3 +3463,49 @@ ld_make_text(Ofl_desc *ofl, size_t size)
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);
+ }
+}
diff --git a/usr/src/cmd/sgs/packages/common/SUNWonld-README b/usr/src/cmd/sgs/packages/common/SUNWonld-README
index fa55c5d1e9..2a6d570955 100644
--- a/usr/src/cmd/sgs/packages/common/SUNWonld-README
+++ b/usr/src/cmd/sgs/packages/common/SUNWonld-README
@@ -1644,3 +1644,5 @@ Bugid Risk Synopsis
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