Print this page
10366 ld(1) should support GNU-style linker sets
10367 ld(1) tests should be a real test suite
10368 want an ld(1) regression test for i386 LD tls transition (10267)


  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  *      Copyright (c) 1988 AT&T
  24  *        All Rights Reserved
  25  *
  26  *
  27  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  28  */
  29 
  30 /*
  31  * Symbol table management routines
  32  */
  33 
  34 #define ELF_TARGET_AMD64
  35 
  36 #include        <stdio.h>
  37 #include        <string.h>
  38 #include        <debug.h>

  39 #include        "msg.h"
  40 #include        "_libld.h"
  41 
  42 /*
  43  * AVL tree comparator function:
  44  *
  45  * The primary key is the symbol name hash with a secondary key of the symbol
  46  * name itself.
  47  */
  48 int
  49 ld_sym_avl_comp(const void *elem1, const void *elem2)
  50 {
  51         Sym_avlnode     *sav1 = (Sym_avlnode *)elem1;
  52         Sym_avlnode     *sav2 = (Sym_avlnode *)elem2;
  53         int             res;
  54 
  55         res = sav1->sav_hash - sav2->sav_hash;
  56 
  57         if (res < 0)
  58                 return (-1);


 675                                 if (sdaux_id == SDAUX_ID_GOT) {
 676                                         usdp->sd_flags &= ~FLG_SY_NDIR;
 677                                         usdp->sd_flags |= FLG_SY_PROTECT;
 678                                         usdp->sd_sym->st_other = STV_PROTECTED;
 679                                 } else if (
 680                                     ((usdp->sd_flags & FLG_SY_DIR) == 0) &&
 681                                     ((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
 682                                         usdp->sd_flags |= FLG_SY_NDIR;
 683                                 }
 684                         }
 685                         usdp->sd_flags |= sdflags;
 686 
 687                         /*
 688                          * If the reference originated from a mapfile ensure
 689                          * we mark the symbol as used.
 690                          */
 691                         if (usdp->sd_flags & FLG_SY_MAPREF)
 692                                 usdp->sd_flags |= FLG_SY_MAPUSED;
 693 
 694                         DBG_CALL(Dbg_syms_updated(ofl, usdp, uname));
 695                 } else
 696                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE),
 697                             uname, usdp->sd_file->ifl_name);

 698         } else {
 699                 /*
 700                  * If the symbol does not exist create it.
 701                  */
 702                 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
 703                         return (S_ERROR);
 704                 sym->st_shndx = SHN_ABS;
 705                 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
 706                 sym->st_size = 0;
 707                 sym->st_value = 0;
 708                 DBG_CALL(Dbg_syms_created(ofl->ofl_lml, uname));
 709                 if ((usdp = ld_sym_enter(uname, sym, hash, (Ifl_desc *)NULL,
 710                     ofl, 0, SHN_ABS, (FLG_SY_SPECSEC | sdflags_u), &where)) ==
 711                     (Sym_desc *)S_ERROR)
 712                         return (S_ERROR);
 713                 usdp->sd_ref = REF_REL_NEED;
 714                 /* LINTED */
 715                 usdp->sd_aux->sa_symspec = (Half)sdaux_id;
 716 
 717                 usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;


 868                 name1 = ifl->ifl_name;
 869                 break;
 870         case IMPLICIT:
 871                 name1 = sap->sa_rfile;
 872                 name2 = ifl->ifl_name;
 873                 break;
 874         case NOTAVAIL:
 875                 name1 = sap->sa_rfile;
 876                 name2 = sap->sa_vfile;
 877                 name3 = ifl->ifl_verndx[sap->sa_dverndx].vi_name;
 878                 break;
 879         default:
 880                 return;
 881         }
 882 
 883         ld_eprintf(ofl, ERR_NONE, MSG_INTL(format[type]),
 884             demangle(sdp->sd_name), name1, name2, name3);
 885 }
 886 
 887 /*





















































 888  * At this point all symbol input processing has been completed, therefore
 889  * complete the symbol table entries by generating any necessary internal
 890  * symbols.
 891  */
 892 uintptr_t
 893 ld_sym_spec(Ofl_desc *ofl)
 894 {
 895         Sym_desc        *sdp;


 896 
 897         if (ofl->ofl_flags & FLG_OF_RELOBJ)
 898                 return (1);
 899 
 900         DBG_CALL(Dbg_syms_spec_title(ofl->ofl_lml));
 901 


















 902         if (sym_add_spec(MSG_ORIG(MSG_SYM_ETEXT), MSG_ORIG(MSG_SYM_ETEXT_U),
 903             SDAUX_ID_ETEXT, 0, (FLG_SY_DEFAULT | FLG_SY_EXPDEF),
 904             ofl) == S_ERROR)
 905                 return (S_ERROR);
 906         if (sym_add_spec(MSG_ORIG(MSG_SYM_EDATA), MSG_ORIG(MSG_SYM_EDATA_U),
 907             SDAUX_ID_EDATA, 0, (FLG_SY_DEFAULT | FLG_SY_EXPDEF),
 908             ofl) == S_ERROR)
 909                 return (S_ERROR);
 910         if (sym_add_spec(MSG_ORIG(MSG_SYM_END), MSG_ORIG(MSG_SYM_END_U),
 911             SDAUX_ID_END, FLG_SY_DYNSORT, (FLG_SY_DEFAULT | FLG_SY_EXPDEF),
 912             ofl) == S_ERROR)
 913                 return (S_ERROR);
 914         if (sym_add_spec(MSG_ORIG(MSG_SYM_L_END), MSG_ORIG(MSG_SYM_L_END_U),
 915             SDAUX_ID_END, 0, FLG_SY_HIDDEN, ofl) == S_ERROR)
 916                 return (S_ERROR);
 917         if (sym_add_spec(MSG_ORIG(MSG_SYM_L_START), MSG_ORIG(MSG_SYM_L_START_U),
 918             SDAUX_ID_START, 0, FLG_SY_HIDDEN, ofl) == S_ERROR)
 919                 return (S_ERROR);
 920 
 921         /*




  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  *      Copyright (c) 1988 AT&T
  24  *        All Rights Reserved
  25  *
  26  *
  27  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  28  */
  29 
  30 /*
  31  * Symbol table management routines
  32  */
  33 
  34 #define ELF_TARGET_AMD64
  35 
  36 #include        <stdio.h>
  37 #include        <string.h>
  38 #include        <debug.h>
  39 #include        <alloca.h>
  40 #include        "msg.h"
  41 #include        "_libld.h"
  42 
  43 /*
  44  * AVL tree comparator function:
  45  *
  46  * The primary key is the symbol name hash with a secondary key of the symbol
  47  * name itself.
  48  */
  49 int
  50 ld_sym_avl_comp(const void *elem1, const void *elem2)
  51 {
  52         Sym_avlnode     *sav1 = (Sym_avlnode *)elem1;
  53         Sym_avlnode     *sav2 = (Sym_avlnode *)elem2;
  54         int             res;
  55 
  56         res = sav1->sav_hash - sav2->sav_hash;
  57 
  58         if (res < 0)
  59                 return (-1);


 676                                 if (sdaux_id == SDAUX_ID_GOT) {
 677                                         usdp->sd_flags &= ~FLG_SY_NDIR;
 678                                         usdp->sd_flags |= FLG_SY_PROTECT;
 679                                         usdp->sd_sym->st_other = STV_PROTECTED;
 680                                 } else if (
 681                                     ((usdp->sd_flags & FLG_SY_DIR) == 0) &&
 682                                     ((ofl->ofl_flags & FLG_OF_SYMBOLIC) == 0)) {
 683                                         usdp->sd_flags |= FLG_SY_NDIR;
 684                                 }
 685                         }
 686                         usdp->sd_flags |= sdflags;
 687 
 688                         /*
 689                          * If the reference originated from a mapfile ensure
 690                          * we mark the symbol as used.
 691                          */
 692                         if (usdp->sd_flags & FLG_SY_MAPREF)
 693                                 usdp->sd_flags |= FLG_SY_MAPUSED;
 694 
 695                         DBG_CALL(Dbg_syms_updated(ofl, usdp, uname));
 696                 } else {
 697                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE),
 698                             uname, usdp->sd_file->ifl_name);
 699                 }
 700         } else {
 701                 /*
 702                  * If the symbol does not exist create it.
 703                  */
 704                 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
 705                         return (S_ERROR);
 706                 sym->st_shndx = SHN_ABS;
 707                 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
 708                 sym->st_size = 0;
 709                 sym->st_value = 0;
 710                 DBG_CALL(Dbg_syms_created(ofl->ofl_lml, uname));
 711                 if ((usdp = ld_sym_enter(uname, sym, hash, (Ifl_desc *)NULL,
 712                     ofl, 0, SHN_ABS, (FLG_SY_SPECSEC | sdflags_u), &where)) ==
 713                     (Sym_desc *)S_ERROR)
 714                         return (S_ERROR);
 715                 usdp->sd_ref = REF_REL_NEED;
 716                 /* LINTED */
 717                 usdp->sd_aux->sa_symspec = (Half)sdaux_id;
 718 
 719                 usdp->sd_aux->sa_overndx = VER_NDX_GLOBAL;


 870                 name1 = ifl->ifl_name;
 871                 break;
 872         case IMPLICIT:
 873                 name1 = sap->sa_rfile;
 874                 name2 = ifl->ifl_name;
 875                 break;
 876         case NOTAVAIL:
 877                 name1 = sap->sa_rfile;
 878                 name2 = sap->sa_vfile;
 879                 name3 = ifl->ifl_verndx[sap->sa_dverndx].vi_name;
 880                 break;
 881         default:
 882                 return;
 883         }
 884 
 885         ld_eprintf(ofl, ERR_NONE, MSG_INTL(format[type]),
 886             demangle(sdp->sd_name), name1, name2, name3);
 887 }
 888 
 889 /*
 890  * If an undef symbol exists naming a bound for the output section,
 891  * turn it into a defined symbol with the correct value.
 892  *
 893  * We set an arbitrary 1KB limit on the resulting symbol names.
 894  */
 895 static void
 896 sym_add_bounds(Ofl_desc *ofl, Os_desc *osp, Word bound)
 897 {
 898         Sym_desc *bsdp;
 899         char symn[1024];
 900         size_t nsz;
 901 
 902         switch (bound) {
 903         case SDAUX_ID_SECBOUND_START:
 904                 nsz = snprintf(symn, sizeof (symn), "%s%s",
 905                     MSG_ORIG(MSG_SYM_SECBOUND_START), osp->os_name + 1);
 906                 if (nsz > sizeof (symn))
 907                         return;
 908                 break;
 909         case SDAUX_ID_SECBOUND_STOP:
 910                 nsz = snprintf(symn, sizeof (symn), "%s%s",
 911                     MSG_ORIG(MSG_SYM_SECBOUND_STOP), osp->os_name + 1);
 912                 if (nsz > sizeof (symn))
 913                         return;
 914                 break;
 915         default:
 916                 assert(0);
 917         }
 918 
 919         if ((bsdp = ld_sym_find(symn, SYM_NOHASH, NULL, ofl)) != NULL) {
 920                 if ((bsdp->sd_shndx != SHN_UNDEF) &&
 921                     (bsdp->sd_ref == REF_REL_NEED)) {
 922                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_RESERVE),
 923                             symn, bsdp->sd_file->ifl_name);
 924                         return;
 925                 }
 926 
 927                 DBG_CALL(Dbg_syms_updated(ofl, bsdp, symn));
 928 
 929                 bsdp->sd_aux->sa_symspec = bound;
 930                 bsdp->sd_aux->sa_boundsec = osp;
 931                 bsdp->sd_flags |= FLG_SY_SPECSEC;
 932                 bsdp->sd_ref = REF_REL_NEED;
 933                 bsdp->sd_sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
 934                 bsdp->sd_sym->st_other = STV_PROTECTED;
 935                 bsdp->sd_isc = NULL;
 936                 bsdp->sd_sym->st_size = 0;
 937                 bsdp->sd_sym->st_value = 0;
 938                 bsdp->sd_shndx = bsdp->sd_sym->st_shndx = SHN_ABS;
 939         }
 940 }
 941 
 942 /*
 943  * At this point all symbol input processing has been completed, therefore
 944  * complete the symbol table entries by generating any necessary internal
 945  * symbols.
 946  */
 947 uintptr_t
 948 ld_sym_spec(Ofl_desc *ofl)
 949 {
 950         Sym_desc        *sdp;
 951         Sg_desc         *sgp;
 952         Aliste          idx1;
 953 
 954         if (ofl->ofl_flags & FLG_OF_RELOBJ)
 955                 return (1);
 956 
 957         DBG_CALL(Dbg_syms_spec_title(ofl->ofl_lml));
 958 
 959         /*
 960          * For each section in the output file, look for symbols named for the
 961          * __start/__stop patterns.  If references exist, flesh the symbols to
 962          * be defined.
 963          *
 964          * the symbols are given values at the same time as the other special
 965          * symbols.
 966          */
 967         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
 968                 Os_desc *osp;
 969                 Aliste idx2;
 970 
 971                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
 972                         sym_add_bounds(ofl, osp, SDAUX_ID_SECBOUND_START);
 973                         sym_add_bounds(ofl, osp, SDAUX_ID_SECBOUND_STOP);
 974                 }
 975         }
 976 
 977         if (sym_add_spec(MSG_ORIG(MSG_SYM_ETEXT), MSG_ORIG(MSG_SYM_ETEXT_U),
 978             SDAUX_ID_ETEXT, 0, (FLG_SY_DEFAULT | FLG_SY_EXPDEF),
 979             ofl) == S_ERROR)
 980                 return (S_ERROR);
 981         if (sym_add_spec(MSG_ORIG(MSG_SYM_EDATA), MSG_ORIG(MSG_SYM_EDATA_U),
 982             SDAUX_ID_EDATA, 0, (FLG_SY_DEFAULT | FLG_SY_EXPDEF),
 983             ofl) == S_ERROR)
 984                 return (S_ERROR);
 985         if (sym_add_spec(MSG_ORIG(MSG_SYM_END), MSG_ORIG(MSG_SYM_END_U),
 986             SDAUX_ID_END, FLG_SY_DYNSORT, (FLG_SY_DEFAULT | FLG_SY_EXPDEF),
 987             ofl) == S_ERROR)
 988                 return (S_ERROR);
 989         if (sym_add_spec(MSG_ORIG(MSG_SYM_L_END), MSG_ORIG(MSG_SYM_L_END_U),
 990             SDAUX_ID_END, 0, FLG_SY_HIDDEN, ofl) == S_ERROR)
 991                 return (S_ERROR);
 992         if (sym_add_spec(MSG_ORIG(MSG_SYM_L_START), MSG_ORIG(MSG_SYM_L_START_U),
 993             SDAUX_ID_START, 0, FLG_SY_HIDDEN, ofl) == S_ERROR)
 994                 return (S_ERROR);
 995 
 996         /*