OSDN Git Service

Another mips patch from Steven J. Hill:
authorEric Andersen <andersen@codepoet.org>
Thu, 9 May 2002 08:34:43 +0000 (08:34 -0000)
committerEric Andersen <andersen@codepoet.org>
Thu, 9 May 2002 08:34:43 +0000 (08:34 -0000)
    Uh, this patch fixes a few bugs that I overlooked. Shoot, even BusyBox
    wouldn't work until these are applied. Erik, plop this into CVS please.
    Thanks.

ldso/ldso/dl-elf.c
ldso/ldso/dl-hash.c
ldso/ldso/hash.c
ldso/ldso/ldso.c
ldso/ldso/mips/dl-sysdep.h
ldso/ldso/mips/ld_sysdep.h
ldso/ldso/mips/resolve.S
ldso/ldso/readelflib1.c

index 7dbbe6f..ebb0aec 100644 (file)
@@ -315,11 +315,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        unsigned long minvma = 0xffffffff, maxvma = 0;
        int i;
        int infile;
-#if defined(__mips__)
-       unsigned long mips_gotsym = 0;
-       unsigned long mips_local_gotno = 0;
-       unsigned long mips_symtabno = 0;
-#endif
 
        /* If this file is already loaded, skip this step */
        tpnt = _dl_check_hashed_files(libname);
@@ -529,22 +524,21 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
        dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
        _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+
 #if defined(__mips__)
-       /*
-        * The program header file size for the dynamic section is
-        * calculated differently for MIPS. We look for a null tag
-        * value instead.
-        */
-       while(dpnt->d_tag)
-               if (dpnt->d_tag == DT_MIPS_GOTSYM)
-                       mips_gotsym = (unsigned long) dpnt->d_un.d_val;
-               if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
-                       mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
-               if (dpnt->d_tag == DT_MIPS_SYMTABNO)
-                       mips_symtabno = (unsigned long) dpnt->d_un.d_val;
-#else
-       for (i = 0; i < dynamic_size; i++) 
+       {
+           int i = 1;
+           Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+           while(dpnt->d_tag) {
+               dpnt++;
+               i++;
+           }
+           dynamic_size = i * sizeof(Elf32_Dyn);
+       }
 #endif
+
+       for (i = 0; i < dynamic_size; i++) 
        {
                if (dpnt->d_tag > DT_JMPREL) {
                        dpnt++;
@@ -601,11 +595,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        if (lpnt) {
                lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
                        ((int) libaddr));
-#if defined(__mips__)
-               tpnt->mips_gotsym = mips_gotsym;
-               tpnt->mips_local_gotno = mips_local_gotno;
-               tpnt->mips_symtabno = mips_symtabno;
-#endif
                INIT_GOT(lpnt, tpnt);
        };
 
index c6c77e7..b063d0b 100644 (file)
@@ -125,6 +125,21 @@ struct elf_resolve *_dl_add_elf_hash_table(char *libname,
        tpnt->loadaddr = loadaddr;
        for (i = 0; i < 24; i++)
                tpnt->dynamic_info[i] = dynamic_info[i];
+#ifdef __mips__
+       {
+               Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+               while(dpnt->d_tag) {
+                       if (dpnt->d_tag == DT_MIPS_GOTSYM)
+                               tpnt->mips_gotsym = dpnt->d_un.d_val;
+                       if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+                               tpnt->mips_local_gotno = dpnt->d_un.d_val;
+                       if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+                               tpnt->mips_symtabno = dpnt->d_un.d_val;
+                       dpnt++;
+               }
+       }
+#endif
        return tpnt;
 }
 
@@ -235,7 +250,8 @@ char *_dl_find_hash(char *name, struct dyn_elf *rpnt1,
                                        (ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
                                         ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
                                         ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-                                       symtab[si].st_value != 0) {
+                                       symtab[si].st_value != 0 &&
+                                       symtab[si].st_shndx != 0) {
 
                                        /* Here we make sure that we find a module where the symbol is
                                         * actually defined.
index c6c77e7..b063d0b 100644 (file)
@@ -125,6 +125,21 @@ struct elf_resolve *_dl_add_elf_hash_table(char *libname,
        tpnt->loadaddr = loadaddr;
        for (i = 0; i < 24; i++)
                tpnt->dynamic_info[i] = dynamic_info[i];
+#ifdef __mips__
+       {
+               Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+               while(dpnt->d_tag) {
+                       if (dpnt->d_tag == DT_MIPS_GOTSYM)
+                               tpnt->mips_gotsym = dpnt->d_un.d_val;
+                       if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
+                               tpnt->mips_local_gotno = dpnt->d_un.d_val;
+                       if (dpnt->d_tag == DT_MIPS_SYMTABNO)
+                               tpnt->mips_symtabno = dpnt->d_un.d_val;
+                       dpnt++;
+               }
+       }
+#endif
        return tpnt;
 }
 
@@ -235,7 +250,8 @@ char *_dl_find_hash(char *name, struct dyn_elf *rpnt1,
                                        (ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
                                         ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
                                         ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-                                       symtab[si].st_value != 0) {
+                                       symtab[si].st_value != 0 &&
+                                       symtab[si].st_shndx != 0) {
 
                                        /* Here we make sure that we find a module where the symbol is
                                         * actually defined.
index f902900..d2eee05 100644 (file)
@@ -368,12 +368,6 @@ DL_BOOT(unsigned long args)
        /* OK, that was easy.  Next scan the DYNAMIC section of the image.
           We are only doing ourself right now - we will have to do the rest later */
        while (dpnt->d_tag) {
-               if (dpnt->d_tag < 24) {
-                       tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-                       if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT) {
-                               tpnt->dynamic_info[DT_TEXTREL] = 1;
-                       }
-               }
 #if defined(__mips__)
                if (dpnt->d_tag == DT_MIPS_GOTSYM)
                        tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
@@ -382,6 +376,12 @@ DL_BOOT(unsigned long args)
                if (dpnt->d_tag == DT_MIPS_SYMTABNO)
                        tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
 #endif
+               if (dpnt->d_tag < 24) {
+                       tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+                       if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT) {
+                               tpnt->dynamic_info[DT_TEXTREL] = 1;
+                       }
+               }
                dpnt++;
        }
 
@@ -473,9 +473,10 @@ DL_BOOT(unsigned long args)
 #endif
 
 
-       /* For MIPS, we have to do special stuff to the GOT before we do
-          any relocations. */
 #if defined(__mips__)
+       /*
+        * For MIPS we have to do stuff to the GOT before we do relocations.
+        */
        PERFORM_BOOTSTRAP_GOT(got);
 #endif
 
@@ -612,11 +613,6 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
        struct elf_resolve *tpnt1;
        unsigned long brk_addr, *lpnt;
        int (*_dl_atexit) (void *);
-#ifdef __mips__
-       unsigned long mips_gotsym = 0;
-       unsigned long mips_local_gotno = 0;
-       unsigned long mips_symtabno = 0;
-#endif
 
 
        /* Now we have done the mandatory linking of some things.  We are now
@@ -649,7 +645,20 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
                for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
                        if (ppnt->p_type == PT_DYNAMIC) {
                                tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
+#if defined(__mips__)
+                               {
+                                       int i = 1;
+                                       Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+
+                                       while(dpnt->d_tag) {
+                                               dpnt++;
+                                               i++;
+                                       }
+                                       tpnt->dynamic_size = i * sizeof(Elf32_Dyn);
+                               }
+#else
                                tpnt->dynamic_size = ppnt->p_filesz;
+#endif
                        }
                }
        }
@@ -674,31 +683,38 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
                                continue;
 #endif
                        /* OK, we have what we need - slip this one into the list. */
-#ifdef __mips__
-                       mips_gotsym = app_tpnt->mips_gotsym;
-                       mips_local_gotno = app_tpnt->mips_local_gotno;
-                       mips_symtabno = app_tpnt->mips_symtabno;
-#endif
+#if defined(__mips__)
+                       {
+                               int i = 1;
+                               Elf32_Dyn *dpnt = (Elf32_Dyn *) tpnt->dynamic_addr;
+
+                               while(dpnt->d_tag) {
+                                       dpnt++;
+                                       i++;
+                               }
+                               app_tpnt = _dl_add_elf_hash_table("", 0, 
+                                       app_tpnt->dynamic_info, ppnt->p_vaddr,
+                                       (i * sizeof(Elf32_Dyn)));
+                       }
+#else
                        app_tpnt = _dl_add_elf_hash_table("", 0, 
                                        app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+#endif
                        _dl_loaded_modules->libtype = elf_executable;
                        _dl_loaded_modules->ppnt = (elf_phdr *) auxvt[AT_PHDR].a_un.a_ptr;
                        _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
-#ifdef __mips__
-                       _dl_loaded_modules->mips_gotsym = mips_gotsym; 
-                       _dl_loaded_modules->mips_local_gotno = mips_local_gotno;
-                       _dl_loaded_modules->mips_symtabno = mips_symtabno;
-#endif
                        _dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
                        _dl_memset(rpnt, 0, sizeof(*rpnt));
                        rpnt->dyn = _dl_loaded_modules;
                        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 */
@@ -1063,8 +1079,8 @@ static void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *a
           up each symbol individually. */
 
 
-       _dl_brkp =
-               (unsigned long *) _dl_find_hash("___brk_addr", NULL, NULL, 0);
+       _dl_brkp = (unsigned long *) _dl_find_hash("___brk_addr", NULL, NULL, 0);
+       
        if (_dl_brkp) {
                *_dl_brkp = brk_addr;
        }
@@ -1075,6 +1091,11 @@ 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 f54e812..9d48d8f 100644 (file)
@@ -20,7 +20,7 @@
 
 
 /*
- * Initialization sequence for the application GOT.
+ * Initialization sequence for the application or library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)                                                                              \
 do {                                                                                                                                   \
@@ -56,12 +56,12 @@ do {                                                                                                                                        \
                                        (unsigned long) MODULE->loadaddr;                                       \
                        else {                                                                                                          \
                                *GOT_BASE = (unsigned long) _dl_find_hash(strtab +              \
-                                       sym->st_name, MODULE->symbol_scope, NULL, 0);           \
+                                       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, 0);                   \
+                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
                }                                                                                                                               \
                else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&                             \
                        *GOT_BASE != sym->st_value)                                                                     \
@@ -72,7 +72,7 @@ do {                                                                                                                                  \
                }                                                                                                                               \
                else {                                                                                                                  \
                        *GOT_BASE = (unsigned long) _dl_find_hash(strtab +                      \
-                               sym->st_name, MODULE->symbol_scope, NULL, 0);                   \
+                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
                }                                                                                                                               \
                                                                                                                                                \
                ++GOT_BASE;                                                                                                             \
index f54e812..9d48d8f 100644 (file)
@@ -20,7 +20,7 @@
 
 
 /*
- * Initialization sequence for the application GOT.
+ * Initialization sequence for the application or library GOT.
  */
 #define INIT_GOT(GOT_BASE,MODULE)                                                                              \
 do {                                                                                                                                   \
@@ -56,12 +56,12 @@ do {                                                                                                                                        \
                                        (unsigned long) MODULE->loadaddr;                                       \
                        else {                                                                                                          \
                                *GOT_BASE = (unsigned long) _dl_find_hash(strtab +              \
-                                       sym->st_name, MODULE->symbol_scope, NULL, 0);           \
+                                       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, 0);                   \
+                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
                }                                                                                                                               \
                else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&                             \
                        *GOT_BASE != sym->st_value)                                                                     \
@@ -72,7 +72,7 @@ do {                                                                                                                                  \
                }                                                                                                                               \
                else {                                                                                                                  \
                        *GOT_BASE = (unsigned long) _dl_find_hash(strtab +                      \
-                               sym->st_name, MODULE->symbol_scope, NULL, 0);                   \
+                               sym->st_name, MODULE->symbol_scope, NULL, 1);                   \
                }                                                                                                                               \
                                                                                                                                                \
                ++GOT_BASE;                                                                                                             \
index b6dda82..f1d7cff 100644 (file)
@@ -23,18 +23,22 @@ _dl_linux_resolve:
        addu    $25, 8          # t9 ($25) now points at .cpload instruction
        .cpload $25             # Compute GP
        .set reorder
-       subu    $29, 32
-       .cprestore 28
+       subu    $29, 40
+       .cprestore 32
+       sw      $15, 36($29)
        sw      $4, 16($29)
        sw      $5, 20($29)
-       sw      $15, 24($29)
+       sw      $6, 24($29)
+       sw      $7, 28($29)
        move    $4, $24
        move    $5, $3
        jal     _dl_linux_resolver
-       lw      $31, 24($29)
+       lw      $31, 36($29)
        lw      $4, 16($29)
        lw      $5, 20($29)
-       addu    $29, 32
+       lw      $6, 24($29)
+       lw      $7, 28($29)
+       addu    $29, 40
        move    $25, $2
        jr      $25
 .size _dl_linux_resolve,.-_dl_linux_resolve
index 7dbbe6f..ebb0aec 100644 (file)
@@ -315,11 +315,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        unsigned long minvma = 0xffffffff, maxvma = 0;
        int i;
        int infile;
-#if defined(__mips__)
-       unsigned long mips_gotsym = 0;
-       unsigned long mips_local_gotno = 0;
-       unsigned long mips_symtabno = 0;
-#endif
 
        /* If this file is already loaded, skip this step */
        tpnt = _dl_check_hashed_files(libname);
@@ -529,22 +524,21 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
 
        dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
        _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+
 #if defined(__mips__)
-       /*
-        * The program header file size for the dynamic section is
-        * calculated differently for MIPS. We look for a null tag
-        * value instead.
-        */
-       while(dpnt->d_tag)
-               if (dpnt->d_tag == DT_MIPS_GOTSYM)
-                       mips_gotsym = (unsigned long) dpnt->d_un.d_val;
-               if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
-                       mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
-               if (dpnt->d_tag == DT_MIPS_SYMTABNO)
-                       mips_symtabno = (unsigned long) dpnt->d_un.d_val;
-#else
-       for (i = 0; i < dynamic_size; i++) 
+       {
+           int i = 1;
+           Elf32_Dyn *dpnt = (Elf32_Dyn *) dynamic_addr;
+
+           while(dpnt->d_tag) {
+               dpnt++;
+               i++;
+           }
+           dynamic_size = i * sizeof(Elf32_Dyn);
+       }
 #endif
+
+       for (i = 0; i < dynamic_size; i++) 
        {
                if (dpnt->d_tag > DT_JMPREL) {
                        dpnt++;
@@ -601,11 +595,6 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
        if (lpnt) {
                lpnt = (unsigned long *) (dynamic_info[DT_PLTGOT] +
                        ((int) libaddr));
-#if defined(__mips__)
-               tpnt->mips_gotsym = mips_gotsym;
-               tpnt->mips_local_gotno = mips_local_gotno;
-               tpnt->mips_symtabno = mips_symtabno;
-#endif
                INIT_GOT(lpnt, tpnt);
        };