Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 72343 | Differences between
and this patch

Collapse All | Expand All

(-)libc/elf/rtld.c (-117 / +130 lines)
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"
(-)libc/elf/do-lookup.h (-1 / +1 lines)
Lines 42-48 Link Here
42
      int num_versions = 0;
42
      int num_versions = 0;
43
      const ElfW(Sym) *versioned_sym = NULL;
43
      const ElfW(Sym) *versioned_sym = NULL;
44
44
45
      map = list[i];
45
      map = list[i]->l_real;
46
46
47
      /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */
47
      /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */
48
      if (skip != NULL && map == skip)
48
      if (skip != NULL && map == skip)
(-)libc/elf/dl-support.c (-15 / +2 lines)
Lines 67-76 Link Here
67
/* Nonzero if runtime lookup should not update the .got/.plt.  */
67
/* Nonzero if runtime lookup should not update the .got/.plt.  */
68
int _dl_bind_not;
68
int _dl_bind_not;
69
69
70
/* Initially empty list of loaded objects.  */
70
/* Namespace information.  */
71
struct link_map *_dl_loaded;
71
struct link_namespaces _dl_ns[DL_NNS];
72
/* Number of object in the _dl_loaded list.  */
73
unsigned int _dl_nloaded;
74
72
75
/* Incremented whenever something may have been added to dl_loaded. */
73
/* Incremented whenever something may have been added to dl_loaded. */
76
unsigned long long _dl_load_adds;
74
unsigned long long _dl_load_adds;
Lines 79-90 Link Here
79
   main application but here we don't have something like this.  So
77
   main application but here we don't have something like this.  So
80
   create a fake scope containing nothing.  */
78
   create a fake scope containing nothing.  */
81
struct r_scope_elem _dl_initial_searchlist;
79
struct r_scope_elem _dl_initial_searchlist;
82
/* Variable which can be used in lookup to process the global scope.  */
83
struct r_scope_elem *_dl_global_scope[2] = { &_dl_initial_searchlist, NULL };
84
/* This is a global pointer to this structure which is public.  It is
85
   used by dlopen/dlclose to add and remove objects from what is regarded
86
   to be the global scope.  */
87
struct r_scope_elem *_dl_main_searchlist = &_dl_initial_searchlist;
88
80
89
#ifndef HAVE_INLINED_SYSCALLS
81
#ifndef HAVE_INLINED_SYSCALLS
90
/* Nonzero during startup.  */
82
/* Nonzero during startup.  */
Lines 109-119 Link Here
109
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
101
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
110
#endif
102
#endif
111
103
112
/* This is zero at program start to signal that the global scope map is
113
   allocated by rtld.  Later it keeps the size of the map.  It might be
114
   reset if in _dl_close if the last global object is removed.  */
115
size_t _dl_global_scope_alloc;
116
117
size_t _dl_pagesize;
104
size_t _dl_pagesize;
118
105
119
unsigned int _dl_osversion;
106
unsigned int _dl_osversion;
(-)libc/elf/dl-open.c (-45 / +84 lines)
Lines 72-77 Link Here
72
  /* This is the caller if _dl_open().  */
72
  /* This is the caller if _dl_open().  */
73
  const void *caller_dl_open;
73
  const void *caller_dl_open;
74
  struct link_map *map;
74
  struct link_map *map;
75
  /* Namespace ID.  */
76
  Lmid_t nsid;
75
};
77
};
76
78
77
79
Lines 101-115 Link Here
101
     in an realloc() call.  Therefore we allocate a completely new
103
     in an realloc() call.  Therefore we allocate a completely new
102
     array the first time we have to add something to the locale scope.  */
104
     array the first time we have to add something to the locale scope.  */
103
105
104
  if (GL(dl_global_scope_alloc) == 0)
106
  if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0)
105
    {
107
    {
106
      /* This is the first dynamic object given global scope.  */
108
      /* This is the first dynamic object given global scope.  */
107
      GL(dl_global_scope_alloc) = GL(dl_main_searchlist)->r_nlist + to_add + 8;
109
      GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
110
	= GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8;
108
      new_global = (struct link_map **)
111
      new_global = (struct link_map **)
109
	malloc (GL(dl_global_scope_alloc) * sizeof (struct link_map *));
112
	malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
113
		* sizeof (struct link_map *));
110
      if (new_global == NULL)
114
      if (new_global == NULL)
111
	{
115
	{
112
	  GL(dl_global_scope_alloc) = 0;
116
	  GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0;
113
	nomem:
117
	nomem:
114
	  GLRO(dl_signal_error) (ENOMEM, new->l_libname->name, NULL,
118
	  GLRO(dl_signal_error) (ENOMEM, new->l_libname->name, NULL,
115
				 N_("cannot extend global scope"));
119
				 N_("cannot extend global scope"));
Lines 117-141 Link Here
117
	}
121
	}
118
122
119
      /* Copy over the old entries.  */
123
      /* Copy over the old entries.  */
120
      memcpy (new_global, GL(dl_main_searchlist)->r_list,
124
      GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list
121
	      (GL(dl_main_searchlist)->r_nlist * sizeof (struct link_map *)));
125
	= memcpy (new_global,
122
126
		  GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
123
      GL(dl_main_searchlist)->r_list = new_global;
127
		  (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist
128
		   * sizeof (struct link_map *)));
124
    }
129
    }
125
  else if (GL(dl_main_searchlist)->r_nlist + to_add
130
  else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add
126
	   > GL(dl_global_scope_alloc))
131
	   > GL(dl_ns)[new->l_ns]._ns_global_scope_alloc)
127
    {
132
    {
128
      /* We have to extend the existing array of link maps in the
133
      /* We have to extend the existing array of link maps in the
129
	 main map.  */
134
	 main map.  */
130
      new_global = (struct link_map **)
135
      new_global = (struct link_map **)
131
	realloc (GL(dl_main_searchlist)->r_list,
136
	realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
132
		 ((GL(dl_global_scope_alloc) + to_add + 8)
137
		 ((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8)
133
		  * sizeof (struct link_map *)));
138
		  * sizeof (struct link_map *)));
134
      if (new_global == NULL)
139
      if (new_global == NULL)
135
	goto nomem;
140
	goto nomem;
136
141
137
      GL(dl_global_scope_alloc) += to_add + 8;
142
      GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8;
138
      GL(dl_main_searchlist)->r_list = new_global;
143
      GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global;
139
    }
144
    }
140
145
141
  /* Now add the new entries.  */
146
  /* Now add the new entries.  */
Lines 146-154 Link Here
146
      if (map->l_global == 0)
151
      if (map->l_global == 0)
147
	{
152
	{
148
	  map->l_global = 1;
153
	  map->l_global = 1;
149
	  GL(dl_main_searchlist)->r_list[GL(dl_main_searchlist)->r_nlist]
154
	  GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist]
150
	    = map;
155
	    = map;
151
	  ++GL(dl_main_searchlist)->r_nlist;
156
	  ++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist;
152
	}
157
	}
153
    }
158
    }
154
159
Lines 175-202 Link Here
175
    GLRO(dl_signal_error) (0, "dlopen", NULL, N_("invalid caller"));
180
    GLRO(dl_signal_error) (0, "dlopen", NULL, N_("invalid caller"));
176
181
177
  /* Determine the caller's map if necessary.  This is needed in case
182
  /* Determine the caller's map if necessary.  This is needed in case
178
     we have a DST or when the file name has no path in which case we
183
     we have a DST, when we don't know the namespace ID we have to put
179
     need to look along the RUNPATH/RPATH of the caller.  */
184
     the new object in, or when the file name has no path in which
185
     case we need to look along the RUNPATH/RPATH of the caller.  */
180
  const char *dst = strchr (file, '$');
186
  const char *dst = strchr (file, '$');
181
  if (dst != NULL || strchr (file, '/') == NULL)
187
  if (dst != NULL || args->nsid == __LM_ID_CALLER
188
      || strchr (file, '/') == NULL)
182
    {
189
    {
183
      const void *caller_dlopen = args->caller_dlopen;
190
      const void *caller_dlopen = args->caller_dlopen;
184
191
185
      /* We have to find out from which object the caller is calling.  */
192
      /* We have to find out from which object the caller is calling.
186
      call_map = NULL;
193
	 By default we assume this is the main application.  */
187
      for (l = GL(dl_loaded); l; l = l->l_next)
194
      call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
188
	if (caller_dlopen >= (const void *) l->l_map_start
195
189
	    && caller_dlopen < (const void *) l->l_map_end)
196
      for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
190
	  {
197
	for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
191
	    /* There must be exactly one DSO for the range of the virtual
198
	  if (caller_dlopen >= (const void *) l->l_map_start
192
	       memory.  Otherwise something is really broken.  */
199
	      && caller_dlopen < (const void *) l->l_map_end)
193
	    call_map = l;
200
	    {
194
	    break;
201
	      /* There must be exactly one DSO for the range of the virtual
195
	  }
202
		 memory.  Otherwise something is really broken.  */
203
	      assert (ns == l->l_ns);
204
	      call_map = l;
205
	      goto found_caller;
206
	    }
196
207
197
      if (call_map == NULL)
208
    found_caller:
198
	/* In this case we assume this is the main application.  */
209
      if (args->nsid == __LM_ID_CALLER)
199
	call_map = GL(dl_loaded);
210
	args->nsid = call_map->l_ns;
200
    }
211
    }
201
212
202
  /* Maybe we have to expand a DST.  */
213
  /* Maybe we have to expand a DST.  */
Lines 238-244 Link Here
238
249
239
  /* Load the named object.  */
250
  /* Load the named object.  */
240
  args->map = new = GLRO(dl_map_object) (call_map, file, 0, lt_loaded, 0,
251
  args->map = new = GLRO(dl_map_object) (call_map, file, 0, lt_loaded, 0,
241
					 mode | __RTLD_CALLMAP);
252
					 mode | __RTLD_CALLMAP, args->nsid);
242
253
243
  /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
254
  /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is
244
     set and the object is not already loaded.  */
255
     set and the object is not already loaded.  */
Lines 252-272 Link Here
252
    /* This happens only if we load a DSO for 'sprof'.  */
263
    /* This happens only if we load a DSO for 'sprof'.  */
253
    return;
264
    return;
254
265
266
  /* This object is directly loaded.  */
267
  ++new->l_direct_opencount;
268
255
  /* It was already open.  */
269
  /* It was already open.  */
256
  if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
270
  if (__builtin_expect (new->l_searchlist.r_list != NULL, 0))
257
    {
271
    {
258
      /* Let the user know about the opencount.  */
272
      /* Let the user know about the opencount.  */
259
      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
273
      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
260
	GLRO(dl_debug_printf) ("opening file=%s; opencount == %u\n\n",
274
	GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
261
			       new->l_name, new->l_opencount);
275
			       new->l_name, new->l_ns, new->l_opencount);
262
276
263
      /* If the user requested the object to be in the global namespace
277
      /* If the user requested the object to be in the global namespace
264
	 but it is not so far, add it now.  */
278
	 but it is not so far, add it now.  */
265
      if ((mode & RTLD_GLOBAL) && new->l_global == 0)
279
      if ((mode & RTLD_GLOBAL) && new->l_global == 0)
266
	(void) add_to_global (new);
280
	(void) add_to_global (new);
267
281
268
      /* Increment just the reference counter of the object.  */
282
      if (new->l_direct_opencount == 1)
269
      ++new->l_opencount;
283
	/* This is the only direct reference.  Increment all the
284
	   dependencies' reference counter.  */
285
	for (i = 0; i < new->l_searchlist.r_nlist; ++i)
286
	  ++new->l_searchlist.r_list[i]->l_opencount;
287
      else
288
	/* Increment just the reference counter of the object.  */
289
	++new->l_opencount;
270
290
271
      return;
291
      return;
272
    }
292
    }
Lines 277-284 Link Here
277
297
278
  /* So far, so good.  Now check the versions.  */
298
  /* So far, so good.  Now check the versions.  */
279
  for (i = 0; i < new->l_searchlist.r_nlist; ++i)
299
  for (i = 0; i < new->l_searchlist.r_nlist; ++i)
280
    if (new->l_searchlist.r_list[i]->l_versions == NULL)
300
    if (new->l_searchlist.r_list[i]->l_real->l_versions == NULL)
281
      (void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i], 0, 0);
301
      (void) GLRO(dl_check_map_versions) (new->l_searchlist.r_list[i]->l_real,
302
					  0, 0);
282
303
283
#ifdef SCOPE_DEBUG
304
#ifdef SCOPE_DEBUG
284
  show_scope (new);
305
  show_scope (new);
Lines 295-301 Link Here
295
    l = l->l_next;
316
    l = l->l_next;
296
  while (1)
317
  while (1)
297
    {
318
    {
298
      if (! l->l_relocated)
319
      if (! l->l_real->l_relocated)
299
	{
320
	{
300
#ifdef SHARED
321
#ifdef SHARED
301
	  if (GLRO(dl_profile) != NULL)
322
	  if (GLRO(dl_profile) != NULL)
Lines 349-355 Link Here
349
     loaded object to the scope.  */
370
     loaded object to the scope.  */
350
  for (i = 0; i < new->l_searchlist.r_nlist; ++i)
371
  for (i = 0; i < new->l_searchlist.r_nlist; ++i)
351
    if (++new->l_searchlist.r_list[i]->l_opencount > 1
372
    if (++new->l_searchlist.r_list[i]->l_opencount > 1
352
	&& new->l_searchlist.r_list[i]->l_type == lt_loaded)
373
	&& new->l_real->l_searchlist.r_list[i]->l_type == lt_loaded)
353
      {
374
      {
354
	struct link_map *imap = new->l_searchlist.r_list[i];
375
	struct link_map *imap = new->l_searchlist.r_list[i];
355
	struct r_scope_elem **runp = imap->l_scope;
376
	struct r_scope_elem **runp = imap->l_scope;
Lines 503-516 Link Here
503
524
504
  /* Let the user know about the opencount.  */
525
  /* Let the user know about the opencount.  */
505
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
526
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
506
    GLRO(dl_debug_printf) ("opening file=%s; opencount == %u\n\n",
527
    GLRO(dl_debug_printf) ("opening file=%s [%lu]; opencount=%u\n\n",
507
			   new->l_name, new->l_opencount);
528
			   new->l_name, new->l_ns, new->l_opencount);
508
}
529
}
509
530
510
531
511
void *
532
void *
512
internal_function
533
internal_function
513
_dl_open (const char *file, int mode, const void *caller_dlopen)
534
_dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid)
514
{
535
{
515
  struct dl_open_args args;
536
  struct dl_open_args args;
516
  const char *objname;
537
  const char *objname;
Lines 525-535 Link Here
525
  /* Make sure we are alone.  */
546
  /* Make sure we are alone.  */
526
  __rtld_lock_lock_recursive (GL(dl_load_lock));
547
  __rtld_lock_lock_recursive (GL(dl_load_lock));
527
548
549
  if (nsid == LM_ID_NEWLM)
550
    {
551
      /* Find a new namespace.  */
552
      for (nsid = 1; nsid < DL_NNS; ++nsid)
553
	if (GL(dl_ns)[nsid]._ns_loaded == NULL)
554
	  break;
555
556
      if (nsid == DL_NNS)
557
	{
558
	  /* No more namespace available.  */
559
	  __rtld_lock_unlock_recursive (GL(dl_load_lock));
560
561
	  GLRO(dl_signal_error) (EINVAL, file, NULL, N_("\
562
no more namespaces available for dlmopen()"));
563
	}
564
    }
565
528
  args.file = file;
566
  args.file = file;
529
  args.mode = mode;
567
  args.mode = mode;
530
  args.caller_dlopen = caller_dlopen;
568
  args.caller_dlopen = caller_dlopen;
531
  args.caller_dl_open = RETURN_ADDRESS (0);
569
  args.caller_dl_open = RETURN_ADDRESS (0);
532
  args.map = NULL;
570
  args.map = NULL;
571
  args.nsid = nsid;
533
  errcode = GLRO(dl_catch_error) (&objname, &errstring, dl_open_worker, &args);
572
  errcode = GLRO(dl_catch_error) (&objname, &errstring, dl_open_worker, &args);
534
573
535
#ifndef MAP_COPY
574
#ifndef MAP_COPY
(-)libc/elf/dl-object.c (-6 / +8 lines)
Lines 32-38 Link Here
32
struct link_map *
32
struct link_map *
33
internal_function
33
internal_function
34
_dl_new_object (char *realname, const char *libname, int type,
34
_dl_new_object (char *realname, const char *libname, int type,
35
		struct link_map *loader, int mode)
35
		struct link_map *loader, int mode, Lmid_t nsid)
36
{
36
{
37
  struct link_map *l;
37
  struct link_map *l;
38
  int idx;
38
  int idx;
Lines 45-50 Link Here
45
  if (new == NULL)
45
  if (new == NULL)
46
    return NULL;
46
    return NULL;
47
47
48
  new->l_real = new;
48
  new->l_libname = newname = (struct libname_list *) (new + 1);
49
  new->l_libname = newname = (struct libname_list *) (new + 1);
49
  newname->name = (char *) memcpy (newname + 1, libname, libname_len);
50
  newname->name = (char *) memcpy (newname + 1, libname, libname_len);
50
  /* newname->next = NULL;	We use calloc therefore not necessary.  */
51
  /* newname->next = NULL;	We use calloc therefore not necessary.  */
Lines 56-61 Link Here
56
#if defined USE_TLS && NO_TLS_OFFSET != 0
57
#if defined USE_TLS && NO_TLS_OFFSET != 0
57
  new->l_tls_offset = NO_TLS_OFFSET;
58
  new->l_tls_offset = NO_TLS_OFFSET;
58
#endif
59
#endif
60
  new->l_ns = nsid;
59
61
60
  /* new->l_global = 0;	We use calloc therefore not necessary.  */
62
  /* new->l_global = 0;	We use calloc therefore not necessary.  */
61
63
Lines 68-76 Link Here
68
  /* Counter for the scopes we have to handle.  */
70
  /* Counter for the scopes we have to handle.  */
69
  idx = 0;
71
  idx = 0;
70
72
71
  if (GL(dl_loaded) != NULL)
73
  if (GL(dl_ns)[nsid]._ns_loaded != NULL)
72
    {
74
    {
73
      l = GL(dl_loaded);
75
      l = GL(dl_ns)[nsid]._ns_loaded;
74
      while (l->l_next != NULL)
76
      while (l->l_next != NULL)
75
	l = l->l_next;
77
	l = l->l_next;
76
      new->l_prev = l;
78
      new->l_prev = l;
Lines 78-88 Link Here
78
      l->l_next = new;
80
      l->l_next = new;
79
81
80
      /* Add the global scope.  */
82
      /* Add the global scope.  */
81
      new->l_scope[idx++] = &GL(dl_loaded)->l_searchlist;
83
      new->l_scope[idx++] = &GL(dl_ns)[nsid]._ns_loaded->l_searchlist;
82
    }
84
    }
83
  else
85
  else
84
    GL(dl_loaded) = new;
86
    GL(dl_ns)[nsid]._ns_loaded = new;
85
  ++GL(dl_nloaded);
87
  ++GL(dl_ns)[nsid]._ns_nloaded;
86
  ++GL(dl_load_adds);
88
  ++GL(dl_load_adds);
87
89
88
  /* If we have no loader the new object acts as it.  */
90
  /* If we have no loader the new object acts as it.  */
(-)libc/elf/dl-lookup.c (-7 / +12 lines)
Lines 137-143 Link Here
137
     reference is still available.  There is a brief period in
137
     reference is still available.  There is a brief period in
138
     which the object could have been removed since we found the
138
     which the object could have been removed since we found the
139
     definition.  */
139
     definition.  */
140
  runp = GL(dl_loaded);
140
  runp = GL(dl_ns)[undef_map->l_ns]._ns_loaded;
141
  while (runp != NULL && runp != map)
141
  while (runp != NULL && runp != map)
142
    runp = runp->l_next;
142
    runp = runp->l_next;
143
143
Lines 182-194 Link Here
182
	for (list = map->l_initfini; *list != NULL; ++list)
182
	for (list = map->l_initfini; *list != NULL; ++list)
183
	  ++(*list)->l_opencount;
183
	  ++(*list)->l_opencount;
184
184
185
      /* As if it is opened through _dl_open.  */
186
      ++map->l_direct_opencount;
187
185
      /* Display information if we are debugging.  */
188
      /* Display information if we are debugging.  */
186
      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
189
      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
187
	_dl_debug_printf ("\
190
	_dl_debug_printf ("\
188
\nfile=%s;  needed by %s (relocation dependency)\n\n",
191
\nfile=%s [%lu];  needed by %s [%lu] (relocation dependency)\n\n",
189
			  map->l_name[0] ? map->l_name : rtld_progname,
192
			  map->l_name[0] ? map->l_name : rtld_progname,
193
			  map->l_ns,
190
			  undef_map->l_name[0]
194
			  undef_map->l_name[0]
191
			  ? undef_map->l_name : rtld_progname);
195
			  ? undef_map->l_name : rtld_progname,
196
			  undef_map->l_ns);
192
    }
197
    }
193
  else
198
  else
194
    /* Whoa, that was bad luck.  We have to search again.  */
199
    /* Whoa, that was bad luck.  We have to search again.  */
Lines 408-415 Link Here
408
      struct sym_val val = { NULL, NULL };
413
      struct sym_val val = { NULL, NULL };
409
414
410
      if ((GLRO(dl_trace_prelink_map) == NULL
415
      if ((GLRO(dl_trace_prelink_map) == NULL
411
	   || GLRO(dl_trace_prelink_map) == GL(dl_loaded))
416
	   || GLRO(dl_trace_prelink_map) == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
412
	  && undef_map != GL(dl_loaded))
417
	  && undef_map != GL(dl_ns)[LM_ID_BASE]._ns_loaded)
413
	{
418
	{
414
	  const unsigned long int hash = _dl_elf_hash (undef_name);
419
	  const unsigned long int hash = _dl_elf_hash (undef_name);
415
420
Lines 421-432 Link Here
421
	    conflict = 1;
426
	    conflict = 1;
422
	}
427
	}
423
428
424
#ifdef USE_TLS
429
# ifdef USE_TLS
425
      if (value->s
430
      if (value->s
426
	  && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
431
	  && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
427
				== STT_TLS, 0)))
432
				== STT_TLS, 0)))
428
	type_class = 4;
433
	type_class = 4;
429
#endif
434
# endif
430
435
431
      if (conflict
436
      if (conflict
432
	  || GLRO(dl_trace_prelink_map) == undef_map
437
	  || GLRO(dl_trace_prelink_map) == undef_map
(-)libc/elf/dl-load.c (-27 / +63 lines)
Lines 699-705 Link Here
699
699
700
#ifdef SHARED
700
#ifdef SHARED
701
  /* This points to the map of the main object.  */
701
  /* This points to the map of the main object.  */
702
  l = GL(dl_loaded);
702
  l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
703
  if (l != NULL)
703
  if (l != NULL)
704
    {
704
    {
705
      assert (l->l_type != lt_loaded);
705
      assert (l->l_type != lt_loaded);
Lines 795-804 Link Here
795
      if (l->l_prev == NULL)
795
      if (l->l_prev == NULL)
796
	/* No other module loaded. This happens only in the static library,
796
	/* No other module loaded. This happens only in the static library,
797
	   or in rtld under --verify.  */
797
	   or in rtld under --verify.  */
798
	GL(dl_loaded) = NULL;
798
	GL(dl_ns)[l->l_ns]._ns_loaded = NULL;
799
      else
799
      else
800
	l->l_prev->l_next = NULL;
800
	l->l_prev->l_next = NULL;
801
      --GL(dl_nloaded);
801
      --GL(dl_ns)[l->l_ns]._ns_nloaded;
802
      free (l);
802
      free (l);
803
    }
803
    }
804
  free (realname);
804
  free (realname);
Lines 815-821 Link Here
815
struct link_map *
815
struct link_map *
816
_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
816
_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
817
			char *realname, struct link_map *loader, int l_type,
817
			char *realname, struct link_map *loader, int l_type,
818
			int mode, void **stack_endp)
818
			int mode, void **stack_endp, Lmid_t nsid)
819
{
819
{
820
  struct link_map *l = NULL;
820
  struct link_map *l = NULL;
821
  const ElfW(Ehdr) *header;
821
  const ElfW(Ehdr) *header;
Lines 839-845 Link Here
839
    }
839
    }
840
840
841
  /* Look again to see if the real name matched another already loaded.  */
841
  /* Look again to see if the real name matched another already loaded.  */
842
  for (l = GL(dl_loaded); l; l = l->l_next)
842
  for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
843
    if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
843
    if (l->l_ino == st.st_ino && l->l_dev == st.st_dev)
844
      {
844
      {
845
	/* The object is already loaded.
845
	/* The object is already loaded.
Lines 854-859 Link Here
854
	return l;
854
	return l;
855
      }
855
      }
856
856
857
#ifdef SHARED
858
  /* When loading into a namespace other than the base one we must
859
     avoid loading ld.so since there can only be one copy.  Ever.  */
860
  if (__builtin_expect (nsid != LM_ID_BASE, 0)
861
      && ((st.st_ino == GL(dl_rtld_map).l_ino
862
	   && st.st_dev == GL(dl_rtld_map).l_dev)
863
	  || _dl_name_match_p (name, &GL(dl_rtld_map))))
864
    {
865
      /* This is indeed ld.so.  Create a new link_map which refers to
866
	 the real one for almost everything.  */
867
      l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
868
      if (l == NULL)
869
	goto fail_new;
870
871
      /* Refer to the real descriptor.  */
872
      l->l_real = &GL(dl_rtld_map);
873
874
      /* No need to bump the refcount of the real object, ld.so will
875
	 never be unloaded.  */
876
      __close (fd);
877
878
      return l;
879
    }
880
#endif
881
857
  if (mode & RTLD_NOLOAD)
882
  if (mode & RTLD_NOLOAD)
858
    /* We are not supposed to load the object unless it is already
883
    /* We are not supposed to load the object unless it is already
859
       loaded.  So return now.  */
884
       loaded.  So return now.  */
Lines 861-867 Link Here
861
886
862
  /* Print debugging message.  */
887
  /* Print debugging message.  */
863
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
888
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0))
864
    _dl_debug_printf ("file=%s;  generating link map\n", name);
889
    _dl_debug_printf ("file=%s [%lu];  generating link map\n", name, nsid);
865
890
866
  /* This is the ELF header.  We read it in `open_verify'.  */
891
  /* This is the ELF header.  We read it in `open_verify'.  */
867
  header = (void *) fbp->buf;
892
  header = (void *) fbp->buf;
Lines 881-889 Link Here
881
#endif
906
#endif
882
907
883
  /* Enter the new object in the list of loaded objects.  */
908
  /* Enter the new object in the list of loaded objects.  */
884
  l = _dl_new_object (realname, name, l_type, loader, mode);
909
  l = _dl_new_object (realname, name, l_type, loader, mode, nsid);
885
  if (__builtin_expect (! l, 0))
910
  if (__builtin_expect (l == NULL, 0))
886
    {
911
    {
912
    fail_new:
887
      errstring = N_("cannot create shared object descriptor");
913
      errstring = N_("cannot create shared object descriptor");
888
      goto call_lose_errno;
914
      goto call_lose_errno;
889
    }
915
    }
Lines 1771-1777 Link Here
1771
struct link_map *
1797
struct link_map *
1772
internal_function
1798
internal_function
1773
_dl_map_object (struct link_map *loader, const char *name, int preloaded,
1799
_dl_map_object (struct link_map *loader, const char *name, int preloaded,
1774
		int type, int trace_mode, int mode)
1800
		int type, int trace_mode, int mode, Lmid_t nsid)
1775
{
1801
{
1776
  int fd;
1802
  int fd;
1777
  char *realname;
1803
  char *realname;
Lines 1779-1786 Link Here
1779
  struct link_map *l;
1805
  struct link_map *l;
1780
  struct filebuf fb;
1806
  struct filebuf fb;
1781
1807
1808
  assert (nsid >= 0);
1809
  assert (nsid < DL_NNS);
1810
1782
  /* Look for this name among those already loaded.  */
1811
  /* Look for this name among those already loaded.  */
1783
  for (l = GL(dl_loaded); l; l = l->l_next)
1812
  for (l = GL(dl_ns)[nsid]._ns_loaded; l; l = l->l_next)
1784
    {
1813
    {
1785
      /* If the requested name matches the soname of a loaded object,
1814
      /* If the requested name matches the soname of a loaded object,
1786
	 use that object.  Elide this check for names that have not
1815
	 use that object.  Elide this check for names that have not
Lines 1812-1820 Link Here
1812
  /* Display information if we are debugging.  */
1841
  /* Display information if we are debugging.  */
1813
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
1842
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_FILES, 0)
1814
      && loader != NULL)
1843
      && loader != NULL)
1815
    _dl_debug_printf ("\nfile=%s;  needed by %s\n", name,
1844
    _dl_debug_printf ("\nfile=%s [%lu];  needed by %s [%lu]\n", name, nsid,
1816
			      loader->l_name[0]
1845
			      loader->l_name[0]
1817
			      ? loader->l_name : rtld_progname);
1846
			      ? loader->l_name : rtld_progname, loader->l_ns);
1818
1847
1819
  if (strchr (name, '/') == NULL)
1848
  if (strchr (name, '/') == NULL)
1820
    {
1849
    {
Lines 1823-1829 Link Here
1823
      size_t namelen = strlen (name) + 1;
1852
      size_t namelen = strlen (name) + 1;
1824
1853
1825
      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
1854
      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_LIBS, 0))
1826
	_dl_debug_printf ("find library=%s; searching\n", name);
1855
	_dl_debug_printf ("find library=%s [%lu]; searching\n", name, nsid);
1827
1856
1828
      fd = -1;
1857
      fd = -1;
1829
1858
Lines 1839-1850 Link Here
1839
			      &realname, &fb);
1868
			      &realname, &fb);
1840
1869
1841
	  /* If dynamically linked, try the DT_RPATH of the executable
1870
	  /* If dynamically linked, try the DT_RPATH of the executable
1842
             itself.  */
1871
             itself.  NB: we do this for lookups in any namespace.  */
1843
	  l = GL(dl_loaded);
1872
	  if (fd == -1)
1844
	  if (fd == -1 && l && l->l_type != lt_loaded && l != loader
1873
	    {
1845
	      && l->l_rpath_dirs.dirs != (void *) -1)
1874
	      l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
1846
	    fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
1875
	      if (l && l->l_type != lt_loaded && l != loader
1847
			    &realname, &fb);
1876
		  && l->l_rpath_dirs.dirs != (void *) -1)
1877
		fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs,
1878
				&realname, &fb);
1879
	    }
1848
	}
1880
	}
1849
1881
1850
      /* Try the LD_LIBRARY_PATH environment variable.  */
1882
      /* Try the LD_LIBRARY_PATH environment variable.  */
Lines 1870-1876 Link Here
1870
	  if (cached != NULL)
1902
	  if (cached != NULL)
1871
	    {
1903
	    {
1872
#ifdef SHARED
1904
#ifdef SHARED
1873
	      l = loader ?: GL(dl_loaded);
1905
	      // XXX Correct to unconditionally default to namespace 0?
1906
	      l = loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded;
1874
#else
1907
#else
1875
	      l = loader;
1908
	      l = loader;
1876
#endif
1909
#endif
Lines 1920-1926 Link Here
1920
1953
1921
      /* Finally, try the default path.  */
1954
      /* Finally, try the default path.  */
1922
      if (fd == -1
1955
      if (fd == -1
1923
	  && ((l = loader ?: GL(dl_loaded)) == NULL
1956
	  && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL
1924
	      || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
1957
	      || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1))
1925
	  && rtld_search_dirs.dirs != (void *) -1)
1958
	  && rtld_search_dirs.dirs != (void *) -1)
1926
	fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
1959
	fd = open_path (name, namelen, preloaded, &rtld_search_dirs,
Lines 1966-1972 Link Here
1966
	  /* Enter the new object in the list of loaded objects.  */
1999
	  /* Enter the new object in the list of loaded objects.  */
1967
	  if ((name_copy = local_strdup (name)) == NULL
2000
	  if ((name_copy = local_strdup (name)) == NULL
1968
	      || (l = _dl_new_object (name_copy, name, type, loader,
2001
	      || (l = _dl_new_object (name_copy, name, type, loader,
1969
				      mode)) == NULL)
2002
				      mode, nsid)) == NULL)
1970
	    _dl_signal_error (ENOMEM, name, NULL,
2003
	    _dl_signal_error (ENOMEM, name, NULL,
1971
			      N_("cannot create shared object descriptor"));
2004
			      N_("cannot create shared object descriptor"));
1972
	  /* Signal that this is a faked entry.  */
2005
	  /* Signal that this is a faked entry.  */
Lines 1987-1993 Link Here
1987
2020
1988
  void *stack_end = __libc_stack_end;
2021
  void *stack_end = __libc_stack_end;
1989
  return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode,
2022
  return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode,
1990
				 &stack_end);
2023
				 &stack_end, nsid);
1991
}
2024
}
1992
2025
1993
2026
Lines 2047-2056 Link Here
2047
      while (l != NULL);
2080
      while (l != NULL);
2048
2081
2049
      /* If dynamically linked, try the DT_RPATH of the executable itself.  */
2082
      /* If dynamically linked, try the DT_RPATH of the executable itself.  */
2050
      l = GL(dl_loaded);
2083
      if (loader->l_ns == LM_ID_BASE)
2051
      if (l != NULL && l->l_type != lt_loaded && l != loader)
2084
	{
2052
	if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
2085
	  l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
2053
	  add_path (&l->l_rpath_dirs, XXX_RPATH);
2086
	  if (l != NULL && l->l_type != lt_loaded && l != loader)
2087
	    if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH"))
2088
	      add_path (&l->l_rpath_dirs, XXX_RPATH);
2089
	}
2054
    }
2090
    }
2055
2091
2056
  /* Try the LD_LIBRARY_PATH environment variable.  */
2092
  /* Try the LD_LIBRARY_PATH environment variable.  */
(-)libc/elf/dl-libc.c (-14 / +15 lines)
Lines 77-83 Link Here
77
{
77
{
78
  struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
78
  struct do_dlopen_args *args = (struct do_dlopen_args *) ptr;
79
  /* Open and relocate the shared object.  */
79
  /* Open and relocate the shared object.  */
80
  args->map = _dl_open (args->name, args->mode, NULL);
80
  args->map = _dl_open (args->name, args->mode, NULL, __LM_ID_CALLER);
81
}
81
}
82
82
83
static void
83
static void
Lines 217-234 Link Here
217
    }
217
    }
218
218
219
  /* Remove all additional names added to the objects.  */
219
  /* Remove all additional names added to the objects.  */
220
  for (l = GL(dl_loaded); l != NULL; l = l->l_next)
220
  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
221
    {
221
    for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
222
      struct libname_list *lnp = l->l_libname->next;
222
      {
223
223
	struct libname_list *lnp = l->l_libname->next;
224
      l->l_libname->next = NULL;
224
225
225
	l->l_libname->next = NULL;
226
      while (lnp != NULL)
226
227
	{
227
	while (lnp != NULL)
228
	  struct libname_list *old = lnp;
228
	  {
229
	  lnp = lnp->next;
229
	    struct libname_list *old = lnp;
230
	  if (! old->dont_free)
230
	    lnp = lnp->next;
231
	    if (! old->dont_free)
231
	    free (old);
232
	    free (old);
232
	}
233
	  }
233
    }
234
      }
234
}
235
}
235
236
236
237
(-)libc/elf/dl-iteratephdr.c (-3 / +21 lines)
Lines 42-55 Link Here
42
  __rtld_lock_lock_recursive (GL(dl_load_lock));
42
  __rtld_lock_lock_recursive (GL(dl_load_lock));
43
  __libc_cleanup_push (cancel_handler, 0);
43
  __libc_cleanup_push (cancel_handler, 0);
44
44
45
  for (l = GL(dl_loaded); l != NULL; l = l->l_next)
45
  /* We have to determine the namespace of the caller since this determines
46
     which namespace is reported.  */
47
  const void *caller = RETURN_ADDRESS (0);
48
  size_t nloaded = GL(dl_ns)[0]._ns_nloaded;
49
  Lmid_t ns = 0;
50
  for (Lmid_t cnt = DL_NNS - 1; cnt > 0; --cnt)
51
    for (struct link_map *l = GL(dl_ns)[cnt]._ns_loaded; l; l = l->l_next)
52
      {
53
	/* We have to count the total number of loaded objects.  */
54
	nloaded += GL(dl_ns)[cnt]._ns_nloaded;
55
56
	if (caller >= (const void *) l->l_map_start
57
	    && caller < (const void *) l->l_map_end)
58
	  /* There must be exactly one DSO for the range of the virtual
59
	     memory.  Otherwise something is really broken.  */
60
	  ns = cnt;
61
      }
62
63
  for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
46
    {
64
    {
47
      info.dlpi_addr = l->l_addr;
65
      info.dlpi_addr = l->l_addr;
48
      info.dlpi_name = l->l_name;
66
      info.dlpi_name = l->l_name;
49
      info.dlpi_phdr = l->l_phdr;
67
      info.dlpi_phdr = l->l_phdr;
50
      info.dlpi_phnum = l->l_phnum;
68
      info.dlpi_phnum = l->l_phnum;
51
      info.dlpi_adds = GL(dl_load_adds);
69
      info.dlpi_adds = GL(dl_load_adds);
52
      info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
70
      info.dlpi_subs = GL(dl_load_adds) - nloaded;
53
      ret = callback (&info, sizeof (struct dl_phdr_info), data);
71
      ret = callback (&info, sizeof (struct dl_phdr_info), data);
54
      if (ret)
72
      if (ret)
55
	break;
73
	break;
Lines 87-93 Link Here
87
      info.dlpi_phdr = _dl_phdr;
105
      info.dlpi_phdr = _dl_phdr;
88
      info.dlpi_phnum = _dl_phnum;
106
      info.dlpi_phnum = _dl_phnum;
89
      info.dlpi_adds = GL(dl_load_adds);
107
      info.dlpi_adds = GL(dl_load_adds);
90
      info.dlpi_subs = GL(dl_load_adds) - GL(dl_nloaded);
108
      info.dlpi_subs = GL(dl_load_adds) - GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
91
      ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
109
      ret = (*callback) (&info, sizeof (struct dl_phdr_info), data);
92
      if (ret)
110
      if (ret)
93
	return ret;
111
	return ret;
(-)libc/elf/dl-fini.c (-112 / +151 lines)
Lines 32-41 Link Here
32
_dl_fini (void)
32
_dl_fini (void)
33
{
33
{
34
  /* Lots of fun ahead.  We have to call the destructors for all still
34
  /* Lots of fun ahead.  We have to call the destructors for all still
35
     loaded objects.  The problem is that the ELF specification now
35
     loaded objects, in all namespaces.  The problem is that the ELF
36
     demands that dependencies between the modules are taken into account.
36
     specification now demands that dependencies between the modules
37
     I.e., the destructor for a module is called before the ones for any
37
     are taken into account.  I.e., the destructor for a module is
38
     of its dependencies.
38
     called before the ones for any of its dependencies.
39
39
40
     To make things more complicated, we cannot simply use the reverse
40
     To make things more complicated, we cannot simply use the reverse
41
     order of the constructors.  Since the user might have loaded objects
41
     order of the constructors.  Since the user might have loaded objects
Lines 45-184 Link Here
45
  unsigned int i;
45
  unsigned int i;
46
  unsigned int nloaded;
46
  unsigned int nloaded;
47
  struct link_map *l;
47
  struct link_map *l;
48
  struct link_map **maps;
48
  struct link_map **maps = NULL;
49
  size_t maps_size = 0;
49
50
50
  /* Protect against concurrent loads and unloads.  */
51
  /* We First run the destructors of the main namespaces, then the
51
  __rtld_lock_lock_recursive (GL(dl_load_lock));
52
     other ones.  The order should not matter since the namespace
52
53
     content is supposed to be independent.  But we can have auditing
53
  nloaded = GL(dl_nloaded);
54
     code in a auxiliaty namespace and we want it to monitor the
54
55
     destructors.  */
55
  /* XXX Could it be (in static binaries) that there is no object loaded?  */
56
  for (Lmid_t cnt = 0; cnt < DL_NNS; ++cnt)
56
  assert (nloaded > 0);
57
58
  /* Now we can allocate an array to hold all the pointers and copy
59
     the pointers in.  */
60
  maps = (struct link_map **) alloca (nloaded * sizeof (struct link_map *));
61
  for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next)
62
    {
57
    {
63
      assert (i < nloaded);
58
      /* Protect against concurrent loads and unloads.  */
59
      __rtld_lock_lock_recursive (GL(dl_load_lock));
64
60
65
      maps[i++] = l;
61
      nloaded = GL(dl_ns)[cnt]._ns_nloaded;
66
62
67
      /* Bump l_opencount of all objects so that they are not dlclose()ed
63
      /* XXX Could it be (in static binaries) that there is no object
68
	 from underneath us.  */
64
	 loaded?  */
69
      ++l->l_opencount;
65
      assert (cnt != LM_ID_BASE || nloaded > 0);
70
    }
66
71
  assert (i == nloaded);
67
      /* Now we can allocate an array to hold all the pointers and copy
72
68
	 the pointers in.  */
73
  /* Now we have to do the sorting.  */
69
      if (maps_size < nloaded * sizeof (struct link_map *))
74
  for (l = GL(dl_loaded)->l_next; l != NULL; l = l->l_next)
70
	{
75
    {
71
	  if (maps_size == 0)
76
      unsigned int j;
72
	    {
77
      unsigned int k;
73
	      maps_size = nloaded * sizeof (struct link_map *);
74
	      maps = (struct link_map **) alloca (maps_size);
75
	    }
76
	  else
77
	    maps = (struct link_map **)
78
	      extend_alloca (maps, maps_size,
79
			     nloaded * sizeof (struct link_map *));
80
	}
78
81
79
      /* Find the place in the 'maps' array.  */
82
      for (l = GL(dl_ns)[cnt]._ns_loaded, i = 0; l != NULL; l = l->l_next)
80
      for (j = 1; maps[j] != l; ++j)
81
	;
82
83
      /* Find all object for which the current one is a dependency and
84
	 move the found object (if necessary) in front.  */
85
      for (k = j + 1; k < nloaded; ++k)
86
	{
83
	{
87
	  struct link_map **runp = maps[k]->l_initfini;
84
	  assert (i < nloaded);
88
	  if (runp != NULL)
85
86
	  /* Do not handle ld.so in secondary namespaces.  */
87
	  if (l == l->l_real)
89
	    {
88
	    {
90
	      while (*runp != NULL)
89
	      maps[i++] = l;
91
		if (*runp == l)
90
92
		  {
91
	      /* Bump l_opencount of all objects so that they are not
93
		    struct link_map *here = maps[k];
92
		 dlclose()ed from underneath us.  */
94
93
	      ++l->l_opencount;
95
		    /* Move it now.  */
96
		    memmove (&maps[j] + 1,
97
			     &maps[j],
98
			     (k - j) * sizeof (struct link_map *));
99
		    maps[j++] = here;
100
101
		    break;
102
		  }
103
		else
104
		  ++runp;
105
	    }
94
	    }
95
	}
96
      assert (cnt != LM_ID_BASE || i == nloaded);
97
      assert (cnt == LM_ID_BASE || i == nloaded || i == nloaded - 1);
98
      unsigned int nmaps = i;
106
99
107
	  if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
100
      if (nmaps != 0)
101
	{
102
	  /* Now we have to do the sorting.  */
103
	  l = GL(dl_ns)[cnt]._ns_loaded;
104
	  if (cnt == LM_ID_BASE)
105
	    /* The main executable always comes first.  */
106
	    l = l->l_next;
107
	  for (; l != NULL; l = l->l_next)
108
	    {
108
	    {
109
	      unsigned int m = maps[k]->l_reldepsact;
109
	      unsigned int j;
110
	      struct link_map **relmaps = maps[k]->l_reldeps;
110
	      unsigned int k;
111
111
112
	      while (m-- > 0)
112
	      /* Find the place in the 'maps' array.  */
113
	      for (j = 1; maps[j] != l; ++j)
114
		;
115
116
	      /* Find all object for which the current one is a dependency and
117
		 move the found object (if necessary) in front.  */
118
	      for (k = j + 1; k < nmaps; ++k)
113
		{
119
		{
114
		  if (relmaps[m] == l)
120
		  struct link_map **runp = maps[k]->l_initfini;
121
		  if (runp != NULL)
115
		    {
122
		    {
116
		      struct link_map *here = maps[k];
123
		      while (*runp != NULL)
124
			if (*runp == l)
125
			  {
126
			    struct link_map *here = maps[k];
127
128
			    /* Move it now.  */
129
			    memmove (&maps[j] + 1,
130
				     &maps[j],
131
				     (k - j) * sizeof (struct link_map *));
132
			    maps[j++] = here;
133
134
			    break;
135
			  }
136
			else
137
			  ++runp;
138
		    }
117
139
118
		      /* Move it now.  */
140
		  if (__builtin_expect (maps[k]->l_reldeps != NULL, 0))
119
		      memmove (&maps[j] + 1,
141
		    {
120
			       &maps[j],
142
		      unsigned int m = maps[k]->l_reldepsact;
121
			       (k - j) * sizeof (struct link_map *));
143
		      struct link_map **relmaps = maps[k]->l_reldeps;
122
		      maps[j] = here;
123
144
124
		      break;
145
		      while (m-- > 0)
146
			{
147
			  if (relmaps[m] == l)
148
			    {
149
			      struct link_map *here = maps[k];
150
151
			      /* Move it now.  */
152
			      memmove (&maps[j] + 1,
153
				       &maps[j],
154
				       (k - j) * sizeof (struct link_map *));
155
			      maps[j] = here;
156
157
			      break;
158
			    }
159
			}
125
		    }
160
		    }
126
		}
161
		}
127
	    }
162
	    }
128
	}
163
	}
129
    }
130
164
131
  /* We do not rely on the linked list of loaded object anymore from
165
      /* We do not rely on the linked list of loaded object anymore from
132
     this point on.  We have our own list here (maps).  The various
166
	 this point on.  We have our own list here (maps).  The various
133
     members of this list cannot vanish since the open count is too
167
	 members of this list cannot vanish since the open count is too
134
     high and will be decremented in this loop.  So we release the
168
	 high and will be decremented in this loop.  So we release the
135
     lock so that some code which might be called from a destructor
169
	 lock so that some code which might be called from a destructor
136
     can directly or indirectly access the lock.  */
170
	 can directly or indirectly access the lock.  */
137
  __rtld_lock_unlock_recursive (GL(dl_load_lock));
171
      __rtld_lock_unlock_recursive (GL(dl_load_lock));
138
172
139
  /* 'maps' now contains the objects in the right order.  Now call the
173
      /* 'maps' now contains the objects in the right order.  Now call the
140
     destructors.  We have to process this array from the front.  */
174
	 destructors.  We have to process this array from the front.  */
141
  for (i = 0; i < nloaded; ++i)
175
      for (i = 0; i < nmaps; ++i)
142
    {
143
      l = maps[i];
144
145
      if (l->l_init_called)
146
	{
176
	{
147
	  /* Make sure nothing happens if we are called twice.  */
177
	  l = maps[i];
148
	  l->l_init_called = 0;
149
150
	  /* Don't call the destructors for objects we are not supposed to.  */
151
	  if (l->l_name[0] == '\0' && l->l_type == lt_executable)
152
	    continue;
153
154
	  /* Is there a destructor function?  */
155
	  if (l->l_info[DT_FINI_ARRAY] == NULL && l->l_info[DT_FINI] == NULL)
156
	    continue;
157
158
	  /* When debugging print a message first.  */
159
	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
160
	    _dl_debug_printf ("\ncalling fini: %s\n\n",
161
			      l->l_name[0] ? l->l_name : rtld_progname);
162
178
163
	  /* First see whether an array is given.  */
179
	  if (l->l_init_called)
164
	  if (l->l_info[DT_FINI_ARRAY] != NULL)
165
	    {
180
	    {
166
	      ElfW(Addr) *array =
181
	      /* Make sure nothing happens if we are called twice.  */
167
		(ElfW(Addr) *) (l->l_addr
182
	      l->l_init_called = 0;
168
				+ l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
183
169
	      unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
184
	      /* Don't call the destructors for objects we are not
170
				/ sizeof (ElfW(Addr)));
185
		 supposed to.  */
171
	      while (i-- > 0)
186
	      if (l->l_name[0] == '\0' && l->l_type == lt_executable)
172
		((fini_t) array[i]) ();
187
		continue;
188
189
	      /* Is there a destructor function?  */
190
	      if (l->l_info[DT_FINI_ARRAY] == NULL
191
		  && l->l_info[DT_FINI] == NULL)
192
		continue;
193
194
	      /* When debugging print a message first.  */
195
	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
196
				    0))
197
		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
198
				  l->l_name[0] ? l->l_name : rtld_progname,
199
				  cnt);
200
201
	      /* First see whether an array is given.  */
202
	      if (l->l_info[DT_FINI_ARRAY] != NULL)
203
		{
204
		  ElfW(Addr) *array =
205
		    (ElfW(Addr) *) (l->l_addr
206
				    + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr);
207
		  unsigned int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val
208
				    / sizeof (ElfW(Addr)));
209
		  while (i-- > 0)
210
		    ((fini_t) array[i]) ();
211
		}
212
213
	      /* Next try the old-style destructor.  */
214
	      if (l->l_info[DT_FINI] != NULL)
215
		((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
173
	    }
216
	    }
174
217
175
	  /* Next try the old-style destructor.  */
218
	  /* Correct the previous increment.  */
176
	  if (l->l_info[DT_FINI] != NULL)
219
	  --l->l_opencount;
177
	    ((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
178
	}
220
	}
179
180
      /* Correct the previous increment.  */
181
      --l->l_opencount;
182
    }
221
    }
183
222
184
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
223
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
(-)libc/elf/dl-deps.c (-2 / +3 lines)
Lines 63-69 Link Here
63
  args->aux = _dl_map_object (args->map, args->name, 0,
63
  args->aux = _dl_map_object (args->map, args->name, 0,
64
			      (args->map->l_type == lt_executable
64
			      (args->map->l_type == lt_executable
65
			       ? lt_library : args->map->l_type),
65
			       ? lt_library : args->map->l_type),
66
			      args->trace_mode, args->open_mode);
66
			      args->trace_mode, args->open_mode,
67
			      args->map->l_ns);
67
}
68
}
68
69
69
static ptrdiff_t
70
static ptrdiff_t
Lines 510-516 Link Here
510
    }
511
    }
511
512
512
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
513
  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK, 0) != 0
513
      && map == GL(dl_loaded))
514
      && map == GL(dl_ns)[LM_ID_BASE]._ns_loaded)
514
    {
515
    {
515
      /* If we are to compute conflicts, we have to build local scope
516
      /* If we are to compute conflicts, we have to build local scope
516
	 for each library, not just the ultimate loader.  */
517
	 for each library, not just the ultimate loader.  */
(-)libc/elf/dl-close.c (-44 / +99 lines)
Lines 130-135 Link Here
130
  /* Acquire the lock.  */
130
  /* Acquire the lock.  */
131
  __rtld_lock_lock_recursive (GL(dl_load_lock));
131
  __rtld_lock_lock_recursive (GL(dl_load_lock));
132
132
133
  /* One less direct use.  */
134
  assert (map->l_direct_opencount > 0);
135
  --map->l_direct_opencount;
136
133
  /* Decrement the reference count.  */
137
  /* Decrement the reference count.  */
134
  if (map->l_opencount > 1 || map->l_type != lt_loaded)
138
  if (map->l_opencount > 1 || map->l_type != lt_loaded)
135
    {
139
    {
Lines 141-146 Link Here
141
      /* Decrement the object's reference counter, not the dependencies'.  */
145
      /* Decrement the object's reference counter, not the dependencies'.  */
142
      --map->l_opencount;
146
      --map->l_opencount;
143
147
148
      /* If the direct use counter reaches zero we have to decrement
149
	 all the dependencies' usage counter.  */
150
      if (map->l_direct_opencount == 0)
151
	for (i = 1; i < map->l_searchlist.r_nlist; ++i)
152
	  --map->l_searchlist.r_list[i]->l_opencount;
153
144
      __rtld_lock_unlock_recursive (GL(dl_load_lock));
154
      __rtld_lock_unlock_recursive (GL(dl_load_lock));
145
      return;
155
      return;
146
    }
156
    }
Lines 167-178 Link Here
167
  for (i = 1; list[i] != NULL; ++i)
177
  for (i = 1; list[i] != NULL; ++i)
168
    if ((list[i]->l_flags_1 & DF_1_NODELETE) == 0
178
    if ((list[i]->l_flags_1 & DF_1_NODELETE) == 0
169
	/* Decrement counter.  */
179
	/* Decrement counter.  */
170
	&& --new_opencount[i] == 0)
180
	&& (assert (new_opencount[i] > 0), --new_opencount[i] == 0))
171
      {
181
      {
172
	void mark_removed (struct link_map *remmap)
182
	void mark_removed (struct link_map *remmap)
173
	  {
183
	  {
174
	    /* Test whether this object was also loaded directly.  */
184
	    /* Test whether this object was also loaded directly.  */
175
	    if (remmap->l_searchlist.r_list != NULL)
185
	    if (remmap->l_searchlist.r_list != NULL
186
		&& remmap->l_direct_opencount > 0)
176
	      {
187
	      {
177
		/* In this case we have to decrement all the dependencies of
188
		/* In this case we have to decrement all the dependencies of
178
		   this object.  They are all in MAP's dependency list.  */
189
		   this object.  They are all in MAP's dependency list.  */
Lines 184-189 Link Here
184
		      || ! dep_list[j]->l_init_called)
195
		      || ! dep_list[j]->l_init_called)
185
		{
196
		{
186
		  assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
197
		  assert (dep_list[j]->l_idx < map->l_searchlist.r_nlist);
198
		  assert (new_opencount[dep_list[j]->l_idx] > 0);
187
		  if (--new_opencount[dep_list[j]->l_idx] == 0)
199
		  if (--new_opencount[dep_list[j]->l_idx] == 0)
188
		    {
200
		    {
189
		      assert (dep_list[j]->l_type == lt_loaded);
201
		      assert (dep_list[j]->l_type == lt_loaded);
Lines 197-213 Link Here
197
		unsigned int j;
209
		unsigned int j;
198
		for (j = 0; j < remmap->l_reldepsact; ++j)
210
		for (j = 0; j < remmap->l_reldepsact; ++j)
199
		  {
211
		  {
212
		    struct link_map *depmap = remmap->l_reldeps[j];
213
200
		    /* Find out whether this object is in our list.  */
214
		    /* Find out whether this object is in our list.  */
201
		    if (remmap->l_reldeps[j]->l_idx < nopencount
215
		    if (depmap->l_idx < nopencount
202
			&& (list[remmap->l_reldeps[j]->l_idx]
216
			&& list[depmap->l_idx] == depmap)
203
			    == remmap->l_reldeps[j]))
217
		      {
204
		      /* Yes, it is.  */
218
			/* Yes, it is.  If is has a search list, make a
205
		      if (--new_opencount[remmap->l_reldeps[j]->l_idx] == 0)
219
			   recursive call to handle this.  */
206
			{
220
			if (depmap->l_searchlist.r_list != NULL)
207
			  /* This one is now gone, too.  */
221
			  {
208
			  assert (remmap->l_reldeps[j]->l_type == lt_loaded);
222
			    assert (new_opencount[depmap->l_idx] > 0);
209
			  mark_removed (remmap->l_reldeps[j]);
223
			    if (--new_opencount[depmap->l_idx] == 0)
210
			}
224
			      {
225
				/* This one is now gone, too.  */
226
				assert (depmap->l_type == lt_loaded);
227
				mark_removed (depmap);
228
			      }
229
			  }
230
			else
231
			  {
232
			    /* Otherwise we have to handle the dependency
233
			       deallocation here.  */
234
			    unsigned int k;
235
			    for (k = 0; depmap->l_initfini[k] != NULL; ++k)
236
			      {
237
				struct link_map *rl = depmap->l_initfini[k];
238
239
				if (rl->l_idx < nopencount
240
				    & list[rl->l_idx] == rl)
241
				  {
242
				    assert (new_opencount[rl->l_idx] > 0);
243
				    if (--new_opencount[rl->l_idx] ==  0)
244
				      {
245
					/* Another module to remove.  */
246
					assert (rl->l_type == lt_loaded);
247
					mark_removed (rl);
248
				      }
249
				  }
250
				else
251
				  {
252
				    assert (rl->l_opencount > 0);
253
				    if (--rl->l_opencount == 0)
254
				      mark_removed (rl);
255
				  }
256
			      }
257
			  }
258
		      }
211
		  }
259
		  }
212
	      }
260
	      }
213
	  }
261
	  }
Lines 225-231 Link Here
225
	{
273
	{
226
	  /* When debugging print a message first.  */
274
	  /* When debugging print a message first.  */
227
	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
275
	  if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
228
	    GLRO(dl_debug_printf) ("\ncalling fini: %s\n\n", imap->l_name);
276
	    GLRO(dl_debug_printf) ("\ncalling fini: %s [%lu]\n\n",
277
				   imap->l_name, imap->l_ns);
229
278
230
	  /* Call its termination function.  Do not do it for
279
	  /* Call its termination function.  Do not do it for
231
	     half-cooked objects.  */
280
	     half-cooked objects.  */
Lines 340-357 Link Here
340
	  if (__builtin_expect (imap->l_global, 0))
389
	  if (__builtin_expect (imap->l_global, 0))
341
	    {
390
	    {
342
	      /* This object is in the global scope list.  Remove it.  */
391
	      /* This object is in the global scope list.  Remove it.  */
343
	      unsigned int cnt = GL(dl_main_searchlist)->r_nlist;
392
	      unsigned int cnt
393
		= GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
344
394
345
	      do
395
	      do
346
		--cnt;
396
		--cnt;
347
	      while (GL(dl_main_searchlist)->r_list[cnt] != imap);
397
	      while (GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt]
398
		     != imap);
348
399
349
	      /* The object was already correctly registered.  */
400
	      /* The object was already correctly registered.  */
350
	      while (++cnt < GL(dl_main_searchlist)->r_nlist)
401
	      while (++cnt
351
		GL(dl_main_searchlist)->r_list[cnt - 1]
402
		     < GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist)
352
		  = GL(dl_main_searchlist)->r_list[cnt];
403
		GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt - 1]
404
		  = GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_list[cnt];
353
405
354
	      --GL(dl_main_searchlist)->r_nlist;
406
	      --GL(dl_ns)[imap->l_ns]._ns_main_searchlist->r_nlist;
355
	    }
407
	    }
356
408
357
#ifdef USE_TLS
409
#ifdef USE_TLS
Lines 442-460 Link Here
442
	  DL_UNMAP (imap);
494
	  DL_UNMAP (imap);
443
495
444
	  /* Finally, unlink the data structure and free it.  */
496
	  /* Finally, unlink the data structure and free it.  */
445
#ifdef SHARED
446
	  /* We will unlink the first object only if this is a statically
447
	     linked program.  */
448
	  assert (imap->l_prev != NULL);
449
	  imap->l_prev->l_next = imap->l_next;
450
#else
451
	  if (imap->l_prev != NULL)
497
	  if (imap->l_prev != NULL)
452
	    imap->l_prev->l_next = imap->l_next;
498
	    imap->l_prev->l_next = imap->l_next;
453
	  else
499
	  else
454
	    GL(dl_loaded) = imap->l_next;
500
	    {
501
#ifdef SHARED
502
	      assert (imap->l_ns != LM_ID_BASE);
455
#endif
503
#endif
456
	  --GL(dl_nloaded);
504
	      GL(dl_ns)[imap->l_ns]._ns_loaded = imap->l_next;
457
	  if (imap->l_next)
505
	    }
506
507
	  --GL(dl_ns)[imap->l_ns]._ns_nloaded;
508
	  if (imap->l_next != NULL)
458
	    imap->l_next->l_prev = imap->l_prev;
509
	    imap->l_next->l_prev = imap->l_prev;
459
510
460
	  free (imap->l_versions);
511
	  free (imap->l_versions);
Lines 528-534 Link Here
528
  if (any_tls)
579
  if (any_tls)
529
    {
580
    {
530
      if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
581
      if (__builtin_expect (++GL(dl_tls_generation) == 0, 0))
531
	__libc_fatal (_("TLS generation counter wrapped!  Please send report as described in <http://www.gnu.org/software/libc/bugs.html>."));
582
	__libc_fatal (_("TLS generation counter wrapped!  Please report as described in <http://www.gnu.org/software/libc/bugs.html>."));
532
583
533
      if (tls_free_end == GL(dl_tls_static_used))
584
      if (tls_free_end == GL(dl_tls_static_used))
534
	GL(dl_tls_static_used) = tls_free_start;
585
	GL(dl_tls_static_used) = tls_free_start;
Lines 596-617 Link Here
596
647
597
libc_freeres_fn (free_mem)
648
libc_freeres_fn (free_mem)
598
{
649
{
599
  if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0
650
  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
600
      && (GL(dl_main_searchlist)->r_nlist
651
    if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
601
	  == GLRO(dl_initial_searchlist).r_nlist))
652
	&& (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
602
    {
653
	    // XXX Check whether we need NS-specific initial_searchlist
603
      /* All object dynamically loaded by the program are unloaded.  Free
654
	    == GLRO(dl_initial_searchlist).r_nlist))
604
	 the memory allocated for the global scope variable.  */
655
      {
605
      struct link_map **old = GL(dl_main_searchlist)->r_list;
656
	/* All object dynamically loaded by the program are unloaded.  Free
606
657
	   the memory allocated for the global scope variable.  */
607
      /* Put the old map in.  */
658
	struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
608
      GL(dl_main_searchlist)->r_list = GLRO(dl_initial_searchlist).r_list;
659
609
      /* Signal that the original map is used.  */
660
	/* Put the old map in.  */
610
      GL(dl_global_scope_alloc) = 0;
661
	GL(dl_ns)[ns]._ns_main_searchlist->r_list
662
	  // XXX Check whether we need NS-specific initial_searchlist
663
	  = GLRO(dl_initial_searchlist).r_list;
664
	/* Signal that the original map is used.  */
665
	GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
611
666
612
      /* Now free the old map.  */
667
	/* Now free the old map.  */
613
      free (old);
668
	free (old);
614
    }
669
      }
615
670
616
#ifdef USE_TLS
671
#ifdef USE_TLS
617
  if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
672
  if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
(-)libc/elf/Makefile (-5 / +198 lines)
Lines 154-160 Link Here
154
	 circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
154
	 circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
155
	 tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
155
	 tst-tls10 tst-tls11 tst-tls12 tst-tls13 tst-tls14 tst-align \
156
	 $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
156
	 $(tests-execstack-$(have-z-execstack)) tst-dlmodcount \
157
	 tst-dlopenrpath tst-deep1
157
	 tst-dlopenrpath tst-deep1 tst-dlmopen1 tst-dlmopen2
158
#	 reldep9
158
#	 reldep9
159
test-srcs = tst-pathopt
159
test-srcs = tst-pathopt
160
tests-vis-yes = vismain
160
tests-vis-yes = vismain
Lines 187-193 Link Here
187
		reldep8mod1 reldep8mod2 reldep8mod3 \
187
		reldep8mod1 reldep8mod2 reldep8mod3 \
188
		reldep9mod1 reldep9mod2 reldep9mod3 \
188
		reldep9mod1 reldep9mod2 reldep9mod3 \
189
		tst-alignmod $(modules-execstack-$(have-z-execstack)) \
189
		tst-alignmod $(modules-execstack-$(have-z-execstack)) \
190
		tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3
190
		tst-dlopenrpathmod tst-deep1mod1 tst-deep1mod2 tst-deep1mod3 \
191
		tst-dlmopen1mod
191
ifeq (yes,$(have-initfini-array))
192
ifeq (yes,$(have-initfini-array))
192
modules-names += tst-array2dep
193
modules-names += tst-array2dep
193
endif
194
endif
Lines 762-764 Link Here
762
$(objpfx)tst-deep1.out: $(objpfx)tst-deep1mod2.so
763
$(objpfx)tst-deep1.out: $(objpfx)tst-deep1mod2.so
763
LDFLAGS-tst-deep1 += -rdynamic
764
LDFLAGS-tst-deep1 += -rdynamic
764
tst-deep1mod3.so-no-z-defs = yes
765
tst-deep1mod3.so-no-z-defs = yes
765
-- libc/elf/tst-dlmopen2.c
766
767
$(objpfx)tst-dlmopen1mod.so: $(libdl)
768
$(objpfx)tst-dlmopen1: $(libdl)
769
$(objpfx)tst-dlmopen1.out: $(objpfx)tst-dlmopen1mod.so
770
771
$(objpfx)tst-dlmopen2: $(libdl)
772
$(objpfx)tst-dlmopen2.out: $(objpfx)tst-dlmopen1mod.so
Line 0 Link Here
0
-- libc/elf/tst-dlmopen1mod.c
1
#include <dlfcn.h>
2
#include <stdio.h>
3
#include <string.h>
4
#include <gnu/lib-names.h>
5
#include <ldsodefs.h>
6
7
8
static int
9
do_test (void)
10
{
11
  int result = 0;
12
13
  for (int i = 1; i <= 10; ++i)
14
    {
15
      void *h[DL_NNS - 1];
16
      char used[DL_NNS];
17
18
      printf ("round %d\n", i);
19
20
      memset (used, '\0', sizeof (used));
21
      used[LM_ID_BASE] = 1;
22
23
      for (int j = 0; j < DL_NNS - 1; ++j)
24
	{
25
	  h[j] = dlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so",
26
			  RTLD_LAZY);
27
	  if (h[j] == NULL)
28
	    {
29
	      printf ("round %d, namespace %d: load failed: %s\n",
30
		      i, j, dlerror ());
31
	      return 1;
32
	    }
33
	  Lmid_t ns;
34
	  if (dlinfo (h[j], RTLD_DI_LMID, &ns) != 0)
35
	    {
36
	      printf ("round %d, namespace %d: dlinfo failed: %s\n",
37
		      i, j, dlerror ());
38
	      return 1;
39
	    }
40
	  if (ns < 0 || ns >= DL_NNS)
41
	    {
42
	      printf ("round %d, namespace %d: invalid namespace %ld",
43
		      i, j, (long int) ns);
44
	      result = 1;
45
	    }
46
	  else if (used[ns] != 0)
47
	    {
48
	      printf ("\
49
round %d, namespace %d: duplicate allocate of namespace %ld",
50
		      i, j, (long int) ns);
51
	      result = 1;
52
	    }
53
	  else
54
	    used[ns] = 1;
55
	}
56
57
      for (int j = 0; j < DL_NNS - 1; ++j)
58
	if (dlclose (h[j]) != 0)
59
	  {
60
	    printf ("round %d, namespace %d: close failed: %s\n",
61
		    i, j, dlerror ());
62
	    return 1;
63
	  }
64
    }
65
66
  return result;
67
}
68
69
#define TEST_FUNCTION do_test ()
70
#include "../test-skeleton.c"
Line 0 Link Here
0
-- libc/elf/tst-dlmopen1.c
1
#include <dlfcn.h>
2
#include <stdio.h>
3
#include <gnu/lib-names.h>
4
5
6
int
7
foo (Lmid_t ns2)
8
{
9
  void *h = dlopen (LIBC_SO, RTLD_LAZY|RTLD_NOLOAD);
10
  if (h == NULL)
11
    {
12
      printf ("cannot get handle for %s: %s\n", LIBC_SO, dlerror ());
13
      return 1;
14
    }
15
16
  Lmid_t ns = -10;
17
  if (dlinfo (h, RTLD_DI_LMID, &ns) != 0)
18
    {
19
      printf ("dlinfo for %s in %s failed: %s\n",
20
	      LIBC_SO, __func__, dlerror ());
21
      return 1;
22
    }
23
24
  if (ns != ns2)
25
    {
26
      printf ("namespace for %s not LM_ID_BASE\n", LIBC_SO);
27
      return 1;
28
    }
29
30
  if (dlclose (h) != 0)
31
    {
32
      printf ("dlclose for %s in %s failed: %s\n",
33
	      LIBC_SO, __func__, dlerror ());
34
      return 1;
35
    }
36
37
  return 0;
38
}
Line 0 Link Here
1
#include <dlfcn.h>
2
#include <stdio.h>
3
#include <gnu/lib-names.h>
4
5
6
static int
7
do_test (void)
8
{
9
  void *h = dlopen (LIBC_SO, RTLD_LAZY|RTLD_NOLOAD);
10
  if (h == NULL)
11
    {
12
      printf ("cannot get handle for %s: %s\n", LIBC_SO, dlerror ());
13
      return 1;
14
    }
15
16
  Lmid_t ns = -10;
17
  if (dlinfo (h, RTLD_DI_LMID, &ns) != 0)
18
    {
19
      printf ("dlinfo for %s in %s failed: %s\n",
20
	      LIBC_SO, __func__, dlerror ());
21
      return 1;
22
    }
23
24
  if (ns != LM_ID_BASE)
25
    {
26
      printf ("namespace for %s not LM_ID_BASE\n", LIBC_SO);
27
      return 1;
28
    }
29
30
  if (dlclose (h) != 0)
31
    {
32
      printf ("dlclose for %s in %s failed: %s\n",
33
	      LIBC_SO, __func__, dlerror ());
34
      return 1;
35
    }
36
37
  h = dlmopen (LM_ID_NEWLM, "$ORIGIN/tst-dlmopen1mod.so", RTLD_LAZY);
38
  if (h == NULL)
39
    {
40
      printf ("cannot get handle for %s: %s\n",
41
	      "tst-dlmopen1mod.so", dlerror ());
42
      return 1;
43
    }
44
45
  ns = -10;
46
  if (dlinfo (h, RTLD_DI_LMID, &ns) != 0)
47
    {
48
      printf ("dlinfo for %s in %s failed: %s\n",
49
	      "tst-dlmopen1mod.so", __func__, dlerror ());
50
      return 1;
51
    }
52
53
  if (ns == LM_ID_BASE)
54
    {
55
      printf ("namespace for %s is LM_ID_BASE\n", LIBC_SO);
56
      return 1;
57
    }
58
59
  int (*fct) (Lmid_t) = dlsym (h, "foo");
60
  if (fct == NULL)
61
    {
62
      printf ("could not find %s: %s\n", "foo", dlerror ());
63
      return 1;
64
    }
65
66
  if (fct (ns) != 0)
67
    return 1;
68
69
  if (dlclose (h) != 0)
70
    {
71
      printf ("dlclose for %s in %s failed: %s\n",
72
	      LIBC_SO, __func__, dlerror ());
73
      return 1;
74
    }
75
76
  return 0;
77
}
78
79
#define TEST_FUNCTION do_test ()
80
#include "../test-skeleton.c"
(-)libc/include/link.h (-1 / +10 lines)
Lines 129-134 Link Here
129
    /* All following members are internal to the dynamic linker.
129
    /* All following members are internal to the dynamic linker.
130
       They may change without notice.  */
130
       They may change without notice.  */
131
131
132
    /* This is an element which is only ever different from a pointer to
133
       the very same copy of this type for ld.so when it is used in more
134
       than one namespace.  */
135
    struct link_map *l_real;
136
137
    /* Number of the namespace this link map belongs to.  */
138
    Lmid_t l_ns;
139
132
    struct libname_list *l_libname;
140
    struct libname_list *l_libname;
133
    /* Indexed pointers to dynamic section.
141
    /* Indexed pointers to dynamic section.
134
       [0,DT_NUM) are indexed by the processor-independent tags.
142
       [0,DT_NUM) are indexed by the processor-independent tags.
Lines 169-175 Link Here
169
    Elf_Symndx l_nbuckets;
177
    Elf_Symndx l_nbuckets;
170
    const Elf_Symndx *l_buckets, *l_chain;
178
    const Elf_Symndx *l_buckets, *l_chain;
171
179
172
    unsigned int l_opencount;	/* Reference count for dlopen/dlclose.  */
180
    unsigned int l_opencount;	/* Counter for direct and indirect usage.  */
181
    unsigned int l_direct_opencount; /* Reference count for dlopen/dlclose.  */
173
    enum			/* Where this object came from.  */
182
    enum			/* Where this object came from.  */
174
      {
183
      {
175
	lt_executable,		/* The main executable program.  */
184
	lt_executable,		/* The main executable program.  */
(-)libc/include/dlfcn.h (-1 / +4 lines)
Lines 8-13 Link Here
8
#define __RTLD_OPENEXEC	0x20000000
8
#define __RTLD_OPENEXEC	0x20000000
9
#define __RTLD_CALLMAP	0x10000000
9
#define __RTLD_CALLMAP	0x10000000
10
10
11
#define __LM_ID_CALLER	-2
12
11
/* Now define the internal interfaces.  */
13
/* Now define the internal interfaces.  */
12
extern void *__dlvsym (void *__handle, __const char *__name,
14
extern void *__dlvsym (void *__handle, __const char *__name,
13
		       __const char *__version);
15
		       __const char *__version);
Lines 31-37 Link Here
31
/* Open the shared object NAME, relocate it, and run its initializer if it
33
/* Open the shared object NAME, relocate it, and run its initializer if it
32
   hasn't already been run.  MODE is as for `dlopen' (see <dlfcn.h>).  If
34
   hasn't already been run.  MODE is as for `dlopen' (see <dlfcn.h>).  If
33
   the object is already opened, returns its existing map.  */
35
   the object is already opened, returns its existing map.  */
34
extern void *_dl_open (const char *name, int mode, const void *caller)
36
extern void *_dl_open (const char *name, int mode, const void *caller,
37
		       Lmid_t nsid)
35
     internal_function;
38
     internal_function;
36
libc_hidden_proto (_dl_open)
39
libc_hidden_proto (_dl_open)
37
40
(-)libc/malloc/malloc.c (-2 / +6 lines)
Lines 24-30 Link Here
24
  Doug Lea and adapted to multiple threads/arenas by Wolfram Gloger.
24
  Doug Lea and adapted to multiple threads/arenas by Wolfram Gloger.
25
25
26
* Version ptmalloc2-20011215
26
* Version ptmalloc2-20011215
27
  $Id: malloc.c,v 1.130 2004/10/06 18:01:28 drepper Exp $
27
  $Id: malloc.c,v 1.131 2004/10/14 01:56:52 drepper Exp $
28
  based on:
28
  based on:
29
  VERSION 2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
29
  VERSION 2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
30
30
Lines 289-297 Link Here
289
289
290
/* For writev and struct iovec.  */
290
/* For writev and struct iovec.  */
291
#include <sys/uio.h>
291
#include <sys/uio.h>
292
  /* For syslog.  */
292
/* For syslog.  */
293
#include <sys/syslog.h>
293
#include <sys/syslog.h>
294
294
295
/* For various dynamic linking things.  */
296
#include <dlfcn.h>
297
298
295
/*
299
/*
296
  Debugging:
300
  Debugging:
297
301
(-)libc/malloc/arena.c (-1 / +18 lines)
Lines 18-24 Link Here
18
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
19
   Boston, MA 02111-1307, USA.  */
20
20
21
/* $Id: arena.c,v 1.10 2004/10/04 02:27:14 drepper Exp $ */
21
/* $Id: arena.c,v 1.11 2004/10/14 01:55:55 drepper Exp $ */
22
22
23
/* Compile-time constants.  */
23
/* Compile-time constants.  */
24
24
Lines 339-345 Link Here
339
  mp_.pagesize       = malloc_getpagesize;
339
  mp_.pagesize       = malloc_getpagesize;
340
}
340
}
341
341
342
342
#ifdef _LIBC
343
#ifdef _LIBC
344
# ifdef SHARED
345
static void *
346
__failing_morecore (ptrdiff_t d)
347
{
348
  return (void *) MORECORE_FAILURE;
349
}
350
# endif
351
343
# if defined SHARED && defined USE_TLS && !USE___THREAD
352
# if defined SHARED && defined USE_TLS && !USE___THREAD
344
# include <stdbool.h>
353
# include <stdbool.h>
345
354
Lines 419-424 Link Here
419
  mutex_init(&main_arena.mutex);
428
  mutex_init(&main_arena.mutex);
420
  main_arena.next = &main_arena;
429
  main_arena.next = &main_arena;
421
430
431
#if defined _LIBC && defined SHARED
432
  /* In case this libc copy is in a non-default namespace, never use brk.  */
433
  Dl_info di;
434
  struct link_map *l;
435
  if (_dl_addr (ptmalloc_init, &di, &l, NULL) != 0 && l->l_ns != LM_ID_BASE)
436
    __morecore = __failing_morecore;
437
#endif
438
422
  mutex_init(&list_lock);
439
  mutex_init(&list_lock);
423
  tsd_key_create(&arena_key, NULL);
440
  tsd_key_create(&arena_key, NULL);
424
  tsd_setspecific(arena_key, (Void_t *)&main_arena);
441
  tsd_setspecific(arena_key, (Void_t *)&main_arena);
(-)libc/sysdeps/generic/dl-tls.c (-1 / +1 lines)
Lines 33-39 Link Here
33
33
34
/* Amount of excess space to allocate in the static TLS area
34
/* Amount of excess space to allocate in the static TLS area
35
   to allow dynamic loading of modules defining IE-model TLS data.  */
35
   to allow dynamic loading of modules defining IE-model TLS data.  */
36
# define TLS_STATIC_SURPLUS	64
36
# define TLS_STATIC_SURPLUS	64 + DL_NNS * 100
37
37
38
/* Value used for dtv entries for which the allocation is delayed.  */
38
/* Value used for dtv entries for which the allocation is delayed.  */
39
# define TLS_DTV_UNALLOCATED	((void *) -1l)
39
# define TLS_DTV_UNALLOCATED	((void *) -1l)
(-)libc/sysdeps/generic/ldsodefs.h (-15 / +25 lines)
Lines 216-233 Link Here
216
  /* Don't change the order of the following elements.  'dl_loaded'
216
  /* Don't change the order of the following elements.  'dl_loaded'
217
     must remain the first element.  Forever.  */
217
     must remain the first element.  Forever.  */
218
218
219
  /* And a pointer to the map for the main map.  */
219
/* Non-shared code has no support for multiple namespaces.  */
220
  EXTERN struct link_map *_dl_loaded;
220
#ifdef SHARED
221
  /* Number of object in the _dl_loaded list.  */
221
# define DL_NNS 16
222
  EXTERN unsigned int _dl_nloaded;
222
#else
223
  /* Array representing global scope.  */
223
# define DL_NNS 1
224
  EXTERN struct r_scope_elem *_dl_global_scope[2];
224
#endif
225
  /* Direct pointer to the searchlist of the main object.  */
225
  EXTERN struct link_namespaces
226
  EXTERN struct r_scope_elem *_dl_main_searchlist;
226
  {
227
  /* This is zero at program start to signal that the global scope map is
227
    /* And a pointer to the map for the main map.  */
228
     allocated by rtld.  Later it keeps the size of the map.  It might be
228
    struct link_map *_ns_loaded;
229
     reset if in _dl_close if the last global object is removed.  */
229
    /* Number of object in the _dl_loaded list.  */
230
  EXTERN size_t _dl_global_scope_alloc;
230
    unsigned int _ns_nloaded;
231
    /* Array representing global scope.  */
232
    struct r_scope_elem *_ns_global_scope[2];
233
    /* Direct pointer to the searchlist of the main object.  */
234
    struct r_scope_elem *_ns_main_searchlist;
235
    /* This is zero at program start to signal that the global scope map is
236
       allocated by rtld.  Later it keeps the size of the map.  It might be
237
       reset if in _dl_close if the last global object is removed.  */
238
    size_t _ns_global_scope_alloc;
239
  } _dl_ns[DL_NNS];
231
240
232
  /* During the program run we must not modify the global data of
241
  /* During the program run we must not modify the global data of
233
     loaded shared object simultanously in two threads.  Therefore we
242
     loaded shared object simultanously in two threads.  Therefore we
Lines 477-483 Link Here
477
  char *(*_dl_dst_substitute) (struct link_map *, const char *, char *, int);
486
  char *(*_dl_dst_substitute) (struct link_map *, const char *, char *, int);
478
  struct link_map *(internal_function *_dl_map_object) (struct link_map *,
487
  struct link_map *(internal_function *_dl_map_object) (struct link_map *,
479
							const char *, int,
488
							const char *, int,
480
							int, int, int);
489
							int, int, int, Lmid_t);
481
  void (internal_function *_dl_map_object_deps) (struct link_map *,
490
  void (internal_function *_dl_map_object_deps) (struct link_map *,
482
						 struct link_map **,
491
						 struct link_map **,
483
						 unsigned int, int, int);
492
						 unsigned int, int, int);
Lines 658-664 Link Here
658
   value to allow additional security checks.  */
667
   value to allow additional security checks.  */
659
extern struct link_map *_dl_map_object (struct link_map *loader,
668
extern struct link_map *_dl_map_object (struct link_map *loader,
660
					const char *name, int preloaded,
669
					const char *name, int preloaded,
661
					int type, int trace_mode, int mode)
670
					int type, int trace_mode, int mode,
671
					Lmid_t nsid)
662
     internal_function attribute_hidden;
672
     internal_function attribute_hidden;
663
673
664
/* Call _dl_map_object on the dependencies of MAP, and set up
674
/* Call _dl_map_object on the dependencies of MAP, and set up
Lines 723-729 Link Here
723
   and enter it into the _dl_main_map list.  */
733
   and enter it into the _dl_main_map list.  */
724
extern struct link_map *_dl_new_object (char *realname, const char *libname,
734
extern struct link_map *_dl_new_object (char *realname, const char *libname,
725
					int type, struct link_map *loader,
735
					int type, struct link_map *loader,
726
					int mode)
736
					int mode, Lmid_t nsid)
727
     internal_function attribute_hidden;
737
     internal_function attribute_hidden;
728
738
729
/* Relocate the given object (if it hasn't already been).
739
/* Relocate the given object (if it hasn't already been).
(-)libc/sysdeps/unix/sysv/linux/i386/dl-librecon.h (-3 / +3 lines)
Lines 28-42 Link Here
28
      /* We have to find out whether the binary is linked against	      \
28
      /* We have to find out whether the binary is linked against	      \
29
	 libc 5 or glibc.  We do this by looking at all the DT_NEEDED	      \
29
	 libc 5 or glibc.  We do this by looking at all the DT_NEEDED	      \
30
	 entries.  If one is libc.so.5 this is a libc 5 linked binary.  */    \
30
	 entries.  If one is libc.so.5 this is a libc 5 linked binary.  */    \
31
      if (GL(dl_loaded)->l_info[DT_NEEDED])				      \
31
      if (main_map->l_info[DT_NEEDED])					      \
32
	{								      \
32
	{								      \
33
	  /* We have dependencies.  */					      \
33
	  /* We have dependencies.  */					      \
34
	  const ElfW(Dyn) *d;						      \
34
	  const ElfW(Dyn) *d;						      \
35
	  const char *strtab;						      \
35
	  const char *strtab;						      \
36
									      \
36
									      \
37
	  strtab = (const char *) D_PTR (GL(dl_loaded), l_info[DT_STRTAB]);   \
37
	  strtab = (const char *) D_PTR (main_map, l_info[DT_STRTAB]);	      \
38
									      \
38
									      \
39
	  for (d = GL(dl_loaded)->l_ld; d->d_tag != DT_NULL; ++d)	      \
39
	  for (d = main_map->l_ld; d->d_tag != DT_NULL; ++d)		      \
40
	    if (d->d_tag == DT_NEEDED					      \
40
	    if (d->d_tag == DT_NEEDED					      \
41
		&& strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0)	      \
41
		&& strcmp (strtab + d->d_un.d_val, "libc.so.5") == 0)	      \
42
	      break;							      \
42
	      break;							      \
(-)libc/elf/dl-version.c (-2 / +3 lines)
Lines 59-65 Link Here
59
  struct link_map *tmap;
59
  struct link_map *tmap;
60
  unsigned int n;
60
  unsigned int n;
61
61
62
  for (tmap = GL(dl_loaded); tmap != NULL; tmap = tmap->l_next)
62
  for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
63
       tmap = tmap->l_next)
63
    if (_dl_name_match_p (name, tmap))
64
    if (_dl_name_match_p (name, tmap))
64
      return tmap;
65
      return tmap;
65
66
Lines 243-249 Link Here
243
					   ? map->l_name : rtld_progname),
244
					   ? map->l_name : rtld_progname),
244
					  aux->vna_hash,
245
					  aux->vna_hash,
245
					  strtab + aux->vna_name,
246
					  strtab + aux->vna_name,
246
					  needed, verbose,
247
					  needed->l_real, verbose,
247
					  aux->vna_flags & VER_FLG_WEAK);
248
					  aux->vna_flags & VER_FLG_WEAK);
248
249
249
		  /* Compare the version index.  */
250
		  /* Compare the version index.  */
(-)libc/elf/dl-sym.c (-10 / +12 lines)
Lines 69-85 Link Here
69
69
70
  /* If the address is not recognized the call comes from the main
70
  /* If the address is not recognized the call comes from the main
71
     program (we hope).  */
71
     program (we hope).  */
72
  struct link_map *match = GL(dl_loaded);
72
  struct link_map *match = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
73
73
74
  /* Find the highest-addressed object that CALLER is not below.  */
74
  /* Find the highest-addressed object that CALLER is not below.  */
75
  for (struct link_map *l = GL(dl_loaded); l != NULL; l = l->l_next)
75
  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
76
    if (caller >= l->l_map_start && caller < l->l_map_end)
76
    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
77
      {
77
	 l = l->l_next)
78
	/* There must be exactly one DSO for the range of the virtual
78
      if (caller >= l->l_map_start && caller < l->l_map_end)
79
	   memory.  Otherwise something is really broken.  */
79
	{
80
	match = l;
80
	  /* There must be exactly one DSO for the range of the virtual
81
	break;
81
	     memory.  Otherwise something is really broken.  */
82
      }
82
	  match = l;
83
	  break;
84
	}
83
85
84
  if (handle == RTLD_DEFAULT)
86
  if (handle == RTLD_DEFAULT)
85
    /* Search the global scope.  */
87
    /* Search the global scope.  */
Lines 88-94 Link Here
88
				       NULL);
90
				       NULL);
89
  else if (handle == RTLD_NEXT)
91
  else if (handle == RTLD_NEXT)
90
    {
92
    {
91
      if (__builtin_expect (match == GL(dl_loaded), 0))
93
      if (__builtin_expect (match == GL(dl_ns)[LM_ID_BASE]._ns_loaded, 0))
92
	{
94
	{
93
	  if (match == NULL
95
	  if (match == NULL
94
	      || caller < match->l_map_start
96
	      || caller < match->l_map_start
(-)libc/elf/dl-debug.c (-1 / +3 lines)
Lines 39-45 Link Here
39
      /* Tell the debugger where to find the map of loaded objects.  */
39
      /* Tell the debugger where to find the map of loaded objects.  */
40
      _r_debug.r_version = 1	/* R_DEBUG_VERSION XXX */;
40
      _r_debug.r_version = 1	/* R_DEBUG_VERSION XXX */;
41
      _r_debug.r_ldbase = ldbase;
41
      _r_debug.r_ldbase = ldbase;
42
      _r_debug.r_map = GL(dl_loaded);
42
      // XXX This is problematic.  It means we cannot tell the debugger
43
      // XXX about namespaces other than the main one.
44
      _r_debug.r_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
43
      _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state;
45
      _r_debug.r_brk = (ElfW(Addr)) &_dl_debug_state;
44
    }
46
    }
45
47
(-)libc/elf/dl-conflict.c (-1 / +3 lines)
Lines 54-61 Link Here
54
    (map) = resolve_conflict_map;					      \
54
    (map) = resolve_conflict_map;					      \
55
  } while (0)
55
  } while (0)
56
56
57
    /* Prelinking makes no sense for anything but the main namespace.  */
58
    assert (l->l_ns == LM_ID_BASE);
57
    struct link_map *resolve_conflict_map __attribute__ ((__unused__))
59
    struct link_map *resolve_conflict_map __attribute__ ((__unused__))
58
      = GL(dl_loaded);
60
      = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
59
61
60
#include "dynamic-link.h"
62
#include "dynamic-link.h"
61
63
(-)libc/elf/dl-caller.c (-30 / +32 lines)
Lines 35-78 Link Here
35
#endif
35
#endif
36
  static const char expected4[] = LD_SO;
36
  static const char expected4[] = LD_SO;
37
37
38
  for (struct link_map *l = GL(dl_loaded); l != NULL; l = l->l_next)
38
  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
39
    if (caller >= (const void *) l->l_map_start
39
    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
40
	&& caller < (const void *) l->l_text_end)
40
	 l = l->l_next)
41
      {
41
      if (caller >= (const void *) l->l_map_start
42
	/* The address falls into this DSO's address range.  Check the
42
	  && caller < (const void *) l->l_text_end)
43
	   name.  */
43
	{
44
	if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
44
	  /* The address falls into this DSO's address range.  Check the
45
	  return 0;
45
	     name.  */
46
	if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
46
	  if ((mask & allow_libc) && strcmp (expected1, l->l_name) == 0)
47
	  return 0;
47
	    return 0;
48
	  if ((mask & allow_libdl) && strcmp (expected2, l->l_name) == 0)
49
	    return 0;
48
#ifdef LIBPTHREAD_SO
50
#ifdef LIBPTHREAD_SO
49
	if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
51
	  if ((mask & allow_libpthread) && strcmp (expected3, l->l_name) == 0)
50
	  return 0;
52
	    return 0;
51
#endif
53
#endif
52
	if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
54
	  if ((mask & allow_ldso) && strcmp (expected4, l->l_name) == 0)
53
	  return 0;
55
	    return 0;
54
56
55
	struct libname_list *runp = l->l_libname;
57
	  struct libname_list *runp = l->l_libname;
56
58
57
	while (runp != NULL)
59
	  while (runp != NULL)
58
	  {
60
	    {
59
	    if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
61
	      if ((mask & allow_libc) && strcmp (expected1, runp->name) == 0)
60
		  return 0;
62
		return 0;
61
	    if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
63
	      if ((mask & allow_libdl) && strcmp (expected2, runp->name) == 0)
62
	      return 0;
64
		return 0;
63
#ifdef LIBPTHREAD_SO
65
#ifdef LIBPTHREAD_SO
64
	    if ((mask & allow_libpthread)
66
	      if ((mask & allow_libpthread)
65
		&& strcmp (expected3, runp->name) == 0)
67
		  && strcmp (expected3, runp->name) == 0)
66
	      return 0;
68
		return 0;
67
#endif
69
#endif
68
	    if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
70
	      if ((mask & allow_ldso) && strcmp (expected4, runp->name) == 0)
69
	      return 0;
71
		return 0;
70
72
71
	    runp = runp->next;
73
	      runp = runp->next;
72
	  }
74
	    }
73
75
74
	break;
76
	  break;
75
      }
77
	}
76
78
77
  /* Maybe the dynamic linker is not yet on the list.  */
79
  /* Maybe the dynamic linker is not yet on the list.  */
78
  if ((mask & allow_ldso) != 0
80
  if ((mask & allow_ldso) != 0
(-)libc/elf/dl-addr.c (-20 / +21 lines)
Lines 38-63 Link Here
38
38
39
  /* Find the highest-addressed object that ADDRESS is not below.  */
39
  /* Find the highest-addressed object that ADDRESS is not below.  */
40
  match = NULL;
40
  match = NULL;
41
  for (struct link_map *l = GL(dl_loaded); l; l = l->l_next)
41
  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
42
    if (addr >= l->l_map_start && addr < l->l_map_end)
42
    for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
43
      {
43
      if (addr >= l->l_map_start && addr < l->l_map_end)
44
	/* We know ADDRESS lies within L if in any shared object.
44
	{
45
	   Make sure it isn't past the end of L's segments.  */
45
	  /* We know ADDRESS lies within L if in any shared object.
46
	size_t n = l->l_phnum;
46
	     Make sure it isn't past the end of L's segments.  */
47
	if (n > 0)
47
	  size_t n = l->l_phnum;
48
	  {
48
	  if (n > 0)
49
	    do
49
	    {
50
	      --n;
50
	      do
51
	    while (l->l_phdr[n].p_type != PT_LOAD);
51
		--n;
52
	    if (addr >= (l->l_addr +
52
	      while (l->l_phdr[n].p_type != PT_LOAD);
53
			 l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
53
	      if (addr >= (l->l_addr +
54
	      /* Off the end of the highest-addressed shared object.  */
54
			   l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
55
	      continue;
55
		/* Off the end of the highest-addressed shared object.  */
56
	  }
56
		continue;
57
57
	    }
58
	match = l;
58
59
	break;
59
	  match = l;
60
      }
60
	  break;
61
	}
61
62
62
  int result = 0;
63
  int result = 0;
63
  if (match != NULL)
64
  if (match != NULL)
(-)libc/dlfcn/dlopenold.c (-2 / +10 lines)
Lines 1-5 Link Here
1
/* Load a shared object at run time.
1
/* Load a shared object at run time.
2
   Copyright (C) 1995-1999, 2000 Free Software Foundation, Inc.
2
   Copyright (C) 1995-1999, 2000, 2004 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
3
   This file is part of the GNU C Library.
4
4
5
   The GNU C Library is free software; you can redistribute it and/or
5
   The GNU C Library is free software; you can redistribute it and/or
Lines 37-49 Link Here
37
};
37
};
38
38
39
39
40
/* Non-shared code has no support for multiple namespaces.  */
41
#ifdef SHARED
42
# define NS __LM_ID_CALLER
43
#else
44
# define NS LM_ID_BASE
45
#endif
46
47
40
static void
48
static void
41
dlopen_doit (void *a)
49
dlopen_doit (void *a)
42
{
50
{
43
  struct dlopen_args *args = (struct dlopen_args *) a;
51
  struct dlopen_args *args = (struct dlopen_args *) a;
44
52
45
  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
53
  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
46
			args->caller);
54
			args->caller, args->file == NULL ? LM_ID_BASE : NS);
47
}
55
}
48
56
49
extern void *__dlopen_nocheck (const char *file, int mode);
57
extern void *__dlopen_nocheck (const char *file, int mode);
(-)libc/dlfcn/dlopen.c (-2 / +11 lines)
Lines 1-5 Link Here
1
/* Load a shared object at run time.
1
/* Load a shared object at run time.
2
   Copyright (C) 1995,96,97,98,99,2000,2003 Free Software Foundation, Inc.
2
   Copyright (C) 1995,96,97,98,99,2000,2003,2004 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
3
   This file is part of the GNU C Library.
4
4
5
   The GNU C Library is free software; you can redistribute it and/or
5
   The GNU C Library is free software; you can redistribute it and/or
Lines 31-43 Link Here
31
  const void *caller;
31
  const void *caller;
32
};
32
};
33
33
34
35
/* Non-shared code has no support for multiple namespaces.  */
36
#ifdef SHARED
37
# define NS __LM_ID_CALLER
38
#else
39
# define NS LM_ID_BASE
40
#endif
41
42
34
static void
43
static void
35
dlopen_doit (void *a)
44
dlopen_doit (void *a)
36
{
45
{
37
  struct dlopen_args *args = (struct dlopen_args *) a;
46
  struct dlopen_args *args = (struct dlopen_args *) a;
38
47
39
  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
48
  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
40
			args->caller);
49
			args->caller, args->file == NULL ? LM_ID_BASE : NS);
41
}
50
}
42
51
43
52
(-)libc/dlfcn/dlinfo.c (-1 / +4 lines)
Lines 55-66 Link Here
55
55
56
  switch (args->request)
56
  switch (args->request)
57
    {
57
    {
58
    case RTLD_DI_LMID:
59
    case RTLD_DI_CONFIGADDR:
58
    case RTLD_DI_CONFIGADDR:
60
    default:
59
    default:
61
      GLRO(dl_signal_error) (0, NULL, NULL, N_("unsupported dlinfo request"));
60
      GLRO(dl_signal_error) (0, NULL, NULL, N_("unsupported dlinfo request"));
62
      break;
61
      break;
63
62
63
    case RTLD_DI_LMID:
64
      *(Lmid_t *) args->arg = l->l_ns;
65
      break;
66
64
    case RTLD_DI_LINKMAP:
67
    case RTLD_DI_LINKMAP:
65
      *(struct link_map **) args->arg = l;
68
      *(struct link_map **) args->arg = l;
66
      break;
69
      break;
(-)libc/dlfcn/dlfcn.h (-2 / +15 lines)
Lines 1-5 Link Here
1
/* User functions for run-time dynamic loading.
1
/* User functions for run-time dynamic loading.
2
   Copyright (C) 1995-1999,2000,2001,2003 Free Software Foundation, Inc.
2
   Copyright (C) 1995-1999,2000,2001,2003,2004 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
3
   This file is part of the GNU C Library.
4
4
5
   The GNU C Library is free software; you can redistribute it and/or
5
   The GNU C Library is free software; you can redistribute it and/or
Lines 39-44 Link Here
39
   the run-time address of the symbol called NAME in the global scope
39
   the run-time address of the symbol called NAME in the global scope
40
   is returned.  */
40
   is returned.  */
41
# define RTLD_DEFAULT	((void *) 0)
41
# define RTLD_DEFAULT	((void *) 0)
42
43
44
/* Type for namespace indeces.  */
45
typedef long int Lmid_t;
46
47
/* Special namespace ID values.  */
48
# define LM_ID_BASE	0	/* Initial namespace.  */
49
# define LM_ID_NEWLM	-1	/* For dlmopen: request new namespace.  */
42
#endif
50
#endif
43
51
44
52
Lines 58-63 Link Here
58
		    __const char *__restrict __name) __THROW;
66
		    __const char *__restrict __name) __THROW;
59
67
60
#ifdef __USE_GNU
68
#ifdef __USE_GNU
69
/* Like `dlopen', but request object to be allocated in a new namespace.  */
70
extern void *dlmopen (Lmid_t __nsid, __const char *__file, int __mode) __THROW;
71
61
/* Find the run-time address in the shared object HANDLE refers to
72
/* Find the run-time address in the shared object HANDLE refers to
62
   of the symbol called NAME with VERSION.  */
73
   of the symbol called NAME with VERSION.  */
63
extern void *dlvsym (void *__restrict __handle,
74
extern void *dlvsym (void *__restrict __handle,
Lines 114-119 Link Here
114
/* These are the possible values for the REQUEST argument to `dlinfo'.  */
125
/* These are the possible values for the REQUEST argument to `dlinfo'.  */
115
enum
126
enum
116
  {
127
  {
128
    /* Treat ARG as `lmid_t *'; store namespace ID for HANDLE there.  */
129
    RTLD_DI_LMID = 1,
130
117
    /* Treat ARG as `struct link_map **';
131
    /* Treat ARG as `struct link_map **';
118
       store the `struct link_map *' for HANDLE there.  */
132
       store the `struct link_map *' for HANDLE there.  */
119
    RTLD_DI_LINKMAP = 2,
133
    RTLD_DI_LINKMAP = 2,
Lines 130-136 Link Here
130
       expand $ORIGIN in this shared object's dependency file names.  */
144
       expand $ORIGIN in this shared object's dependency file names.  */
131
    RTLD_DI_ORIGIN = 6,
145
    RTLD_DI_ORIGIN = 6,
132
146
133
    RTLD_DI_LMID = 1,		/* Unsupported, defined by Solaris.  */
134
    RTLD_DI_CONFIGADDR = 3	/* Unsupported, defined by Solaris.  */
147
    RTLD_DI_CONFIGADDR = 3	/* Unsupported, defined by Solaris.  */
135
  };
148
  };
136
149
(-)libc/dlfcn/Versions (+3 lines)
Lines 8-11 Link Here
8
  GLIBC_2.3.3 {
8
  GLIBC_2.3.3 {
9
    dladdr1; dlinfo;
9
    dladdr1; dlinfo;
10
  }
10
  }
11
  GLIBC_2.3.4 {
12
    dlmopen;
13
  }
11
}
14
}
(-)libc/dlfcn/Makefile (-2 / +71 lines)
Lines 19-25 Link Here
19
subdir		:= dlfcn
19
subdir		:= dlfcn
20
headers		:= bits/dlfcn.h dlfcn.h
20
headers		:= bits/dlfcn.h dlfcn.h
21
extra-libs	:= libdl
21
extra-libs	:= libdl
22
libdl-routines	:= dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo
22
libdl-routines	:= dlopen dlclose dlsym dlvsym dlerror dladdr dladdr1 dlinfo \
23
		   dlmopen
23
distribute	:= dlopenold.c glreflib1.c glreflib2.c failtestmod.c \
24
distribute	:= dlopenold.c glreflib1.c glreflib2.c failtestmod.c \
24
		   defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \
25
		   defaultmod1.c defaultmod2.c errmsg1mod.c modatexit.c \
25
		   modcxaatexit.c modstatic.c \
26
		   modcxaatexit.c modstatic.c \
26
-- libc/dlfcn/dlmopen.c
Line 0 Link Here
1
/* Load a shared object at run time.
2
   Copyright (C) 1995,96,97,98,99,2000,2003,2004 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
20
#include <dlfcn.h>
21
#include <errno.h>
22
#include <libintl.h>
23
#include <stddef.h>
24
#include <ldsodefs.h>
25
26
struct dlmopen_args
27
{
28
  /* Namespace ID.  */
29
  Lmid_t nsid;
30
  /* The arguments for dlopen_doit.  */
31
  const char *file;
32
  int mode;
33
  /* The return value of dlopen_doit.  */
34
  void *new;
35
  /* Address of the caller.  */
36
  const void *caller;
37
};
38
39
static void
40
dlmopen_doit (void *a)
41
{
42
  struct dlmopen_args *args = (struct dlmopen_args *) a;
43
44
  /* Non-shared code has no support for multiple namespaces.  */
45
  if (args->nsid != LM_ID_BASE)
46
#ifdef SHARED
47
    /* If trying to open the link map for the main executable the namespace
48
       must be the main one.  */
49
    if (args->file == NULL)
50
#endif
51
      GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
52
53
  args->new = _dl_open (args->file ?: "", args->mode | __RTLD_DLOPEN,
54
			args->caller, args->nsid);
55
}
56
57
58
void *
59
dlmopen (Lmid_t nsid, const char *file, int mode)
60
{
61
  struct dlmopen_args args;
62
  args.nsid = nsid;
63
  args.file = file;
64
  args.mode = mode;
65
  args.caller = RETURN_ADDRESS (0);
66
67
  return _dlerror_run (dlmopen_doit, &args) ? NULL : args.new;
68
}
69
static_link_warning (dlmopen)

Return to bug 72343