Lines 269-274
Link Here
|
269 |
GL(dl_rtld_map).l_mach = info->l.l_mach; |
269 |
GL(dl_rtld_map).l_mach = info->l.l_mach; |
270 |
#endif |
270 |
#endif |
271 |
_dl_setup_hash (&GL(dl_rtld_map)); |
271 |
_dl_setup_hash (&GL(dl_rtld_map)); |
|
|
272 |
GL(dl_rtld_map).l_real = &GL(dl_rtld_map); |
272 |
GL(dl_rtld_map).l_opencount = 1; |
273 |
GL(dl_rtld_map).l_opencount = 1; |
273 |
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin; |
274 |
GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin; |
274 |
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; |
275 |
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; |
Lines 585-598
Link Here
|
585 |
{ |
586 |
{ |
586 |
struct map_args *args = (struct map_args *) a; |
587 |
struct map_args *args = (struct map_args *) a; |
587 |
args->map = _dl_map_object (args->loader, args->str, |
588 |
args->map = _dl_map_object (args->loader, args->str, |
588 |
args->is_preloaded, lt_library, 0, args->mode); |
589 |
args->is_preloaded, lt_library, 0, args->mode, |
|
|
590 |
LM_ID_BASE); |
589 |
} |
591 |
} |
590 |
|
592 |
|
591 |
static void |
593 |
static void |
592 |
version_check_doit (void *a) |
594 |
version_check_doit (void *a) |
593 |
{ |
595 |
{ |
594 |
struct version_check_args *args = (struct version_check_args *) a; |
596 |
struct version_check_args *args = (struct version_check_args *) a; |
595 |
if (_dl_check_all_versions (GL(dl_loaded), 1, args->dotrace) && args->doexit) |
597 |
if (_dl_check_all_versions (GL(dl_ns)[LM_ID_BASE]._ns_loaded, 1, |
|
|
598 |
args->dotrace) && args->doexit) |
596 |
/* We cannot start the application. Abort now. */ |
599 |
/* We cannot start the application. Abort now. */ |
597 |
_exit (1); |
600 |
_exit (1); |
598 |
} |
601 |
} |
Lines 601-611
Link Here
|
601 |
static inline struct link_map * |
604 |
static inline struct link_map * |
602 |
find_needed (const char *name) |
605 |
find_needed (const char *name) |
603 |
{ |
606 |
{ |
604 |
unsigned int n = GL(dl_loaded)->l_searchlist.r_nlist; |
607 |
struct r_scope_elem *scope = &GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_searchlist; |
|
|
608 |
unsigned int n = scope->r_nlist; |
605 |
|
609 |
|
606 |
while (n-- > 0) |
610 |
while (n-- > 0) |
607 |
if (_dl_name_match_p (name, GL(dl_loaded)->l_searchlist.r_list[n])) |
611 |
if (_dl_name_match_p (name, scope->r_list[n])) |
608 |
return GL(dl_loaded)->l_searchlist.r_list[n]; |
612 |
return scope->r_list[n]; |
609 |
|
613 |
|
610 |
/* Should never happen. */ |
614 |
/* Should never happen. */ |
611 |
return NULL; |
615 |
return NULL; |
Lines 685-690
Link Here
|
685 |
enum mode mode; |
689 |
enum mode mode; |
686 |
struct link_map **preloads; |
690 |
struct link_map **preloads; |
687 |
unsigned int npreloads; |
691 |
unsigned int npreloads; |
|
|
692 |
struct link_map *main_map; |
688 |
size_t file_size; |
693 |
size_t file_size; |
689 |
char *file; |
694 |
char *file; |
690 |
bool has_interp = false; |
695 |
bool has_interp = false; |
Lines 860-890
Link Here
|
860 |
{ |
865 |
{ |
861 |
HP_TIMING_NOW (start); |
866 |
HP_TIMING_NOW (start); |
862 |
_dl_map_object (NULL, rtld_progname, 0, lt_library, 0, |
867 |
_dl_map_object (NULL, rtld_progname, 0, lt_library, 0, |
863 |
__RTLD_OPENEXEC); |
868 |
__RTLD_OPENEXEC, LM_ID_BASE); |
864 |
HP_TIMING_NOW (stop); |
869 |
HP_TIMING_NOW (stop); |
865 |
|
870 |
|
866 |
HP_TIMING_DIFF (load_time, start, stop); |
871 |
HP_TIMING_DIFF (load_time, start, stop); |
867 |
} |
872 |
} |
868 |
|
873 |
|
869 |
phdr = GL(dl_loaded)->l_phdr; |
874 |
/* Now the map for the main executable is available. */ |
870 |
phnum = GL(dl_loaded)->l_phnum; |
875 |
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; |
|
|
876 |
|
877 |
phdr = main_map->l_phdr; |
878 |
phnum = main_map->l_phnum; |
871 |
/* We overwrite here a pointer to a malloc()ed string. But since |
879 |
/* We overwrite here a pointer to a malloc()ed string. But since |
872 |
the malloc() implementation used at this point is the dummy |
880 |
the malloc() implementation used at this point is the dummy |
873 |
implementations which has no real free() function it does not |
881 |
implementations which has no real free() function it does not |
874 |
makes sense to free the old string first. */ |
882 |
makes sense to free the old string first. */ |
875 |
GL(dl_loaded)->l_name = (char *) ""; |
883 |
main_map->l_name = (char *) ""; |
876 |
*user_entry = GL(dl_loaded)->l_entry; |
884 |
*user_entry = main_map->l_entry; |
877 |
} |
885 |
} |
878 |
else |
886 |
else |
879 |
{ |
887 |
{ |
880 |
/* Create a link_map for the executable itself. |
888 |
/* Create a link_map for the executable itself. |
881 |
This will be what dlopen on "" returns. */ |
889 |
This will be what dlopen on "" returns. */ |
882 |
_dl_new_object ((char *) "", "", lt_executable, NULL, 0); |
890 |
_dl_new_object ((char *) "", "", lt_executable, NULL, 0, LM_ID_BASE); |
883 |
if (GL(dl_loaded) == NULL) |
891 |
main_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; |
|
|
892 |
if (main_map == NULL) |
884 |
_dl_fatal_printf ("cannot allocate memory for link map\n"); |
893 |
_dl_fatal_printf ("cannot allocate memory for link map\n"); |
885 |
GL(dl_loaded)->l_phdr = phdr; |
894 |
main_map->l_phdr = phdr; |
886 |
GL(dl_loaded)->l_phnum = phnum; |
895 |
main_map->l_phnum = phnum; |
887 |
GL(dl_loaded)->l_entry = *user_entry; |
896 |
main_map->l_entry = *user_entry; |
888 |
|
897 |
|
889 |
/* At this point we are in a bit of trouble. We would have to |
898 |
/* At this point we are in a bit of trouble. We would have to |
890 |
fill in the values for l_dev and l_ino. But in general we |
899 |
fill in the values for l_dev and l_ino. But in general we |
Lines 905-916
Link Here
|
905 |
information for the program. */ |
914 |
information for the program. */ |
906 |
} |
915 |
} |
907 |
|
916 |
|
908 |
GL(dl_loaded)->l_map_end = 0; |
917 |
main_map->l_map_end = 0; |
909 |
GL(dl_loaded)->l_text_end = 0; |
918 |
main_map->l_text_end = 0; |
910 |
/* Perhaps the executable has no PT_LOAD header entries at all. */ |
919 |
/* Perhaps the executable has no PT_LOAD header entries at all. */ |
911 |
GL(dl_loaded)->l_map_start = ~0; |
920 |
main_map->l_map_start = ~0; |
912 |
/* We opened the file, account for it. */ |
921 |
/* We opened the file, account for it. */ |
913 |
++GL(dl_loaded)->l_opencount; |
922 |
++main_map->l_opencount; |
|
|
923 |
/* And it was opened directly. */ |
924 |
++main_map->l_direct_opencount; |
914 |
|
925 |
|
915 |
/* Scan the program header table for the dynamic section. */ |
926 |
/* Scan the program header table for the dynamic section. */ |
916 |
for (ph = phdr; ph < &phdr[phnum]; ++ph) |
927 |
for (ph = phdr; ph < &phdr[phnum]; ++ph) |
Lines 918-929
Link Here
|
918 |
{ |
929 |
{ |
919 |
case PT_PHDR: |
930 |
case PT_PHDR: |
920 |
/* Find out the load address. */ |
931 |
/* Find out the load address. */ |
921 |
GL(dl_loaded)->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr; |
932 |
main_map->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr; |
922 |
break; |
933 |
break; |
923 |
case PT_DYNAMIC: |
934 |
case PT_DYNAMIC: |
924 |
/* This tells us where to find the dynamic section, |
935 |
/* This tells us where to find the dynamic section, |
925 |
which tells us everything we need to do. */ |
936 |
which tells us everything we need to do. */ |
926 |
GL(dl_loaded)->l_ld = (void *) GL(dl_loaded)->l_addr + ph->p_vaddr; |
937 |
main_map->l_ld = (void *) main_map->l_addr + ph->p_vaddr; |
927 |
break; |
938 |
break; |
928 |
case PT_INTERP: |
939 |
case PT_INTERP: |
929 |
/* This "interpreter segment" was used by the program loader to |
940 |
/* This "interpreter segment" was used by the program loader to |
Lines 932-938
Link Here
|
932 |
dlopen call or DT_NEEDED entry, for something that wants to link |
943 |
dlopen call or DT_NEEDED entry, for something that wants to link |
933 |
against the dynamic linker as a shared library, will know that |
944 |
against the dynamic linker as a shared library, will know that |
934 |
the shared object is already loaded. */ |
945 |
the shared object is already loaded. */ |
935 |
_dl_rtld_libname.name = ((const char *) GL(dl_loaded)->l_addr |
946 |
_dl_rtld_libname.name = ((const char *) main_map->l_addr |
936 |
+ ph->p_vaddr); |
947 |
+ ph->p_vaddr); |
937 |
/* _dl_rtld_libname.next = NULL; Already zero. */ |
948 |
/* _dl_rtld_libname.next = NULL; Already zero. */ |
938 |
GL(dl_rtld_map).l_libname = &_dl_rtld_libname; |
949 |
GL(dl_rtld_map).l_libname = &_dl_rtld_libname; |
Lines 968-984
Link Here
|
968 |
ElfW(Addr) allocend; |
979 |
ElfW(Addr) allocend; |
969 |
|
980 |
|
970 |
/* Remember where the main program starts in memory. */ |
981 |
/* Remember where the main program starts in memory. */ |
971 |
mapstart = (GL(dl_loaded)->l_addr |
982 |
mapstart = (main_map->l_addr + (ph->p_vaddr & ~(ph->p_align - 1))); |
972 |
+ (ph->p_vaddr & ~(ph->p_align - 1))); |
983 |
if (main_map->l_map_start > mapstart) |
973 |
if (GL(dl_loaded)->l_map_start > mapstart) |
984 |
main_map->l_map_start = mapstart; |
974 |
GL(dl_loaded)->l_map_start = mapstart; |
|
|
975 |
|
985 |
|
976 |
/* Also where it ends. */ |
986 |
/* Also where it ends. */ |
977 |
allocend = GL(dl_loaded)->l_addr + ph->p_vaddr + ph->p_memsz; |
987 |
allocend = main_map->l_addr + ph->p_vaddr + ph->p_memsz; |
978 |
if (GL(dl_loaded)->l_map_end < allocend) |
988 |
if (main_map->l_map_end < allocend) |
979 |
GL(dl_loaded)->l_map_end = allocend; |
989 |
main_map->l_map_end = allocend; |
980 |
if ((ph->p_flags & PF_X) && allocend > GL(dl_loaded)->l_text_end) |
990 |
if ((ph->p_flags & PF_X) && allocend > main_map->l_text_end) |
981 |
GL(dl_loaded)->l_text_end = allocend; |
991 |
main_map->l_text_end = allocend; |
982 |
} |
992 |
} |
983 |
break; |
993 |
break; |
984 |
#ifdef USE_TLS |
994 |
#ifdef USE_TLS |
Lines 989-1006
Link Here
|
989 |
here since we read the PT_TLS entry already in |
999 |
here since we read the PT_TLS entry already in |
990 |
_dl_start_final. But the result is repeatable so do not |
1000 |
_dl_start_final. But the result is repeatable so do not |
991 |
check for this special but unimportant case. */ |
1001 |
check for this special but unimportant case. */ |
992 |
GL(dl_loaded)->l_tls_blocksize = ph->p_memsz; |
1002 |
main_map->l_tls_blocksize = ph->p_memsz; |
993 |
GL(dl_loaded)->l_tls_align = ph->p_align; |
1003 |
main_map->l_tls_align = ph->p_align; |
994 |
if (ph->p_align == 0) |
1004 |
if (ph->p_align == 0) |
995 |
GL(dl_loaded)->l_tls_firstbyte_offset = 0; |
1005 |
main_map->l_tls_firstbyte_offset = 0; |
996 |
else |
1006 |
else |
997 |
GL(dl_loaded)->l_tls_firstbyte_offset = (ph->p_vaddr |
1007 |
main_map->l_tls_firstbyte_offset = (ph->p_vaddr |
998 |
& (ph->p_align - 1)); |
1008 |
& (ph->p_align - 1)); |
999 |
GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz; |
1009 |
main_map->l_tls_initimage_size = ph->p_filesz; |
1000 |
GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr; |
1010 |
main_map->l_tls_initimage = (void *) ph->p_vaddr; |
1001 |
|
1011 |
|
1002 |
/* This image gets the ID one. */ |
1012 |
/* This image gets the ID one. */ |
1003 |
GL(dl_tls_max_dtv_idx) = GL(dl_loaded)->l_tls_modid = 1; |
1013 |
GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1; |
1004 |
} |
1014 |
} |
1005 |
break; |
1015 |
break; |
1006 |
#endif |
1016 |
#endif |
Lines 1009-1029
Link Here
|
1009 |
break; |
1019 |
break; |
1010 |
|
1020 |
|
1011 |
case PT_GNU_RELRO: |
1021 |
case PT_GNU_RELRO: |
1012 |
GL(dl_loaded)->l_relro_addr = ph->p_vaddr; |
1022 |
main_map->l_relro_addr = ph->p_vaddr; |
1013 |
GL(dl_loaded)->l_relro_size = ph->p_memsz; |
1023 |
main_map->l_relro_size = ph->p_memsz; |
1014 |
break; |
1024 |
break; |
1015 |
} |
1025 |
} |
1016 |
#ifdef USE_TLS |
1026 |
#ifdef USE_TLS |
1017 |
/* Adjust the address of the TLS initialization image in case |
1027 |
/* Adjust the address of the TLS initialization image in case |
1018 |
the executable is actually an ET_DYN object. */ |
1028 |
the executable is actually an ET_DYN object. */ |
1019 |
if (GL(dl_loaded)->l_tls_initimage != NULL) |
1029 |
if (main_map->l_tls_initimage != NULL) |
1020 |
GL(dl_loaded)->l_tls_initimage |
1030 |
main_map->l_tls_initimage |
1021 |
= (char *) GL(dl_loaded)->l_tls_initimage + GL(dl_loaded)->l_addr; |
1031 |
= (char *) main_map->l_tls_initimage + main_map->l_addr; |
1022 |
#endif |
1032 |
#endif |
1023 |
if (! GL(dl_loaded)->l_map_end) |
1033 |
if (! main_map->l_map_end) |
1024 |
GL(dl_loaded)->l_map_end = ~0; |
1034 |
main_map->l_map_end = ~0; |
1025 |
if (! GL(dl_loaded)->l_text_end) |
1035 |
if (! main_map->l_text_end) |
1026 |
GL(dl_loaded)->l_text_end = ~0; |
1036 |
main_map->l_text_end = ~0; |
1027 |
if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name) |
1037 |
if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name) |
1028 |
{ |
1038 |
{ |
1029 |
/* We were invoked directly, so the program might not have a |
1039 |
/* We were invoked directly, so the program might not have a |
Lines 1038-1046
Link Here
|
1038 |
if (! rtld_is_main) |
1048 |
if (! rtld_is_main) |
1039 |
{ |
1049 |
{ |
1040 |
/* Extract the contents of the dynamic section for easy access. */ |
1050 |
/* Extract the contents of the dynamic section for easy access. */ |
1041 |
elf_get_dynamic_info (GL(dl_loaded), NULL); |
1051 |
elf_get_dynamic_info (main_map, NULL); |
1042 |
/* Set up our cache of pointers into the hash table. */ |
1052 |
/* Set up our cache of pointers into the hash table. */ |
1043 |
_dl_setup_hash (GL(dl_loaded)); |
1053 |
_dl_setup_hash (main_map); |
1044 |
} |
1054 |
} |
1045 |
|
1055 |
|
1046 |
if (__builtin_expect (mode, normal) == verify) |
1056 |
if (__builtin_expect (mode, normal) == verify) |
Lines 1049-1055
Link Here
|
1049 |
executable using us as the program interpreter. Exit with an |
1059 |
executable using us as the program interpreter. Exit with an |
1050 |
error if we were not able to load the binary or no interpreter |
1060 |
error if we were not able to load the binary or no interpreter |
1051 |
is specified (i.e., this is no dynamically linked binary. */ |
1061 |
is specified (i.e., this is no dynamically linked binary. */ |
1052 |
if (GL(dl_loaded)->l_ld == NULL) |
1062 |
if (main_map->l_ld == NULL) |
1053 |
_exit (1); |
1063 |
_exit (1); |
1054 |
|
1064 |
|
1055 |
/* We allow here some platform specific code. */ |
1065 |
/* We allow here some platform specific code. */ |
Lines 1072-1087
Link Here
|
1072 |
found by the PT_INTERP name. */ |
1082 |
found by the PT_INTERP name. */ |
1073 |
GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name; |
1083 |
GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name; |
1074 |
GL(dl_rtld_map).l_type = lt_library; |
1084 |
GL(dl_rtld_map).l_type = lt_library; |
1075 |
GL(dl_loaded)->l_next = &GL(dl_rtld_map); |
1085 |
main_map->l_next = &GL(dl_rtld_map); |
1076 |
GL(dl_rtld_map).l_prev = GL(dl_loaded); |
1086 |
GL(dl_rtld_map).l_prev = main_map; |
1077 |
++GL(dl_nloaded); |
1087 |
++GL(dl_ns)[LM_ID_BASE]._ns_nloaded; |
1078 |
++GL(dl_load_adds); |
1088 |
++GL(dl_load_adds); |
1079 |
|
1089 |
|
1080 |
/* If LD_USE_LOAD_BIAS env variable has not been seen, default |
1090 |
/* If LD_USE_LOAD_BIAS env variable has not been seen, default |
1081 |
to not using bias for non-prelinked PIEs and libraries |
1091 |
to not using bias for non-prelinked PIEs and libraries |
1082 |
and using it for executables or prelinked PIEs or libraries. */ |
1092 |
and using it for executables or prelinked PIEs or libraries. */ |
1083 |
if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2) |
1093 |
if (GLRO(dl_use_load_bias) == (ElfW(Addr)) -2) |
1084 |
GLRO(dl_use_load_bias) = (GL(dl_loaded)->l_addr == 0) ? -1 : 0; |
1094 |
GLRO(dl_use_load_bias) = main_map->l_addr == 0 ? -1 : 0; |
1085 |
|
1095 |
|
1086 |
/* Set up the program header information for the dynamic linker |
1096 |
/* Set up the program header information for the dynamic linker |
1087 |
itself. It is needed in the dl_iterate_phdr() callbacks. */ |
1097 |
itself. It is needed in the dl_iterate_phdr() callbacks. */ |
Lines 1125-1132
Link Here
|
1125 |
&& (__builtin_expect (! INTUSE(__libc_enable_secure), 1) |
1135 |
&& (__builtin_expect (! INTUSE(__libc_enable_secure), 1) |
1126 |
|| strchr (p, '/') == NULL)) |
1136 |
|| strchr (p, '/') == NULL)) |
1127 |
{ |
1137 |
{ |
1128 |
struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1, |
1138 |
struct link_map *new_map = _dl_map_object (main_map, p, 1, |
1129 |
lt_library, 0, 0); |
1139 |
lt_library, 0, 0, |
|
|
1140 |
LM_ID_BASE); |
1130 |
if (++new_map->l_opencount == 1) |
1141 |
if (++new_map->l_opencount == 1) |
1131 |
/* It is no duplicate. */ |
1142 |
/* It is no duplicate. */ |
1132 |
++npreloads; |
1143 |
++npreloads; |
Lines 1208-1214
Link Here
|
1208 |
struct map_args args; |
1219 |
struct map_args args; |
1209 |
|
1220 |
|
1210 |
args.str = p; |
1221 |
args.str = p; |
1211 |
args.loader = GL(dl_loaded); |
1222 |
args.loader = main_map; |
1212 |
args.is_preloaded = 1; |
1223 |
args.is_preloaded = 1; |
1213 |
args.mode = 0; |
1224 |
args.mode = 0; |
1214 |
|
1225 |
|
Lines 1231-1238
Link Here
|
1231 |
if (problem != NULL) |
1242 |
if (problem != NULL) |
1232 |
{ |
1243 |
{ |
1233 |
char *p = strndupa (problem, file_size - (problem - file)); |
1244 |
char *p = strndupa (problem, file_size - (problem - file)); |
1234 |
struct link_map *new_map = _dl_map_object (GL(dl_loaded), p, 1, |
1245 |
struct link_map *new_map = _dl_map_object (main_map, p, 1, |
1235 |
lt_library, 0, 0); |
1246 |
lt_library, 0, 0, |
|
|
1247 |
LM_ID_BASE); |
1236 |
if (++new_map->l_opencount == 1) |
1248 |
if (++new_map->l_opencount == 1) |
1237 |
/* It is no duplicate. */ |
1249 |
/* It is no duplicate. */ |
1238 |
++npreloads; |
1250 |
++npreloads; |
Lines 1272-1278
Link Here
|
1272 |
We just want our data structures to describe it as if we had just |
1284 |
We just want our data structures to describe it as if we had just |
1273 |
mapped and relocated it normally. */ |
1285 |
mapped and relocated it normally. */ |
1274 |
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, |
1286 |
struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL, |
1275 |
0); |
1287 |
0, LM_ID_BASE); |
1276 |
if (__builtin_expect (l != NULL, 1)) |
1288 |
if (__builtin_expect (l != NULL, 1)) |
1277 |
{ |
1289 |
{ |
1278 |
static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; |
1290 |
static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro; |
Lines 1337-1354
Link Here
|
1337 |
specified some libraries to load, these are inserted before the actual |
1349 |
specified some libraries to load, these are inserted before the actual |
1338 |
dependencies in the executable's searchlist for symbol resolution. */ |
1350 |
dependencies in the executable's searchlist for symbol resolution. */ |
1339 |
HP_TIMING_NOW (start); |
1351 |
HP_TIMING_NOW (start); |
1340 |
_dl_map_object_deps (GL(dl_loaded), preloads, npreloads, mode == trace, 0); |
1352 |
_dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0); |
1341 |
HP_TIMING_NOW (stop); |
1353 |
HP_TIMING_NOW (stop); |
1342 |
HP_TIMING_DIFF (diff, start, stop); |
1354 |
HP_TIMING_DIFF (diff, start, stop); |
1343 |
HP_TIMING_ACCUM_NT (load_time, diff); |
1355 |
HP_TIMING_ACCUM_NT (load_time, diff); |
1344 |
|
1356 |
|
1345 |
/* Mark all objects as being in the global scope and set the open |
1357 |
/* Mark all objects as being in the global scope and set the open |
1346 |
counter. */ |
1358 |
counter. */ |
1347 |
for (i = GL(dl_loaded)->l_searchlist.r_nlist; i > 0; ) |
1359 |
for (i = main_map->l_searchlist.r_nlist; i > 0; ) |
1348 |
{ |
1360 |
{ |
1349 |
--i; |
1361 |
--i; |
1350 |
GL(dl_loaded)->l_searchlist.r_list[i]->l_global = 1; |
1362 |
main_map->l_searchlist.r_list[i]->l_global = 1; |
1351 |
++GL(dl_loaded)->l_searchlist.r_list[i]->l_opencount; |
1363 |
++main_map->l_searchlist.r_list[i]->l_opencount; |
1352 |
} |
1364 |
} |
1353 |
|
1365 |
|
1354 |
#ifndef MAP_ANON |
1366 |
#ifndef MAP_ANON |
Lines 1369-1381
Link Here
|
1369 |
chain in symbol search order because gdb uses the chain's order as |
1381 |
chain in symbol search order because gdb uses the chain's order as |
1370 |
its symbol search order. */ |
1382 |
its symbol search order. */ |
1371 |
i = 1; |
1383 |
i = 1; |
1372 |
while (GL(dl_loaded)->l_searchlist.r_list[i] != &GL(dl_rtld_map)) |
1384 |
while (main_map->l_searchlist.r_list[i] != &GL(dl_rtld_map)) |
1373 |
++i; |
1385 |
++i; |
1374 |
GL(dl_rtld_map).l_prev = GL(dl_loaded)->l_searchlist.r_list[i - 1]; |
1386 |
GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1]; |
1375 |
if (__builtin_expect (mode, normal) == normal) |
1387 |
if (__builtin_expect (mode, normal) == normal) |
1376 |
{ |
1388 |
{ |
1377 |
GL(dl_rtld_map).l_next = (i + 1 < GL(dl_loaded)->l_searchlist.r_nlist |
1389 |
GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist |
1378 |
? GL(dl_loaded)->l_searchlist.r_list[i + 1] |
1390 |
? main_map->l_searchlist.r_list[i + 1] |
1379 |
: NULL); |
1391 |
: NULL); |
1380 |
#ifdef NEED_DL_SYSINFO |
1392 |
#ifdef NEED_DL_SYSINFO |
1381 |
if (sysinfo_map != NULL |
1393 |
if (sysinfo_map != NULL |
Lines 1459-1465
Link Here
|
1459 |
GL(dl_tls_dtv_slotinfo_list)->next = NULL; |
1471 |
GL(dl_tls_dtv_slotinfo_list)->next = NULL; |
1460 |
|
1472 |
|
1461 |
/* Fill in the information from the loaded modules. */ |
1473 |
/* Fill in the information from the loaded modules. */ |
1462 |
for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next) |
1474 |
for (l = main_map, i = 0; l != NULL; l = l->l_next) |
1463 |
if (l->l_tls_blocksize != 0) |
1475 |
if (l->l_tls_blocksize != 0) |
1464 |
/* This is a module with TLS data. Store the map reference. |
1476 |
/* This is a module with TLS data. Store the map reference. |
1465 |
The generation counter is zero. */ |
1477 |
The generation counter is zero. */ |
Lines 1495-1501
Link Here
|
1495 |
|
1507 |
|
1496 |
if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) |
1508 |
if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) |
1497 |
{ |
1509 |
{ |
1498 |
struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist; |
1510 |
struct r_scope_elem *scope = &main_map->l_searchlist; |
1499 |
|
1511 |
|
1500 |
for (i = 0; i < scope->r_nlist; i++) |
1512 |
for (i = 0; i < scope->r_nlist; i++) |
1501 |
{ |
1513 |
{ |
Lines 1531-1537
Link Here
|
1531 |
/* Look through the dependencies of the main executable |
1543 |
/* Look through the dependencies of the main executable |
1532 |
and determine which of them is not actually |
1544 |
and determine which of them is not actually |
1533 |
required. */ |
1545 |
required. */ |
1534 |
struct link_map *l = GL(dl_loaded); |
1546 |
struct link_map *l = main_map; |
1535 |
|
1547 |
|
1536 |
/* Relocate the main executable. */ |
1548 |
/* Relocate the main executable. */ |
1537 |
struct relocate_args args = { .l = l, .lazy = GLRO(dl_lazy) }; |
1549 |
struct relocate_args args = { .l = l, .lazy = GLRO(dl_lazy) }; |
Lines 1539-1545
Link Here
|
1539 |
|
1551 |
|
1540 |
/* This loop depends on the dependencies of the executable to |
1552 |
/* This loop depends on the dependencies of the executable to |
1541 |
correspond in number and order to the DT_NEEDED entries. */ |
1553 |
correspond in number and order to the DT_NEEDED entries. */ |
1542 |
ElfW(Dyn) *dyn = GL(dl_loaded)->l_ld; |
1554 |
ElfW(Dyn) *dyn = main_map->l_ld; |
1543 |
bool first = true; |
1555 |
bool first = true; |
1544 |
while (dyn->d_tag != DT_NULL) |
1556 |
while (dyn->d_tag != DT_NULL) |
1545 |
{ |
1557 |
{ |
Lines 1564-1574
Link Here
|
1564 |
|
1576 |
|
1565 |
_exit (first != true); |
1577 |
_exit (first != true); |
1566 |
} |
1578 |
} |
1567 |
else if (! GL(dl_loaded)->l_info[DT_NEEDED]) |
1579 |
else if (! main_map->l_info[DT_NEEDED]) |
1568 |
_dl_printf ("\tstatically linked\n"); |
1580 |
_dl_printf ("\tstatically linked\n"); |
1569 |
else |
1581 |
else |
1570 |
{ |
1582 |
{ |
1571 |
for (l = GL(dl_loaded)->l_next; l; l = l->l_next) |
1583 |
for (l = main_map->l_next; l; l = l->l_next) |
1572 |
if (l->l_faked) |
1584 |
if (l->l_faked) |
1573 |
/* The library was not found. */ |
1585 |
/* The library was not found. */ |
1574 |
_dl_printf ("\t%s => not found\n", l->l_libname->name); |
1586 |
_dl_printf ("\t%s => not found\n", l->l_libname->name); |
Lines 1589-1596
Link Here
|
1589 |
ElfW(Addr) loadbase; |
1601 |
ElfW(Addr) loadbase; |
1590 |
lookup_t result; |
1602 |
lookup_t result; |
1591 |
|
1603 |
|
1592 |
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], GL(dl_loaded), |
1604 |
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map, |
1593 |
&ref, GL(dl_loaded)->l_scope, NULL, |
1605 |
&ref, main_map->l_scope, NULL, |
1594 |
ELF_RTYPE_CLASS_PLT, |
1606 |
ELF_RTYPE_CLASS_PLT, |
1595 |
DL_LOOKUP_ADD_DEPENDENCY, NULL); |
1607 |
DL_LOOKUP_ADD_DEPENDENCY, NULL); |
1596 |
|
1608 |
|
Lines 1613-1619
Link Here
|
1613 |
|
1625 |
|
1614 |
args.lazy = GLRO(dl_lazy); |
1626 |
args.lazy = GLRO(dl_lazy); |
1615 |
|
1627 |
|
1616 |
l = GL(dl_loaded); |
1628 |
l = main_map; |
1617 |
while (l->l_next) |
1629 |
while (l->l_next) |
1618 |
l = l->l_next; |
1630 |
l = l->l_next; |
1619 |
do |
1631 |
do |
Lines 1629-1635
Link Here
|
1629 |
|
1641 |
|
1630 |
if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) |
1642 |
if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK) |
1631 |
&& GL(dl_rtld_map).l_opencount > 1) |
1643 |
&& GL(dl_rtld_map).l_opencount > 1) |
1632 |
_dl_relocate_object (&GL(dl_rtld_map), GL(dl_loaded)->l_scope, |
1644 |
_dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, |
1633 |
0, 0); |
1645 |
0, 0); |
1634 |
} |
1646 |
} |
1635 |
|
1647 |
|
Lines 1639-1647
Link Here
|
1639 |
/* Print more information. This means here, print information |
1651 |
/* Print more information. This means here, print information |
1640 |
about the versions needed. */ |
1652 |
about the versions needed. */ |
1641 |
int first = 1; |
1653 |
int first = 1; |
1642 |
struct link_map *map = GL(dl_loaded); |
1654 |
struct link_map *map; |
1643 |
|
1655 |
|
1644 |
for (map = GL(dl_loaded); map != NULL; map = map->l_next) |
1656 |
for (map = main_map; map != NULL; map = map->l_next) |
1645 |
{ |
1657 |
{ |
1646 |
const char *strtab; |
1658 |
const char *strtab; |
1647 |
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG]; |
1659 |
ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG]; |
Lines 1709-1736
Link Here
|
1709 |
_exit (0); |
1721 |
_exit (0); |
1710 |
} |
1722 |
} |
1711 |
|
1723 |
|
1712 |
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)] |
1724 |
if (main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)] |
1713 |
&& ! __builtin_expect (GLRO(dl_profile) != NULL, 0)) |
1725 |
&& ! __builtin_expect (GLRO(dl_profile) != NULL, 0)) |
1714 |
{ |
1726 |
{ |
1715 |
ElfW(Lib) *liblist, *liblistend; |
1727 |
ElfW(Lib) *liblist, *liblistend; |
1716 |
struct link_map **r_list, **r_listend, *l; |
1728 |
struct link_map **r_list, **r_listend, *l; |
1717 |
const char *strtab = (const void *) D_PTR (GL(dl_loaded), |
1729 |
const char *strtab = (const void *) D_PTR (main_map, l_info[DT_STRTAB]); |
1718 |
l_info[DT_STRTAB]); |
|
|
1719 |
|
1730 |
|
1720 |
assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL); |
1731 |
assert (main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)] != NULL); |
1721 |
liblist = (ElfW(Lib) *) |
1732 |
liblist = (ElfW(Lib) *) |
1722 |
GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr; |
1733 |
main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr; |
1723 |
liblistend = (ElfW(Lib) *) |
1734 |
liblistend = (ElfW(Lib) *) |
1724 |
((char *) liblist |
1735 |
((char *) liblist + |
1725 |
+ GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val); |
1736 |
main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val); |
1726 |
r_list = GL(dl_loaded)->l_searchlist.r_list; |
1737 |
r_list = main_map->l_searchlist.r_list; |
1727 |
r_listend = r_list + GL(dl_loaded)->l_searchlist.r_nlist; |
1738 |
r_listend = r_list + main_map->l_searchlist.r_nlist; |
1728 |
|
1739 |
|
1729 |
for (; r_list < r_listend && liblist < liblistend; r_list++) |
1740 |
for (; r_list < r_listend && liblist < liblistend; r_list++) |
1730 |
{ |
1741 |
{ |
1731 |
l = *r_list; |
1742 |
l = *r_list; |
1732 |
|
1743 |
|
1733 |
if (l == GL(dl_loaded)) |
1744 |
if (l == main_map) |
1734 |
continue; |
1745 |
continue; |
1735 |
|
1746 |
|
1736 |
/* If the library is not mapped where it should, fail. */ |
1747 |
/* If the library is not mapped where it should, fail. */ |
Lines 1767-1775
Link Here
|
1767 |
/* Initialize _r_debug. */ |
1778 |
/* Initialize _r_debug. */ |
1768 |
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr); |
1779 |
struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr); |
1769 |
{ |
1780 |
{ |
1770 |
struct link_map *l; |
1781 |
struct link_map *l = main_map; |
1771 |
|
|
|
1772 |
l = GL(dl_loaded); |
1773 |
|
1782 |
|
1774 |
#ifdef ELF_MACHINE_DEBUG_SETUP |
1783 |
#ifdef ELF_MACHINE_DEBUG_SETUP |
1775 |
|
1784 |
|
Lines 1793-1810
Link Here
|
1793 |
} |
1802 |
} |
1794 |
|
1803 |
|
1795 |
/* Now set up the variable which helps the assembler startup code. */ |
1804 |
/* Now set up the variable which helps the assembler startup code. */ |
1796 |
GL(dl_main_searchlist) = &GL(dl_loaded)->l_searchlist; |
1805 |
GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist; |
1797 |
GL(dl_global_scope)[0] = &GL(dl_loaded)->l_searchlist; |
1806 |
GL(dl_ns)[LM_ID_BASE]._ns_global_scope[0] = &main_map->l_searchlist; |
1798 |
|
1807 |
|
1799 |
/* Save the information about the original global scope list since |
1808 |
/* Save the information about the original global scope list since |
1800 |
we need it in the memory handling later. */ |
1809 |
we need it in the memory handling later. */ |
1801 |
GLRO(dl_initial_searchlist) = *GL(dl_main_searchlist); |
1810 |
GLRO(dl_initial_searchlist) = *GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist; |
1802 |
|
1811 |
|
1803 |
if (prelinked) |
1812 |
if (prelinked) |
1804 |
{ |
1813 |
{ |
1805 |
struct link_map *l; |
1814 |
struct link_map *l; |
1806 |
|
1815 |
|
1807 |
if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) |
1816 |
if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL) |
1808 |
{ |
1817 |
{ |
1809 |
ElfW(Rela) *conflict, *conflictend; |
1818 |
ElfW(Rela) *conflict, *conflictend; |
1810 |
#ifndef HP_TIMING_NONAVAIL |
1819 |
#ifndef HP_TIMING_NONAVAIL |
Lines 1813-1832
Link Here
|
1813 |
#endif |
1822 |
#endif |
1814 |
|
1823 |
|
1815 |
HP_TIMING_NOW (start); |
1824 |
HP_TIMING_NOW (start); |
1816 |
assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); |
1825 |
assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL); |
1817 |
conflict = (ElfW(Rela) *) |
1826 |
conflict = (ElfW(Rela) *) |
1818 |
GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; |
1827 |
main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr; |
1819 |
conflictend = (ElfW(Rela) *) |
1828 |
conflictend = (ElfW(Rela) *) |
1820 |
((char *) conflict |
1829 |
((char *) conflict |
1821 |
+ GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); |
1830 |
+ main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val); |
1822 |
_dl_resolve_conflicts (GL(dl_loaded), conflict, conflictend); |
1831 |
_dl_resolve_conflicts (main_map, conflict, conflictend); |
1823 |
HP_TIMING_NOW (stop); |
1832 |
HP_TIMING_NOW (stop); |
1824 |
HP_TIMING_DIFF (relocate_time, start, stop); |
1833 |
HP_TIMING_DIFF (relocate_time, start, stop); |
1825 |
} |
1834 |
} |
1826 |
|
1835 |
|
1827 |
|
1836 |
|
1828 |
/* Mark all the objects so we know they have been already relocated. */ |
1837 |
/* Mark all the objects so we know they have been already relocated. */ |
1829 |
for (l = GL(dl_loaded); l != NULL; l = l->l_next) |
1838 |
for (l = main_map; l != NULL; l = l->l_next) |
1830 |
{ |
1839 |
{ |
1831 |
l->l_relocated = 1; |
1840 |
l->l_relocated = 1; |
1832 |
if (l->l_relro_size) |
1841 |
if (l->l_relro_size) |
Lines 1857-1863
Link Here
|
1857 |
/* If we are profiling we also must do lazy reloaction. */ |
1866 |
/* If we are profiling we also must do lazy reloaction. */ |
1858 |
GLRO(dl_lazy) |= consider_profiling; |
1867 |
GLRO(dl_lazy) |= consider_profiling; |
1859 |
|
1868 |
|
1860 |
l = GL(dl_loaded); |
1869 |
l = main_map; |
1861 |
while (l->l_next) |
1870 |
while (l->l_next) |
1862 |
l = l->l_next; |
1871 |
l = l->l_next; |
1863 |
|
1872 |
|
Lines 1906-1912
Link Here
|
1906 |
/* There was an explicit ref to the dynamic linker as a shared lib. |
1915 |
/* There was an explicit ref to the dynamic linker as a shared lib. |
1907 |
Re-relocate ourselves with user-controlled symbol definitions. */ |
1916 |
Re-relocate ourselves with user-controlled symbol definitions. */ |
1908 |
HP_TIMING_NOW (start); |
1917 |
HP_TIMING_NOW (start); |
1909 |
_dl_relocate_object (&GL(dl_rtld_map), GL(dl_loaded)->l_scope, 0, 0); |
1918 |
_dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0); |
1910 |
HP_TIMING_NOW (stop); |
1919 |
HP_TIMING_NOW (stop); |
1911 |
HP_TIMING_DIFF (add, start, stop); |
1920 |
HP_TIMING_DIFF (add, start, stop); |
1912 |
HP_TIMING_ACCUM_NT (relocate_time, add); |
1921 |
HP_TIMING_ACCUM_NT (relocate_time, add); |
Lines 2323-2342
Link Here
|
2323 |
#endif |
2332 |
#endif |
2324 |
|
2333 |
|
2325 |
unsigned long int num_relative_relocations = 0; |
2334 |
unsigned long int num_relative_relocations = 0; |
2326 |
struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist; |
2335 |
for (Lmid_t ns = 0; ns < DL_NNS; ++ns) |
2327 |
unsigned int i; |
|
|
2328 |
|
2329 |
for (i = 0; i < scope->r_nlist; i++) |
2330 |
{ |
2336 |
{ |
2331 |
struct link_map *l = scope->r_list [i]; |
2337 |
struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist; |
2332 |
|
2338 |
|
2333 |
if (!l->l_addr) |
2339 |
for (unsigned int i = 0; i < scope->r_nlist; i++) |
2334 |
continue; |
2340 |
{ |
|
|
2341 |
struct link_map *l = scope->r_list [i]; |
2342 |
|
2343 |
if (!l->l_addr) |
2344 |
continue; |
2335 |
|
2345 |
|
2336 |
if (l->l_info[VERSYMIDX (DT_RELCOUNT)]) |
2346 |
if (l->l_info[VERSYMIDX (DT_RELCOUNT)]) |
2337 |
num_relative_relocations += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val; |
2347 |
num_relative_relocations |
2338 |
if (l->l_info[VERSYMIDX (DT_RELACOUNT)]) |
2348 |
+= l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val; |
2339 |
num_relative_relocations += l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val; |
2349 |
if (l->l_info[VERSYMIDX (DT_RELACOUNT)]) |
|
|
2350 |
num_relative_relocations |
2351 |
+= l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val; |
2352 |
} |
2340 |
} |
2353 |
} |
2341 |
|
2354 |
|
2342 |
_dl_debug_printf (" number of relocations: %lu\n" |
2355 |
_dl_debug_printf (" number of relocations: %lu\n" |