]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/m68k/dl-machine.h
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / m68k / dl-machine.h
index e52893889ddf076b775deb14fc7b4070df7d031e..2a8b3cdd04caad149563c215f82a8699e2126094 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  m68k version.
-   Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2019 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
@@ -13,9 +13,8 @@
    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.  */
+   License along with the GNU C Library.  If not, see
+   <http://www.gnu.org/licenses/>.  */
 
 #ifndef dl_machine_h
 #define dl_machine_h
@@ -23,6 +22,8 @@
 #define ELF_MACHINE_NAME "m68k"
 
 #include <sys/param.h>
+#include <sysdep.h>
+#include <dl-tls.h>
 
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int
@@ -32,14 +33,16 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
 }
 
 
-/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
-   first element of the GOT.  This must be inlined in a function which
-   uses global data.  */
+/* Return the link-time address of _DYNAMIC.
+   This must be inlined in a function which uses global data.  */
 static inline Elf32_Addr
 elf_machine_dynamic (void)
 {
-  register Elf32_Addr *got asm ("%a5");
-  return *got;
+  Elf32_Addr addr;
+
+  asm ("move.l _DYNAMIC@GOT.w(%%a5), %0"
+       : "=a" (addr));
+  return addr;
 }
 
 
@@ -48,9 +51,15 @@ static inline Elf32_Addr
 elf_machine_load_address (void)
 {
   Elf32_Addr addr;
-  asm ("lea _dl_start(%%pc), %0\n\t"
+#ifdef SHARED
+  asm (PCREL_OP ("lea", "_dl_start", "%0", "%0", "%%pc") "\n\t"
        "sub.l _dl_start@GOT.w(%%a5), %0"
        : "=a" (addr));
+#else
+  asm (PCREL_OP ("lea", "_dl_relocate_static_pie", "%0", "%0", "%%pc") "\n\t"
+       "sub.l _dl_relocate_static_pie@GOT.w(%%a5), %0"
+       : "=a" (addr));
+#endif
   return addr;
 }
 
@@ -85,7 +94,8 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
        {
          got[2] = (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))
            {
              /* This is the object we are looking for.  Say that we really
                 want profiling and the timers are started.  */
@@ -101,37 +111,8 @@ 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) \
-"| Trampoline for " #fixup_name "\n\
-       .globl " #tramp_name "\n\
-       .type " #tramp_name ", @function\n\
-" #tramp_name ":\n\
-       | Save %a0 (struct return address) and %a1.\n\
-       move.l %a0, -(%sp)\n\
-       move.l %a1, -(%sp)\n\
-       | Call the real address resolver.\n\
-       jbsr " #fixup_name "\n\
-       | Restore register %a0 and %a1.\n\
-       move.l (%sp)+, %a1\n\
-       move.l (%sp)+, %a0\n\
-       | Pop parameters\n\
-       addq.l #8, %sp\n\
-       | Call real function.\n\
-       jmp (%d0)\n\
-       .size " #tramp_name ", . - " #tramp_name "\n"
-#ifndef PROF
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
-asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \
-     TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup));
-#else
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE \
-asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \
-     ".globl _dl_runtime_profile\n" \
-     ".set _dl_runtime_profile, _dl_runtime_resolve");
-#endif
 #define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0, long int save_a1
+#define ELF_MACHINE_RUNTIME_FIXUP_PARAMS save_a0, save_a1
 
 
 /* Mask identifying addresses reserved for the user program,
@@ -147,6 +128,7 @@ asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \
        .globl _start\n\
        .type _start,@function\n\
 _start:\n\
+       sub.l %fp, %fp\n\
        move.l %sp, -(%sp)\n\
        jbsr _dl_start\n\
        addq.l #4, %sp\n\
@@ -159,7 +141,7 @@ _dl_start_user:\n\
        move.l %d0, %a4\n\
        | See if we were run as a command with the executable file\n\
        | name as an extra leading argument.\n\
-       move.l _dl_skip_args(%pc), %d0\n\
+       " PCREL_OP ("move.l", "_dl_skip_args", "%d0", "%d0", "%pc") "\n\
        | Pop the original argument count\n\
        move.l (%sp)+, %d1\n\
        | Subtract _dl_skip_args from it.\n\
@@ -172,12 +154,12 @@ _dl_start_user:\n\
        pea 8(%sp, %d1*4)\n\
        pea 8(%sp)\n\
        move.l %d1, -(%sp)\n\
-       move.l _rtld_local(%pc), -(%sp)\n\
-       jbsr _dl_init_internal@PLTPC\n\
+       " PCREL_OP ("move.l", "_rtld_local", "-(%sp)", "%d0", "%pc") "\n\
+       jbsr _dl_init\n\
        addq.l #8, %sp\n\
        addq.l #8, %sp\n\
        | Pass our finalizer function to the user in %a1.\n\
-       lea _dl_fini(%pc), %a1\n\
+       " PCREL_OP ("lea", "_dl_fini", "%a1", "%a1", "%pc") "\n\
        | Initialize %fp with the stack pointer.\n\
        move.l %sp, %fp\n\
        | Jump to the user's entry point.\n\
@@ -185,12 +167,16 @@ _dl_start_user:\n\
        .size _dl_start_user, . - _dl_start_user\n\
        .previous");
 
-/* 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
+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
+   TLS variable, so undefined references should not be allowed to
+   define the value.
+   ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
    of the main executable's symbols, as for a COPY reloc.  */
 #define elf_machine_type_class(type) \
-  ((((type) == R_68K_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)  \
+  ((((type) == R_68K_JMP_SLOT       \
+     || (type) == R_68K_TLS_DTPMOD32 \
+     || (type) == R_68K_TLS_DTPREL32 \
+     || (type) == R_68K_TLS_TPREL32) * ELF_RTYPE_CLASS_PLT)    \
    | (((type) == R_68K_COPY) * ELF_RTYPE_CLASS_COPY))
 
 /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
@@ -198,9 +184,11 @@ _dl_start_user:\n\
 
 /* The m68k never uses Elf32_Rel relocations.  */
 #define ELF_MACHINE_NO_REL 1
+#define ELF_MACHINE_NO_RELA 0
 
 static inline Elf32_Addr
 elf_machine_fixup_plt (struct link_map *map, lookup_t t,
+                      const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
                       const Elf32_Rela *reloc,
                       Elf32_Addr *reloc_addr, Elf32_Addr value)
 {
@@ -216,17 +204,21 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
   return value;
 }
 
+/* Names of the architecture-specific auditing callback functions.  */
+#define ARCH_LA_PLTENTER m68k_gnu_pltenter
+#define ARCH_LA_PLTEXIT m68k_gnu_pltexit
+
 #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 __attribute__ ((always_inline))
+auto inline void __attribute__ ((unused, always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
                  const Elf32_Sym *sym, const struct r_found_version *version,
-                 void *const reloc_addr_arg)
+                 void *const reloc_addr_arg, int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
@@ -236,9 +228,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
   else
     {
       const Elf32_Sym *const refsym = sym;
-      Elf32_Addr value = RESOLVE (&sym, version, r_type);
-      if (sym)
-       value += sym->st_value;
+      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
+      Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true);
 
       switch (r_type)
        {
@@ -255,8 +246,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
              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);
+                               RTLD_PROGNAME, strtab + refsym->st_name);
            }
          memcpy (reloc_addr_arg, (void *) value,
                  MIN (sym->st_size, refsym->st_size));
@@ -285,6 +275,25 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
        case R_68K_PC32:
          *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr;
          break;
+#ifndef RTLD_BOOTSTRAP
+       case R_68K_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_68K_TLS_DTPREL32:
+         if (sym != NULL)
+           *reloc_addr = TLS_DTPREL_VALUE (sym, reloc);
+         break;
+       case R_68K_TLS_TPREL32:
+         if (sym != NULL)
+           {
+             CHECK_STATIC_TLS (map, sym_map);
+             *reloc_addr = TLS_TPREL_VALUE (sym_map, sym, reloc);
+           }
+         break;
+#endif /* !RTLD_BOOTSTRAP */
        case R_68K_NONE:                /* Alright, Wilbur.  */
          break;
        default:
@@ -294,7 +303,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-static inline void
+auto inline void __attribute__ ((unused, always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
                           void *const reloc_addr_arg)
 {
@@ -302,9 +311,10 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-static inline void
+auto inline void __attribute__ ((unused, always_inline))
 elf_machine_lazy_rel (struct link_map *map,
-                     Elf32_Addr l_addr, const Elf32_Rela *reloc)
+                     Elf32_Addr l_addr, const Elf32_Rela *reloc,
+                     int skip_ifunc)
 {
   Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
   if (ELF32_R_TYPE (reloc->r_info) == R_68K_JMP_SLOT)
@@ -313,4 +323,4 @@ elf_machine_lazy_rel (struct link_map *map,
     _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1);
 }
 
-#endif /* RESOLVE */
+#endif /* RESOLVE_MAP */