]> sourceware.org Git - glibc.git/commitdiff
* sysdeps/sparc/sparc32/dl-trampoline.S: New file.
authorRoland McGrath <roland@gnu.org>
Tue, 5 Apr 2005 21:37:05 +0000 (21:37 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 5 Apr 2005 21:37:05 +0000 (21:37 +0000)
* sysdeps/sparc/sparc32/dl-machine.h: Move PLT trampolines there.
Use RESOLVE_MAP instead of RESOLVE to protect relocation code.
(elf_machine_runtime_setup): Test for dl_profile non-null.
* sysdeps/sparc/sparc64/dl-trampoline.S: New file.
(ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): New.
* sysdeps/sparc/sparc64/dl-machine.h: Move PLT trampolines there.
Use RESOLVE_MAP instead of RESOLVE to protect relocation code.
(elf_machine_runtime_setup): Test for dl_profile non-null.
* sysdeps/sparc/bits/link.h: New file.
* sysdeps/generic/ldsodefs.h (La_sparc32_regs, La_sparc32_retval,
La_sparc64_regs, La_sparc64_retval): New.
(struct audit_ifaces): Add sparc entries.
* elf/tst-auditmod1.c: Add sparc entries.

ChangeLog
elf/tst-auditmod1.c
sysdeps/generic/ldsodefs.h
sysdeps/sparc/bits/link.h [new file with mode: 0644]
sysdeps/sparc/sparc32/dl-machine.h
sysdeps/sparc/sparc32/dl-trampoline.S [new file with mode: 0644]
sysdeps/sparc/sparc64/dl-machine.h
sysdeps/sparc/sparc64/dl-trampoline.S [new file with mode: 0644]

index dc9e0741c04c7647eb64a028663a75b2caee024e..74d5c2365d0fd21cf64b858da7fc488b99ccd3cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-04-04  David S. Miller  <davem@davemloft.net>
+
+       * sysdeps/sparc/sparc32/dl-trampoline.S: New file.
+       * sysdeps/sparc/sparc32/dl-machine.h: Move PLT trampolines there.
+       Use RESOLVE_MAP instead of RESOLVE to protect relocation code.
+       (elf_machine_runtime_setup): Test for dl_profile non-null.
+       * sysdeps/sparc/sparc64/dl-trampoline.S: New file.
+       (ARCH_LA_PLTENTER, ARCH_LA_PLTEXIT): New.
+       * sysdeps/sparc/sparc64/dl-machine.h: Move PLT trampolines there.
+       Use RESOLVE_MAP instead of RESOLVE to protect relocation code.
+       (elf_machine_runtime_setup): Test for dl_profile non-null.
+       * sysdeps/sparc/bits/link.h: New file.
+       * sysdeps/generic/ldsodefs.h (La_sparc32_regs, La_sparc32_retval,
+       La_sparc64_regs, La_sparc64_retval): New.
+       (struct audit_ifaces): Add sparc entries.
+       * elf/tst-auditmod1.c: Add sparc entries.
+
 2005-03-27  Bruno Haible  <bruno@clisp.org>
 
        * intl/tst-gettext3.c: New file.
index 38768224299813fe09a749acc02736d387870621..73d341d72b9936e7bdf623b2965477abe7ebfb70 100644 (file)
@@ -180,6 +180,18 @@ la_symbind64 (Elf64_Sym *sym, unsigned int ndx, uintptr_t *refcook,
 # define La_regs La_mips_64_regs
 # define La_retval La_mips_64_retval
 # define int_retval lrv_v0
+#elif defined __sparc__ && __WORDSIZE == 32
+# define pltenter la_sparc32_gnu_pltenter
+# define pltexit la_sparc32_gnu_pltexit
+# define La_regs La_sparc32_regs
+# define La_retval La_sparc32_retval
+# define int_retval lrv_reg[0]
+#elif defined __sparc__ && __WORDSIZE == 64
+# define pltenter la_sparc64_gnu_pltenter
+# define pltexit la_sparc64_gnu_pltexit
+# define La_regs La_sparc64_regs
+# define La_retval La_sparc64_retval
+# define int_retval lrv_reg[0]
 #else
 # error "architecture specific code needed"
 #endif
index e1a934aeda9aecc406c96c7a748b7ea9d3b30406..2e3254356bc819023744d60a97592fe5856905f5 100644 (file)
@@ -199,6 +199,10 @@ struct La_mips_32_regs;
 struct La_mips_32_retval;
 struct La_mips_64_regs;
 struct La_mips_64_retval;
+struct La_sparc32_regs;
+struct La_sparc32_retval;
+struct La_sparc64_regs;
+struct La_sparc64_retval;
 
 struct audit_ifaces
 {
@@ -270,6 +274,16 @@ struct audit_ifaces
                                         const struct La_mips_64_regs *,
                                         unsigned int *, const char *name,
                                         long int *framesizep);
+    Elf32_Addr (*sparc32_gnu_pltenter) (Elf32_Sym *, unsigned int,
+                                       uintptr_t *, uintptr_t *,
+                                       const struct La_sparc32_regs *,
+                                       unsigned int *, const char *name,
+                                       long int *framesizep);
+    Elf64_Addr (*sparc64_gnu_pltenter) (Elf64_Sym *, unsigned int,
+                                       uintptr_t *, uintptr_t *,
+                                       const struct La_sparc64_regs *,
+                                       unsigned int *, const char *name,
+                                       long int *framesizep);
   };
   union
   {
@@ -328,6 +342,16 @@ struct audit_ifaces
                                          const struct La_mips_64_regs *,
                                          struct La_mips_64_retval *,
                                          const char *);
+    unsigned int (*sparc32_gnu_pltexit) (Elf32_Sym *, unsigned int,
+                                        uintptr_t *, uintptr_t *,
+                                        const struct La_sparc32_regs *,
+                                        struct La_sparc32_retval *,
+                                        const char *);
+    unsigned int (*sparc64_gnu_pltexit) (Elf64_Sym *, unsigned int,
+                                        uintptr_t *, uintptr_t *,
+                                        const struct La_sparc32_regs *,
+                                        struct La_sparc32_retval *,
+                                        const char *);
   };
   unsigned int (*objclose) (uintptr_t *);
 
@@ -587,10 +611,10 @@ struct rtld_global_ro
   EXTERN int _dl_correct_cache_id;
 
   /* Mask for hardware capabilities that are available.  */
-  EXTERN unsigned long int _dl_hwcap;
+  EXTERN uint64_t _dl_hwcap;
 
   /* Mask for important hardware capabilities we honour. */
-  EXTERN unsigned long int _dl_hwcap_mask;
+  EXTERN uint64_t _dl_hwcap_mask;
 
   /* Get architecture specific definitions.  */
 #define PROCINFO_DECL
@@ -636,6 +660,10 @@ struct rtld_global_ro
   /* The vsyscall page is a virtual DSO pre-mapped by the kernel.
      This points to its ELF header.  */
   EXTERN const ElfW(Ehdr) *_dl_sysinfo_dso;
+
+  /* At startup time we set up the normal DSO data structure for it,
+     and this points to it.  */
+  EXTERN struct link_map *_dl_sysinfo_map;
 #endif
 
 #ifdef SHARED
diff --git a/sysdeps/sparc/bits/link.h b/sysdeps/sparc/bits/link.h
new file mode 100644 (file)
index 0000000..9b8434f
--- /dev/null
@@ -0,0 +1,100 @@
+/* Machine-specific audit interfaces for dynamic linker.  SPARC version.
+   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
+
+#if __WORDSIZE == 32
+
+typedef struct La_sparc32_regs
+{
+  uint32_t lr_lreg[8];  /* %l0 through %l7 */
+  uint32_t lr_reg[6];   /* %o0 through %o5 */
+  uint32_t lr_sp;       /* %o6 */
+  uint32_t lr_ra;       /* %o7 */
+  uint32_t lr_struct;   /* Pass-by-reference struct pointer */
+} La_sparc32_regs;
+
+typedef struct La_sparc32_retval
+{
+  uint32_t lrv_reg[2]; /* %o0 and %o1 */
+  double lrv_fpreg[2]; /* %f0 and %f2 */
+} La_sparc32_retval;
+
+#else
+
+typedef struct La_sparc64_regs
+{
+  uint64_t lr_lreg[8];  /* %l0 through %l7 */
+  uint64_t lr_reg[6];  /* %o0 through %o5 */
+  uint64_t lr_sp;      /* %o6 */
+  uint64_t lr_ra;      /* %o7 */
+  double lr_fpreg[16]; /* %f0 through %f30 */
+} La_sparc64_regs;
+
+typedef struct La_sparc64_retval
+{
+  uint64_t lrv_reg[4]; /* %o0 through %o3 */
+  double lrv_fprev[4]; /* %f0 through %f8 */
+} La_sparc64_retval;
+
+#endif
+
+__BEGIN_DECLS
+
+#if __WORDSIZE == 32
+
+extern Elf32_Addr la_sparc32_gnu_pltenter (Elf32_Sym *__sym,
+                                          unsigned int __ndx,
+                                          uintptr_t *__refcook,
+                                          uintptr_t *__defcook,
+                                          La_sparc32_regs *__regs,
+                                          unsigned int *__flags,
+                                          const char *__symname,
+                                          long int *__framesizep);
+extern unsigned int la_sparc32_gnu_pltexit (Elf32_Sym *__sym,
+                                           unsigned int __ndx,
+                                           uintptr_t *__refcook,
+                                           uintptr_t *__defcook,
+                                            const La_sparc32_regs *__inregs,
+                                           La_sparc32_retval *__outregs,
+                                           const char *symname);
+
+#else
+
+extern Elf64_Addr la_sparc64_gnu_pltenter (Elf64_Sym *__sym,
+                                          unsigned int __ndx,
+                                          uintptr_t *__refcook,
+                                          uintptr_t *__defcook,
+                                          La_sparc64_regs *__regs,
+                                          unsigned int *__flags,
+                                          const char *__symname,
+                                          long int *__framesizep);
+extern unsigned int la_sparc64_gnu_pltexit (Elf64_Sym *__sym,
+                                           unsigned int __ndx,
+                                           uintptr_t *__refcook,
+                                           uintptr_t *__defcook,
+                                           const La_sparc64_regs *__inregs,
+                                           La_sparc64_retval *__outregs,
+                                           const char *symname);
+
+#endif
+
+__END_DECLS
index d0af232d4867f188ffe8fe5459cb2589129cd360..4ea122c46b9ae4b5c71e6c617e736ef9c03bcec9 100644 (file)
@@ -131,30 +131,31 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
         bits of %g1 with an offset into the .rela.plt section and jump to
         the beginning of the PLT.  */
       plt = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
-      if (! profile)
-       rfunc = (Elf32_Addr) &_dl_runtime_resolve;
-      else
+      if (__builtin_expect(profile, 0))
        {
          rfunc = (Elf32_Addr) &_dl_runtime_profile;
 
-         if (_dl_name_match_p (GLRO(dl_profile), l))
+         if (GLRO(dl_profile) != NULL
+             && _dl_name_match_p (GLRO(dl_profile), l))
            GL(dl_profile_map) = l;
        }
+      else
+       {
+         rfunc = (Elf32_Addr) &_dl_runtime_resolve;
+       }
 
       /* The beginning of the PLT does:
 
-               save %sp, -64, %sp
-        pltpc: call _dl_runtime_resolve
-               nop
+               sethi %hi(_dl_runtime_{resolve,profile}), %g2
+        pltpc: jmpl %g2 + %lo(_dl_runtime_{resolve,profile}), %g2
+                nop
                .word MAP
 
-         This saves the register window containing the arguments, and the
-        PC value (pltpc) implicitly saved in %o7 by the call points near the
+         The PC value (pltpc) saved in %g2 by the jmpl points near the
         location where we store the link_map pointer for this object.  */
 
-      plt[0] = OPCODE_SAVE_SP;
-      /* Construct PC-relative word address.  */
-      plt[1] = OPCODE_CALL | ((rfunc - (Elf32_Addr) &plt[1]) >> 2);
+      plt[0] = 0x05000000 | ((rfunc >> 10) & 0x003fffff);
+      plt[1] = 0x85c0a000 | (rfunc & 0x3ff);
       plt[2] = OPCODE_NOP;     /* Fill call delay slot.  */
       plt[3] = (Elf32_Addr) l;
       if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
@@ -190,39 +191,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
   return lazy;
 }
 
-/* This code is used in dl-runtime.c to call the `fixup' function
-   and then redirect to the address it returns.  */
-#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name)    \
-  asm ( "\
-       .text\n\
-       .globl  " #tramp_name "\n\
-       .type   " #tramp_name ", @function\n\
-       .align  32\n\
-" #tramp_name ":\n\
-       /* Set up the arguments to fixup --\n\
-          %o0 = link_map out of plt0\n\
-          %o1 = offset of reloc entry\n\
-          %o2 = return address  */\n\
-       ld      [%o7 + 8], %o0\n\
-       srl     %g1, 10, %o1\n\
-       mov     %i7, %o2\n\
-       call    " #fixup_name "\n\
-        sub    %o1, 4*12, %o1\n\
-       jmp     %o0\n\
-        restore\n\
-       .size   " #tramp_name ", . - " #tramp_name "\n\
-       .previous")
-
-#ifndef PROF
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                 \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);    \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
-#else
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                 \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);    \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup);
-#endif
-
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.
    ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
@@ -406,7 +374,10 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
 
 #endif /* dl_machine_h */
 
-#ifdef RESOLVE
+#define ARCH_LA_PLTENTER       sparc32_gnu_pltenter
+#define ARCH_LA_PLTEXIT                sparc32_gnu_pltexit
+
+#ifdef RESOLVE_MAP
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
@@ -418,7 +389,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
                  void *const reloc_addr_arg)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
+  const Elf32_Sym *const refsym = sym;
+  Elf32_Addr value;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
+  struct link_map *sym_map = NULL;
 
 #if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
   /* This is defined in rtld.c, but nowhere in the static libc.a; make the
@@ -429,6 +403,9 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   weak_extern (_dl_rtld_map);
 #endif
 
+  if (__builtin_expect (r_type == R_SPARC_NONE, 0))
+    return;
+
 #if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
   if (__builtin_expect (r_type == R_SPARC_RELATIVE, 0))
     {
@@ -436,161 +413,143 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
       if (map != &_dl_rtld_map) /* Already done in rtld itself. */
 # endif
        *reloc_addr += map->l_addr + reloc->r_addend;
+      return;
     }
-  else
-#endif
-    {
-#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
-      const Elf32_Sym *const refsym = sym;
-# ifdef USE_TLS
-      struct link_map *sym_map;
-# endif
 #endif
-      Elf32_Addr value;
+
 #ifndef RESOLVE_CONFLICT_FIND_MAP
-      if (sym->st_shndx != SHN_UNDEF &&
-         ELF32_ST_BIND (sym->st_info) == STB_LOCAL)
-       {
-         value = map->l_addr;
-# if defined USE_TLS && !defined RTLD_BOOTSTRAP
-         sym_map = map;
-# endif
-       }
-      else
-       {
-# if defined USE_TLS && !defined RTLD_BOOTSTRAP
-         sym_map = RESOLVE_MAP (&sym, version, r_type);
-         value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
-# else
-         value = RESOLVE (&sym, version, r_type);
-         if (sym)
-           value += sym->st_value;
-# endif
-       }
+  if (__builtin_expect (ELF32_ST_BIND (sym->st_info) == STB_LOCAL, 0)
+      && sym->st_shndx != SHN_UNDEF)
+    {
+      value = map->l_addr;
+    }
+  else
+    {
+      sym_map = RESOLVE_MAP (&sym, version, r_type);
+      value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+    }
 #else
-      value = 0;
+  value = 0;
 #endif
-      value += reloc->r_addend;        /* Assume copy relocs have zero addend.  */
 
-      switch (r_type)
-       {
+  value += reloc->r_addend;    /* Assume copy relocs have zero addend.  */
+
+  switch (r_type)
+    {
 #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
-       case R_SPARC_COPY:
-         if (sym == NULL)
-           /* This can happen in trace mode if an object could not be
-              found.  */
-           break;
-         if (sym->st_size > refsym->st_size
-             || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
-           {
-             const char *strtab;
+    case R_SPARC_COPY:
+      if (sym == NULL)
+       /* This can happen in trace mode if an object could not be
+          found.  */
+       break;
+      if (sym->st_size > refsym->st_size
+         || (GLRO(dl_verbose) && sym->st_size < refsym->st_size))
+       {
+         const char *strtab;
 
-             strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
-             _dl_error_printf ("\
+         strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
+         _dl_error_printf ("\
 %s: Symbol `%s' has different size in shared object, consider re-linking\n",
-                               rtld_progname ?: "<program name unknown>",
-                               strtab + refsym->st_name);
-           }
-         memcpy (reloc_addr_arg, (void *) value,
-                 MIN (sym->st_size, refsym->st_size));
-         break;
+                           rtld_progname ?: "<program name unknown>",
+                           strtab + refsym->st_name);
+       }
+      memcpy (reloc_addr_arg, (void *) value,
+             MIN (sym->st_size, refsym->st_size));
+      break;
 #endif
-       case R_SPARC_GLOB_DAT:
-       case R_SPARC_32:
-         *reloc_addr = value;
-         break;
-       case R_SPARC_JMP_SLOT:
-         /* At this point we don't need to bother with thread safety,
-            so we can optimize the first instruction of .plt out.  */
-         sparc_fixup_plt (reloc, reloc_addr, value, 0);
-         break;
+    case R_SPARC_GLOB_DAT:
+    case R_SPARC_32:
+      *reloc_addr = value;
+      break;
+    case R_SPARC_JMP_SLOT:
+      /* At this point we don't need to bother with thread safety,
+        so we can optimize the first instruction of .plt out.  */
+      sparc_fixup_plt (reloc, reloc_addr, value, 0);
+      break;
 #if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) \
     && !defined RESOLVE_CONFLICT_FIND_MAP
-       case R_SPARC_TLS_DTPMOD32:
-         /* Get the information from the link map returned by the
-            resolv function.  */
-         if (sym_map != NULL)
-           *reloc_addr = sym_map->l_tls_modid;
-         break;
-       case R_SPARC_TLS_DTPOFF32:
-         /* During relocation all TLS symbols are defined and used.
-            Therefore the offset is already correct.  */
-         *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
-         break;
-       case R_SPARC_TLS_TPOFF32:
-         /* The offset is negative, forward from the thread pointer.  */
-         /* We know the offset of object the symbol is contained in.
-            It is a negative value which will be added to the
-            thread pointer.  */
-         if (sym != NULL)
-           {
-             CHECK_STATIC_TLS (map, sym_map);
-             *reloc_addr = sym->st_value - sym_map->l_tls_offset
-                           + reloc->r_addend;
-           }
-         break;
+    case R_SPARC_TLS_DTPMOD32:
+      /* Get the information from the link map returned by the
+        resolv function.  */
+      if (sym_map != NULL)
+       *reloc_addr = sym_map->l_tls_modid;
+      break;
+    case R_SPARC_TLS_DTPOFF32:
+      /* During relocation all TLS symbols are defined and used.
+        Therefore the offset is already correct.  */
+      *reloc_addr = (sym == NULL ? 0 : sym->st_value) + reloc->r_addend;
+      break;
+    case R_SPARC_TLS_TPOFF32:
+      /* The offset is negative, forward from the thread pointer.  */
+      /* We know the offset of object the symbol is contained in.
+        It is a negative value which will be added to the
+        thread pointer.  */
+      if (sym != NULL)
+       {
+         CHECK_STATIC_TLS (map, sym_map);
+         *reloc_addr = sym->st_value - sym_map->l_tls_offset
+           + reloc->r_addend;
+       }
+      break;
 # ifndef RTLD_BOOTSTRAP
-       case R_SPARC_TLS_LE_HIX22:
-       case R_SPARC_TLS_LE_LOX10:
-         if (sym != NULL)
-           {
-             CHECK_STATIC_TLS (map, sym_map);
-             value = sym->st_value - sym_map->l_tls_offset
-                     + reloc->r_addend;
-             if (r_type == R_SPARC_TLS_LE_HIX22)
-               *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
-             else
-               *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
-                             | 0x1c00;
-           }
-         break;
+    case R_SPARC_TLS_LE_HIX22:
+    case R_SPARC_TLS_LE_LOX10:
+      if (sym != NULL)
+       {
+         CHECK_STATIC_TLS (map, sym_map);
+         value = sym->st_value - sym_map->l_tls_offset
+           + reloc->r_addend;
+         if (r_type == R_SPARC_TLS_LE_HIX22)
+           *reloc_addr = (*reloc_addr & 0xffc00000) | ((~value) >> 10);
+         else
+           *reloc_addr = (*reloc_addr & 0xffffe000) | (value & 0x3ff)
+             | 0x1c00;
+       }
+      break;
 # endif
 #endif
 #ifndef RTLD_BOOTSTRAP
-       case R_SPARC_8:
-         *(char *) reloc_addr = value;
-         break;
-       case R_SPARC_16:
-         *(short *) reloc_addr = value;
-         break;
-       case R_SPARC_DISP8:
-         *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
-         break;
-       case R_SPARC_DISP16:
-         *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
-         break;
-       case R_SPARC_DISP32:
-         *reloc_addr = (value - (Elf32_Addr) reloc_addr);
-         break;
-       case R_SPARC_LO10:
-         *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff);
-         break;
-       case R_SPARC_WDISP30:
-         *reloc_addr = ((*reloc_addr & 0xc0000000)
-                        | ((value - (unsigned int) reloc_addr) >> 2));
-         break;
-       case R_SPARC_HI22:
-         *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10);
-         break;
-       case R_SPARC_UA16:
-         ((unsigned char *) reloc_addr_arg) [0] = value >> 8;
-         ((unsigned char *) reloc_addr_arg) [1] = value;
-         break;
-       case R_SPARC_UA32:
-         ((unsigned char *) reloc_addr_arg) [0] = value >> 24;
-         ((unsigned char *) reloc_addr_arg) [1] = value >> 16;
-         ((unsigned char *) reloc_addr_arg) [2] = value >> 8;
-         ((unsigned char *) reloc_addr_arg) [3] = value;
-         break;
+    case R_SPARC_8:
+      *(char *) reloc_addr = value;
+      break;
+    case R_SPARC_16:
+      *(short *) reloc_addr = value;
+      break;
+    case R_SPARC_DISP8:
+      *(char *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+      break;
+    case R_SPARC_DISP16:
+      *(short *) reloc_addr = (value - (Elf32_Addr) reloc_addr);
+      break;
+    case R_SPARC_DISP32:
+      *reloc_addr = (value - (Elf32_Addr) reloc_addr);
+      break;
+    case R_SPARC_LO10:
+      *reloc_addr = (*reloc_addr & ~0x3ff) | (value & 0x3ff);
+      break;
+    case R_SPARC_WDISP30:
+      *reloc_addr = ((*reloc_addr & 0xc0000000)
+                    | ((value - (unsigned int) reloc_addr) >> 2));
+      break;
+    case R_SPARC_HI22:
+      *reloc_addr = (*reloc_addr & 0xffc00000) | (value >> 10);
+      break;
+    case R_SPARC_UA16:
+      ((unsigned char *) reloc_addr_arg) [0] = value >> 8;
+      ((unsigned char *) reloc_addr_arg) [1] = value;
+      break;
+    case R_SPARC_UA32:
+      ((unsigned char *) reloc_addr_arg) [0] = value >> 24;
+      ((unsigned char *) reloc_addr_arg) [1] = value >> 16;
+      ((unsigned char *) reloc_addr_arg) [2] = value >> 8;
+      ((unsigned char *) reloc_addr_arg) [3] = value;
+      break;
 #endif
-       case R_SPARC_NONE:              /* Alright, Wilbur.  */
-         break;
 #if !defined RTLD_BOOTSTRAP || defined _NDEBUG
-       default:
-         _dl_reloc_bad_type (map, r_type, 0);
-         break;
+    default:
+      _dl_reloc_bad_type (map, r_type, 0);
+      break;
 #endif
-       }
     }
 }
 
@@ -620,4 +579,4 @@ elf_machine_lazy_rel (struct link_map *map,
     }
 }
 
-#endif /* RESOLVE */
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/sparc/sparc32/dl-trampoline.S b/sysdeps/sparc/sparc32/dl-trampoline.S
new file mode 100644 (file)
index 0000000..1253a33
--- /dev/null
@@ -0,0 +1,155 @@
+/* PLT trampolines.  Sparc 32-bit version.
+   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.  */
+
+#include <sysdep.h>
+
+       .text
+       .align  32
+
+       /* %g1: PLT offset loaded by PLT entry
+        * %g2: callers PC, which is PLT0 + 4, and we store the
+        *      link map at PLT0 + 12, therefore we add 8 to get
+        *      the address of the link map
+        */
+       .globl  _dl_runtime_resolve
+       .type   _dl_runtime_resolve, @function
+_dl_runtime_resolve:
+       save    %sp, -104, %sp
+       ld      [%g2 + 8], %o0
+       srl     %g1, 10, %o1
+       call    _dl_fixup
+        sub    %o1, 4*12, %o1
+       jmp     %o0
+        restore
+       .size   _dl_runtime_resolve, .-_dl_runtime_resolve
+
+       /* For the profiling cases we pass in our stack frame
+        * as the base of the La_sparc64_regs, so it looks
+        * like:
+        *      %l0                     %sp
+        *      ...
+        *      %l7                     %sp + (7 * 8)
+        *      %i0                     %sp + (8 * 8)
+        *      ...
+        *      %i7                     %sp + (15 * 8)
+        *      %f0                     %sp + (16 * 8)
+        *      %f16                    %sp + (31 * 8)
+        *      framesize               %sp + (32 * 8)
+        */
+
+       .globl  _dl_profile_save_regs
+       .type   _dl_profile_save_regs, @function
+_dl_profile_save_regs:
+       std     %l0, [%sp + ( 0 * 8)]
+       std     %l2, [%sp + ( 1 * 8)]
+       std     %l4, [%sp + ( 2 * 8)]
+       std     %l6, [%sp + ( 3 * 8)]
+       std     %i0, [%sp + ( 4 * 8)]
+       std     %i2, [%sp + ( 5 * 8)]
+       std     %i4, [%sp + ( 6 * 8)]
+       std     %i6, [%sp + ( 7 * 8)]
+       ld      [%sp + (8 * 8)], %l4
+       retl
+        st     %l4, [%sp + (8 * 8)]
+       .size   _dl_profile_save_regs, .-_dl_profile_save_regs
+
+       /* If we are going to call pltexit, then we must replicate
+        * the caller's stack frame.
+        * %o0: PLT resolved function address
+        */
+       .globl  _dl_profile_invoke
+       .type   _dl_profile_invoke, @function
+_dl_profile_invoke:
+       sub     %sp, %l0, %sp
+1:
+       srl     %l0, 3, %l7
+       mov     %o0, %l1
+       mov     %i0, %o0
+       mov     %i1, %o1
+       mov     %i2, %o2
+       mov     %i3, %o3
+       mov     %i4, %o4
+       mov     %i5, %o5
+       mov     %fp, %l2
+       mov     %sp, %l3
+1:     ldd     [%l2], %g2
+       add     %l2, 0x8, %l2
+       subcc   %l7, 1, %l7
+       stx     %g2, [%l3]
+       bne     1b
+        add    %l3, 0x8, %l3
+
+       jmpl    %l1, %o7
+        nop
+
+       std     %o0, [%sp + ( 9 * 8)]
+       std     %f0, [%sp + (10 * 8)]
+
+       mov     %l5, %o0
+       mov     %l6, %o1
+       add     %sp, %l0, %o2
+       call    _dl_call_pltexit
+        add    %sp, (16 * 8), %o3
+
+       ldd     [%sp + (9 * 8)], %i0
+
+       jmpl    %i7 + 8, %g0
+        restore
+
+       /* %g1: PLT offset loaded by PLT entry
+        * %g2: callers PC, which is PLT0 + 4, and we store the
+        *      link map at PLT0 + 12, therefore we add 8 to get
+        *      the address of the link map
+        */
+       .align  32
+       .globl  _dl_runtime_profile
+       .type   _dl_runtime_profile, @function
+_dl_runtime_profile:
+       cmp     %fp, 0
+       be,a    1f
+        mov    104, %g3
+       sub     %fp, %sp, %g3
+1:     save    %sp, -104, %sp
+       ld      [%g2 + 8], %o0
+       srl     %g1, 10, %o1
+       mov     %i7, %o2
+       sub     %o1, 4*12, %o1
+
+       mov     %g3, %l0
+       mov     %o0, %l5
+       mov     %o1, %l6
+
+       call _dl_profile_save_regs
+        nop
+
+       mov     %sp, %o3
+       call    _dl_profile_fixup
+        add    %sp, (9 * 8), %o4
+
+       ld      [%sp + (9 * 8)], %o1
+       cmp     %o1, 0
+       bgeu    1f
+        nop
+       
+       call    _dl_profile_invoke
+        nop
+
+1:     jmp     %o0
+        restore
+       .size   _dl_runtime_profile, .-_dl_runtime_profile
index 72b88e235c5aedb6763a0431120d639142bd0d6b..e2089cd0395f7d65c86658798b57efcb5d33eeed 100644 (file)
@@ -233,7 +233,10 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc,
   return value;
 }
 
-#ifdef RESOLVE
+#define ARCH_LA_PLTENTER       sparc64_gnu_pltenter
+#define ARCH_LA_PLTEXIT                sparc64_gnu_pltexit
+
+#ifdef RESOLVE_MAP
 
 /* Perform the relocation specified by RELOC and SYM (which is fully resolved).
    MAP is the object containing the reloc.  */
@@ -267,9 +270,10 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
        value = map->l_addr;
       else
        {
-         value = RESOLVE (&sym, version, r_type);
-         if (sym)
-           value += sym->st_value;
+         struct link_map *sym_map;
+
+         sym_map = RESOLVE_MAP (&sym, version, r_type);
+         value = (sym_map == NULL) ? 0 : (sym_map->l_addr + sym->st_value);
        }
 #else
       value = 0;
@@ -490,74 +494,67 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
       extern void _dl_runtime_profile_1 (void);
       Elf64_Addr res0_addr, res1_addr;
       unsigned int *plt = (void *) D_PTR (l, l_info[DT_PLTGOT]);
-      int i = 0;
 
-      if (! profile)
-       {
-         res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0;
-         res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1;
-       }
-      else
+      if (__builtin_expect(profile, 0))
        {
          res0_addr = (Elf64_Addr) &_dl_runtime_profile_0;
          res1_addr = (Elf64_Addr) &_dl_runtime_profile_1;
-         if (_dl_name_match_p (GLRO(dl_profile), l))
+
+         if (GLRO(dl_profile) != NULL
+             && _dl_name_match_p (GLRO(dl_profile), l))
            GL(dl_profile_map) = l;
        }
+      else
+       {
+         res0_addr = (Elf64_Addr) &_dl_runtime_resolve_0;
+         res1_addr = (Elf64_Addr) &_dl_runtime_resolve_1;
+       }
 
       /* PLT0 looks like:
 
-        save   %sp, -192, %sp
-        sethi  %hh(_dl_runtime_{resolve,profile}_0), %l0
-        sethi  %lm(_dl_runtime_{resolve,profile}_0), %l1
-        or     %l0, %hm(_dl_runtime_{resolve,profile}_0), %l0
-        or     %l1, %lo(_dl_runtime_{resolve,profile}_0), %l1
-        sllx   %l0, 32, %l0
-        jmpl   %l0 + %l1, %l6
-         sethi %hi(0xffc00), %l2
+         sethi %uhi(_dl_runtime_{resolve,profile}_0), %g4
+        sethi  %hi(_dl_runtime_{resolve,profile}_0), %g5
+        or     %g4, %ulo(_dl_runtime_{resolve,profile}_0), %g4
+        or     %g5, %lo(_dl_runtime_{resolve,profile}_0), %g5
+        sllx   %g4, 32, %g4
+        add    %g4, %g5, %g5
+        jmpl   %g5, %g4
+         nop
        */
 
-      plt[0] = 0x9de3bf40;
-      plt[1] = 0x21000000 | (res0_addr >> (64 - 22));
-      plt[2] = 0x23000000 | ((res0_addr >> 10) & 0x003fffff);
-      plt[3] = 0xa0142000 | ((res0_addr >> 32) & 0x3ff);
-      plt[4] = 0xa2146000 | (res0_addr & 0x3ff);
-      plt[5] = 0xa12c3020;
-      plt[6] = 0xadc40011;
-      plt[7] = 0x250003ff;
+      plt[0] = 0x09000000 | (res0_addr >> (64 - 22));
+      plt[1] = 0x0b000000 | ((res0_addr >> 10) & 0x003fffff);
+      plt[2] = 0x88112000 | ((res0_addr >> 32) & 0x3ff);
+      plt[3] = 0x8a116000 | (res0_addr & 0x3ff);
+      plt[4] = 0x89293020;
+      plt[5] = 0x8a010005;
+      plt[6] = 0x89c14000;
+      plt[7] = 0x01000000;
 
       /* PLT1 looks like:
 
-        save   %sp, -192, %sp
-        sethi  %hh(_dl_runtime_{resolve,profile}_1), %l0
-        sethi  %lm(_dl_runtime_{resolve,profile}_1), %l1
-        or     %l0, %hm(_dl_runtime_{resolve,profile}_1), %l0
-        or     %l1, %lo(_dl_runtime_{resolve,profile}_1), %l1
-        sllx   %l0, 32, %l0
-        jmpl   %l0 + %l1, %l6
-         srlx  %g1, 12, %o1
+         sethi %uhi(_dl_runtime_{resolve,profile}_1), %g4
+        sethi  %hi(_dl_runtime_{resolve,profile}_1), %g5
+        or     %g4, %ulo(_dl_runtime_{resolve,profile}_1), %g4
+        or     %g5, %lo(_dl_runtime_{resolve,profile}_1), %g5
+        sllx   %g4, 32, %g4
+        add    %g4, %g5, %g5
+        jmpl   %g5, %g4
+         nop
        */
 
-      plt[8 + 0] = 0x9de3bf40;
-      if (__builtin_expect (((res1_addr + 4) >> 32) & 0x3ff, 0))
-       i = 1;
-      else
-       res1_addr += 4;
-      plt[8 + 1] = 0x21000000 | (res1_addr >> (64 - 22));
-      plt[8 + 2] = 0x23000000 | ((res1_addr >> 10) & 0x003fffff);
-      if (__builtin_expect (i, 0))
-       plt[8 + 3] = 0xa0142000 | ((res1_addr >> 32) & 0x3ff);
-      else
-       plt[8 + 3] = 0xa12c3020;
-      plt[8 + 4] = 0xa2146000 | (res1_addr & 0x3ff);
-      if (__builtin_expect (i, 0))
-       plt[8 + 5] = 0xa12c3020;
-      plt[8 + 5 + i] = 0xadc40011;
-      plt[8 + 6 + i] = 0x9330700c;
+      plt[8] = 0x09000000 | (res1_addr >> (64 - 22));
+      plt[9] = 0x0b000000 | ((res1_addr >> 10) & 0x003fffff);
+      plt[10] = 0x88112000 | ((res1_addr >> 32) & 0x3ff);
+      plt[11] = 0x8a116000 | (res1_addr & 0x3ff);
+      plt[12] = 0x89293020;
+      plt[13] = 0x8a010005;
+      plt[14] = 0x89c14000;
+      plt[15] = 0x01000000;
 
       /* Now put the magic cookie at the beginning of .PLT2
         Entry .PLT3 is unused by this implementation.  */
-      *((struct link_map **)(&plt[16 + 0])) = l;
+      *((struct link_map **)(&plt[16])) = l;
 
       if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
          || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0))
@@ -604,68 +601,6 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
   return lazy;
 }
 
-/* This code is used in dl-runtime.c to call the `fixup' function
-   and then redirect to the address it returns.  */
-#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name)    \
-  asm ("\n"                                            \
-"      .text\n"                                        \
-"      .globl  " #tramp_name "_0\n"                    \
-"      .type   " #tramp_name "_0, @function\n"         \
-"      .align  32\n"                                   \
-"\t" #tramp_name "_0:\n"                               \
-"      ! sethi   %hi(1047552), %l2 - Done in .PLT0\n"  \
-"      ldx     [%l6 + 32 + 8], %o0\n"                  \
-"      sub     %g1, %l6, %l0\n"                        \
-"      xor     %l2, -1016, %l2\n"                      \
-"      sethi   %hi(5120), %l3  ! 160 * 32\n"           \
-"      add     %l0, %l2, %l0\n"                        \
-"      sethi   %hi(32768), %l4\n"                      \
-"      udivx   %l0, %l3, %l3\n"                        \
-"      sllx    %l3, 2, %l1\n"                          \
-"      add     %l1, %l3, %l1\n"                        \
-"      sllx    %l1, 10, %l2\n"                         \
-"      sub     %l4, 4, %l4     ! No thanks to Sun for not obeying their own ABI\n" \
-"      sllx    %l1, 5, %l1\n"                          \
-"      sub     %l0, %l2, %l0\n"                        \
-"      udivx   %l0, 24, %l0\n"                         \
-"      add     %l0, %l4, %l0\n"                        \
-"      add     %l1, %l0, %l1\n"                        \
-"      add     %l1, %l1, %l0\n"                        \
-"      add     %l0, %l1, %l0\n"                        \
-"      mov     %i7, %o2\n"                             \
-"      call    " #fixup_name "\n"                      \
-"       sllx    %l0, 3, %o1\n"                         \
-"      jmp     %o0\n"                                  \
-"       restore\n"                                     \
-"      .size   " #tramp_name "_0, . - " #tramp_name "_0\n" \
-"\n"                                                   \
-"      .globl  " #tramp_name "_1\n"                    \
-"      .type   " #tramp_name "_1, @function\n"         \
-"      ! tramp_name_1 + 4 needs to be .align 32\n"     \
-"\t" #tramp_name "_1:\n"                               \
-"      sub     %l6, 4, %l6\n"                          \
-"      ! srlx  %g1, 12, %o1 - Done in .PLT1\n"         \
-"      ldx     [%l6 + 12], %o0\n"                      \
-"      add     %o1, %o1, %o3\n"                        \
-"      sub     %o1, 96, %o1    ! No thanks to Sun for not obeying their own ABI\n" \
-"      mov     %i7, %o2\n"                             \
-"      call    " #fixup_name "\n"                      \
-"       add    %o1, %o3, %o1\n"                        \
-"      jmp     %o0\n"                                  \
-"       restore\n"                                     \
-"      .size   " #tramp_name "_1, . - " #tramp_name "_1\n" \
-"      .previous\n");
-
-#ifndef PROF
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                 \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);    \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup);
-#else
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE                 \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup);    \
-  TRAMPOLINE_TEMPLATE (_dl_runtime_profile, fixup);
-#endif
-
 /* The PLT uses Elf64_Rela relocs.  */
 #define elf_machine_relplt elf_machine_rela
 
diff --git a/sysdeps/sparc/sparc64/dl-trampoline.S b/sysdeps/sparc/sparc64/dl-trampoline.S
new file mode 100644 (file)
index 0000000..f85527f
--- /dev/null
@@ -0,0 +1,280 @@
+/* PLT trampolines.  Sparc 64-bit version.
+   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.  */
+
+#include <sysdep.h>
+
+       .text
+       .align  32
+
+       /* %g1: PLT offset loaded by PLT entry
+        * %g4: callers PC, which is PLT0 + 24, therefore we
+        *      add (32 + 8) to get the address of PLT2 which
+        *      is where the magic cookie is stored
+        */
+       .globl  _dl_runtime_resolve_0
+       .type   _dl_runtime_resolve_0, @function
+_dl_runtime_resolve_0:
+       save    %sp, -192, %sp
+       sethi   %hi(1047552), %l2
+       ldx     [%g4 + 32 + 8], %o0
+       sub     %g1, %g4, %l0
+       xor     %l2, -1016, %l2
+       sethi   %hi(5120), %l3  /* 160 * 32 */
+       add     %l0, %l2, %l0
+       sethi   %hi(32768), %l4
+       udivx   %l0, %l3, %l3
+       sllx    %l3, 2, %l1
+       add     %l1, %l3, %l1
+       sllx    %l1, 10, %l2
+       sub     %l4, 4, %l4
+       sllx    %l1, 5, %l1
+       sub     %l0, %l2, %l0
+       udivx   %l0, 24, %l0
+       add     %l0, %l4, %l0
+       add     %l1, %l0, %l1
+       add     %l1, %l1, %l0
+       add     %l0, %l1, %l0
+       call    _dl_fixup
+        sllx    %l0, 3, %o1
+       jmp     %o0
+        restore
+       .size   _dl_runtime_resolve_0, .-_dl_runtime_resolve_0
+
+       /* %g1: PLT offset loaded by PLT entry
+        * %g4: callers PC, which is PLT1 + 24, therefore we
+        *      add 8 to get the address of PLT2 which
+        *      is where the magic cookie is stored
+        */
+       .globl  _dl_runtime_resolve_1
+       .type   _dl_runtime_resolve_1, @function
+_dl_runtime_resolve_1:
+       save    %sp, -192, %sp
+       srlx    %g1, 12, %o1
+       ldx     [%g4 + 8], %o0
+       add     %o1, %o1, %o3
+       sub     %o1, 96, %o1
+       call    _dl_fixup
+        add    %o1, %o3, %o1
+       jmp     %o0
+        restore
+       .size   _dl_runtime_resolve_1, .-_dl_runtime_resolve_1
+
+       /* For the profiling cases we pass in our stack frame
+        * as the base of the La_sparc64_regs, so it looks
+        * like:
+        *      %l0                     %sp
+        *      ...
+        *      %l7                     %sp + (7 * 8)
+        *      %i0                     %sp + (8 * 8)
+        *      ...
+        *      %i7                     %sp + (15 * 8)
+        *      %f0                     %sp + (16 * 8)
+        *      %f16                    %sp + (31 * 8)
+        *      framesize               %sp + (32 * 8)
+        */
+
+       .globl  _dl_profile_save_regs
+       .type   _dl_profile_save_regs, @function
+_dl_profile_save_regs:
+       stx     %l0, [%sp + STACK_BIAS + ( 0 * 8)]
+       stx     %l1, [%sp + STACK_BIAS + ( 1 * 8)]
+       stx     %l2, [%sp + STACK_BIAS + ( 2 * 8)]
+       stx     %l3, [%sp + STACK_BIAS + ( 3 * 8)]
+       stx     %l4, [%sp + STACK_BIAS + ( 4 * 8)]
+       stx     %l5, [%sp + STACK_BIAS + ( 5 * 8)]
+       stx     %l6, [%sp + STACK_BIAS + ( 6 * 8)]
+       stx     %l7, [%sp + STACK_BIAS + ( 7 * 8)]
+       stx     %i0, [%sp + STACK_BIAS + ( 8 * 8)]
+       stx     %i1, [%sp + STACK_BIAS + ( 9 * 8)]
+       stx     %i2, [%sp + STACK_BIAS + (10 * 8)]
+       stx     %i3, [%sp + STACK_BIAS + (11 * 8)]
+       stx     %i4, [%sp + STACK_BIAS + (12 * 8)]
+       stx     %i5, [%sp + STACK_BIAS + (13 * 8)]
+       stx     %i6, [%sp + STACK_BIAS + (14 * 8)]
+       stx     %i7, [%sp + STACK_BIAS + (15 * 8)]
+       std     %f0, [%sp + STACK_BIAS + (16 * 8)]
+       std     %f2, [%sp + STACK_BIAS + (17 * 8)]
+       std     %f4, [%sp + STACK_BIAS + (18 * 8)]
+       std     %f6, [%sp + STACK_BIAS + (19 * 8)]
+       std     %f8, [%sp + STACK_BIAS + (20 * 8)]
+       std     %f10, [%sp + STACK_BIAS + (21 * 8)]
+       std     %f12, [%sp + STACK_BIAS + (22 * 8)]
+       std     %f14, [%sp + STACK_BIAS + (23 * 8)]
+       std     %f16, [%sp + STACK_BIAS + (24 * 8)]
+       std     %f18, [%sp + STACK_BIAS + (25 * 8)]
+       std     %f20, [%sp + STACK_BIAS + (26 * 8)]
+       std     %f22, [%sp + STACK_BIAS + (27 * 8)]
+       std     %f24, [%sp + STACK_BIAS + (28 * 8)]
+       std     %f26, [%sp + STACK_BIAS + (29 * 8)]
+       std     %f28, [%sp + STACK_BIAS + (30 * 8)]
+       retl
+        std    %f30, [%sp + STACK_BIAS + (31 * 8)]
+       .size   _dl_profile_save_regs, .-_dl_profile_save_regs
+
+       /* If we are going to call pltexit, then we must replicate
+        * the caller's stack frame.
+        * %o0: PLT resolved function address
+        */
+       .globl  _dl_profile_invoke
+       .type   _dl_profile_invoke, @function
+_dl_profile_invoke:
+       sub     %sp, %l0, %sp
+1:
+       srlx    %l0, 3, %l7
+       mov     %o0, %l1
+       mov     %i0, %o0
+       mov     %i1, %o1
+       mov     %i2, %o2
+       mov     %i3, %o3
+       mov     %i4, %o4
+       mov     %i5, %o5
+       add     %fp, STACK_BIAS, %l2
+       add     %sp, STACK_BIAS, %l3
+1:     ldx     [%l2], %l4
+       add     %l2, 0x8, %l2
+       subcc   %l7, 1, %l7
+       stx     %l4, [%l3]
+       bne,pt  %xcc, 1b
+        add    %l3, 0x8, %l3
+
+       jmpl    %l1, %o7
+        nop
+
+       stx     %o0, [%sp + STACK_BIAS + (16 * 8)]
+       stx     %o1, [%sp + STACK_BIAS + (17 * 8)]
+       stx     %o2, [%sp + STACK_BIAS + (18 * 8)]
+       stx     %o3, [%sp + STACK_BIAS + (19 * 8)]
+       std     %f0, [%sp + STACK_BIAS + (20 * 8)]
+       std     %f2, [%sp + STACK_BIAS + (21 * 8)]
+       std     %f4, [%sp + STACK_BIAS + (22 * 8)]
+       std     %f8, [%sp + STACK_BIAS + (23 * 8)]
+
+       mov     %l5, %o0
+       mov     %l6, %o1
+       add     %sp, %l0, %o2
+       add     %sp, STACK_BIAS + (16 * 8), %o3
+       call    _dl_call_pltexit
+        add    %o2, STACK_BIAS, %o2
+
+       ldx     [%sp + STACK_BIAS + (16 * 8)], %i0
+       ldx     [%sp + STACK_BIAS + (17 * 8)], %i1
+       ldx     [%sp + STACK_BIAS + (18 * 8)], %i2
+       ldx     [%sp + STACK_BIAS + (19 * 8)], %i3
+
+       jmpl    %i7 + 8, %g0
+        restore
+
+       /* %g1: PLT offset loaded by PLT entry
+        * %g4: callers PC, which is PLT0 + 24, therefore we
+        *      add (32 + 8) to get the address of PLT2 which
+        *      is where the magic cookie is stored
+        */
+       .align  32
+       .globl  _dl_runtime_profile_0
+       .type   _dl_runtime_profile_0, @function
+_dl_runtime_profile_0:
+       brz,a,pn %fp, 1f
+        mov    192, %g5
+       sub     %fp, %sp, %g5
+1:     save    %sp, -336, %sp
+       sethi   %hi(1047552), %l2
+       ldx     [%g4 + 32 + 8], %o0
+       sub     %g1, %g4, %l0
+       xor     %l2, -1016, %l2
+       sethi   %hi(5120), %l3  /* 160 * 32 */
+       add     %l0, %l2, %l0
+       sethi   %hi(32768), %l4
+       udivx   %l0, %l3, %l3
+       sllx    %l3, 2, %l1
+       add     %l1, %l3, %l1
+       sllx    %l1, 10, %l2
+       sub     %l4, 4, %l4
+       sllx    %l1, 5, %l1
+       sub     %l0, %l2, %l0
+       udivx   %l0, 24, %l0
+       add     %l0, %l4, %l0
+       add     %l1, %l0, %l1
+       add     %l1, %l1, %l0
+       add     %l0, %l1, %l0
+
+       mov     %i7, %o2
+       sllx    %l0, 3, %o1
+
+       mov     %g5, %l0
+       mov     %o0, %l5
+       mov     %o1, %l6
+
+       call    _dl_profile_save_regs
+        nop
+
+       add     %sp, STACK_BIAS, %o3
+       call    _dl_profile_fixup
+        add    %sp, (STACK_BIAS + (32 * 8)), %o4
+
+       ldx     [%sp + STACK_BIAS + (32 * 8)], %o1
+       brgez,pt %o1, 1f
+        nop
+
+       call    _dl_profile_invoke
+        nop
+
+1:     jmp     %o0
+        restore
+       .size   _dl_runtime_profile_0, .-_dl_runtime_profile_0
+
+       /* %g1: PLT offset loaded by PLT entry
+        * %g4: callers PC, which is PLT1 + 24, therefore we
+        *      add 8 to get the address of PLT2 which
+        *      is where the magic cookie is stored
+        */
+       .globl  _dl_runtime_profile_1
+       .type   _dl_runtime_profile_1, @function
+_dl_runtime_profile_1:
+       brz,a,pn %fp, 1f
+        mov    192, %g5
+       sub     %fp, %sp, %g5
+1:     save    %sp, -336, %sp
+       srlx    %g1, 12, %o1
+       ldx     [%g4 + 8], %o0
+       add     %o1, %o1, %o3
+       sub     %o1, 96, %o1
+       mov     %i7, %o2
+       add     %o1, %o3, %o1
+
+       mov     %g5, %l0
+       mov     %o0, %l5
+       mov     %o1, %l6
+
+       call    _dl_profile_save_regs
+        nop
+
+       add     %sp, STACK_BIAS, %o3
+       call    _dl_profile_fixup
+        add    %sp, (STACK_BIAS + (32 * 8)), %o4
+
+       ldx     [%sp + STACK_BIAS + (32 * 8)], %o1
+       brgez,pt %o1, 1f
+        nop
+
+       call    _dl_profile_invoke
+        nop
+
+1:     jmp     %o0
+        restore
+       .size   _dl_runtime_resolve_1, .-_dl_runtime_resolve_1
This page took 0.079908 seconds and 5 git commands to generate.