Update.
authorAndreas Jaeger <aj@suse.de>
Mon, 18 Sep 2000 16:41:55 +0000 (16:41 +0000)
committerAndreas Jaeger <aj@suse.de>
Mon, 18 Sep 2000 16:41:55 +0000 (16:41 +0000)
2000-09-16  Ralf Baechle  <ralf@gnu.org>

* sysdeps/mips/dl-machine.h (_RTLD_PROLOGUE): Reformat.  Declare
as function.
(_RTLD_EPILOGUE): Reformat.  Declare size of entry function.
(ELF_MACHINE_BEFORE_RTLD_RELOC): Relocate the dynamic linker itself so
it will even work when not loaded to the standard address.
(RTLD_START): Reformat.  Call _dl_start in a way that is safe even
before the dynamic linker itself is relocated.

2000-09-18  Andreas Jaeger  <aj@suse.de>

* sysdeps/unix/sysv/linux/kernel-features.h: Always define
__ASSUME_32BITUIDS for MIPS.
* sysdeps/unix/sysv/linux/mips/ipc_priv.h: New file.
* sysdeps/unix/sysv/linux/mips/Dist: Add ipc_priv.h.

ChangeLog
sysdeps/mips/dl-machine.h
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/mips/Dist

index 2b5a30d..729e29e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2000-09-16  Ralf Baechle  <ralf@gnu.org>
+
+       * sysdeps/mips/dl-machine.h (_RTLD_PROLOGUE): Reformat.  Declare
+       as function.
+       (_RTLD_EPILOGUE): Reformat.  Declare size of entry function.
+       (ELF_MACHINE_BEFORE_RTLD_RELOC): Relocate the dynamic linker itself so
+       it will even work when not loaded to the standard address.
+       (RTLD_START): Reformat.  Call _dl_start in a way that is safe even
+       before the dynamic linker itself is relocated.
+
+2000-09-18  Andreas Jaeger  <aj@suse.de>
+
+       * sysdeps/unix/sysv/linux/kernel-features.h: Always define
+       __ASSUME_32BITUIDS for MIPS.
+       * sysdeps/unix/sysv/linux/mips/ipc_priv.h: New file.
+       * sysdeps/unix/sysv/linux/mips/Dist: Add ipc_priv.h.
+
 2000-09-17  H.J. Lu  <hjl@gnu.org>
 
        * catgets/Makefile ($(objpfx)de/libc.cat): Use
index 0d2bf9d..6d95705 100644 (file)
 #define OFFSET_GP_GOT 0x7ff0
 
 #ifndef _RTLD_PROLOGUE
-# define _RTLD_PROLOGUE(entry) "\n\t.globl " __STRING(entry)   \
-                              "\n\t.ent " __STRING(entry)      \
-                              "\n\t" __STRING(entry) ":\n\t"
+# define _RTLD_PROLOGUE(entry)                                         \
+       ".globl\t" __STRING(entry) "\n\t"                               \
+       ".ent\t" __STRING(entry) "\n\t"                                 \
+       ".type\t" __STRING(entry) ", @function\n"                       \
+       __STRING(entry) ":\n\t"
 #endif
 
 #ifndef _RTLD_EPILOGUE
-# define _RTLD_EPILOGUE(entry) "\t.end " __STRING(entry) "\n"
+# define _RTLD_EPILOGUE(entry)                                         \
+       ".end\t" __STRING(entry) "\n\t"                                 \
+       ".size\t" __STRING(entry) ", . - " __STRING(entry) "\n\t"
 #endif
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.
@@ -134,6 +138,60 @@ 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
 
+/* We can't rely on elf_machine_got_rel because _dl_object_relocation_scope
+   fiddles with global data.  */
+#define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info)                    \
+do {                                                                   \
+  struct link_map *map = &bootstrap_map;                               \
+  ElfW(Sym) *sym;                                                      \
+  ElfW(Addr) *got;                                                     \
+  int i, n;                                                            \
+                                                                       \
+  got = (ElfW(Addr) *) D_PTR (map, l_info[DT_PLTGOT]);                 \
+                                                                       \
+                                                                       \
+  if (__builtin_expect (map->l_addr == 0, 1))                          \
+    goto done;                                                         \
+                                                                       \
+  /* 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. */             \
+  while (i < n)                                                                \
+    got[i++] += map->l_addr;                                           \
+                                                                       \
+  /* Handle global got entries. */                                     \
+  got += n;                                                            \
+  sym = (ElfW(Sym) *) D_PTR(map, l_info[DT_SYMTAB])                    \
+       + map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;                    \
+  i = (map->l_info[DT_MIPS (SYMTABNO)]->d_un.d_val                     \
+       - map->l_info[DT_MIPS (GOTSYM)]->d_un.d_val);                   \
+                                                                       \
+  while (i--)                                                          \
+    {                                                                  \
+      if (sym->st_shndx == SHN_UNDEF || sym->st_shndx == SHN_COMMON)   \
+       *got = map->l_addr + sym->st_value;                             \
+      else if (ELFW(ST_TYPE) (sym->st_info) == STT_FUNC                        \
+              && *got != sym->st_value)                                \
+       *got += map->l_addr;                                            \
+      else if (ELFW(ST_TYPE) (sym->st_info) == STT_SECTION)            \
+       {                                                               \
+         if (sym->st_other == 0)                                       \
+           *got += map->l_addr;                                        \
+       }                                                               \
+      else                                                             \
+       *got = map->l_addr + sym->st_value;                             \
+                                                                       \
+      got++;                                                           \
+      sym++;                                                           \
+    }                                                                  \
+done:                                                                  \
+} while(0)
+
+
 /* Get link map for callers object containing STUB_PC.  */
 static inline struct link_map *
 elf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
@@ -354,10 +412,10 @@ _dl_runtime_resolve:\n                                                          \
    2) That under Linux the entry is named __start
       and not just plain _start.  */
 
-#define RTLD_START asm ("\
-       .text\n"\
-_RTLD_PROLOGUE(ENTRY_POINT)\
-"      .globl _dl_start_user\n\
+#define RTLD_START asm (\
+       ".text\n"\
+       _RTLD_PROLOGUE(ENTRY_POINT)\
+       ".set noreorder\n\
        .set noreorder\n\
        bltzal $0, 0f\n\
        nop\n\
@@ -371,10 +429,19 @@ _RTLD_PROLOGUE(ENTRY_POINT)\
        sw $4, -0x7ff0($28)\n\
        move $4, $29\n\
        subu $29, 16\n\
-       jal _dl_start\n\
+       \n\
+       la $8, coff\n\
+       bltzal $8, coff\n\
+coff:  subu $8, $31, $8\n\
+       \n\
+       la $25, _dl_start\n\
+       addu $25, $8\n\
+       jalr $25\n\
+       \n\
        addiu $29, 16\n\
        # Get the value of label '_dl_start_user' in t9 ($25).\n\
        la $25, _dl_start_user\n\
+       .globl _dl_start_user\n\
 _dl_start_user:\n\
        .set noreorder\n\
        .cpload $25\n\
@@ -410,9 +477,9 @@ _dl_start_user:\n\
        la $2, _dl_fini\n\
        # Jump to the user entry point.\n\
        move $25, $17\n\
-       jr $25\n"\
-_RTLD_EPILOGUE(ENTRY_POINT)\
-       "\n.previous"\
+       jr $25\n\t"\
+       _RTLD_EPILOGUE(ENTRY_POINT)\
+       ".previous"\
 );
 
 /* The MIPS never uses Elfxx_Rela relocations.  */
@@ -513,7 +580,7 @@ elf_machine_got_rel (struct link_map *map, int lazy)
 
   /* 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;
+  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))
index 48dc192..9639be3 100644 (file)
 
 /* Linux 2.3.39 introduced 32bit UID/GIDs.  Some platforms had 32 bit
    type all along.  */
-#if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__
+#if __LINUX_KERNEL_VERSION >= 131879 || defined __powerpc__ || defined __mips__
 # define __ASSUME_32BITUIDS            1
 # ifdef __sparc__
 #  define __ASSUME_SETRESUID_SYSCALL   1
index d8943b6..a983244 100644 (file)
@@ -1,6 +1,7 @@
 _test_and_set.c
 clone.S
 entry.h
+ipc_priv.h
 kernel_sigaction.h
 kernel_stat.h
 kernel_termios.h