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 /*
|