Print this page
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>
@@ -116,10 +116,50 @@
ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ELF_NOGROUPSECT),
ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name);
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;
+
+ /* No room for leader, hash, and periods */
+ if (strlen(name) < 37)
+ return (B_FALSE);
+
+ if ((strncmp(name, "wm4.", 4) != 0) &&
+ strncmp(name, "wm8.", 4) != 0)
+ return (B_FALSE);
+
+ c = &name[strlen(name) - 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)
{
Ifl_desc *gifl = gisc->is_file;
Shdr *sshdr, *gshdr = gisc->is_shdr;
@@ -219,10 +259,21 @@
gisc->is_name, str);
return (0);
}
/*
+ * 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.
*/
for (ndx = 1; ndx < gd.gd_cnt; ndx++) {
Word gndx;