瀏覽代碼

Add BIND NOW support to MIPS.

Mips did not honour the LD_BIND_NOW env. variable or the DT_BIND_NOW flag
in the dynamic section.
Joakim Tjernlund 19 年之前
父節點
當前提交
a5ebab1766
共有 4 個文件被更改,包括 17 次插入15 次删除
  1. 1 1
      ldso/ldso/ldso.c
  2. 1 1
      ldso/ldso/mips/dl-sysdep.h
  3. 5 5
      ldso/ldso/mips/elfinterp.c
  4. 10 8
      ldso/libdl/libdl.c

+ 1 - 1
ldso/ldso/ldso.c

@@ -747,7 +747,7 @@ next_lib2:
 	 * Relocation of the GOT entries for MIPS have to be done
 	 * after all the libraries have been loaded.
 	 */
-	_dl_perform_mips_global_got_relocations(_dl_loaded_modules);
+	_dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
 #endif
 
 	/*

+ 1 - 1
ldso/ldso/mips/dl-sysdep.h

@@ -59,7 +59,7 @@ unsigned long _dl_linux_resolver(unsigned long sym_index,
 	unsigned long old_gpreg);
 
 struct elf_resolve;
-void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt);
+void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
 
 #define do_rem(result, n, base) ((result) = (n) % (base))
 

+ 5 - 5
ldso/ldso/mips/elfinterp.c

@@ -247,11 +247,11 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
 }
 
 /* Relocate the global GOT entries for the object */
-void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy)
 {
 	Elf32_Sym *sym;
 	char *strtab;
-	unsigned long i;
+	unsigned long i, tmp_lazy;
 	unsigned long *got_entry;
 
 	for (; tpnt ; tpnt = tpnt->next) {
@@ -273,11 +273,11 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
 		if(_dl_debug_reloc)
 			_dl_dprintf(2, "_dl_perform_mips_global_got_relocations for '%s'\n", tpnt->libname);
 #endif
-
+		tmp_lazy = lazy && !tpnt->dynamic_info[DT_BIND_NOW];
 		/* Relocate the global GOT entries for the object */
 		while(i--) {
 			if (sym->st_shndx == SHN_UNDEF) {
-				if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value) {
+				if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && sym->st_value && tmp_lazy) {
 					*got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
 				}
 				else {
@@ -290,7 +290,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
 					sym->st_name, tpnt->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT);
 			}
 			else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
-				*got_entry != sym->st_value) {
+				*got_entry != sym->st_value && tmp_lazy) {
 				*got_entry += (unsigned long) tpnt->loadaddr;
 			}
 			else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {

+ 10 - 8
ldso/libdl/libdl.c

@@ -61,7 +61,7 @@ int _dl_map_cache(void) __attribute__ ((__weak__));
 int _dl_unmap_cache(void) __attribute__ ((__weak__));
 #endif
 #ifdef __mips__
-extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+extern void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy)
 	__attribute__ ((__weak__));
 #endif
 #ifdef __SUPPORT_LD_DEBUG__
@@ -299,13 +299,6 @@ void *dlopen(const char *libname, int flag)
 		 * further needs to be done. */
 		return (void *) dyn_chain;
 	}
-#ifdef __mips__
-	/*
-	 * Relocation of the GOT entries for MIPS have to be done
-	 * after all the libraries have been loaded.
-	 */
-	_dl_perform_mips_global_got_relocations(tpnt);
-#endif
 
 #ifdef __SUPPORT_LD_DEBUG__
 	if(_dl_debug)
@@ -319,6 +312,15 @@ void *dlopen(const char *libname, int flag)
 	now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
 	if (getenv("LD_BIND_NOW"))
 		now_flag = RTLD_NOW;
+
+#ifdef __mips__
+	/*
+	 * Relocation of the GOT entries for MIPS have to be done
+	 * after all the libraries have been loaded.
+	 */
+	_dl_perform_mips_global_got_relocations(tpnt, !now_flag);
+#endif
+
 	if (_dl_fixup(dyn_chain, now_flag))
 		goto oops;