Browse Source

Let ldso decide if it should relocate itselft a second time. This
is needed if ldso should use libcs malloc whenever possible.

Fix RTLD_LAZY propagation to RTLD_NOW relocation when requested by
libdl.

Joakim Tjernlund 20 years ago
parent
commit
6d6f3a5c26

+ 1 - 1
ldso/include/dl-hash.h

@@ -6,7 +6,6 @@
 #endif
 #endif
 
 
 struct dyn_elf{
 struct dyn_elf{
-  unsigned long flags;
   struct elf_resolve * dyn;
   struct elf_resolve * dyn;
   struct dyn_elf * next_handle;  /* Used by dlopen et al. */
   struct dyn_elf * next_handle;  /* Used by dlopen et al. */
   struct dyn_elf * next;
   struct dyn_elf * next;
@@ -26,6 +25,7 @@ struct elf_resolve{
   struct dyn_elf * symbol_scope;
   struct dyn_elf * symbol_scope;
   unsigned short usage_count;
   unsigned short usage_count;
   unsigned short int init_flag;
   unsigned short int init_flag;
+  unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
   unsigned int nbucket;
   unsigned int nbucket;
   unsigned long * elf_buckets;
   unsigned long * elf_buckets;
   /*
   /*

+ 0 - 5
ldso/ldso/arm/elfinterp.c

@@ -189,11 +189,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 	ELF_RELOC *rpnt;
 	ELF_RELOC *rpnt;
 	int symtab_index;
 	int symtab_index;
 
 
-	/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-	   Make sure we do not do them again */
-	if (tpnt->libtype == program_interpreter)
-		return 0;
-
 	/* Now parse the relocation information */
 	/* Now parse the relocation information */
 	rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);
 	rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);
 	rel_size = rel_size / sizeof(ELF_RELOC);
 	rel_size = rel_size / sizeof(ELF_RELOC);

+ 0 - 12
ldso/ldso/cris/elfinterp.c

@@ -182,18 +182,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope, unsigned long rel_add
 
 
 	for (i = 0; i < rel_size; i++, rpnt++) {
 	for (i = 0; i < rel_size; i++, rpnt++) {
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
-
-		/*
-		 * Make sure the same symbols that the linker resolved when it
-		 * bootstapped itself isn't resolved again.
-		 */
-		if (!symtab_index && tpnt->libtype == program_interpreter)
-			continue;
-
-		if (symtab_index && tpnt->libtype == program_interpreter &&
-			_dl_symbol(strtab + symtab[symtab_index].st_name))
-			continue;
-
 #if defined (__SUPPORT_LD_DEBUG__)
 #if defined (__SUPPORT_LD_DEBUG__)
 		debug_sym(symtab, strtab, symtab_index);
 		debug_sym(symtab, strtab, symtab_index);
 		debug_reloc(symtab, strtab, rpnt);
 		debug_reloc(symtab, strtab, rpnt);

+ 12 - 15
ldso/ldso/dl-elf.c

@@ -730,15 +730,15 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 
 	return tpnt;
 	return tpnt;
 }
 }
-
-int _dl_fixup(struct dyn_elf *rpnt, int flag)
+/* now_flag must be RTLD_NOW or zero */
+int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
 {
 {
 	int goof = 0;
 	int goof = 0;
 	struct elf_resolve *tpnt;
 	struct elf_resolve *tpnt;
 	unsigned long reloc_size;
 	unsigned long reloc_size;
 
 
 	if (rpnt->next)
 	if (rpnt->next)
-		goof += _dl_fixup(rpnt->next, flag);
+		goof += _dl_fixup(rpnt->next, now_flag);
 	tpnt = rpnt->dyn;
 	tpnt = rpnt->dyn;
 
 
 #if defined (__SUPPORT_LD_DEBUG__)
 #if defined (__SUPPORT_LD_DEBUG__)
@@ -756,28 +756,25 @@ int _dl_fixup(struct dyn_elf *rpnt, int flag)
 		return goof;
 		return goof;
 	}
 	}
 
 
+	reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE];
 /* On some machines, notably SPARC & PPC, DT_REL* includes DT_JMPREL in its
 /* On some machines, notably SPARC & PPC, DT_REL* includes DT_JMPREL in its
    range.  Note that according to the ELF spec, this is completely legal! */
    range.  Note that according to the ELF spec, this is completely legal! */
 #ifdef ELF_MACHINE_PLTREL_OVERLAP
 #ifdef ELF_MACHINE_PLTREL_OVERLAP
-	reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE] - 
-		tpnt->dynamic_info [DT_PLTRELSZ];
-#else
-	reloc_size = tpnt->dynamic_info[DT_RELOC_TABLE_SIZE];
+	reloc_size -= tpnt->dynamic_info [DT_PLTRELSZ];
 #endif
 #endif
-	if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]) {
-		if (tpnt->init_flag & RELOCS_DONE)
-			return goof;
+	if (tpnt->dynamic_info[DT_RELOC_TABLE_ADDR] &&
+	    !(tpnt->init_flag & RELOCS_DONE)) {
 		tpnt->init_flag |= RELOCS_DONE;
 		tpnt->init_flag |= RELOCS_DONE;
 		goof += _dl_parse_relocation_information(rpnt,
 		goof += _dl_parse_relocation_information(rpnt,
 				tpnt->dynamic_info[DT_RELOC_TABLE_ADDR],
 				tpnt->dynamic_info[DT_RELOC_TABLE_ADDR],
 				reloc_size, 0);
 				reloc_size, 0);
 	}
 	}
-
-	if (tpnt->dynamic_info[DT_JMPREL]) {
-		if (tpnt->init_flag & JMP_RELOCS_DONE)
-			return goof;
+	if (tpnt->dynamic_info[DT_JMPREL] &&
+	    (!(tpnt->init_flag & JMP_RELOCS_DONE) ||
+	     (now_flag && !(tpnt->rtld_flags & now_flag)))) {
+		tpnt->rtld_flags |= now_flag; 
 		tpnt->init_flag |= JMP_RELOCS_DONE;
 		tpnt->init_flag |= JMP_RELOCS_DONE;
-		if (flag & RTLD_LAZY) {
+		if (!(tpnt->rtld_flags & RTLD_NOW)) {
 			_dl_parse_lazy_relocation_information(rpnt,
 			_dl_parse_lazy_relocation_information(rpnt,
 					tpnt->dynamic_info[DT_JMPREL],
 					tpnt->dynamic_info[DT_JMPREL],
 					tpnt->dynamic_info [DT_PLTRELSZ], 0);
 					tpnt->dynamic_info [DT_PLTRELSZ], 0);

+ 0 - 14
ldso/ldso/frv/elfinterp.c

@@ -213,15 +213,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 	        int res;
 	        int res;
 	    
 	    
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
-		
-		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-		   Make sure we do not do them again */
-		if (!symtab_index && tpnt->libtype == program_interpreter)
-			continue;
-		if (symtab_index && tpnt->libtype == program_interpreter &&
-		    _dl_symbol(strtab + symtab[symtab_index].st_name))
-			continue;
-
 #if defined (__SUPPORT_LD_DEBUG__)
 #if defined (__SUPPORT_LD_DEBUG__)
 		debug_sym(symtab,strtab,symtab_index);
 		debug_sym(symtab,strtab,symtab_index);
 		debug_reloc(symtab,strtab,rpnt);
 		debug_reloc(symtab,strtab,rpnt);
@@ -444,11 +435,6 @@ _dl_parse_relocation_information
 (struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size,
 (struct dyn_elf *rpnt, unsigned long rel_addr, unsigned long rel_size,
  int type __attribute_used__)
  int type __attribute_used__)
 {
 {
-  /* The interpreter initial self-relocation is complete, and we
-     can't re-apply relocations.  */
-  if (rpnt->dyn->libtype == program_interpreter)
-    return 0;
-
   return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
   return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size, _dl_do_reloc);
 }
 }
 
 

+ 0 - 5
ldso/ldso/i386/elfinterp.c

@@ -183,11 +183,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 	ELF_RELOC *rpnt;
 	ELF_RELOC *rpnt;
 	int symtab_index;
 	int symtab_index;
 
 
-	/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-	   Make sure we do not do them again */
-	if (tpnt->libtype == program_interpreter)
-		return 0;
-
 	/* Now parse the relocation information */
 	/* Now parse the relocation information */
 	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
 	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
 	rel_size = rel_size / sizeof(ELF_RELOC);
 	rel_size = rel_size / sizeof(ELF_RELOC);

+ 25 - 40
ldso/ldso/ldso.c

@@ -91,7 +91,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 {
 {
 	ElfW(Phdr) *ppnt;
 	ElfW(Phdr) *ppnt;
 	char *lpntstr;
 	char *lpntstr;
-	int i, goof = 0, be_lazy = RTLD_LAZY, trace_loaded_objects = 0;
+	int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
 	struct dyn_elf *rpnt;
 	struct dyn_elf *rpnt;
 	struct elf_resolve *tcurr;
 	struct elf_resolve *tcurr;
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
@@ -127,26 +127,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 	 * this beast to run.  We start with the basic executable, and then
 	 * this beast to run.  We start with the basic executable, and then
 	 * go from there.  Eventually we will run across ourself, and we
 	 * go from there.  Eventually we will run across ourself, and we
 	 * will need to properly deal with that as well. */
 	 * will need to properly deal with that as well. */
-	lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
-
-	tpnt->chains = hash_addr;
-	tpnt->next = 0;
-	tpnt->libname = 0;
-	tpnt->libtype = program_interpreter;
-	tpnt->loadaddr = (ElfW(Addr)) load_addr;
-
-#ifdef ALLOW_ZERO_PLTGOT
-	if (tpnt->dynamic_info[DT_PLTGOT])
-#endif
-	{
-		INIT_GOT(lpnt, tpnt);
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
-		_dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
-#endif
-	}
-
-	/* OK, this was a big step, now we need to scan all of the user images
-	   and load them properly. */
 	{
 	{
 		ElfW(Ehdr) *epnt;
 		ElfW(Ehdr) *epnt;
 		ElfW(Phdr) *myppnt;
 		ElfW(Phdr) *myppnt;
@@ -165,6 +145,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 
 
 	brk_addr = 0;
 	brk_addr = 0;
 	rpnt = NULL;
 	rpnt = NULL;
+	if (_dl_getenv("LD_BIND_NOW", envp))
+		unlazy = RTLD_NOW;
 
 
 	/* At this point we are now free to examine the user application,
 	/* At this point we are now free to examine the user application,
 	   and figure out which libraries are supposed to be called.  Until
 	   and figure out which libraries are supposed to be called.  Until
@@ -191,6 +173,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 			_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
 			rpnt->dyn = _dl_loaded_modules;
 			rpnt->dyn = _dl_loaded_modules;
+			app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
 			app_tpnt->usage_count++;
 			app_tpnt->usage_count++;
 			app_tpnt->symbol_scope = _dl_symbol_tables;
 			app_tpnt->symbol_scope = _dl_symbol_tables;
 			lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr);
 			lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr);
@@ -236,13 +219,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 		}
 		}
 	}
 	}
 
 
-
 	/* Now we need to figure out what kind of options are selected.
 	/* Now we need to figure out what kind of options are selected.
 	   Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
 	   Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
 	{
 	{
-		if (_dl_getenv("LD_BIND_NOW", envp))
-			be_lazy = 0;
-
 		if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
 		if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
 				(auxvt[AT_UID].a_un.a_val != -1 &&
 				(auxvt[AT_UID].a_un.a_val != -1 &&
 				 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val
 				 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val
@@ -383,6 +362,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 						_dl_exit(15);
 						_dl_exit(15);
 					}
 					}
 				} else {
 				} else {
+					tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 					_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 					_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 #endif
 #endif
@@ -468,6 +448,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 								_dl_exit(15);
 								_dl_exit(15);
 							}
 							}
 						} else {
 						} else {
+							tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 							_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 							_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 #endif
 #endif
@@ -525,6 +506,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 						_dl_exit(16);
 						_dl_exit(16);
 					}
 					}
 				} else {
 				} else {
+					tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 #ifdef __SUPPORT_LD_DEBUG_EARLY__
 					_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 					_dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
 #endif
 #endif
@@ -545,23 +527,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 	/*
 	/*
 	 * If the program interpreter is not in the module chain, add it.  This will
 	 * If the program interpreter is not in the module chain, add it.  This will
 	 * be required for dlopen to be able to access the internal functions in the
 	 * be required for dlopen to be able to access the internal functions in the
-	 * dynamic linker.
+	 * dynamic linker and to relocate the interpreter again once all libs are loaded.
 	 */
 	 */
 	if (tpnt) {
 	if (tpnt) {
-		tcurr = _dl_loaded_modules;
-		if (tcurr)
-			while (tcurr->next)
-				tcurr = tcurr->next;
-		tpnt->next = NULL;
+		tpnt = _dl_add_elf_hash_table(tpnt->libname, (char *)load_addr, tpnt->dynamic_info,
+					 (unsigned long)tpnt->dynamic_addr, tpnt->dynamic_size);
+		tpnt->libtype = program_interpreter;
 		tpnt->usage_count++;
 		tpnt->usage_count++;
-
-		if (tcurr) {
-			tcurr->next = tpnt;
-			tpnt->prev = tcurr;
-		} else {
-			_dl_loaded_modules = tpnt;
-			tpnt->prev = NULL;
-		}
+		tpnt->symbol_scope = _dl_symbol_tables;
 		if (rpnt) {
 		if (rpnt) {
 			rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
 			_dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
 			_dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
@@ -572,6 +545,18 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
 			_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
 		}
 		}
 		rpnt->dyn = tpnt;
 		rpnt->dyn = tpnt;
+		tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
+#ifdef RERELOCATE_LDSO
+		/* Only rerelocate functions for now. */
+		tpnt->init_flag = RELOCS_DONE | COPY_RELOCS_DONE;
+		lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+# ifdef ALLOW_ZERO_PLTGOT
+		if (tpnt->dynamic_info[DT_PLTGOT])
+# endif
+			INIT_GOT(lpnt, tpnt);
+#else
+		tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE | COPY_RELOCS_DONE;
+#endif
 		tpnt = NULL;
 		tpnt = NULL;
 	}
 	}
 
 
@@ -602,7 +587,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt
 	 * to the GOT tables.  We need to do this in reverse order so that COPY
 	 * to the GOT tables.  We need to do this in reverse order so that COPY
 	 * directives work correctly */
 	 * directives work correctly */
 	if (_dl_symbol_tables)
 	if (_dl_symbol_tables)
-		goof += _dl_fixup(_dl_symbol_tables, be_lazy);
+		goof += _dl_fixup(_dl_symbol_tables, unlazy);
 
 
 
 
 	/* OK, at this point things are pretty much ready to run.  Now we
 	/* OK, at this point things are pretty much ready to run.  Now we

+ 0 - 17
ldso/ldso/m68k/elfinterp.c

@@ -152,13 +152,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
       reloc_type = ELF32_R_TYPE (rpnt->r_info);
       reloc_type = ELF32_R_TYPE (rpnt->r_info);
       symtab_index = ELF32_R_SYM (rpnt->r_info);
       symtab_index = ELF32_R_SYM (rpnt->r_info);
 
 
-      /* When the dynamic linker bootstrapped itself, it resolved some symbols.
-         Make sure we do not do them again.  */
-      if (tpnt->libtype == program_interpreter
-	  && (!symtab_index
-	      || _dl_symbol (strtab + symtab[symtab_index].st_name)))
-	continue;
-
       switch (reloc_type)
       switch (reloc_type)
 	{
 	{
 	case R_68K_NONE:
 	case R_68K_NONE:
@@ -207,12 +200,6 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
       reloc_type = ELF32_R_TYPE (rpnt->r_info);
       reloc_type = ELF32_R_TYPE (rpnt->r_info);
       symtab_index = ELF32_R_SYM (rpnt->r_info);
       symtab_index = ELF32_R_SYM (rpnt->r_info);
       symbol_addr = 0;
       symbol_addr = 0;
-
-      if (tpnt->libtype == program_interpreter
-	  && (!symtab_index
-	      || _dl_symbol (strtab + symtab[symtab_index].st_name)))
-	continue;
-
       if (symtab_index)
       if (symtab_index)
 	{
 	{
 	  symbol_addr = (unsigned int)
 	  symbol_addr = (unsigned int)
@@ -334,10 +321,6 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt,
 	continue;
 	continue;
       symtab_index = ELF32_R_SYM (rpnt->r_info);
       symtab_index = ELF32_R_SYM (rpnt->r_info);
       symbol_addr = 0;
       symbol_addr = 0;
-      if (tpnt->libtype == program_interpreter
-	  && (!symtab_index
-	      || _dl_symbol (strtab + symtab[symtab_index].st_name)))
-	continue;
       if (symtab_index)
       if (symtab_index)
 	{
 	{
 	  symbol_addr = (unsigned int)
 	  symbol_addr = (unsigned int)

+ 0 - 9
ldso/ldso/mips/elfinterp.c

@@ -186,10 +186,6 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
 #if defined (__SUPPORT_LD_DEBUG__)
 #if defined (__SUPPORT_LD_DEBUG__)
 	unsigned long old_val=0;
 	unsigned long old_val=0;
 #endif
 #endif
-
-	if (tpnt->libtype == program_interpreter)
-		return 0;
-
 	/* Now parse the relocation information */
 	/* Now parse the relocation information */
 	rel_size = rel_size / sizeof(Elf32_Rel);
 	rel_size = rel_size / sizeof(Elf32_Rel);
 	rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
 	rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
@@ -264,11 +260,6 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
 	unsigned long *got_entry;
 	unsigned long *got_entry;
 
 
 	for (; tpnt ; tpnt = tpnt->next) {
 	for (; tpnt ; tpnt = tpnt->next) {
-
-		/* We don't touch the dynamic linker */
-		if (tpnt->libtype == program_interpreter)
-			continue;
-
 		/* Setup the loop variables */
 		/* Setup the loop variables */
 		got_entry = (unsigned long *) (tpnt->loadaddr +
 		got_entry = (unsigned long *) (tpnt->loadaddr +
 			tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
 			tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;

+ 0 - 9
ldso/ldso/powerpc/elfinterp.c

@@ -396,10 +396,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
 	(void) type;
 	(void) type;
 	num_plt_entries = rel_size / sizeof(ELF_RELOC);
 	num_plt_entries = rel_size / sizeof(ELF_RELOC);
 
 
-	/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-	   Make sure we do not do them again */
-	if (tpnt->libtype == program_interpreter)
-		return;
 	rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
 	rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
 	plt = (Elf32_Word *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
 	plt = (Elf32_Word *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);
 
 
@@ -443,11 +439,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 	ELF_RELOC *rpnt;
 	ELF_RELOC *rpnt;
 	int symtab_index;
 	int symtab_index;
 
 
-	/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-	   Make sure we do not do them again */
-	if (tpnt->libtype == program_interpreter)
-		return 0;
-
 	/* Now parse the relocation information */
 	/* Now parse the relocation information */
 	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
 	rpnt = (ELF_RELOC *)(intptr_t) (rel_addr + tpnt->loadaddr);
 	rel_size = rel_size / sizeof(ELF_RELOC);
 	rel_size = rel_size / sizeof(ELF_RELOC);

+ 0 - 9
ldso/ldso/sh/elfinterp.c

@@ -199,15 +199,6 @@ _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 	        int res;
 	        int res;
 
 
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
-
-		/* When the dynamic linker bootstrapped itself, it resolved some symbols.
-		   Make sure we do not do them again */
-		if (!symtab_index && tpnt->libtype == program_interpreter)
-			continue;
-		if (symtab_index && tpnt->libtype == program_interpreter &&
-		    _dl_symbol(strtab + symtab[symtab_index].st_name))
-			continue;
-
 #if defined (__SUPPORT_LD_DEBUG__)
 #if defined (__SUPPORT_LD_DEBUG__)
 		debug_sym(symtab,strtab,symtab_index);
 		debug_sym(symtab,strtab,symtab_index);
 		debug_reloc(symtab,strtab,rpnt);
 		debug_reloc(symtab,strtab,rpnt);

+ 0 - 9
ldso/ldso/sh64/elfinterp.c

@@ -244,15 +244,6 @@ static int _dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
 		int res;
 		int res;
 
 
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
 		symtab_index = ELF32_R_SYM(rpnt->r_info);
-
-		/* When the dynamic linker bootstrapped itself, it resolved
-		   some symbols. Make sure we do not do them again */
-		if (!symtab_index && tpnt->libtype == program_interpreter)
-			continue;
-		if (symtab_index && tpnt->libtype == program_interpreter &&
-		    _dl_symbol(strtab + symtab[symtab_index].st_name))
-			continue;
-
 #ifdef __SUPPORT_LD_DEBUG__
 #ifdef __SUPPORT_LD_DEBUG__
 		debug_sym(symtab,strtab,symtab_index);
 		debug_sym(symtab,strtab,symtab_index);
 		debug_reloc(symtab,strtab,rpnt);
 		debug_reloc(symtab,strtab,rpnt);

+ 0 - 19
ldso/ldso/sparc/elfinterp.c

@@ -169,13 +169,6 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
     reloc_type = ELF32_R_TYPE(rpnt->r_info);
     reloc_type = ELF32_R_TYPE(rpnt->r_info);
     symtab_index = ELF32_R_SYM(rpnt->r_info);
     symtab_index = ELF32_R_SYM(rpnt->r_info);
 
 
-    /* When the dynamic linker bootstrapped itself, it resolved some symbols.
-       Make sure we do not do them again */
-    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
-    if(symtab_index && tpnt->libtype == program_interpreter &&
-       _dl_symbol(strtab + symtab[symtab_index].st_name))
-      continue;
-
     switch(reloc_type){
     switch(reloc_type){
     case R_SPARC_NONE:
     case R_SPARC_NONE:
       break;
       break;
@@ -219,14 +212,8 @@ int _dl_parse_relocation_information(struct dyn_elf *rpnt,
     symtab_index = ELF32_R_SYM(rpnt->r_info);
     symtab_index = ELF32_R_SYM(rpnt->r_info);
     symbol_addr = 0;
     symbol_addr = 0;
 
 
-    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
-
     if(symtab_index) {
     if(symtab_index) {
 
 
-      if(tpnt->libtype == program_interpreter &&
-	 _dl_symbol(strtab + symtab[symtab_index].st_name))
-	continue;
-
       symbol_addr = (unsigned int)
       symbol_addr = (unsigned int)
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
 		      tpnt->symbol_scope, elf_machine_type_class(reloc_type));
 		      tpnt->symbol_scope, elf_machine_type_class(reloc_type));
@@ -337,13 +324,7 @@ int _dl_parse_copy_information(struct dyn_elf *xpnt,
     if(reloc_type != R_SPARC_COPY) continue;
     if(reloc_type != R_SPARC_COPY) continue;
     symtab_index = ELF32_R_SYM(rpnt->r_info);
     symtab_index = ELF32_R_SYM(rpnt->r_info);
     symbol_addr = 0;
     symbol_addr = 0;
-    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
     if(symtab_index) {
     if(symtab_index) {
-
-      if(tpnt->libtype == program_interpreter &&
-	 _dl_symbol(strtab + symtab[symtab_index].st_name))
-	continue;
-
       symbol_addr = (unsigned int)
       symbol_addr = (unsigned int)
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
 	_dl_find_hash(strtab + symtab[symtab_index].st_name,
 		      xpnt->next,  ELF_RTYPE_CLASS_COPY);
 		      xpnt->next,  ELF_RTYPE_CLASS_COPY);

+ 1 - 1
ldso/libdl/Makefile

@@ -71,7 +71,7 @@ libdl_pic.o: libdl.c
 
 
 $(OBJ): Makefile
 $(OBJ): Makefile
 
 
-shared:
+shared: $(TOPDIR)lib/$(LIBDL_SHARED_FULLNAME)
 	$(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
 	$(LD) $(LDFLAGS) -soname=$(LIBDL_SHARED).$(MAJOR_VERSION) \
 		-o $(LIBDL_SHARED_FULLNAME) -fini dl_cleanup --whole-archive $(LIBDL_PIC) \
 		-o $(LIBDL_SHARED_FULLNAME) -fini dl_cleanup --whole-archive $(LIBDL_PIC) \
 		--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \
 		--no-whole-archive $(TOPDIR)/libc/misc/internals/interp.o \

+ 7 - 2
ldso/libdl/libdl.c

@@ -134,6 +134,7 @@ void *dlopen(const char *libname, int flag)
 	ElfW(Addr) from;
 	ElfW(Addr) from;
 	struct elf_resolve *tpnt1;
 	struct elf_resolve *tpnt1;
 	void (*dl_brk) (void);
 	void (*dl_brk) (void);
+	int now_flag;
 
 
 	/* A bit of sanity checking... */
 	/* A bit of sanity checking... */
 	if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
 	if (!(flag & (RTLD_LAZY|RTLD_NOW))) {
@@ -188,7 +189,7 @@ void *dlopen(const char *libname, int flag)
 	dyn_chain = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
 	dyn_chain = (struct dyn_elf *) malloc(sizeof(struct dyn_elf));
 	_dl_memset(dyn_chain, 0, sizeof(struct dyn_elf));
 	_dl_memset(dyn_chain, 0, sizeof(struct dyn_elf));
 	dyn_chain->dyn = tpnt;
 	dyn_chain->dyn = tpnt;
-	dyn_chain->flags = flag;
+	tpnt->rtld_flags |= RTLD_GLOBAL;
 
 
 	dyn_chain->next_handle = _dl_handles;
 	dyn_chain->next_handle = _dl_handles;
 	_dl_handles = dyn_ptr = dyn_chain;
 	_dl_handles = dyn_ptr = dyn_chain;
@@ -219,6 +220,7 @@ void *dlopen(const char *libname, int flag)
 				_dl_memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
 				_dl_memset (dyn_ptr->next, 0, sizeof (struct dyn_elf));
 				dyn_ptr = dyn_ptr->next;
 				dyn_ptr = dyn_ptr->next;
 				dyn_ptr->dyn = tpnt1;
 				dyn_ptr->dyn = tpnt1;
+				tpnt->rtld_flags |= RTLD_GLOBAL;
 				if (!tpnt1) {
 				if (!tpnt1) {
 					tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0);
 					tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0);
 					if (!tpnt1)
 					if (!tpnt1)
@@ -254,7 +256,10 @@ void *dlopen(const char *libname, int flag)
 	 * Now we go through and look for REL and RELA records that indicate fixups
 	 * Now we go through and look for REL and RELA records that indicate fixups
 	 * to the GOT tables.  We need to do this in reverse order so that COPY
 	 * to the GOT tables.  We need to do this in reverse order so that COPY
 	 * directives work correctly */
 	 * directives work correctly */
-	if (_dl_fixup(dyn_chain, dyn_chain->flags))
+	now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
+	if (getenv("LD_BIND_NOW"))
+		now_flag = RTLD_NOW;
+	if (_dl_fixup(dyn_chain, now_flag))
 		goto oops;
 		goto oops;
 
 
 	/* TODO:  Should we set the protections of all pages back to R/O now ? */
 	/* TODO:  Should we set the protections of all pages back to R/O now ? */