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


 143                 }
 144         }
 145 
 146         /*
 147          * Do not discard any symbols that are associated with non-allocable
 148          * segments.
 149          */
 150         if (isp && ((isp->is_flags & FLG_IS_SECTREF) == 0) &&
 151             ((osp = isp->is_osdesc) != 0) &&
 152             (osp->os_sgdesc->sg_phdr.p_type == PT_LOAD)) {
 153                 DBG_CALL(Dbg_syms_discarded(ofl->ofl_lml, sdp));
 154                 if (ifl->ifl_flags & FLG_IF_IGNORE) {
 155                         if (bind == STB_LOCAL)
 156                                 remove_local(ofl, sdp, allow_ldynsym);
 157                         else
 158                                 remove_scoped(ofl, sdp, allow_ldynsym);
 159                 }
 160         }
 161 }
 162 

























 163 /*
 164  * There are situations where we may count output sections (ofl_shdrcnt)
 165  * that are subsequently eliminated from the output object. Whether or
 166  * not this happens cannot be known until all input has been seen and
 167  * section elimination code has run. However, the situations where this
 168  * outcome is possible are known, and are flagged by setting FLG_OF_ADJOSCNT.
 169  *
 170  * If FLG_OF_ADJOSCNT is set, this routine makes a pass over the output
 171  * sections. If an unused output section is encountered, we decrement
 172  * ofl->ofl_shdrcnt and remove the section name from the .shstrtab string
 173  * table (ofl->ofl_shdrsttab).
 174  *
 175  * This code must be kept in sync with the similar code
 176  * found in outfile.c:ld_create_outfile().
 177  */
 178 static void
 179 adjust_os_count(Ofl_desc *ofl)
 180 {
 181         Sg_desc         *sgp;
 182         Is_desc         *isp;
 183         Os_desc         *osp;
 184         Ifl_desc        *ifl;
 185         Aliste          idx1;
 186 
 187         if ((ofl->ofl_flags & FLG_OF_ADJOSCNT) == 0)
 188                 return;
 189 
 190         /*
 191          * For each output section, look at the input sections to find at least
 192          * one input section that has not been eliminated. If none are found,
 193          * the -z ignore processing above has eliminated that output section.
 194          */
 195         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
 196                 Aliste  idx2;
 197                 Word    ptype = sgp->sg_phdr.p_type;
 198 
 199                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
 200                         Aliste  idx3;
 201                         int     keep = 0, os_isdescs_idx;
 202 
 203                         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                                 /*
 223                                  * We have found a kept input section,
 224                                  * so the output section will be created.
 225                                  */

 226                                 keep = 1;
 227                                 break;
 228                         }

 229                         /*
 230                          * If no section of this name was kept, decrement
 231                          * the count and remove the name from .shstrtab.
 232                          */
 233                         if (keep == 0) {
 234                                 /* LINTED - only used for assert() */
 235                                 int err;
 236 
 237                                 ofl->ofl_shdrcnt--;
 238                                 err = st_delstring(ofl->ofl_shdrsttab,
 239                                     osp->os_name);
 240                                 assert(err != -1);
 241                         }
 242                 }
 243         }
 244 }
 245 
 246 /*
 247  * If -zignore has been in effect, scan all input files to determine if the
 248  * file, or sections from the file, have been referenced.  If not, the file or


2832         Is_desc         *isp;
2833         Shdr            *mstr_shdr;
2834         Elf_Data        *mstr_data;
2835         Sym_desc        *sdp;
2836         Rel_desc        *rsp;
2837         Aliste          idx;
2838         size_t          data_size;
2839         int             st_setstring_status;
2840         size_t          stoff;
2841 
2842         /* If string table compression is disabled, there's nothing to do */
2843         if ((ofl->ofl_flags1 & FLG_OF1_NCSTTAB) != 0)
2844                 return (1);
2845 
2846         /*
2847          * Pass over the mergeable input sections, and if they haven't
2848          * all been discarded, create a string table.
2849          */
2850         mstrtab = NULL;
2851         for (APLIST_TRAVERSE(osp->os_mstrisdescs, idx, isp)) {
2852                 if (isp->is_flags & FLG_IS_DISCARD)







2853                         continue;
2854 
2855                 /*
2856                  * We have at least one non-discarded section.
2857                  * Create a string table descriptor.
2858                  */
2859                 if ((mstrtab = st_new(FLG_STNEW_COMPRESS)) == NULL)
2860                         return (S_ERROR);
2861                 break;
2862         }
2863 
2864         /* If no string table was created, we have no mergeable sections */
2865         if (mstrtab == NULL)
2866                 return (1);
2867 
2868         /*
2869          * This routine has to make 3 passes:
2870          *
2871          *      1) Examine all relocations, insert strings from relocations
2872          *              to the mergeable input sections into the string table.




 143                 }
 144         }
 145 
 146         /*
 147          * Do not discard any symbols that are associated with non-allocable
 148          * segments.
 149          */
 150         if (isp && ((isp->is_flags & FLG_IS_SECTREF) == 0) &&
 151             ((osp = isp->is_osdesc) != 0) &&
 152             (osp->os_sgdesc->sg_phdr.p_type == PT_LOAD)) {
 153                 DBG_CALL(Dbg_syms_discarded(ofl->ofl_lml, sdp));
 154                 if (ifl->ifl_flags & FLG_IF_IGNORE) {
 155                         if (bind == STB_LOCAL)
 156                                 remove_local(ofl, sdp, allow_ldynsym);
 157                         else
 158                                 remove_scoped(ofl, sdp, allow_ldynsym);
 159                 }
 160         }
 161 }
 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 
 188 /*
 189  * There are situations where we may count output sections (ofl_shdrcnt)
 190  * that are subsequently eliminated from the output object. Whether or
 191  * not this happens cannot be known until all input has been seen and
 192  * section elimination code has run. However, the situations where this
 193  * outcome is possible are known, and are flagged by setting FLG_OF_ADJOSCNT.
 194  *
 195  * If FLG_OF_ADJOSCNT is set, this routine makes a pass over the output
 196  * sections. If an unused output section is encountered, we decrement
 197  * ofl->ofl_shdrcnt and remove the section name from the .shstrtab string
 198  * table (ofl->ofl_shdrsttab).
 199  *
 200  * This code must be kept in sync with the similar code
 201  * found in outfile.c:ld_create_outfile().
 202  */
 203 static void
 204 adjust_os_count(Ofl_desc *ofl)
 205 {
 206         Sg_desc         *sgp;
 207         Is_desc         *isp;
 208         Os_desc         *osp;

 209         Aliste          idx1;
 210 
 211         if ((ofl->ofl_flags & FLG_OF_ADJOSCNT) == 0)
 212                 return;
 213 
 214         /*
 215          * For each output section, look at the input sections to find at least
 216          * one input section that has not been eliminated. If none are found,
 217          * the -z ignore processing above has eliminated that output section.
 218          */
 219         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
 220                 Aliste  idx2;

 221 
 222                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
 223                         Aliste  idx3;
 224                         int     keep = 0, os_isdescs_idx;
 225 
 226                         OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx3, isp) {


















 227                                 /*
 228                                  * We have found a kept input section,
 229                                  * so the output section will be created.
 230                                  */
 231                                 if (!isdesc_discarded(isp)) {
 232                                         keep = 1;
 233                                         break;
 234                                 }
 235                         }
 236                         /*
 237                          * If no section of this name was kept, decrement
 238                          * the count and remove the name from .shstrtab.
 239                          */
 240                         if (keep == 0) {
 241                                 /* LINTED - only used for assert() */
 242                                 int err;
 243 
 244                                 ofl->ofl_shdrcnt--;
 245                                 err = st_delstring(ofl->ofl_shdrsttab,
 246                                     osp->os_name);
 247                                 assert(err != -1);
 248                         }
 249                 }
 250         }
 251 }
 252 
 253 /*
 254  * If -zignore has been in effect, scan all input files to determine if the
 255  * file, or sections from the file, have been referenced.  If not, the file or


2839         Is_desc         *isp;
2840         Shdr            *mstr_shdr;
2841         Elf_Data        *mstr_data;
2842         Sym_desc        *sdp;
2843         Rel_desc        *rsp;
2844         Aliste          idx;
2845         size_t          data_size;
2846         int             st_setstring_status;
2847         size_t          stoff;
2848 
2849         /* If string table compression is disabled, there's nothing to do */
2850         if ((ofl->ofl_flags1 & FLG_OF1_NCSTTAB) != 0)
2851                 return (1);
2852 
2853         /*
2854          * Pass over the mergeable input sections, and if they haven't
2855          * all been discarded, create a string table.
2856          */
2857         mstrtab = NULL;
2858         for (APLIST_TRAVERSE(osp->os_mstrisdescs, idx, isp)) {
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)
2867                         continue;
2868 
2869                 /*
2870                  * We have at least one non-discarded section.
2871                  * Create a string table descriptor.
2872                  */
2873                 if ((mstrtab = st_new(FLG_STNEW_COMPRESS)) == NULL)
2874                         return (S_ERROR);
2875                 break;
2876         }
2877 
2878         /* If no string table was created, we have no mergeable sections */
2879         if (mstrtab == NULL)
2880                 return (1);
2881 
2882         /*
2883          * This routine has to make 3 passes:
2884          *
2885          *      1) Examine all relocations, insert strings from relocations
2886          *              to the mergeable input sections into the string table.