]> sourceware.org Git - glibc.git/commitdiff
[BZ #783]
authorAndreas Jaeger <aj@suse.de>
Mon, 28 Mar 2005 07:49:19 +0000 (07:49 +0000)
committerAndreas Jaeger <aj@suse.de>
Mon, 28 Mar 2005 07:49:19 +0000 (07:49 +0000)
2005-03-28  Daniel Jacobowitz  <dan@codesourcery.com>
[BZ #783]
* elf/tst-auditmod1.c: Add MIPS support.
* sysdeps/generic/ldsodefs.h (La_mips_32_regs): New.
(La_mips_32_retval): New.
(La_mips_64_regs): New.
(La_mips_64_retval): New.
(struct audit_ifaces): Add MIPS entries.
* sysdeps/mips/dl-machine.h: Check RESOLVE_MAP instead of RESOLVE.
(elf_machine_runtime_link_map, ELF_DL_FRAME_SIZE,
ELF_DL_SAVE_ARG_REGS, ELF_DL_RESTORE_ARG_REGS,
ELF_MACHINE_RUNTIME_TRAMPOLINE): Move to dl-trampoline.c.
(RTLD_START): Align the stack before calling _dl_init_internal.
Use .ent for _dl_start_user.
(ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): Define.
(elf_machine_rel, elf_machine_rel_relative, elf_machine_lazy_rel)
(elf_machine_runtime_setup): Use "auto inline".
(elf_machine_rela, elf_machine_rela_relative): Provide empty versions.
(elf_machine_got_rel): Likewise.  Use RESOLVE_MAP.
* sysdeps/mips/dl-trampoline.c: New file.
* sysdeps/mips/bits/link.h: New file.
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
(internal_syscall5): Use register operands instead of non-lvalue
memory operands.
(internal_syscall6): Likewise.
(internal_syscall7): Likewise.
2005-03-28  Daniel Jacobowitz  <dan@codesourcery.com>

[BZ #783]
* elf/tst-auditmod1.c: Add MIPS support.
* sysdeps/generic/ldsodefs.h (La_mips_32_regs): New.
(La_mips_32_retval): New.
(La_mips_64_regs): New.
(La_mips_64_retval): New.
(struct audit_ifaces): Add MIPS entries.
* sysdeps/mips/dl-machine.h: Check RESOLVE_MAP instead of RESOLVE.
(elf_machine_runtime_link_map, ELF_DL_FRAME_SIZE,
ELF_DL_SAVE_ARG_REGS, ELF_DL_RESTORE_ARG_REGS,
ELF_MACHINE_RUNTIME_TRAMPOLINE): Move to dl-trampoline.c.
(RTLD_START): Align the stack before calling _dl_init_internal.
Use .ent for _dl_start_user.
(ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): Define.
(elf_machine_rel, elf_machine_rel_relative, elf_machine_lazy_rel)
(elf_machine_runtime_setup): Use "auto inline".
(elf_machine_rela, elf_machine_rela_relative): Provide empty versions.
(elf_machine_got_rel): Likewise.  Use RESOLVE_MAP.
* sysdeps/mips/dl-trampoline.c: New file.
* sysdeps/mips/bits/link.h: New file.
* sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
(internal_syscall5): Use register operands instead of non-lvalue
memory operands.
(internal_syscall6): Likewise.
(internal_syscall7): Likewise.

ChangeLog
elf/tst-auditmod1.c
sysdeps/generic/ldsodefs.h
sysdeps/mips/bits/link.h [new file with mode: 0644]
sysdeps/mips/dl-machine.h
sysdeps/mips/dl-trampoline.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/mips/mips32/sysdep.h

index 9ca084cc2d2f96723e02889f8c7a8603eb2ebe8d..48d7deab70a987f667a854749de459e58cf3433a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2005-03-28  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       [BZ #783]
+       * elf/tst-auditmod1.c: Add MIPS support.
+       * sysdeps/generic/ldsodefs.h (La_mips_32_regs): New.
+       (La_mips_32_retval): New.
+       (La_mips_64_regs): New.
+       (La_mips_64_retval): New.
+       (struct audit_ifaces): Add MIPS entries.
+       * sysdeps/mips/dl-machine.h: Check RESOLVE_MAP instead of RESOLVE.
+       (elf_machine_runtime_link_map, ELF_DL_FRAME_SIZE,
+       ELF_DL_SAVE_ARG_REGS, ELF_DL_RESTORE_ARG_REGS,
+       ELF_MACHINE_RUNTIME_TRAMPOLINE): Move to dl-trampoline.c.
+       (RTLD_START): Align the stack before calling _dl_init_internal.
+       Use .ent for _dl_start_user.
+       (ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): Define.
+       (elf_machine_rel, elf_machine_rel_relative, elf_machine_lazy_rel)
+       (elf_machine_runtime_setup): Use "auto inline".
+       (elf_machine_rela, elf_machine_rela_relative): Provide empty versions.
+       (elf_machine_got_rel): Likewise.  Use RESOLVE_MAP.
+       * sysdeps/mips/dl-trampoline.c: New file.
+       * sysdeps/mips/bits/link.h: New file.
+       * sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+       (internal_syscall5): Use register operands instead of non-lvalue
+       memory operands.
+       (internal_syscall6): Likewise.
+       (internal_syscall7): Likewise.
+
 2005-03-27  Andreas Jaeger  <aj@suse.de>
 
        * debug/warning-nop.c (__builtin___memcpy_chk): Define away to
index 9b07588288126c3287f593a975a2f97f19526467..38768224299813fe09a749acc02736d387870621 100644 (file)
@@ -162,6 +162,24 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
 # define La_regs La_ia64_regs
 # define La_retval La_ia64_retval
 # define int_retval lrv_r8
+#elif defined __mips__ && _MIPS_SIM == _ABIO32
+# define pltenter la_mips_o32_gnu_pltenter
+# define pltexit la_mips_o32_gnu_pltexit
+# define La_regs La_mips_32_regs
+# define La_retval La_mips_32_retval
+# define int_retval lrv_v0
+#elif defined __mips__ && _MIPS_SIM == _ABIN32
+# define pltenter la_mips_n32_gnu_pltenter
+# define pltexit la_mips_n32_gnu_pltexit
+# define La_regs La_mips_64_regs
+# define La_retval La_mips_64_retval
+# define int_retval lrv_v0
+#elif defined __mips__ && _MIPS_SIM == _ABI64
+# define pltenter la_mips_n64_gnu_pltenter
+# define pltexit la_mips_n64_gnu_pltexit
+# define La_regs La_mips_64_regs
+# define La_retval La_mips_64_retval
+# define int_retval lrv_v0
 #else
 # error "architecture specific code needed"
 #endif
index dd1b2c8345c8fb8228201aa40fabbc1f6569ac6e..e1a934aeda9aecc406c96c7a748b7ea9d3b30406 100644 (file)
@@ -195,6 +195,10 @@ struct La_s390_64_regs;
 struct La_s390_64_retval;
 struct La_ia64_regs;
 struct La_ia64_retval;
+struct La_mips_32_regs;
+struct La_mips_32_retval;
+struct La_mips_64_regs;
+struct La_mips_64_retval;
 
 struct audit_ifaces
 {
@@ -251,6 +255,21 @@ struct audit_ifaces
                                     uintptr_t *, struct La_ia64_regs *,
                                     unsigned int *, const char *name,
                                     long int *framesizep);
+    Elf32_Addr (*mips_o32_gnu_pltenter) (Elf32_Sym *, unsigned int,
+                                        uintptr_t *, uintptr_t *,
+                                        const struct La_mips_32_regs *,
+                                        unsigned int *, const char *name,
+                                        long int *framesizep);
+    Elf32_Addr (*mips_n32_gnu_pltenter) (Elf32_Sym *, unsigned int,
+                                        uintptr_t *, uintptr_t *,
+                                        const struct La_mips_64_regs *,
+                                        unsigned int *, const char *name,
+                                        long int *framesizep);
+    Elf64_Addr (*mips_n64_gnu_pltenter) (Elf64_Sym *, unsigned int,
+                                        uintptr_t *, uintptr_t *,
+                                        const struct La_mips_64_regs *,
+                                        unsigned int *, const char *name,
+                                        long int *framesizep);
   };
   union
   {
@@ -294,6 +313,21 @@ struct audit_ifaces
                                      uintptr_t *,
                                      const struct La_ia64_regs *,
                                      struct La_ia64_retval *, const char *);
+    unsigned int (*mips_o32_gnu_pltexit) (Elf32_Sym *, unsigned int,
+                                         uintptr_t *, uintptr_t *,
+                                         const struct La_mips_32_regs *,
+                                         struct La_mips_32_retval *,
+                                         const char *);
+    unsigned int (*mips_n32_gnu_pltexit) (Elf32_Sym *, unsigned int,
+                                         uintptr_t *, uintptr_t *,
+                                         const struct La_mips_64_regs *,
+                                         struct La_mips_64_retval *,
+                                         const char *);
+    unsigned int (*mips_n64_gnu_pltexit) (Elf64_Sym *, unsigned int,
+                                         uintptr_t *, uintptr_t *,
+                                         const struct La_mips_64_regs *,
+                                         struct La_mips_64_retval *,
+                                         const char *);
   };
   unsigned int (*objclose) (uintptr_t *);
 
diff --git a/sysdeps/mips/bits/link.h b/sysdeps/mips/bits/link.h
new file mode 100644 (file)
index 0000000..3d77a4c
--- /dev/null
@@ -0,0 +1,118 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef        _LINK_H
+# error "Never include <bits/link.h> directly; use <link.h> instead."
+#endif
+
+#include <sgidefs.h>
+
+#if _MIPS_SIM == _ABIO32
+
+/* Registers for entry into PLT on MIPS.  */
+typedef struct La_mips_32_regs
+{
+  uint32_t lr_reg[4]; /* $a0 through $a3 */
+  double lr_fpreg[2]; /* $f12 and $f14 */
+  uint32_t lr_ra;
+  uint32_t lr_sp;
+} La_mips_32_regs;
+
+/* Return values for calls from PLT on MIPS.  */
+typedef struct La_mips_32_retval
+{
+  uint32_t lrv_v0;
+  uint32_t lrv_v1;
+  double lrv_f0;
+  double lrv_f2;
+} La_mips_32_retval;
+
+#else
+
+typedef struct La_mips_64_regs
+{
+  uint64_t lr_reg[8]; /* $a0 through $a7 */
+  double lr_fpreg[8]; /* $f12 throgh $f19 */
+  uint64_t lr_ra;
+  uint64_t lr_sp;
+} La_mips_64_regs;
+
+/* Return values for calls from PLT on MIPS.  */
+typedef struct La_mips_64_retval
+{
+  uint64_t lrv_v0;
+  uint64_t lrv_v1;
+  double lrv_f0;
+  double lrv_f2;
+} La_mips_64_retval;
+
+#endif
+
+__BEGIN_DECLS
+
+#if _MIPS_SIM == _ABIO32
+
+extern Elf32_Addr la_mips_o32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+                                           uintptr_t *__refcook,
+                                           uintptr_t *__defcook,
+                                           La_mips_32_regs *__regs,
+                                           unsigned int *__flags,
+                                           const char *__symname,
+                                           long int *__framesizep);
+extern unsigned int la_mips_o32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+                                            uintptr_t *__refcook,
+                                            uintptr_t *__defcook,
+                                            const La_mips_32_regs *__inregs,
+                                            La_mips_32_retval *__outregs,
+                                            const char *symname);
+
+#elif _MIPS_SIM == _ABIN32
+
+extern Elf32_Addr la_mips_n32_gnu_pltenter (Elf32_Sym *__sym, unsigned int __ndx,
+                                           uintptr_t *__refcook,
+                                           uintptr_t *__defcook,
+                                           La_mips_64_regs *__regs,
+                                           unsigned int *__flags,
+                                           const char *__symname,
+                                           long int *__framesizep);
+extern unsigned int la_mips_n32_gnu_pltexit (Elf32_Sym *__sym, unsigned int __ndx,
+                                            uintptr_t *__refcook,
+                                            uintptr_t *__defcook,
+                                            const La_mips_64_regs *__inregs,
+                                            La_mips_64_retval *__outregs,
+                                            const char *symname);
+
+#else
+
+extern Elf64_Addr la_mips_n64_gnu_pltenter (Elf64_Sym *__sym, unsigned int __ndx,
+                                           uintptr_t *__refcook,
+                                           uintptr_t *__defcook,
+                                           La_mips_64_regs *__regs,
+                                           unsigned int *__flags,
+                                           const char *__symname,
+                                           long int *__framesizep);
+extern unsigned int la_mips_n64_gnu_pltexit (Elf64_Sym *__sym, unsigned int __ndx,
+                                            uintptr_t *__refcook,
+                                            uintptr_t *__defcook,
+                                            const La_mips_64_regs *__inregs,
+                                            La_mips_64_retval *__outregs,
+                                            const char *symname);
+
+#endif
+
+__END_DECLS
index 0d87b65691e0a1a533d715bf5405cddb7c2875be..a8a41fff02314e3f832d8b10ffc39f3f7d0e7a44 100644 (file)
@@ -188,248 +188,6 @@ do {                                                                      \
 } 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)
-{
-  extern int _dl_mips_gnu_objects;
-
-  /* got[1] is reserved to keep its link map address for the shared
-     object generated by the gnu linker.  If all are such objects, we
-     can find the link map from current GPREG simply.  If not so, get
-     the link map for caller's object containing STUB_PC.  */
-
-  if (_dl_mips_gnu_objects)
-    {
-      ElfW(Addr) *got = elf_mips_got_from_gpreg (gpreg);
-      ElfW(Word) g1;
-
-      g1 = ((ElfW(Word) *) got)[1];
-
-      if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
-       {
-         struct link_map *l =
-           (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
-         ElfW(Addr) base, limit;
-         const ElfW(Phdr) *p = l->l_phdr;
-         ElfW(Half) this, nent = l->l_phnum;
-
-         /* For the common case of a stub being called from the containing
-            object, STUB_PC will point to somewhere within the object that
-            is described by the link map fetched via got[1].  Otherwise we
-            have to scan all maps.  */
-         for (this = 0; this < nent; this++)
-           {
-             if (p[this].p_type == PT_LOAD)
-               {
-                 base = p[this].p_vaddr + l->l_addr;
-                 limit = base + p[this].p_memsz;
-                 if (stub_pc >= base && stub_pc < limit)
-                   return l;
-               }
-           }
-       }
-    }
-
-    struct link_map *l;
-    Lmid_t nsid;
-
-    for (nsid = 0; nsid < DL_NNS; ++nsid)
-      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
-       {
-         ElfW(Addr) base, limit;
-         const ElfW(Phdr) *p = l->l_phdr;
-         ElfW(Half) this, nent = l->l_phnum;
-
-         for (this = 0; this < nent; ++this)
-           {
-             if (p[this].p_type == PT_LOAD)
-               {
-                 base = p[this].p_vaddr + l->l_addr;
-                 limit = base + p[this].p_memsz;
-                 if (stub_pc >= base && stub_pc < limit)
-                   return l;
-               }
-           }
-       }
-
-  _dl_signal_error (0, NULL, NULL, "cannot find runtime link map");
-  return NULL;
-}
-
-#if _MIPS_SIM == _ABIO32
-#define ELF_DL_FRAME_SIZE 40
-
-#define ELF_DL_SAVE_ARG_REGS "\
-       sw      $15, 36($29)\n                                                \
-       sw      $4, 16($29)\n                                                 \
-       sw      $5, 20($29)\n                                                 \
-       sw      $6, 24($29)\n                                                 \
-       sw      $7, 28($29)\n                                                 \
-"
-
-#define ELF_DL_RESTORE_ARG_REGS "\
-       lw      $31, 36($29)\n                                                \
-       lw      $4, 16($29)\n                                                 \
-       lw      $5, 20($29)\n                                                 \
-       lw      $6, 24($29)\n                                                 \
-       lw      $7, 28($29)\n                                                 \
-"
-
-#define IFABIO32(X) X
-
-#else /* _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 */
-
-#define ELF_DL_FRAME_SIZE 80
-
-#define ELF_DL_SAVE_ARG_REGS "\
-       sd      $15, 72($29)\n                                                \
-       sd      $4, 8($29)\n                                                  \
-       sd      $5, 16($29)\n                                                 \
-       sd      $6, 24($29)\n                                                 \
-       sd      $7, 32($29)\n                                                 \
-       sd      $8, 40($29)\n                                                 \
-       sd      $9, 48($29)\n                                                 \
-       sd      $10, 56($29)\n                                                \
-       sd      $11, 64($29)\n                                                \
-"
-
-#define ELF_DL_RESTORE_ARG_REGS "\
-       ld      $31, 72($29)\n                                                \
-       ld      $4, 8($29)\n                                                  \
-       ld      $5, 16($29)\n                                                 \
-       ld      $6, 24($29)\n                                                 \
-       ld      $7, 32($29)\n                                                 \
-       ld      $8, 40($29)\n                                                 \
-       ld      $9, 48($29)\n                                                 \
-       ld      $10, 56($29)\n                                                \
-       ld      $11, 64($29)\n                                                \
-"
-
-#define IFABIO32(X)
-
-#endif
-
-/* Define mips specific runtime resolver. The function __dl_runtime_resolve
-   is called from assembler function _dl_runtime_resolve which converts
-   special argument registers t7 ($15) and t8 ($24):
-     t7  address to return to the caller of the function
-     t8  index for this function symbol in .dynsym
-   to usual c arguments.
-
-   Other architectures call fixup from dl-runtime.c in
-   _dl_runtime_resolve.  MIPS instead calls __dl_runtime_resolve.  We
-   have to use our own version because of the way the got section is
-   treated on MIPS (we've also got ELF_MACHINE_PLT defined).  */
-
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                                       \
-/* The flag _dl_mips_gnu_objects is set if all dynamic objects are           \
-   generated by the gnu linker. */                                           \
-int _dl_mips_gnu_objects = 1;                                                \
-                                                                             \
-/* This is called from assembly stubs below which the compiler can't see.  */ \
-static ElfW(Addr)                                                            \
-__dl_runtime_resolve (ElfW(Word), ElfW(Word), ElfW(Addr), ElfW(Addr))        \
-                 __attribute_used__;                                         \
-                                                                             \
-static ElfW(Addr)                                                            \
-__dl_runtime_resolve (ElfW(Word) sym_index,                                  \
-                     ElfW(Word) return_address,                              \
-                     ElfW(Addr) old_gpreg,                                   \
-                     ElfW(Addr) stub_pc)                                     \
-{                                                                            \
-  struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc);     \
-  const ElfW(Sym) *const symtab                                                      \
-    = (const ElfW(Sym) *) D_PTR (l, l_info[DT_SYMTAB]);                              \
-  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);          \
-  ElfW(Addr) *got                                                            \
-    = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);                           \
-  const ElfW(Word) local_gotno                                               \
-    = (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;       \
-  const ElfW(Word) gotsym                                                    \
-    = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;            \
-  const ElfW(Sym) *sym = &symtab[sym_index];                                 \
-  ElfW(Addr) value;                                                          \
-                                                                             \
-  /* FIXME: The symbol versioning stuff is not tested yet.  */               \
-  if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)        \
-    {                                                                        \
-      switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)                              \
-       {                                                                     \
-       default:                                                              \
-         {                                                                   \
-           const ElfW(Half) *vernum =                                        \
-             (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);        \
-           ElfW(Half) ndx = vernum[sym_index] & 0x7fff;                      \
-           const struct r_found_version *version = &l->l_versions[ndx];      \
-                                                                             \
-           if (version->hash != 0)                                           \
-             {                                                               \
-               value = _dl_lookup_symbol_x (strtab + sym->st_name, l,        \
-                                            &sym, l->l_scope, version,       \
-                                            ELF_RTYPE_CLASS_PLT, 0, 0);      \
-               break;                                                        \
-             }                                                               \
-           /* Fall through.  */                                              \
-         }                                                                   \
-       case 0:                                                               \
-         value = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,        \
-                                      l->l_scope, 0, ELF_RTYPE_CLASS_PLT,    \
-                                      DL_LOOKUP_ADD_DEPENDENCY, 0);          \
-       }                                                                     \
-                                                                             \
-      /* Currently value contains the base load address of the object        \
-        that defines sym.  Now add in the symbol offset.  */                 \
-      value = (sym ? value + sym->st_value : 0);                             \
-    }                                                                        \
-  else                                                                       \
-    /* We already found the symbol.  The module (and therefore its load              \
-       address) is also known.  */                                           \
-    value = l->l_addr + sym->st_value;                                       \
-                                                                             \
-  /* Apply the relocation with that value.  */                               \
-  *(got + local_gotno + sym_index - gotsym) = value;                         \
-                                                                             \
-  return value;                                                                      \
-}                                                                            \
-                                                                             \
-asm ("\n                                                                     \
-       .text\n                                                               \
-       .align  2\n                                                           \
-       .globl  _dl_runtime_resolve\n                                         \
-       .type   _dl_runtime_resolve,@function\n                               \
-       .ent    _dl_runtime_resolve\n                                         \
-_dl_runtime_resolve:\n                                                       \
-       .frame  $29, " STRINGXP(ELF_DL_FRAME_SIZE) ", $31\n                   \
-       .set noreorder\n                                                      \
-       # Save GP.\n                                                          \
-       move    $3, $28\n                                                     \
-       # Save arguments and sp value in stack.\n                             \
-       " STRINGXP(PTR_SUBIU) "  $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n       \
-       # Modify t9 ($25) so as to point .cpload instruction.\n               \
-       " IFABIO32(STRINGXP(PTR_ADDIU) "        $25, 12\n") "                 \
-       # Compute GP.\n                                                       \
-       " STRINGXP(SETUP_GP) "\n                                              \
-       " STRINGXV(SETUP_GP64 (0, _dl_runtime_resolve)) "\n                   \
-       .set reorder\n                                                        \
-       # Save slot call pc.\n                                                \
-       move    $2, $31\n                                                     \
-       " IFABIO32(STRINGXP(CPRESTORE(32))) "\n                               \
-       " ELF_DL_SAVE_ARG_REGS "                                              \
-       move    $4, $24\n                                                     \
-       move    $5, $15\n                                                     \
-       move    $6, $3\n                                                      \
-       move    $7, $2\n                                                      \
-       jal     __dl_runtime_resolve\n                                        \
-       " ELF_DL_RESTORE_ARG_REGS "                                           \
-       " STRINGXP(RESTORE_GP64) "\n                                          \
-       " STRINGXP(PTR_ADDIU) " $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n        \
-       move    $25, $2\n                                                     \
-       jr      $25\n                                                         \
-       .end    _dl_runtime_resolve\n                                         \
-       .previous\n                                                           \
-");
-
 /* Mask identifying addresses reserved for the user program,
    where the dynamic linker should not map anything.  */
 #define ELF_MACHINE_USER_ADDRESS_MASK  0x80000000UL
@@ -451,8 +209,8 @@ _dl_runtime_resolve:\n                                                            \
       and not just plain _start.  */
 
 #define RTLD_START asm (\
-       ".text\n"\
-       _RTLD_PROLOGUE(ENTRY_POINT) "\
+       ".text\n\
+       _RTLD_PROLOGUE(ENTRY_POINT) "\
        " STRINGXV(SETUP_GPX($25)) "\n\
        " STRINGXV(SETUP_GPX64($18,$25)) "\n\
        # i386 ABI book says that the first entry of GOT holds\n\
@@ -475,10 +233,10 @@ _dl_runtime_resolve:\n                                                          \
        " STRINGXP(PTR_ADDIU) " $29, 16\n\
        # Get the value of label '_dl_start_user' in t9 ($25).\n\
        " STRINGXP(PTR_LA) " $25, _dl_start_user\n\
-       .globl _dl_start_user\n\
-       .type _dl_start_user,@function\n\
-       .aent _dl_start_user\n\
-_dl_start_user:\n\
+       " _RTLD_EPILOGUE(ENTRY_POINT) "\
+       \n\
+       \n\
+       " _RTLD_PROLOGUE(_dl_start_user) "\
        " STRINGXP(SETUP_GP) "\n\
        " STRINGXV(SETUP_GP64($18,_dl_start_user)) "\n\
        move $16, $28\n\
@@ -504,34 +262,48 @@ _dl_start_user:\n\
        sll $7, $5, " STRINGXP (PTRLOG) "\n\
        " STRINGXP(PTR_ADDU) " $7, $7, $6\n\
        " STRINGXP(PTR_ADDU) " $7, $7, " STRINGXP (PTRSIZE) " \n\
-       " STRINGXP(PTR_SUBIU) " $29, 32\n\
+       # Make sure the stack pointer is aligned for _dl_init_internal.\n\
+       and $2, $29, -2 * " STRINGXP(SZREG) "\n\
+       " STRINGXP(PTR_S) " $29, -4($2)\n\
+       " STRINGXP(PTR_SUBIU) " $29, $2, 32\n\
        " STRINGXP(SAVE_GP(16)) "\n\
        # Call the function to run the initializers.\n\
        jal _dl_init_internal\n\
-       " STRINGXP(PTR_ADDIU)  " $29, 32\n\
+       # Restore the stack pointer for _start.\n\
+       " STRINGXP(PTR_L)  " $29, 28($29)\n\
        # Pass our finalizer function to the user in $2 as per ELF ABI.\n\
        " STRINGXP(PTR_LA) " $2, _dl_fini\n\
        # Jump to the user entry point.\n\
        move $25, $17\n\
        jr $25\n\t"\
-       _RTLD_EPILOGUE(ENTRY_POINT)\
+       _RTLD_EPILOGUE(_dl_start_user)\
        ".previous"\
 );
 
 /* The MIPS never uses Elfxx_Rela relocations.  */
 #define ELF_MACHINE_NO_RELA 1
 
+/* Names of the architecture-specific auditing callback functions.  */
+# if _MIPS_SIM == _ABIO32
+#  define ARCH_LA_PLTENTER mips_o32_gnu_pltenter
+#  define ARCH_LA_PLTEXIT mips_o32_gnu_pltexit
+# elif _MIPS_SIM == _ABIN32
+#  define ARCH_LA_PLTENTER mips_n32_gnu_pltenter
+#  define ARCH_LA_PLTEXIT mips_n32_gnu_pltexit
+# else
+#  define ARCH_LA_PLTENTER mips_n64_gnu_pltenter
+#  define ARCH_LA_PLTEXIT mips_n64_gnu_pltexit
+# endif
+
 #endif /* !dl_machine_h */
 
-#ifdef RESOLVE
+#ifdef RESOLVE_MAP
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
 
-static inline void
-#ifdef RTLD_BOOTSTRAP
-  __attribute__ ((always_inline))
-#endif
+auto inline void
+__attribute__ ((always_inline))
 elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
                 const ElfW(Sym) *sym, const struct r_found_version *version,
                 void *const reloc_addr)
@@ -635,23 +407,41 @@ elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc,
     }
 }
 
-static inline void
+auto inline void
+__attribute__((always_inline))
 elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc,
                          void *const reloc_addr)
 {
   /* XXX Nothing to do.  There is no relative relocation, right?  */
 }
 
-static inline void
+auto inline void
+__attribute__((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
                      ElfW(Addr) l_addr, const ElfW(Rel) *reloc)
 {
   /* Do nothing.  */
 }
 
+auto inline void
+__attribute__ ((always_inline))
+elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
+                 const ElfW(Sym) *sym, const struct r_found_version *version,
+                void *const reloc_addr)
+{
+}
+
+auto inline void
+__attribute__((always_inline))
+elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc,
+                          void *const reloc_addr)
+{
+}
+
 #ifndef RTLD_BOOTSTRAP
 /* Relocate GOT. */
-static inline void
+auto inline void
+__attribute__((always_inline))
 elf_machine_got_rel (struct link_map *map, int lazy)
 {
   ElfW(Addr) *got;
@@ -664,9 +454,9 @@ elf_machine_got_rel (struct link_map *map, int lazy)
       const ElfW(Sym) *ref = sym;                                        \
       const struct r_found_version *version                              \
         = vernum ? &map->l_versions[vernum[sym_index] & 0x7fff] : NULL;          \
-      ElfW(Addr) value;                                                          \
-      value = RESOLVE (&ref, version, R_MIPS_REL32);                     \
-      (ref)? value + ref->st_value: 0;                                   \
+      struct link_map *sym_map;                                                  \
+      sym_map = RESOLVE_MAP (&ref, version, R_MIPS_REL32);               \
+      ref ? sym_map->l_addr + ref->st_value : 0;                         \
     })
 
   if (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
@@ -738,7 +528,8 @@ elf_machine_got_rel (struct link_map *map, int lazy)
 /* Set up the loaded object described by L so its stub function
    will jump to the on-demand fixup code __dl_runtime_resolve.  */
 
-static inline int
+auto inline int
+__attribute__((always_inline))
 elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 {
 # ifndef RTLD_BOOTSTRAP
@@ -774,4 +565,4 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
   return lazy;
 }
 
-#endif /* RESOLVE */
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/mips/dl-trampoline.c b/sysdeps/mips/dl-trampoline.c
new file mode 100644 (file)
index 0000000..c5ea59c
--- /dev/null
@@ -0,0 +1,272 @@
+/* PLT trampoline.  MIPS version.
+   Copyright (C) 1996-2001, 2002, 2003, 2004, 2005
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Kazumoto Kojima <kkojima@info.kanagawa-u.ac.jp>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/*  FIXME: Profiling of shared libraries is not implemented yet.  */
+
+#include <sysdep.h>
+#include <link.h>
+#include <elf.h>
+#include <ldsodefs.h>
+#include <dl-machine.h>
+
+/* 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)
+{
+  extern int _dl_mips_gnu_objects;
+
+  /* got[1] is reserved to keep its link map address for the shared
+     object generated by the gnu linker.  If all are such objects, we
+     can find the link map from current GPREG simply.  If not so, get
+     the link map for caller's object containing STUB_PC.  */
+
+  if (_dl_mips_gnu_objects)
+    {
+      ElfW(Addr) *got = elf_mips_got_from_gpreg (gpreg);
+      ElfW(Word) g1;
+
+      g1 = ((ElfW(Word) *) got)[1];
+
+      if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
+       {
+         struct link_map *l =
+           (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
+         ElfW(Addr) base, limit;
+         const ElfW(Phdr) *p = l->l_phdr;
+         ElfW(Half) this, nent = l->l_phnum;
+
+         /* For the common case of a stub being called from the containing
+            object, STUB_PC will point to somewhere within the object that
+            is described by the link map fetched via got[1].  Otherwise we
+            have to scan all maps.  */
+         for (this = 0; this < nent; this++)
+           {
+             if (p[this].p_type == PT_LOAD)
+               {
+                 base = p[this].p_vaddr + l->l_addr;
+                 limit = base + p[this].p_memsz;
+                 if (stub_pc >= base && stub_pc < limit)
+                   return l;
+               }
+           }
+       }
+    }
+
+    struct link_map *l;
+    Lmid_t nsid;
+
+    for (nsid = 0; nsid < DL_NNS; ++nsid)
+      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
+       {
+         ElfW(Addr) base, limit;
+         const ElfW(Phdr) *p = l->l_phdr;
+         ElfW(Half) this, nent = l->l_phnum;
+
+         for (this = 0; this < nent; ++this)
+           {
+             if (p[this].p_type == PT_LOAD)
+               {
+                 base = p[this].p_vaddr + l->l_addr;
+                 limit = base + p[this].p_memsz;
+                 if (stub_pc >= base && stub_pc < limit)
+                   return l;
+               }
+           }
+       }
+
+  _dl_signal_error (0, NULL, NULL, "cannot find runtime link map");
+  return NULL;
+}
+
+/* Define mips specific runtime resolver. The function __dl_runtime_resolve
+   is called from assembler function _dl_runtime_resolve which converts
+   special argument registers t7 ($15) and t8 ($24):
+     t7  address to return to the caller of the function
+     t8  index for this function symbol in .dynsym
+   to usual c arguments.
+
+   Other architectures call fixup from dl-runtime.c in
+   _dl_runtime_resolve.  MIPS instead calls __dl_runtime_resolve.  We
+   have to use our own version because of the way the got section is
+   treated on MIPS (we've also got ELF_MACHINE_PLT defined).  */
+
+/* The flag _dl_mips_gnu_objects is set if all dynamic objects are
+   generated by the gnu linker. */
+int _dl_mips_gnu_objects = 1;
+
+#define VERSYMIDX(sym)  (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
+
+/* This is called from assembly stubs below which the compiler can't see.  */
+static ElfW(Addr)
+__dl_runtime_resolve (ElfW(Word), ElfW(Word), ElfW(Addr), ElfW(Addr))
+                 __attribute_used__;
+
+static ElfW(Addr)
+__dl_runtime_resolve (ElfW(Word) sym_index,
+                     ElfW(Word) return_address,
+                     ElfW(Addr) old_gpreg,
+                     ElfW(Addr) stub_pc)
+{
+  struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc);
+  const ElfW(Sym) *const symtab
+    = (const ElfW(Sym) *) D_PTR (l, l_info[DT_SYMTAB]);
+  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
+  ElfW(Addr) *got
+    = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
+  const ElfW(Word) local_gotno
+    = (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
+  const ElfW(Word) gotsym
+    = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
+  const ElfW(Sym) *sym = &symtab[sym_index];
+  struct link_map *sym_map;
+  ElfW(Addr) value;
+
+  /* FIXME: The symbol versioning stuff is not tested yet.  */
+  if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
+    {
+      switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
+       {
+       default:
+         {
+           const ElfW(Half) *vernum =
+             (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
+           ElfW(Half) ndx = vernum[sym_index] & 0x7fff;
+           const struct r_found_version *version = &l->l_versions[ndx];
+
+           if (version->hash != 0)
+             {
+               sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, 
+                                              &sym, l->l_scope, version,
+                                              ELF_RTYPE_CLASS_PLT, 0, 0);
+               break;
+             }
+           /* Fall through.  */
+         }
+       case 0:
+         sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
+                                        l->l_scope, 0, ELF_RTYPE_CLASS_PLT,
+                                        DL_LOOKUP_ADD_DEPENDENCY, 0);
+       }
+
+      /* Currently value contains the base load address of the object
+        that defines sym.  Now add in the symbol offset.  */
+      value = (sym ? sym_map->l_addr + sym->st_value : 0);
+    }
+  else
+    /* We already found the symbol.  The module (and therefore its load
+       address) is also known.  */
+    value = l->l_addr + sym->st_value;
+
+  /* Apply the relocation with that value.  */
+  *(got + local_gotno + sym_index - gotsym) = value;
+
+  return value;
+}
+
+#if _MIPS_SIM == _ABIO32
+#define ELF_DL_FRAME_SIZE 40
+
+#define ELF_DL_SAVE_ARG_REGS "\
+       sw      $15, 36($29)\n                                                \
+       sw      $4, 16($29)\n                                                 \
+       sw      $5, 20($29)\n                                                 \
+       sw      $6, 24($29)\n                                                 \
+       sw      $7, 28($29)\n                                                 \
+"
+
+#define ELF_DL_RESTORE_ARG_REGS "\
+       lw      $31, 36($29)\n                                                \
+       lw      $4, 16($29)\n                                                 \
+       lw      $5, 20($29)\n                                                 \
+       lw      $6, 24($29)\n                                                 \
+       lw      $7, 28($29)\n                                                 \
+"
+
+#define IFABIO32(X) X
+
+#else /* _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64 */
+
+#define ELF_DL_FRAME_SIZE 80
+
+#define ELF_DL_SAVE_ARG_REGS "\
+       sd      $15, 72($29)\n                                                \
+       sd      $4, 8($29)\n                                                  \
+       sd      $5, 16($29)\n                                                 \
+       sd      $6, 24($29)\n                                                 \
+       sd      $7, 32($29)\n                                                 \
+       sd      $8, 40($29)\n                                                 \
+       sd      $9, 48($29)\n                                                 \
+       sd      $10, 56($29)\n                                                \
+       sd      $11, 64($29)\n                                                \
+"
+
+#define ELF_DL_RESTORE_ARG_REGS "\
+       ld      $31, 72($29)\n                                                \
+       ld      $4, 8($29)\n                                                  \
+       ld      $5, 16($29)\n                                                 \
+       ld      $6, 24($29)\n                                                 \
+       ld      $7, 32($29)\n                                                 \
+       ld      $8, 40($29)\n                                                 \
+       ld      $9, 48($29)\n                                                 \
+       ld      $10, 56($29)\n                                                \
+       ld      $11, 64($29)\n                                                \
+"
+
+#define IFABIO32(X)
+
+#endif
+
+asm ("\n\
+       .text\n\
+       .align  2\n\
+       .globl  _dl_runtime_resolve\n\
+       .type   _dl_runtime_resolve,@function\n\
+       .ent    _dl_runtime_resolve\n\
+_dl_runtime_resolve:\n\
+       .frame  $29, " STRINGXP(ELF_DL_FRAME_SIZE) ", $31\n\
+       .set noreorder\n\
+       # Save GP.\n\
+       move    $3, $28\n\
+       # Save arguments and sp value in stack.\n\
+       " STRINGXP(PTR_SUBIU) "  $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\
+       # Modify t9 ($25) so as to point .cpload instruction.\n\
+       " IFABIO32(STRINGXP(PTR_ADDIU) "        $25, 12\n") "\
+       # Compute GP.\n\
+       " STRINGXP(SETUP_GP) "\n\
+       " STRINGXV(SETUP_GP64 (0, _dl_runtime_resolve)) "\n\
+       .set reorder\n\
+       # Save slot call pc.\n\
+       move    $2, $31\n\
+       " IFABIO32(STRINGXP(CPRESTORE(32))) "\n\
+       " ELF_DL_SAVE_ARG_REGS "\
+       move    $4, $24\n\
+       move    $5, $15\n\
+       move    $6, $3\n\
+       move    $7, $2\n\
+       jal     __dl_runtime_resolve\n\
+       " ELF_DL_RESTORE_ARG_REGS "\
+       " STRINGXP(RESTORE_GP64) "\n\
+       " STRINGXP(PTR_ADDIU) " $29, " STRINGXP(ELF_DL_FRAME_SIZE) "\n\
+       move    $25, $2\n\
+       jr      $25\n\
+       .end    _dl_runtime_resolve\n\
+       .previous\n\
+");
index 5eaf7a276b3005524014b7aef28a9433c3053be2..682ec3d6aa747acf18c1aec573eb3b98b9fd8367 100644 (file)
        register long __a3 asm("$7") = (long) arg4;                     \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
-       "lw\t$2, %6\n\t"                                                \
        "subu\t$29, 32\n\t"                                             \
-       "sw\t$2, 16($29)\n\t"                                           \
+       "sw\t%6, 16($29)\n\t"                                           \
        "li\t$2, %5\t\t\t# " #name "\n\t"                               \
        "syscall\n\t"                                                   \
        "addiu\t$29, 32\n\t"                                            \
        ".set\treorder"                                                 \
        : "=r" (__v0), "+r" (__a3)                                      \
        : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)),      \
-         "m" ((long)arg5)                                              \
+         "r" ((long)arg5)                                              \
        : __SYSCALL_CLOBBERS);                                          \
        err = __a3;                                                     \
        _sys_result = __v0;                                             \
        register long __a3 asm("$7") = (long) arg4;                     \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
-       "lw\t$2, %6\n\t"                                                \
-       "lw\t$8, %7\n\t"                                                \
        "subu\t$29, 32\n\t"                                             \
-       "sw\t$2, 16($29)\n\t"                                           \
-       "sw\t$8, 20($29)\n\t"                                           \
+       "sw\t%6, 16($29)\n\t"                                           \
+       "sw\t%7, 20($29)\n\t"                                           \
        "li\t$2, %5\t\t\t# " #name "\n\t"                               \
        "syscall\n\t"                                                   \
        "addiu\t$29, 32\n\t"                                            \
        ".set\treorder"                                                 \
        : "=r" (__v0), "+r" (__a3)                                      \
        : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)),      \
-         "m" ((long)arg5), "m" ((long)arg6)                            \
+         "r" ((long)arg5), "r" ((long)arg6)                            \
        : __SYSCALL_CLOBBERS);                                          \
        err = __a3;                                                     \
        _sys_result = __v0;                                             \
        register long __a3 asm("$7") = (long) arg4;                     \
        __asm__ volatile (                                              \
        ".set\tnoreorder\n\t"                                           \
-       "lw\t$2, %6\n\t"                                                \
-       "lw\t$8, %7\n\t"                                                \
-       "lw\t$9, %8\n\t"                                                \
        "subu\t$29, 32\n\t"                                             \
-       "sw\t$2, 16($29)\n\t"                                           \
-       "sw\t$8, 20($29)\n\t"                                           \
-       "sw\t$9, 24($29)\n\t"                                           \
+       "sw\t%6, 16($29)\n\t"                                           \
+       "sw\t%7, 20($29)\n\t"                                           \
+       "sw\t%8, 24($29)\n\t"                                           \
        "li\t$2, %5\t\t\t# " #name "\n\t"                               \
        "syscall\n\t"                                                   \
        "addiu\t$29, 32\n\t"                                            \
        ".set\treorder"                                                 \
        : "=r" (__v0), "+r" (__a3)                                      \
        : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)),      \
-         "m" ((long)arg5), "m" ((long)arg6), "m" ((long)arg7)          \
+         "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7)          \
        : __SYSCALL_CLOBBERS);                                          \
        err = __a3;                                                     \
        _sys_result = __v0;                                             \
This page took 0.079976 seconds and 5 git commands to generate.