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


 974  */
 975 static int
 976 sym_cap_vis(const char *name, Word hash, Sym *sym, Ofl_desc *ofl)
 977 {
 978         Sym_desc        *sdp;
 979         uchar_t         vis;
 980         avl_index_t     where;
 981         sd_flag_t       sdflags = 0;
 982 
 983         /*
 984          * Determine the visibility of the new symbol.
 985          */
 986         vis = ELF_ST_VISIBILITY(sym->st_other);
 987         switch (vis) {
 988         case STV_EXPORTED:
 989                 sdflags |= FLG_SY_EXPORT;
 990                 break;
 991         case STV_SINGLETON:
 992                 sdflags |= FLG_SY_SINGLE;
 993                 break;



 994         }
 995 
 996         /*
 997          * Determine whether a symbol definition already exists, and if so
 998          * obtain the visibility.
 999          */
1000         if ((sdp = ld_sym_find(name, hash, &where, ofl)) != NULL)
1001                 sdflags |= sdp->sd_flags;
1002 
1003         /*
1004          * Determine whether the symbol flags indicate this symbol should be
1005          * hidden.
1006          */
1007         if ((ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM)) &&
1008             ((sdflags & MSK_SY_NOAUTO) == 0))
1009                 sdflags |= FLG_SY_HIDDEN;
1010 
1011         return ((sdflags & FLG_SY_HIDDEN) == 0);
1012 }
1013 


1499                  * any further.
1500                  */
1501                 if (sdp->sd_ref == REF_DYN_SEEN)
1502                         continue;
1503 
1504                 /*
1505                  * Calculate the size and alignment requirements for the global
1506                  * .bss and .tls sections.  If we're building a relocatable
1507                  * object only account for scoped COMMON symbols (these will
1508                  * be converted to .bss references).
1509                  *
1510                  * When -z nopartial is in effect, partially initialized
1511                  * symbols are directed to the special .data section
1512                  * created for that purpose (ofl->ofl_isparexpn).
1513                  * Otherwise, partially initialized symbols go to .bss.
1514                  *
1515                  * Also refer to make_mvsections() in sunwmove.c
1516                  */
1517                 if ((sym->st_shndx == SHN_COMMON) &&
1518                     (((oflags & FLG_OF_RELOBJ) == 0) ||
1519                     (SYM_IS_HIDDEN(sdp) && (oflags & FLG_OF_PROCRED)))) {
1520                         if ((sdp->sd_move == NULL) ||
1521                             ((sdp->sd_flags & FLG_SY_PAREXPN) == 0)) {
1522                                 if (type != STT_TLS) {
1523                                         need_bss = TRUE;
1524                                         bsssize = (Xword)S_ROUND(bsssize,
1525                                             sym->st_value) + sym->st_size;
1526                                         if (sym->st_value > bssalign)
1527                                                 bssalign = sym->st_value;
1528                                 } else {
1529                                         need_tlsbss = TRUE;
1530                                         tlssize = (Xword)S_ROUND(tlssize,
1531                                             sym->st_value) + sym->st_size;
1532                                         if (sym->st_value > tlsalign)
1533                                                 tlsalign = sym->st_value;
1534                                 }
1535                         }
1536                 }
1537 
1538 #if     defined(_ELF64)
1539                 /*


1551                 }
1552 #endif
1553                 /*
1554                  * If a symbol was referenced via the command line
1555                  * (ld -u <>, ...), then this counts as a reference against the
1556                  * symbol. Mark any section that symbol is defined in.
1557                  */
1558                 if (((isp = sdp->sd_isc) != 0) &&
1559                     (sdp->sd_flags & FLG_SY_CMDREF)) {
1560                         isp->is_flags |= FLG_IS_SECTREF;
1561                         isp->is_file->ifl_flags |= FLG_IF_FILEREF;
1562                 }
1563 
1564                 /*
1565                  * Update the symbol count and the associated name string size.
1566                  * Note, a capabilities symbol must remain as visible as a
1567                  * global symbol.  However, the runtime linker recognizes the
1568                  * hidden requirement and ensures the symbol isn't made globally
1569                  * available at runtime.
1570                  */
1571                 if (SYM_IS_HIDDEN(sdp) && (oflags & FLG_OF_PROCRED)) {
1572                         /*
1573                          * If any reductions are being processed, keep a count
1574                          * of eliminated symbols, and if the symbol is being
1575                          * reduced to local, count it's size for the .symtab.
1576                          */
1577                         if (sdp->sd_flags & FLG_SY_ELIM) {
1578                                 ofl->ofl_elimcnt++;
1579                         } else {
1580                                 ofl->ofl_scopecnt++;
1581                                 if ((((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
1582                                     sym->st_name) && (st_insert(ofl->ofl_strtab,
1583                                     sdp->sd_name) == -1))
1584                                         return (S_ERROR);
1585                                 if (allow_ldynsym && sym->st_name &&
1586                                     ldynsym_symtype[type]) {
1587                                         ofl->ofl_dynscopecnt++;
1588                                         if (st_insert(ofl->ofl_dynstrtab,
1589                                             sdp->sd_name) == -1)
1590                                                 return (S_ERROR);
1591                                         /* Include it in sort section? */


3115         const char      *fmt;
3116         char            *str;
3117         size_t          len;
3118 
3119         if ((isp == NULL) || (isp->is_name == NULL))
3120                 return (NULL);
3121 
3122         if (isp->is_sym_name == NULL) {
3123                 fmt = (isp->is_flags & FLG_IS_GNSTRMRG) ?
3124                     MSG_INTL(MSG_STR_SECTION_MSTR) : MSG_INTL(MSG_STR_SECTION);
3125 
3126                 len = strlen(fmt) + strlen(isp->is_name) + 1;
3127 
3128                 if ((str = libld_malloc(len)) == NULL)
3129                         return (NULL);
3130                 (void) snprintf(str, len, fmt, isp->is_name);
3131                 isp->is_sym_name = str;
3132         }
3133 
3134         return (isp->is_sym_name);























3135 }


 974  */
 975 static int
 976 sym_cap_vis(const char *name, Word hash, Sym *sym, Ofl_desc *ofl)
 977 {
 978         Sym_desc        *sdp;
 979         uchar_t         vis;
 980         avl_index_t     where;
 981         sd_flag_t       sdflags = 0;
 982 
 983         /*
 984          * Determine the visibility of the new symbol.
 985          */
 986         vis = ELF_ST_VISIBILITY(sym->st_other);
 987         switch (vis) {
 988         case STV_EXPORTED:
 989                 sdflags |= FLG_SY_EXPORT;
 990                 break;
 991         case STV_SINGLETON:
 992                 sdflags |= FLG_SY_SINGLE;
 993                 break;
 994         case STV_HIDDEN:
 995                 sdflags |= FLG_SY_HIDDEN;
 996                 break;
 997         }
 998 
 999         /*
1000          * Determine whether a symbol definition already exists, and if so
1001          * obtain the visibility.
1002          */
1003         if ((sdp = ld_sym_find(name, hash, &where, ofl)) != NULL)
1004                 sdflags |= sdp->sd_flags;
1005 
1006         /*
1007          * Determine whether the symbol flags indicate this symbol should be
1008          * hidden.
1009          */
1010         if ((ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM)) &&
1011             ((sdflags & MSK_SY_NOAUTO) == 0))
1012                 sdflags |= FLG_SY_HIDDEN;
1013 
1014         return ((sdflags & FLG_SY_HIDDEN) == 0);
1015 }
1016 


1502                  * any further.
1503                  */
1504                 if (sdp->sd_ref == REF_DYN_SEEN)
1505                         continue;
1506 
1507                 /*
1508                  * Calculate the size and alignment requirements for the global
1509                  * .bss and .tls sections.  If we're building a relocatable
1510                  * object only account for scoped COMMON symbols (these will
1511                  * be converted to .bss references).
1512                  *
1513                  * When -z nopartial is in effect, partially initialized
1514                  * symbols are directed to the special .data section
1515                  * created for that purpose (ofl->ofl_isparexpn).
1516                  * Otherwise, partially initialized symbols go to .bss.
1517                  *
1518                  * Also refer to make_mvsections() in sunwmove.c
1519                  */
1520                 if ((sym->st_shndx == SHN_COMMON) &&
1521                     (((oflags & FLG_OF_RELOBJ) == 0) ||
1522                     ld_sym_reducable(ofl, sdp))) {
1523                         if ((sdp->sd_move == NULL) ||
1524                             ((sdp->sd_flags & FLG_SY_PAREXPN) == 0)) {
1525                                 if (type != STT_TLS) {
1526                                         need_bss = TRUE;
1527                                         bsssize = (Xword)S_ROUND(bsssize,
1528                                             sym->st_value) + sym->st_size;
1529                                         if (sym->st_value > bssalign)
1530                                                 bssalign = sym->st_value;
1531                                 } else {
1532                                         need_tlsbss = TRUE;
1533                                         tlssize = (Xword)S_ROUND(tlssize,
1534                                             sym->st_value) + sym->st_size;
1535                                         if (sym->st_value > tlsalign)
1536                                                 tlsalign = sym->st_value;
1537                                 }
1538                         }
1539                 }
1540 
1541 #if     defined(_ELF64)
1542                 /*


1554                 }
1555 #endif
1556                 /*
1557                  * If a symbol was referenced via the command line
1558                  * (ld -u <>, ...), then this counts as a reference against the
1559                  * symbol. Mark any section that symbol is defined in.
1560                  */
1561                 if (((isp = sdp->sd_isc) != 0) &&
1562                     (sdp->sd_flags & FLG_SY_CMDREF)) {
1563                         isp->is_flags |= FLG_IS_SECTREF;
1564                         isp->is_file->ifl_flags |= FLG_IF_FILEREF;
1565                 }
1566 
1567                 /*
1568                  * Update the symbol count and the associated name string size.
1569                  * Note, a capabilities symbol must remain as visible as a
1570                  * global symbol.  However, the runtime linker recognizes the
1571                  * hidden requirement and ensures the symbol isn't made globally
1572                  * available at runtime.
1573                  */
1574                 if (ld_sym_reducable(ofl, sdp)) {
1575                         /*
1576                          * If any reductions are being processed, keep a count
1577                          * of eliminated symbols, and if the symbol is being
1578                          * reduced to local, count it's size for the .symtab.
1579                          */
1580                         if (sdp->sd_flags & FLG_SY_ELIM) {
1581                                 ofl->ofl_elimcnt++;
1582                         } else {
1583                                 ofl->ofl_scopecnt++;
1584                                 if ((((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
1585                                     sym->st_name) && (st_insert(ofl->ofl_strtab,
1586                                     sdp->sd_name) == -1))
1587                                         return (S_ERROR);
1588                                 if (allow_ldynsym && sym->st_name &&
1589                                     ldynsym_symtype[type]) {
1590                                         ofl->ofl_dynscopecnt++;
1591                                         if (st_insert(ofl->ofl_dynstrtab,
1592                                             sdp->sd_name) == -1)
1593                                                 return (S_ERROR);
1594                                         /* Include it in sort section? */


3118         const char      *fmt;
3119         char            *str;
3120         size_t          len;
3121 
3122         if ((isp == NULL) || (isp->is_name == NULL))
3123                 return (NULL);
3124 
3125         if (isp->is_sym_name == NULL) {
3126                 fmt = (isp->is_flags & FLG_IS_GNSTRMRG) ?
3127                     MSG_INTL(MSG_STR_SECTION_MSTR) : MSG_INTL(MSG_STR_SECTION);
3128 
3129                 len = strlen(fmt) + strlen(isp->is_name) + 1;
3130 
3131                 if ((str = libld_malloc(len)) == NULL)
3132                         return (NULL);
3133                 (void) snprintf(str, len, fmt, isp->is_name);
3134                 isp->is_sym_name = str;
3135         }
3136 
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         }
3161 }