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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/libld/common/sections.c
          +++ new/usr/src/cmd/sgs/libld/common/sections.c
↓ open down ↓ 152 lines elided ↑ open up ↑
 153  153                  DBG_CALL(Dbg_syms_discarded(ofl->ofl_lml, sdp));
 154  154                  if (ifl->ifl_flags & FLG_IF_IGNORE) {
 155  155                          if (bind == STB_LOCAL)
 156  156                                  remove_local(ofl, sdp, allow_ldynsym);
 157  157                          else
 158  158                                  remove_scoped(ofl, sdp, allow_ldynsym);
 159  159                  }
 160  160          }
 161  161  }
 162  162  
      163 +static Boolean
      164 +isdesc_discarded(Is_desc *isp)
      165 +{
      166 +        Ifl_desc        *ifl = isp->is_file;
      167 +        Os_desc         *osp = isp->is_osdesc;
      168 +        Word            ptype = osp->os_sgdesc->sg_phdr.p_type;
      169 +
      170 +        if (isp->is_flags & FLG_IS_DISCARD)
      171 +                return TRUE;
      172 +
      173 +        /*
      174 +         * If the file is discarded, it will take
      175 +         * the section with it.
      176 +         */
      177 +        if (ifl &&
      178 +            (((ifl->ifl_flags & FLG_IF_FILEREF) == 0) ||
      179 +            ((ptype == PT_LOAD) &&
      180 +            ((isp->is_flags & FLG_IS_SECTREF) == 0) &&
      181 +            (isp->is_shdr->sh_size > 0))) &&
      182 +            (ifl->ifl_flags & FLG_IF_IGNORE))
      183 +                return TRUE;
      184 +
      185 +        return FALSE;
      186 +}
      187 +
 163  188  /*
 164  189   * There are situations where we may count output sections (ofl_shdrcnt)
 165  190   * that are subsequently eliminated from the output object. Whether or
 166  191   * not this happens cannot be known until all input has been seen and
 167  192   * section elimination code has run. However, the situations where this
 168  193   * outcome is possible are known, and are flagged by setting FLG_OF_ADJOSCNT.
 169  194   *
 170  195   * If FLG_OF_ADJOSCNT is set, this routine makes a pass over the output
 171  196   * sections. If an unused output section is encountered, we decrement
 172  197   * ofl->ofl_shdrcnt and remove the section name from the .shstrtab string
↓ open down ↓ 1 lines elided ↑ open up ↑
 174  199   *
 175  200   * This code must be kept in sync with the similar code
 176  201   * found in outfile.c:ld_create_outfile().
 177  202   */
 178  203  static void
 179  204  adjust_os_count(Ofl_desc *ofl)
 180  205  {
 181  206          Sg_desc         *sgp;
 182  207          Is_desc         *isp;
 183  208          Os_desc         *osp;
 184      -        Ifl_desc        *ifl;
 185  209          Aliste          idx1;
 186  210  
 187  211          if ((ofl->ofl_flags & FLG_OF_ADJOSCNT) == 0)
 188  212                  return;
 189  213  
 190  214          /*
 191  215           * For each output section, look at the input sections to find at least
 192  216           * one input section that has not been eliminated. If none are found,
 193  217           * the -z ignore processing above has eliminated that output section.
 194  218           */
 195  219          for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
 196  220                  Aliste  idx2;
 197      -                Word    ptype = sgp->sg_phdr.p_type;
 198  221  
 199  222                  for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
 200  223                          Aliste  idx3;
 201  224                          int     keep = 0, os_isdescs_idx;
 202  225  
 203  226                          OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx3, isp) {
 204      -                                ifl = isp->is_file;
 205      -
 206      -                                /* Input section is tagged for discard? */
 207      -                                if (isp->is_flags & FLG_IS_DISCARD)
 208      -                                        continue;
 209      -
 210      -                                /*
 211      -                                 * If the file is discarded, it will take
 212      -                                 * the section with it.
 213      -                                 */
 214      -                                if (ifl &&
 215      -                                    (((ifl->ifl_flags & FLG_IF_FILEREF) == 0) ||
 216      -                                    ((ptype == PT_LOAD) &&
 217      -                                    ((isp->is_flags & FLG_IS_SECTREF) == 0) &&
 218      -                                    (isp->is_shdr->sh_size > 0))) &&
 219      -                                    (ifl->ifl_flags & FLG_IF_IGNORE))
 220      -                                        continue;
 221      -
 222  227                                  /*
 223  228                                   * We have found a kept input section,
 224  229                                   * so the output section will be created.
 225  230                                   */
 226      -                                keep = 1;
 227      -                                break;
      231 +                                if (!isdesc_discarded(isp)) {
      232 +                                        keep = 1;
      233 +                                        break;
      234 +                                }
 228  235                          }
 229  236                          /*
 230  237                           * If no section of this name was kept, decrement
 231  238                           * the count and remove the name from .shstrtab.
 232  239                           */
 233  240                          if (keep == 0) {
 234  241                                  /* LINTED - only used for assert() */
 235  242                                  int err;
 236  243  
 237  244                                  ofl->ofl_shdrcnt--;
↓ open down ↓ 2604 lines elided ↑ open up ↑
2842 2849          /* If string table compression is disabled, there's nothing to do */
2843 2850          if ((ofl->ofl_flags1 & FLG_OF1_NCSTTAB) != 0)
2844 2851                  return (1);
2845 2852  
2846 2853          /*
2847 2854           * Pass over the mergeable input sections, and if they haven't
2848 2855           * all been discarded, create a string table.
2849 2856           */
2850 2857          mstrtab = NULL;
2851 2858          for (APLIST_TRAVERSE(osp->os_mstrisdescs, idx, isp)) {
2852      -                if (isp->is_flags & FLG_IS_DISCARD)
     2859 +                if (isdesc_discarded(isp))
     2860 +                        continue;
     2861 +
     2862 +                /*
     2863 +                 * Input sections of 0 size are dubiously valid since they do
     2864 +                 * not even contain the NUL string.  Ignore them.
     2865 +                 */
     2866 +                if (isp->is_shdr->sh_size == 0)
2853 2867                          continue;
2854 2868  
2855 2869                  /*
2856 2870                   * We have at least one non-discarded section.
2857 2871                   * Create a string table descriptor.
2858 2872                   */
2859 2873                  if ((mstrtab = st_new(FLG_STNEW_COMPRESS)) == NULL)
2860 2874                          return (S_ERROR);
2861 2875                  break;
2862 2876          }
↓ open down ↓ 649 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX