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>

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/libld/common/groups.c
          +++ new/usr/src/cmd/sgs/libld/common/groups.c
↓ open down ↓ 110 lines elided ↑ open up ↑
 111  111                          if (data[ndx] == scnndx)
 112  112                                  return (gdp);
 113  113                  }
 114  114          }
 115  115  
 116  116          ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_ELF_NOGROUPSECT),
 117  117              ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name);
 118  118          return (NULL);
 119  119  }
 120  120  
      121 +/*
      122 + * When creating a .debug_macro section, in an attempt to make certain DWARF
      123 + * macro information shareable, the GNU compiler must construct group sections
      124 + * with a repeatable signature symbol while nevertheless having no actual
      125 + * symbol to refer to (because it relates to macros).
      126 + *
      127 + * We use this as yet another way to clue ourselves in that sloppy relocation
      128 + * will likely be required.
      129 + *
      130 + * The format of these gensym'd names is:
      131 + *    wm<offset size>.<encoded path name>.<lineno>.<32byte hash>
      132 + * Where the encoded file name may be absent.
      133 + */
      134 +static boolean_t
      135 +is_header_gensym(const char *name)
      136 +{
      137 +        const char *c = NULL;
      138 +
      139 +        /* No room for leader, hash, and periods */
      140 +        if (strlen(name) < 37)
      141 +                return (B_FALSE);
      142 +
      143 +        if ((strncmp(name, "wm4.", 4) != 0) &&
      144 +          strncmp(name, "wm8.", 4) != 0)
      145 +                return (B_FALSE);
      146 +
      147 +        c = &name[strlen(name) - 33];
      148 +        if (*c++ != '.')
      149 +                return (B_FALSE);
      150 +
      151 +        for (; *c != '\0'; c++) {
      152 +                if (!(((*c >= 'a') && (*c <= 'f')) ||
      153 +                    ((*c >= '0') && (*c <= '9')))) {
      154 +                        return (B_FALSE);
      155 +                }
      156 +        }
      157 +
      158 +        return (B_TRUE);
      159 +}
      160 +
 121  161  uintptr_t
 122  162  ld_group_process(Is_desc *gisc, Ofl_desc *ofl)
 123  163  {
 124  164          Ifl_desc        *gifl = gisc->is_file;
 125  165          Shdr            *sshdr, *gshdr = gisc->is_shdr;
 126  166          Is_desc         *isc;
 127  167          Sym             *sym;
 128  168          const char      *str;
 129  169          Group_desc      gd;
 130  170          size_t          ndx;
↓ open down ↓ 83 lines elided ↑ open up ↑
 214  254                                  str = gisc->is_sym_name;
 215  255                  }
 216  256  
 217  257                  ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_GRP_INVALSYM),
 218  258                      gifl->ifl_name, EC_WORD(gisc->is_scnndx),
 219  259                      gisc->is_name, str);
 220  260                  return (0);
 221  261          }
 222  262  
 223  263          /*
      264 +         * If the signature symbol is a name generated by the GNU compiler to
      265 +         * refer to a header, we need sloppy relocation.
      266 +         */
      267 +        if (is_header_gensym(str)) {
      268 +            if ((ofl->ofl_flags1 & FLG_OF1_NRLXREL) == 0)
      269 +                ofl->ofl_flags1 |= FLG_OF1_RLXREL;
      270 +            DBG_CALL(Dbg_sec_gnu_comdat(ofl->ofl_lml, gisc, TRUE,
      271 +              (ofl->ofl_flags1 & FLG_OF1_RLXREL) != 0));
      272 +        }
      273 +
      274 +        /*
 224  275           * Validate the section indices within the group.  If this is a COMDAT
 225  276           * group, mark each section as COMDAT.
 226  277           */
 227  278          for (ndx = 1; ndx < gd.gd_cnt; ndx++) {
 228  279                  Word    gndx;
 229  280  
 230  281                  if ((gndx = gd.gd_data[ndx]) >= gifl->ifl_shnum) {
 231  282                          ld_eprintf(ofl, ERR_FATAL,
 232  283                              MSG_INTL(MSG_GRP_INVALNDX), gifl->ifl_name,
 233  284                              EC_WORD(gisc->is_scnndx), gisc->is_name, ndx, gndx);
↓ open down ↓ 24 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX