diff options
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/ldso.c | 2 | ||||
-rw-r--r-- | ldso/ldso/mips/dl-sysdep.h | 2 | ||||
-rw-r--r-- | ldso/ldso/mips/elfinterp.c | 10 | ||||
-rw-r--r-- | ldso/libdl/libdl.c | 18 |
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; |