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;