Print this page
10346 ld(1) should not reduce symbol visibility of COMDAT symbols when producing relocatable objects

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/sgs/libld/common/syms.c
          +++ new/usr/src/cmd/sgs/libld/common/syms.c
↓ open down ↓ 628 lines elided ↑ open up ↑
 629  629   * other symbol directives will the nodirect binding be recorded.  This ensures
 630  630   * we don't create syminfo sections for all objects we create, as this might add
 631  631   * unnecessary bloat to users who haven't explicitly requested extra symbol
 632  632   * information.
 633  633   */
 634  634  static uintptr_t
 635  635  sym_add_spec(const char *name, const char *uname, Word sdaux_id,
 636  636      sd_flag_t sdflags_u, sd_flag_t sdflags, Ofl_desc *ofl)
 637  637  {
 638  638          Sym_desc        *sdp;
 639      -        Sym_desc        *usdp;
      639 +        Sym_desc        *usdp;
 640  640          Sym             *sym;
 641  641          Word            hash;
 642  642          avl_index_t     where;
 643  643  
 644  644          /* LINTED */
 645  645          hash = (Word)elf_hash(uname);
 646  646          if (usdp = ld_sym_find(uname, hash, &where, ofl)) {
 647  647                  /*
 648  648                   * If the underscore symbol exists and is undefined, or was
 649  649                   * defined in a shared library, convert it to a local symbol.
↓ open down ↓ 138 lines elided ↑ open up ↑
 788  788  /*
 789  789   * Undefined symbols can fall into one of four types:
 790  790   *
 791  791   *  -   the symbol is really undefined (SHN_UNDEF).
 792  792   *
 793  793   *  -   versioning has been enabled, however this symbol has not been assigned
 794  794   *      to one of the defined versions.
 795  795   *
 796  796   *  -   the symbol has been defined by an implicitly supplied library, ie. one
 797  797   *      which was encounted because it was NEEDED by another library, rather
 798      - *      than from a command line supplied library which would become the only
      798 + *      than from a command line supplied library which would become the only
 799  799   *      dependency of the output file being produced.
 800  800   *
 801  801   *  -   the symbol has been defined by a version of a shared object that is
 802  802   *      not permitted for this link-edit.
 803  803   *
 804  804   * In all cases the file who made the first reference to this symbol will have
 805  805   * been recorded via the `sa_rfile' pointer.
 806  806   */
 807  807  typedef enum {
 808  808          UNDEF,          NOVERSION,      IMPLICIT,       NOTAVAIL,
↓ open down ↓ 175 lines elided ↑ open up ↑
 984  984           * Determine the visibility of the new symbol.
 985  985           */
 986  986          vis = ELF_ST_VISIBILITY(sym->st_other);
 987  987          switch (vis) {
 988  988          case STV_EXPORTED:
 989  989                  sdflags |= FLG_SY_EXPORT;
 990  990                  break;
 991  991          case STV_SINGLETON:
 992  992                  sdflags |= FLG_SY_SINGLE;
 993  993                  break;
      994 +        case STV_HIDDEN:
      995 +                sdflags |= FLG_SY_HIDDEN;
      996 +                break;
 994  997          }
 995  998  
 996  999          /*
 997 1000           * Determine whether a symbol definition already exists, and if so
 998 1001           * obtain the visibility.
 999 1002           */
1000 1003          if ((sdp = ld_sym_find(name, hash, &where, ofl)) != NULL)
1001 1004                  sdflags |= sdp->sd_flags;
1002 1005  
1003 1006          /*
↓ open down ↓ 122 lines elided ↑ open up ↑
1126 1129  
1127 1130          return (ret);
1128 1131  }
1129 1132  
1130 1133  /*
1131 1134   * After all symbol table input processing has been finished, and all relocation
1132 1135   * counting has been carried out (ie. no more symbols will be read, generated,
1133 1136   * or modified), validate and count the relevant entries:
1134 1137   *
1135 1138   *  -   check and print any undefined symbols remaining.  Note that if a symbol
1136      - *      has been defined by virtue of the inclusion of  an implicit shared
     1139 + *      has been defined by virtue of the inclusion of  an implicit shared
1137 1140   *      library, it is still classed as undefined.
1138 1141   *
1139 1142   *  -   count the number of global needed symbols together with the size of
1140 1143   *      their associated name strings (if scoping has been indicated these
1141 1144   *      symbols may be reduced to locals).
1142 1145   *
1143 1146   *  -   establish the size and alignment requirements for the global .bss
1144      - *      section (the alignment of this section is based on the  first symbol
     1147 + *      section (the alignment of this section is based on the  first symbol
1145 1148   *      that it will contain).
1146 1149   */
1147 1150  uintptr_t
1148 1151  ld_sym_validate(Ofl_desc *ofl)
1149 1152  {
1150 1153          Sym_avlnode     *sav;
1151 1154          Sym_desc        *sdp;
1152 1155          Sym             *sym;
1153 1156          ofl_flag_t      oflags = ofl->ofl_flags;
1154 1157          ofl_flag_t      undef = 0, needed = 0, verdesc = 0;
↓ open down ↓ 354 lines elided ↑ open up ↑
1509 1512                   *
1510 1513                   * When -z nopartial is in effect, partially initialized
1511 1514                   * symbols are directed to the special .data section
1512 1515                   * created for that purpose (ofl->ofl_isparexpn).
1513 1516                   * Otherwise, partially initialized symbols go to .bss.
1514 1517                   *
1515 1518                   * Also refer to make_mvsections() in sunwmove.c
1516 1519                   */
1517 1520                  if ((sym->st_shndx == SHN_COMMON) &&
1518 1521                      (((oflags & FLG_OF_RELOBJ) == 0) ||
1519      -                    (SYM_IS_HIDDEN(sdp) && (oflags & FLG_OF_PROCRED)))) {
     1522 +                    ld_sym_reducable(ofl, sdp))) {
1520 1523                          if ((sdp->sd_move == NULL) ||
1521 1524                              ((sdp->sd_flags & FLG_SY_PAREXPN) == 0)) {
1522 1525                                  if (type != STT_TLS) {
1523 1526                                          need_bss = TRUE;
1524 1527                                          bsssize = (Xword)S_ROUND(bsssize,
1525 1528                                              sym->st_value) + sym->st_size;
1526 1529                                          if (sym->st_value > bssalign)
1527 1530                                                  bssalign = sym->st_value;
1528 1531                                  } else {
1529 1532                                          need_tlsbss = TRUE;
↓ open down ↓ 31 lines elided ↑ open up ↑
1561 1564                          isp->is_file->ifl_flags |= FLG_IF_FILEREF;
1562 1565                  }
1563 1566  
1564 1567                  /*
1565 1568                   * Update the symbol count and the associated name string size.
1566 1569                   * Note, a capabilities symbol must remain as visible as a
1567 1570                   * global symbol.  However, the runtime linker recognizes the
1568 1571                   * hidden requirement and ensures the symbol isn't made globally
1569 1572                   * available at runtime.
1570 1573                   */
1571      -                if (SYM_IS_HIDDEN(sdp) && (oflags & FLG_OF_PROCRED)) {
     1574 +                if (ld_sym_reducable(ofl, sdp)) {
1572 1575                          /*
1573 1576                           * If any reductions are being processed, keep a count
1574 1577                           * of eliminated symbols, and if the symbol is being
1575 1578                           * reduced to local, count it's size for the .symtab.
1576 1579                           */
1577 1580                          if (sdp->sd_flags & FLG_SY_ELIM) {
1578 1581                                  ofl->ofl_elimcnt++;
1579 1582                          } else {
1580 1583                                  ofl->ofl_scopecnt++;
1581 1584                                  if ((((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
↓ open down ↓ 301 lines elided ↑ open up ↑
1883 1886          Sym_desc        *c_osdp;        /* original symbol */
1884 1887          Cap_group       *c_group;       /* symbol capability group */
1885 1888          Word            c_ndx;          /* symbol index */
1886 1889  } Cap_pair;
1887 1890  
1888 1891  /*
1889 1892   * Process the symbol table for the specified input file.  At this point all
1890 1893   * input sections from this input file have been assigned an input section
1891 1894   * descriptor which is saved in the `ifl_isdesc' array.
1892 1895   *
1893      - *  -   local symbols are saved (as is) if the input file is a  relocatable
     1896 + *  -   local symbols are saved (as is) if the input file is a relocatable
1894 1897   *      object
1895 1898   *
1896 1899   *  -   global symbols are added to the linkers internal symbol table if they
1897 1900   *      are not already present, otherwise a symbol resolution function is
1898 1901   *      called upon to resolve the conflict.
1899 1902   */
1900 1903  uintptr_t
1901 1904  ld_sym_process(Is_desc *isc, Ifl_desc *ifl, Ofl_desc *ofl)
1902 1905  {
1903 1906          /*
↓ open down ↓ 1221 lines elided ↑ open up ↑
3125 3128  
3126 3129                  len = strlen(fmt) + strlen(isp->is_name) + 1;
3127 3130  
3128 3131                  if ((str = libld_malloc(len)) == NULL)
3129 3132                          return (NULL);
3130 3133                  (void) snprintf(str, len, fmt, isp->is_name);
3131 3134                  isp->is_sym_name = str;
3132 3135          }
3133 3136  
3134 3137          return (isp->is_sym_name);
     3138 +}
     3139 +
     3140 +/*
     3141 + * If we're producing a relocatable object and the symbol is eligible for
     3142 + * COMDAT section, it shouldn't be reduced in scope as that will break the
     3143 + * COMDAT matching when the output object is later consumed.  Leave it alone,
     3144 + * and any reduction (and COMDAT) processing will occur then.
     3145 + *
     3146 + * Otherwise, any hidden symbol is reduced when reductions are being processed.
     3147 + */
     3148 +Boolean
     3149 +ld_sym_reducable(Ofl_desc *ofl, Sym_desc *sdp)
     3150 +{
     3151 +        Is_desc *isc = sdp->sd_isc;
     3152 +
     3153 +        if (((ofl->ofl_flags & FLG_OF_RELOBJ) != 0) &&
     3154 +            (isc != NULL) &&
     3155 +            ((isc->is_flags & FLG_IS_COMDAT) != 0)) {
     3156 +                return (FALSE);
     3157 +        } else {
     3158 +                return (SYM_IS_HIDDEN(sdp) &&
     3159 +                    (ofl->ofl_flags & FLG_OF_PROCRED));
     3160 +        }
3135 3161  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX