2000-10-18 Andreas Jaeger <aj@suse.de>
authorAndreas Jaeger <aj@suse.de>
Wed, 18 Oct 2000 10:21:16 +0000 (10:21 +0000)
committerAndreas Jaeger <aj@suse.de>
Wed, 18 Oct 2000 10:21:16 +0000 (10:21 +0000)
* sysdeps/mips/dl-machine.h (ELF_MIPS_GNU_GOT1_OK): New.
(ELF_MACHINE_BEFORE_RTLD_RELOC): Handle newer linkers.
(elf_machine_runtime_link_map): Likewise.
(elf_machine_runtime_setup): Likewise.
Handle dynamic linker's local got entries.
Patches by Ralf Baechle <ralf@gnu.org>.

2000-10-09  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

* sysdeps/mips/dl-machine.h (_dl_runtime_resolve): Define $sp as
the frame pointer.  Allocate stack space for $a0 for
__dl_runtime_resolve().  Do not save $sp in $s0 as it's
callee-saved anyway.

sysdeps/mips/dl-machine.h

index 2a19126..c0ece38 100644 (file)
@@ -136,7 +136,11 @@ elf_machine_load_address (void)
 }
 
 /* The MSB of got[1] of a gnu object is set to identify gnu objects.  */
-#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
+#define ELF_MIPS_GNU_GOT1_MASK 0x80000000
+
+/* GNU Binutils upto 2.10 produce a wrong relocations.  Bit 30 of
+   got[1] marks good objects.  */
+#define ELF_MIPS_GNU_GOT1_OK   0x00000001
 
 /* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
    fiddles with global data.  */
@@ -149,6 +153,9 @@ do {                                                                        \
                                                                        \
   got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);                 \
                                                                        \
+  if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0)                          \
+    got[1] = (ElfW(Addr)) ELF_MIPS_GNU_GOT1_MASK                       \
+              | (got[1] & ELF_MIPS_GNU_GOT1_OK);                       \
                                                                        \
   if (__builtin_expect (map->l_addr == 0, 1))                          \
     goto done;                                                         \
@@ -212,8 +219,8 @@ elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
 
       if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
        {
-         struct link_map *l =
-           (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
+         struct link_map *l = (struct link_map *)
+               (g1 & ~(ELF_MIPS_GNU_GOT1_MASK|ELF_MIPS_GNU_GOT1_OK));
          ElfW(Addr) base, limit;
          const ElfW(Phdr) *p = l->l_phdr;
          ElfW(Half) this, nent = l->l_phnum;
@@ -352,11 +359,12 @@ asm ("\n                                                                \
        .type   _dl_runtime_resolve,@function\n                               \
        .ent    _dl_runtime_resolve\n                                         \
 _dl_runtime_resolve:\n                                                       \
+       .frame  $29, 40, $31\n                                                \
        .set noreorder\n                                                      \
-       # Save GP.\n                                                  \
+       # Save GP.\n                                                          \
        move    $3, $28\n                                                     \
        # Modify t9 ($25) so as to point .cpload instruction.\n               \
-       addu    $25,8\n                                                       \
+       addu    $25, 8\n                                                      \
        # Compute GP.\n                                                       \
        .cpload $25\n                                                         \
        .set reorder\n                                                        \
@@ -366,24 +374,20 @@ _dl_runtime_resolve:\n                                                          \
        subu    $29, 40\n                                                     \
        .cprestore 32\n                                                       \
        sw      $15, 36($29)\n                                                \
-       sw      $4, 12($29)\n                                                 \
-       sw      $5, 16($29)\n                                                 \
-       sw      $6, 20($29)\n                                                 \
-       sw      $7, 24($29)\n                                                 \
-       sw      $16, 28($29)\n                                                \
-       move    $16, $29\n                                                    \
+       sw      $4, 16($29)\n                                                 \
+       sw      $5, 20($29)\n                                                 \
+       sw      $6, 24($29)\n                                                 \
+       sw      $7, 28($29)\n                                                 \
        move    $4, $24\n                                                     \
        move    $5, $15\n                                                     \
        move    $6, $3\n                                                      \
        move    $7, $2\n                                                      \
        jal     __dl_runtime_resolve\n                                        \
-       move    $29, $16\n                                                    \
        lw      $31, 36($29)\n                                                \
-       lw      $4, 12($29)\n                                                 \
-       lw      $5, 16($29)\n                                                 \
-       lw      $6, 20($29)\n                                                 \
-       lw      $7, 24($29)\n                                                 \
-       lw      $16, 28($29)\n                                                \
+       lw      $4, 16($29)\n                                                 \
+       lw      $5, 20($29)\n                                                 \
+       lw      $6, 24($29)\n                                                 \
+       lw      $7, 28($29)\n                                                 \
        addu    $29, 40\n                                                     \
        move    $25, $2\n                                                     \
        jr      $25\n                                                         \
@@ -580,15 +584,20 @@ elf_machine_got_rel (struct link_map *map, int lazy)
 
   got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);
 
-  /* got[0] is reserved. got[1] is also reserved for the dynamic object
-     generated by gnu ld. Skip these reserved entries from relocation.  */
-  i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
   n = map->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
-  /* Add the run-time display to all local got entries if needed. */
-  if (__builtin_expect (map->l_addr != 0, 0))
+  /* The dynamic linker's local got entries have already been relocated.  */
+  if (map != &_dl_rtld_map)
     {
-      while (i < n)
-       got[i++] += map->l_addr;
+      /* got[0] is reserved. got[1] is also reserved for the dynamic object
+        generated by gnu ld. Skip these reserved entries from relocation.  */
+      i = (got[1] & ELF_MIPS_GNU_GOT1_MASK)? 2 : 1;
+
+      /* Add the run-time display to all local got entries if needed. */
+      if (__builtin_expect (map->l_addr != 0, 0))
+       {
+         while (i < n)
+           got[i++] += map->l_addr;
+       }
     }
 
   /* Handle global got entries. */
@@ -661,7 +670,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
         of got[1] of a gnu object is set to identify gnu objects.
         Where we can store l for non gnu objects? XXX  */
       if ((got[1] & ELF_MIPS_GNU_GOT1_MASK) != 0)
-       got[1] = (ElfW(Addr)) ((unsigned) l | ELF_MIPS_GNU_GOT1_MASK);
+       got[1] = (ElfW(Addr)) ((unsigned) l | ELF_MIPS_GNU_GOT1_MASK
+                              | (got[1] & ELF_MIPS_GNU_GOT1_OK));
       else
        _dl_mips_gnu_objects = 0;
     }