OSDN Git Service

Fixed MIPS dynamic linker by removing link order dependency bug.
author"Steven J. Hill" <sjhill@realitydiluted.com>
Mon, 20 May 2002 18:30:17 +0000 (18:30 -0000)
committer"Steven J. Hill" <sjhill@realitydiluted.com>
Mon, 20 May 2002 18:30:17 +0000 (18:30 -0000)
extra/Configs/Config.mips
extra/Configs/Config.mipsel
ldso/ldso/dl-elf.c
ldso/ldso/ldso.c
ldso/ldso/mips/boot1_arch.h
ldso/ldso/mips/dl-startup.h
ldso/ldso/mips/dl-sysdep.h
ldso/ldso/mips/elfinterp.c
ldso/ldso/mips/ld_sysdep.h
ldso/ldso/readelflib1.c

index 2e3bc28..ef2f623 100644 (file)
@@ -187,7 +187,7 @@ DEVEL_PREFIX = /usr/$(TARGET_ARCH)-linux-uclibc
 # the 'make install' target, and is not compiled into anything.  This
 # defaults to $DEVEL_PREFIX/usr, but makers of .rpms and .debs will
 # want to set this to "/usr" instead.
-SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)/usr
+SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)
 
 # If you want 'make install' to install everything under a temporary
 # directory, then define PREFIX during the install step,
index 54e846c..dd929f1 100644 (file)
@@ -187,7 +187,7 @@ DEVEL_PREFIX = /usr/$(TARGET_ARCH)-linux-uclibc
 # the 'make install' target, and is not compiled into anything.  This
 # defaults to $DEVEL_PREFIX/usr, but makers of .rpms and .debs will
 # want to set this to "/usr" instead.
-SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)/usr
+SYSTEM_DEVEL_PREFIX = $(DEVEL_PREFIX)
 
 # If you want 'make install' to install everything under a temporary
 # directory, then define PREFIX during the install step,
index ebb0aec..1bbb793 100644 (file)
@@ -527,14 +527,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 #if defined(__mips__)
        {
-           int i = 1;
-           Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+               int i = 1;
+               Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
 
-           while(dpnt->d_tag) {
-               dpnt++;
-               i++;
-           }
-           dynamic_size = i * sizeof(Elf32_Dyn);
+               while(dpnt->d_tag) {
+                       dpnt++;
+                       i++;
+               }
+               dynamic_size = i;
        }
 #endif
 
index d2eee05..5c3f38d 100644 (file)
@@ -709,12 +709,10 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
                        app_tpnt->usage_count++;
                        app_tpnt->symbol_scope = _dl_symbol_tables;
                        lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
-#ifndef __mips__
 #ifdef ALLOW_ZERO_PLTGOT
                        if (lpnt)
 #endif
                                INIT_GOT(lpnt, _dl_loaded_modules);
-#endif
                }
 
                /* OK, fill this in - we did not have this before */
@@ -1046,6 +1044,14 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
        }
 #endif
 
+#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(_dl_loaded_modules);
+#endif
+
 #ifdef DL_DEBUG
        _dl_dprintf(2, "Beginning relocation fixups\n");
 #endif
@@ -1091,11 +1097,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
                *_dl_envp = (unsigned long) envp;
        }
 
-#ifdef __mips__
-       lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
-       INIT_GOT(lpnt, _dl_loaded_modules);
-#endif
-
 #ifdef DO_MPROTECT_HACKS
        {
                int i;
index 05aaf9e..6dda467 100644 (file)
@@ -16,8 +16,11 @@ _dl_boot:
        sw $4, -0x7ff0($28)
        move $4, $29
        la $8, coff
-       bltzal $8, coff
+       .set noreorder
+       bltzal $0, coff
+       nop
 coff:  subu $8, $31, $8
+       .set reorder
        la $25, _dl_boot2
        addu $25, $8
        jalr $25
index 05aaf9e..6dda467 100644 (file)
@@ -16,8 +16,11 @@ _dl_boot:
        sw $4, -0x7ff0($28)
        move $4, $29
        la $8, coff
-       bltzal $8, coff
+       .set noreorder
+       bltzal $0, coff
+       nop
 coff:  subu $8, $31, $8
+       .set reorder
        la $25, _dl_boot2
        addu $25, $8
        jalr $25
index 9d48d8f..a669bba 100644 (file)
 
 
 /*
- * Initialization sequence for the application or library GOT.
+ * Initialization sequence for the application/library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)                                                                              \
 do {                                                                                                                                   \
-       Elf32_Sym *sym;                                                                                                         \
-       char *strtab;                                                                                                           \
        unsigned long i;                                                                                                        \
                                                                                                                                                \
        /* Check if this is the dynamic linker itself */                                        \
@@ -41,43 +39,6 @@ do {                                                                                                                                 \
        while (i < MODULE->mips_local_gotno)                                                            \
                GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;                              \
                                                                                                                                                \
-       /* Handle global GOT entries */                                                                         \
-       GOT_BASE += MODULE->mips_local_gotno;                                                           \
-       sym = (Elf32_Sym *) (MODULE->dynamic_info[DT_SYMTAB] +                          \
-               (unsigned long) MODULE->loadaddr) + MODULE->mips_gotsym;                \
-       strtab = (char *) (MODULE->dynamic_info[DT_STRTAB] +                            \
-               (unsigned long) MODULE->loadaddr);                                                              \
-       i = MODULE->mips_symtabno - MODULE->mips_gotsym;                                        \
-       while (i--) {                                                                                                           \
-               if (sym->st_shndx == SHN_UNDEF) {                                                               \
-                       if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&                          \
-                               sym->st_value)                                                                                  \
-                               *GOT_BASE = sym->st_value +                                                             \
-                                       (unsigned long) MODULE->loadaddr;                                       \
-                       else {                                                                                                          \
-                               *GOT_BASE = (unsigned long) _dl_find_hash(strtab +              \
-                                       sym->st_name, MODULE->symbol_scope, NULL, 1);           \
-                       }                                                                                                                       \
-               }                                                                                                                               \
-               else if (sym->st_shndx == SHN_COMMON) {                                                 \
-                       *GOT_BASE = (unsigned long) _dl_find_hash(strtab +                      \
-                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
-               }                                                                                                                               \
-               else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&                             \
-                       *GOT_BASE != sym->st_value)                                                                     \
-                       *GOT_BASE += (unsigned long) MODULE->loadaddr;                          \
-               else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {                  \
-                       if (sym->st_other == 0)                                                                         \
-                               *GOT_BASE += (unsigned long) MODULE->loadaddr;                  \
-               }                                                                                                                               \
-               else {                                                                                                                  \
-                       *GOT_BASE = (unsigned long) _dl_find_hash(strtab +                      \
-                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
-               }                                                                                                                               \
-                                                                                                                                               \
-               ++GOT_BASE;                                                                                                             \
-               ++sym;                                                                                                                  \
-       }                                                                                                                                       \
 } while (0)
 
 
index e6c3781..5b11921 100644 (file)
@@ -142,3 +142,62 @@ int _dl_parse_relocation_information(struct elf_resolve *tpnt,
        };
        return 0;
 }
+
+void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt)
+{
+       Elf32_Sym *sym;
+       char *strtab;
+       unsigned long i;
+       unsigned long *got_entry;
+
+       for (; tpnt ; tpnt = tpnt->next) {
+
+               /* We don't touch the dynamic linker */
+               if (tpnt->libtype == program_interpreter)
+                       continue;
+
+               /* Setup the loop variables */
+               got_entry = (unsigned long *) (tpnt->loadaddr +
+                       tpnt->dynamic_info[DT_PLTGOT]) + tpnt->mips_local_gotno;
+               sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+                       (unsigned long) tpnt->loadaddr) + tpnt->mips_gotsym;
+               strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] +
+                       (unsigned long) tpnt->loadaddr);
+               i = tpnt->mips_symtabno - tpnt->mips_gotsym;
+
+               /* 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)
+                                       *got_entry = sym->st_value + (unsigned long) tpnt->loadaddr;
+                               else {
+                                       *got_entry = (unsigned long) _dl_find_hash(strtab +
+                                               sym->st_name, tpnt->symbol_scope, NULL, 1);
+                               }
+                       }
+                       else if (sym->st_shndx == SHN_COMMON) {
+                               *got_entry = (unsigned long) _dl_find_hash(strtab +
+                                       sym->st_name, tpnt->symbol_scope, NULL, 1);
+                       }
+                       else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+                               *got_entry != sym->st_value)
+                               *got_entry += (unsigned long) tpnt->loadaddr;
+                       else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {
+                               if (sym->st_other == 0)
+                                       *got_entry += (unsigned long) tpnt->loadaddr;
+                       }
+                       else {
+                               *got_entry = (unsigned long) _dl_find_hash(strtab +
+                                       sym->st_name, tpnt->symbol_scope, NULL, 1);
+                       }
+
+#ifdef DL_DEBUG
+                       if (*got_entry == 0)
+                               _dl_dprintf(2,"ZERO: %s\n", strtab + sym->st_name);
+#endif
+
+                       got_entry++;
+                       sym++;
+               }
+       }
+}
index 9d48d8f..a669bba 100644 (file)
 
 
 /*
- * Initialization sequence for the application or library GOT.
+ * Initialization sequence for the application/library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)                                                                              \
 do {                                                                                                                                   \
-       Elf32_Sym *sym;                                                                                                         \
-       char *strtab;                                                                                                           \
        unsigned long i;                                                                                                        \
                                                                                                                                                \
        /* Check if this is the dynamic linker itself */                                        \
@@ -41,43 +39,6 @@ do {                                                                                                                                 \
        while (i < MODULE->mips_local_gotno)                                                            \
                GOT_BASE[i++] += (unsigned long) MODULE->loadaddr;                              \
                                                                                                                                                \
-       /* Handle global GOT entries */                                                                         \
-       GOT_BASE += MODULE->mips_local_gotno;                                                           \
-       sym = (Elf32_Sym *) (MODULE->dynamic_info[DT_SYMTAB] +                          \
-               (unsigned long) MODULE->loadaddr) + MODULE->mips_gotsym;                \
-       strtab = (char *) (MODULE->dynamic_info[DT_STRTAB] +                            \
-               (unsigned long) MODULE->loadaddr);                                                              \
-       i = MODULE->mips_symtabno - MODULE->mips_gotsym;                                        \
-       while (i--) {                                                                                                           \
-               if (sym->st_shndx == SHN_UNDEF) {                                                               \
-                       if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&                          \
-                               sym->st_value)                                                                                  \
-                               *GOT_BASE = sym->st_value +                                                             \
-                                       (unsigned long) MODULE->loadaddr;                                       \
-                       else {                                                                                                          \
-                               *GOT_BASE = (unsigned long) _dl_find_hash(strtab +              \
-                                       sym->st_name, MODULE->symbol_scope, NULL, 1);           \
-                       }                                                                                                                       \
-               }                                                                                                                               \
-               else if (sym->st_shndx == SHN_COMMON) {                                                 \
-                       *GOT_BASE = (unsigned long) _dl_find_hash(strtab +                      \
-                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
-               }                                                                                                                               \
-               else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&                             \
-                       *GOT_BASE != sym->st_value)                                                                     \
-                       *GOT_BASE += (unsigned long) MODULE->loadaddr;                          \
-               else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) {                  \
-                       if (sym->st_other == 0)                                                                         \
-                               *GOT_BASE += (unsigned long) MODULE->loadaddr;                  \
-               }                                                                                                                               \
-               else {                                                                                                                  \
-                       *GOT_BASE = (unsigned long) _dl_find_hash(strtab +                      \
-                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
-               }                                                                                                                               \
-                                                                                                                                               \
-               ++GOT_BASE;                                                                                                             \
-               ++sym;                                                                                                                  \
-       }                                                                                                                                       \
 } while (0)
 
 
index ebb0aec..1bbb793 100644 (file)
@@ -527,14 +527,14 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
 #if defined(__mips__)
        {
-           int i = 1;
-           Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+               int i = 1;
+               Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
 
-           while(dpnt->d_tag) {
-               dpnt++;
-               i++;
-           }
-           dynamic_size = i * sizeof(Elf32_Dyn);
+               while(dpnt->d_tag) {
+                       dpnt++;
+                       i++;
+               }
+               dynamic_size = i;
        }
 #endif