summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-11-17 09:36:40 +0000
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>2004-11-17 09:36:40 +0000
commita5ebab17668503a0887dfcace6904d86de8b1d8f (patch)
tree4ba37b469d47256d61fb82192365e4aacaf727ec
parent9699ba89100190c80ab51a4637c321a5dde978c5 (diff)
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.
-rw-r--r--ldso/ldso/ldso.c2
-rw-r--r--ldso/ldso/mips/dl-sysdep.h2
-rw-r--r--ldso/ldso/mips/elfinterp.c10
-rw-r--r--ldso/libdl/libdl.c18
4 files changed, 17 insertions, 15 deletions
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 476dae629..5303a6ec3 100644
--- a/ldso/ldso/ldso.c
+++ b/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
/*
diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h
index 8f5a56185..c3c5a6976 100644
--- a/ldso/ldso/mips/dl-sysdep.h
+++ b/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))
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index 79a681d35..39a147df0 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/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) {
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 5a4bb0dce..271b3550f 100644
--- a/ldso/libdl/libdl.c
+++ b/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;