Print this page
4959 completely discarded merged string sections will corrupt output objects

@@ -158,10 +158,35 @@
                                 remove_scoped(ofl, sdp, allow_ldynsym);
                 }
         }
 }
 
+static Boolean
+isdesc_discarded(Is_desc *isp)
+{
+        Ifl_desc        *ifl = isp->is_file;
+        Os_desc         *osp = isp->is_osdesc;
+        Word            ptype = osp->os_sgdesc->sg_phdr.p_type;
+
+        if (isp->is_flags & FLG_IS_DISCARD)
+                return TRUE;
+
+        /*
+         * If the file is discarded, it will take
+         * the section with it.
+         */
+        if (ifl &&
+            (((ifl->ifl_flags & FLG_IF_FILEREF) == 0) ||
+            ((ptype == PT_LOAD) &&
+            ((isp->is_flags & FLG_IS_SECTREF) == 0) &&
+            (isp->is_shdr->sh_size > 0))) &&
+            (ifl->ifl_flags & FLG_IF_IGNORE))
+                return TRUE;
+
+        return FALSE;
+}
+
 /*
  * There are situations where we may count output sections (ofl_shdrcnt)
  * that are subsequently eliminated from the output object. Whether or
  * not this happens cannot be known until all input has been seen and
  * section elimination code has run. However, the situations where this

@@ -179,11 +204,10 @@
 adjust_os_count(Ofl_desc *ofl)
 {
         Sg_desc         *sgp;
         Is_desc         *isp;
         Os_desc         *osp;
-        Ifl_desc        *ifl;
         Aliste          idx1;
 
         if ((ofl->ofl_flags & FLG_OF_ADJOSCNT) == 0)
                 return;
 

@@ -192,42 +216,25 @@
          * one input section that has not been eliminated. If none are found,
          * the -z ignore processing above has eliminated that output section.
          */
         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
                 Aliste  idx2;
-                Word    ptype = sgp->sg_phdr.p_type;
 
                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
                         Aliste  idx3;
                         int     keep = 0, os_isdescs_idx;
 
                         OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx3, isp) {
-                                ifl = isp->is_file;
-
-                                /* Input section is tagged for discard? */
-                                if (isp->is_flags & FLG_IS_DISCARD)
-                                        continue;
-
-                                /*
-                                 * If the file is discarded, it will take
-                                 * the section with it.
-                                 */
-                                if (ifl &&
-                                    (((ifl->ifl_flags & FLG_IF_FILEREF) == 0) ||
-                                    ((ptype == PT_LOAD) &&
-                                    ((isp->is_flags & FLG_IS_SECTREF) == 0) &&
-                                    (isp->is_shdr->sh_size > 0))) &&
-                                    (ifl->ifl_flags & FLG_IF_IGNORE))
-                                        continue;
-
                                 /*
                                  * We have found a kept input section,
                                  * so the output section will be created.
                                  */
+                                if (!isdesc_discarded(isp)) {
                                 keep = 1;
                                 break;
                         }
+                        }
                         /*
                          * If no section of this name was kept, decrement
                          * the count and remove the name from .shstrtab.
                          */
                         if (keep == 0) {

@@ -2847,11 +2854,18 @@
          * Pass over the mergeable input sections, and if they haven't
          * all been discarded, create a string table.
          */
         mstrtab = NULL;
         for (APLIST_TRAVERSE(osp->os_mstrisdescs, idx, isp)) {
-                if (isp->is_flags & FLG_IS_DISCARD)
+                if (isdesc_discarded(isp))
+                        continue;
+
+                /*
+                 * Input sections of 0 size are dubiously valid since they do
+                 * not even contain the NUL string.  Ignore them.
+                 */
+                if (isp->is_shdr->sh_size == 0)
                         continue;
 
                 /*
                  * We have at least one non-discarded section.
                  * Create a string table descriptor.