Print this page
3436 relocatable objects also need sloppy relocation
3439 discarded sections shouldn't end up on output lists

@@ -849,10 +849,17 @@
                         DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp, oname));
                 }
         }
 
         /*
+         * When building relocatable objects, we must not redirect COMDAT
+         * section names into their outputs, such that our output object may
+         * be successfully used as an input object also requiring COMDAT
+         * processing
+         */
+
+        /*
          * GNU section names may follow the convention:
          *
          *      .gnu.linkonce.*
          *
          * The .gnu.linkonce is a section naming convention that indicates a

@@ -861,17 +868,19 @@
          * discarded or retained.  The comparison of is_name[1] with 'g'
          * is an optimization to skip using strncmp() too much. This is safe,
          * because we know the name is not NULL, and therefore must have
          * at least one character plus a NULL termination.
          */
-        if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
-            (isp->is_name == oname) && (isp->is_name[1] == 'g') &&
+        if ((isp->is_name == oname) && (isp->is_name[1] == 'g') &&
             (strncmp(MSG_ORIG(MSG_SCN_GNU_LINKONCE), isp->is_name,
             MSG_SCN_GNU_LINKONCE_SIZE) == 0)) {
-                if ((oname =
-                    (char *)gnu_linkonce_sec(isp->is_name)) != isp->is_name) {
-                        DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp, oname));
+                if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) {
+                        if ((oname = (char *)gnu_linkonce_sec(isp->is_name)) !=
+                            isp->is_name) {
+                                DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp,
+                                    oname));
+                        }
                 }
 
                 /*
                  * Explicitly identify this section type as COMDAT.  Also,
                  * enable relaxed relocation processing, as this is typically

@@ -892,20 +901,21 @@
          * This convention is used when defining SHT_GROUP sections of type
          * COMDAT.  Thus, any group processing will have discovered any group
          * sections, and this identification can be triggered by a pattern
          * match section names.
          */
-        if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
-            (isp->is_name == oname) && (isp->is_flags & FLG_IS_COMDAT) &&
+        if ((isp->is_name == oname) && (isp->is_flags & FLG_IS_COMDAT) &&
             ((sname = gnu_comdat_sym(ifl, isp)) != NULL)) {
                 size_t  size = sname - isp->is_name;
 
+                if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) {
                 if ((oname = libld_malloc(size + 1)) == NULL)
                         return ((Os_desc *)S_ERROR);
                 (void) strncpy(oname, isp->is_name, size);
                 oname[size] = '\0';
                 DBG_CALL(Dbg_sec_redirected(ofl->ofl_lml, isp, oname));
+                }
 
                 /*
                  * Enable relaxed relocation processing, as this is
                  * typically a requirement with GNU COMDAT sections.
                  */

@@ -1197,10 +1207,11 @@
         /*
          * Sections of type SHT_GROUP are added to the ofl->ofl_osgroups list,
          * so that they can be updated as a group later.
          */
         if ((shdr->sh_type == SHT_GROUP) &&
+            ((isp->is_flags & FLG_IS_DISCARD) == 0) &&
             (aplist_append(&ofl->ofl_osgroups, osp,
             AL_CNT_OFL_OSGROUPS) == NULL))
                 return ((Os_desc *)S_ERROR);
 
         /*