OSDN Git Service

Add BIND NOW support to MIPS.
authorJoakim Tjernlund <joakim.tjernlund@transmode.se>
Wed, 17 Nov 2004 09:36:40 +0000 (09:36 -0000)
committerJoakim Tjernlund <joakim.tjernlund@transmode.se>
Wed, 17 Nov 2004 09:36:40 +0000 (09:36 -0000)
Mips did not honour the LD_BIND_NOW env. variable or the DT_BIND_NOW flag
in the dynamic section.

ldso/ldso/ldso.c
ldso/ldso/mips/dl-sysdep.h
ldso/ldso/mips/elfinterp.c
ldso/libdl/libdl.c

index 476dae6..5303a6e 100644 (file)
@@ -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
 
        /*
index 8f5a561..c3c5a69 100644 (file)
@@ -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))
 
index 79a681d..39a147d 100644 (file)
@@ -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) {
index 5a4bb0d..271b355 100644 (file)
@@ -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;