Blame sysdeps/sh/dl-machine.h

Packit Service 82fcde
/* Machine-dependent ELF dynamic relocation inline functions.  SH version.
Packit Service 82fcde
   Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifndef dl_machine_h
Packit Service 82fcde
#define dl_machine_h
Packit Service 82fcde
Packit Service 82fcde
#define ELF_MACHINE_NAME "SH"
Packit Service 82fcde
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
Packit Service 82fcde
/* Return nonzero iff ELF header is compatible with the running host.  */
Packit Service 82fcde
static inline int __attribute__ ((unused))
Packit Service 82fcde
elf_machine_matches_host (const Elf32_Ehdr *ehdr)
Packit Service 82fcde
{
Packit Service 82fcde
  return ehdr->e_machine == EM_SH;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
Packit Service 82fcde
   first element of the GOT.  This must be inlined in a function which
Packit Service 82fcde
   uses global data.  */
Packit Service 82fcde
static inline Elf32_Addr __attribute__ ((unused))
Packit Service 82fcde
elf_machine_dynamic (void)
Packit Service 82fcde
{
Packit Service 82fcde
  register Elf32_Addr *got;
Packit Service 82fcde
  asm ("mov r12,%0" :"=r" (got));
Packit Service 82fcde
  return *got;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Return the run-time load address of the shared object.  */
Packit Service 82fcde
static inline Elf32_Addr __attribute__ ((unused))
Packit Service 82fcde
elf_machine_load_address (void)
Packit Service 82fcde
{
Packit Service 82fcde
  Elf32_Addr addr;
Packit Service 82fcde
  asm ("mov.l 1f,r0\n\
Packit Service 82fcde
	mov.l 3f,r2\n\
Packit Service 82fcde
	add r12,r2\n\
Packit Service 82fcde
	mov.l @(r0,r12),r0\n\
Packit Service 82fcde
	bra 2f\n\
Packit Service 82fcde
	 sub r0,r2\n\
Packit Service 82fcde
	.align 2\n\
Packit Service 82fcde
	1: .long _dl_start@GOT\n\
Packit Service 82fcde
	3: .long _dl_start@GOTOFF\n\
Packit Service 82fcde
	2: mov r2,%0"
Packit Service 82fcde
       : "=r" (addr) : : "r0", "r1", "r2");
Packit Service 82fcde
  return addr;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Set up the loaded object described by L so its unrelocated PLT
Packit Service 82fcde
   entries will jump to the on-demand fixup code in dl-runtime.c.  */
Packit Service 82fcde
Packit Service 82fcde
static inline int __attribute__ ((unused, always_inline))
Packit Service 82fcde
elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
Packit Service 82fcde
{
Packit Service 82fcde
  Elf32_Addr *got;
Packit Service 82fcde
  extern void _dl_runtime_resolve (Elf32_Word);
Packit Service 82fcde
  extern void _dl_runtime_profile (Elf32_Word);
Packit Service 82fcde
Packit Service 82fcde
  if (l->l_info[DT_JMPREL] && lazy)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* The GOT entries for functions in the PLT have not yet been filled
Packit Service 82fcde
	 in.  Their initial contents will arrange when called to load an
Packit Service 82fcde
	 offset into the .rela.plt section and _GLOBAL_OFFSET_TABLE_[1],
Packit Service 82fcde
	 and then jump to _GLOBAL_OFFSET_TABLE[2].  */
Packit Service 82fcde
      got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
Packit Service 82fcde
      /* If a library is prelinked but we have to relocate anyway,
Packit Service 82fcde
	 we have to be able to undo the prelinking of .got.plt.
Packit Service 82fcde
	 The prelinker saved us here address of .plt + 36.  */
Packit Service 82fcde
      if (got[1])
Packit Service 82fcde
	{
Packit Service 82fcde
	  l->l_mach.plt = got[1] + l->l_addr;
Packit Service 82fcde
	  l->l_mach.gotplt = (Elf32_Addr) &got[3];
Packit Service 82fcde
	}
Packit Service 82fcde
      got[1] = (Elf32_Addr) l;	/* Identify this shared object.	 */
Packit Service 82fcde
Packit Service 82fcde
      /* The got[2] entry contains the address of a function which gets
Packit Service 82fcde
	 called to get the address of a so far unresolved function and
Packit Service 82fcde
	 jump to it.  The profiling extension of the dynamic linker allows
Packit Service 82fcde
	 to intercept the calls to collect information.	 In this case we
Packit Service 82fcde
	 don't store the address in the GOT so that all future calls also
Packit Service 82fcde
	 end in this function.	*/
Packit Service 82fcde
      if (profile)
Packit Service 82fcde
	{
Packit Service 82fcde
	  got[2] = (Elf32_Addr) &_dl_runtime_profile;
Packit Service 82fcde
	  /* Say that we really want profiling and the timers are started.  */
Packit Service 82fcde
	  if (GLRO(dl_profile) != NULL
Packit Service 82fcde
	      && _dl_name_match_p (GLRO(dl_profile), l))
Packit Service 82fcde
	    GL(dl_profile_map) = l;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	/* This function will get called to fix up the GOT entry indicated by
Packit Service 82fcde
	   the offset on the stack, and then jump to the resolved address.  */
Packit Service 82fcde
	got[2] = (Elf32_Addr) &_dl_runtime_resolve;
Packit Service 82fcde
    }
Packit Service 82fcde
  return lazy;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#define ELF_MACHINE_RUNTIME_FIXUP_ARGS int plt_type
Packit Service 82fcde
#define ELF_MACHINE_RUNTIME_FIXUP_PARAMS plt_type
Packit Service 82fcde
Packit Service 82fcde
/* Mask identifying addresses reserved for the user program,
Packit Service 82fcde
   where the dynamic linker should not map anything.  */
Packit Service 82fcde
#define ELF_MACHINE_USER_ADDRESS_MASK	0x80000000UL
Packit Service 82fcde
Packit Service 82fcde
/* Initial entry point code for the dynamic linker.
Packit Service 82fcde
   The C function `_dl_start' is the real entry point;
Packit Service 82fcde
   its return value is the user program's entry point.	*/
Packit Service 82fcde
Packit Service 82fcde
#define RTLD_START asm ("\
Packit Service 82fcde
.text\n\
Packit Service 82fcde
.globl _start\n\
Packit Service 82fcde
.globl _dl_start_user\n\
Packit Service 82fcde
_start:\n\
Packit Service 82fcde
	mov r15,r4\n\
Packit Service 82fcde
	mov.l .L_dl_start,r1\n\
Packit Service 82fcde
	mova .L_dl_start,r0\n\
Packit Service 82fcde
	add r1,r0\n\
Packit Service 82fcde
	jsr @r0\n\
Packit Service 82fcde
	 nop\n\
Packit Service 82fcde
_dl_start_user:\n\
Packit Service 82fcde
	! Save the user entry point address in r8.\n\
Packit Service 82fcde
	mov r0,r8\n\
Packit Service 82fcde
	! Point r12 at the GOT.\n\
Packit Service 82fcde
	mov.l 1f,r12\n\
Packit Service 82fcde
	mova 1f,r0\n\
Packit Service 82fcde
	bra 2f\n\
Packit Service 82fcde
	 add r0,r12\n\
Packit Service 82fcde
	.align 2\n\
Packit Service 82fcde
1:	.long _GLOBAL_OFFSET_TABLE_\n\
Packit Service 82fcde
2:	! See if we were run as a command with the executable file\n\
Packit Service 82fcde
	! name as an extra leading argument.\n\
Packit Service 82fcde
	mov.l .L_dl_skip_args,r0\n\
Packit Service 82fcde
	mov.l @(r0,r12),r0\n\
Packit Service 82fcde
	mov.l @r0,r0\n\
Packit Service 82fcde
	! Get the original argument count.\n\
Packit Service 82fcde
	mov.l @r15,r5\n\
Packit Service 82fcde
	! Subtract _dl_skip_args from it.\n\
Packit Service 82fcde
	sub r0,r5\n\
Packit Service 82fcde
	! Adjust the stack pointer to skip _dl_skip_args words.\n\
Packit Service 82fcde
	shll2 r0\n\
Packit Service 82fcde
	add r0,r15\n\
Packit Service 82fcde
	! Store back the modified argument count.\n\
Packit Service 82fcde
	mov.l r5,@r15\n\
Packit Service 82fcde
	! Compute argv address and envp.\n\
Packit Service 82fcde
	mov r15,r6\n\
Packit Service 82fcde
	add #4,r6\n\
Packit Service 82fcde
	mov r5,r7\n\
Packit Service 82fcde
	shll2 r7\n\
Packit Service 82fcde
	add r15,r7\n\
Packit Service 82fcde
	add #8,r7\n\
Packit Service 82fcde
	mov.l .L_dl_loaded,r0\n\
Packit Service 82fcde
	mov.l @(r0,r12),r0\n\
Packit Service 82fcde
	mov.l @r0,r4\n\
Packit Service 82fcde
	! Call _dl_init.\n\
Packit Service 82fcde
	mov.l .L_dl_init,r1\n\
Packit Service 82fcde
	mova .L_dl_init,r0\n\
Packit Service 82fcde
	add r1,r0\n\
Packit Service 82fcde
	jsr @r0\n\
Packit Service 82fcde
	 nop\n\
Packit Service 82fcde
1:	! Pass our finalizer function to the user in r4, as per ELF ABI.\n\
Packit Service 82fcde
	mov.l .L_dl_fini,r0\n\
Packit Service 82fcde
	mov.l @(r0,r12),r4\n\
Packit Service 82fcde
	! Jump to the user's entry point.\n\
Packit Service 82fcde
	jmp @r8\n\
Packit Service 82fcde
	 nop\n\
Packit Service 82fcde
	.align 2\n\
Packit Service 82fcde
.L_dl_start:\n\
Packit Service 82fcde
	.long _dl_start@PLT\n\
Packit Service 82fcde
.L_dl_skip_args:\n\
Packit Service 82fcde
	.long _dl_skip_args@GOT\n\
Packit Service 82fcde
.L_dl_init:\n\
Packit Service 82fcde
	.long _dl_init@PLT\n\
Packit Service 82fcde
.L_dl_loaded:\n\
Packit Service 82fcde
	.long _rtld_local@GOT\n\
Packit Service 82fcde
.L_dl_fini:\n\
Packit Service 82fcde
	.long _dl_fini@GOT\n\
Packit Service 82fcde
	.type __fpscr_values,@object\n\
Packit Service 82fcde
	.global __fpscr_values\n\
Packit Service 82fcde
__fpscr_values:\n\
Packit Service 82fcde
	.long   0\n\
Packit Service 82fcde
	.long   0x80000\n\
Packit Service 82fcde
	.weak __fpscr_values\n\
Packit Service 82fcde
.previous\n\
Packit Service 82fcde
");
Packit Service 82fcde
Packit Service 82fcde
/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
Packit Service 82fcde
   TLS variable, so undefined references should not be allowed to
Packit Service 82fcde
   define the value.
Packit Service 82fcde
   ELF_RTYPE_CLASS_COPY iff TYPE should not be allowed to resolve to one
Packit Service 82fcde
   of the main executable's symbols, as for a COPY reloc.  */
Packit Service 82fcde
#define elf_machine_type_class(type) \
Packit Service 82fcde
  ((((type) == R_SH_JMP_SLOT || (type) == R_SH_TLS_DTPMOD32		      \
Packit Service 82fcde
     || (type) == R_SH_TLS_DTPOFF32 || (type) == R_SH_TLS_TPOFF32)	      \
Packit Service 82fcde
    * ELF_RTYPE_CLASS_PLT)						      \
Packit Service 82fcde
   | (((type) == R_SH_COPY) * ELF_RTYPE_CLASS_COPY))
Packit Service 82fcde
Packit Service 82fcde
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries.  */
Packit Service 82fcde
#define ELF_MACHINE_JMP_SLOT	R_SH_JMP_SLOT
Packit Service 82fcde
Packit Service 82fcde
/* We define an initialization functions.  This is called very early in
Packit Service 82fcde
   _dl_sysdep_start.  */
Packit Service 82fcde
#define DL_PLATFORM_INIT dl_platform_init ()
Packit Service 82fcde
Packit Service 82fcde
static inline void __attribute__ ((unused))
Packit Service 82fcde
dl_platform_init (void)
Packit Service 82fcde
{
Packit Service 82fcde
  if (GLRO(dl_platform) != NULL && *GLRO(dl_platform) == '\0')
Packit Service 82fcde
    /* Avoid an empty string which would disturb us.  */
Packit Service 82fcde
    GLRO(dl_platform) = NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static inline Elf32_Addr
Packit Service 82fcde
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
Packit Service 82fcde
		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
Packit Service 82fcde
		       const Elf32_Rela *reloc,
Packit Service 82fcde
		       Elf32_Addr *reloc_addr, Elf32_Addr value)
Packit Service 82fcde
{
Packit Service 82fcde
  return *reloc_addr = value;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Return the final value of a plt relocation.	*/
Packit Service 82fcde
static inline Elf32_Addr
Packit Service 82fcde
elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
Packit Service 82fcde
		       Elf32_Addr value)
Packit Service 82fcde
{
Packit Service 82fcde
  return value + reloc->r_addend;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#define ARCH_LA_PLTENTER sh_gnu_pltenter
Packit Service 82fcde
#define ARCH_LA_PLTEXIT sh_gnu_pltexit
Packit Service 82fcde
Packit Service 82fcde
#endif /* !dl_machine_h */
Packit Service 82fcde
Packit Service 82fcde
/* SH never uses Elf32_Rel relocations.	 */
Packit Service 82fcde
#define ELF_MACHINE_NO_REL 1
Packit Service 82fcde
#define ELF_MACHINE_NO_RELA 0
Packit Service 82fcde
Packit Service 82fcde
#ifdef RESOLVE_MAP
Packit Service 82fcde
Packit Service 82fcde
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
Packit Service 82fcde
   MAP is the object containing the reloc.  */
Packit Service 82fcde
Packit Service 82fcde
auto inline void
Packit Service 82fcde
__attribute ((always_inline))
Packit Service 82fcde
elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
Packit Service 82fcde
		  const Elf32_Sym *sym, const struct r_found_version *version,
Packit Service 82fcde
		  void *const reloc_addr_arg, int skip_ifunc)
Packit Service 82fcde
{
Packit Service 82fcde
  Elf32_Addr *const reloc_addr = reloc_addr_arg;
Packit Service 82fcde
  const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
Packit Service 82fcde
  Elf32_Addr value;
Packit Service 82fcde
Packit Service 82fcde
#define COPY_UNALIGNED_WORD(swp, twp, align) \
Packit Service 82fcde
  { \
Packit Service 82fcde
    void *__s = (swp), *__t = (twp); \
Packit Service 82fcde
    unsigned char *__s1 = __s, *__t1 = __t; \
Packit Service 82fcde
    unsigned short *__s2 = __s, *__t2 = __t; \
Packit Service 82fcde
    unsigned long *__s4 = __s, *__t4 = __t; \
Packit Service 82fcde
    switch ((align)) \
Packit Service 82fcde
    { \
Packit Service 82fcde
    case 0: \
Packit Service 82fcde
      *__t4 = *__s4; \
Packit Service 82fcde
      break; \
Packit Service 82fcde
    case 2: \
Packit Service 82fcde
      *__t2++ = *__s2++; \
Packit Service 82fcde
      *__t2 = *__s2; \
Packit Service 82fcde
      break; \
Packit Service 82fcde
    default: \
Packit Service 82fcde
      *__t1++ = *__s1++; \
Packit Service 82fcde
      *__t1++ = *__s1++; \
Packit Service 82fcde
      *__t1++ = *__s1++; \
Packit Service 82fcde
      *__t1 = *__s1; \
Packit Service 82fcde
      break; \
Packit Service 82fcde
    } \
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (r_type == R_SH_RELATIVE))
Packit Service 82fcde
    {
Packit Service 82fcde
#ifndef RTLD_BOOTSTRAP
Packit Service 82fcde
      if (map != &GL(dl_rtld_map)) /* Already done in rtld itself.	 */
Packit Service 82fcde
#endif
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (reloc->r_addend)
Packit Service 82fcde
	    value = map->l_addr + reloc->r_addend;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      COPY_UNALIGNED_WORD (reloc_addr_arg, &value,
Packit Service 82fcde
				   (int) reloc_addr_arg & 3);
Packit Service 82fcde
	      value += map->l_addr;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
Packit Service 82fcde
			       (int) reloc_addr_arg & 3);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
#ifndef RTLD_BOOTSTRAP
Packit Service 82fcde
  else if (__glibc_unlikely (r_type == R_SH_NONE))
Packit Service 82fcde
    return;
Packit Service 82fcde
#endif
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      const Elf32_Sym *const refsym = sym;
Packit Service 82fcde
      struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
Packit Service 82fcde
Packit Service 82fcde
      value = SYMBOL_ADDRESS (sym_map, sym, true);
Packit Service 82fcde
      value += reloc->r_addend;
Packit Service 82fcde
Packit Service 82fcde
      switch (r_type)
Packit Service 82fcde
	{
Packit Service 82fcde
	case R_SH_COPY:
Packit Service 82fcde
	  if (sym == NULL)
Packit Service 82fcde
	    /* This can happen in trace mode if an object could not be
Packit Service 82fcde
	       found.  */
Packit Service 82fcde
	    break;
Packit Service 82fcde
	  if (sym->st_size > refsym->st_size
Packit Service 82fcde
	      || (sym->st_size < refsym->st_size && GLRO(dl_verbose)))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      const char *strtab;
Packit Service 82fcde
Packit Service 82fcde
	      strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
Packit Service 82fcde
	      _dl_error_printf ("\
Packit Service 82fcde
%s: Symbol `%s' has different size in shared object, consider re-linking\n",
Packit Service 82fcde
				RTLD_PROGNAME, strtab + refsym->st_name);
Packit Service 82fcde
	    }
Packit Service 82fcde
	  memcpy (reloc_addr_arg, (void *) value,
Packit Service 82fcde
		  MIN (sym->st_size, refsym->st_size));
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case R_SH_GLOB_DAT:
Packit Service 82fcde
	case R_SH_JMP_SLOT:
Packit Service 82fcde
	  /* These addresses are always aligned.  */
Packit Service 82fcde
	  *reloc_addr = value;
Packit Service 82fcde
	  break;
Packit Service 82fcde
	  /* XXX Remove TLS relocations which are not needed.  */
Packit Service 82fcde
	case R_SH_TLS_DTPMOD32:
Packit Service 82fcde
#ifdef RTLD_BOOTSTRAP
Packit Service 82fcde
	  /* During startup the dynamic linker is always the module
Packit Service 82fcde
	     with index 1.
Packit Service 82fcde
	     XXX If this relocation is necessary move before RESOLVE
Packit Service 82fcde
	     call.  */
Packit Service 82fcde
	  *reloc_addr = 1;
Packit Service 82fcde
#else
Packit Service 82fcde
	  /* Get the information from the link map returned by the
Packit Service 82fcde
	     resolv function.  */
Packit Service 82fcde
	  if (sym_map != NULL)
Packit Service 82fcde
	    *reloc_addr = sym_map->l_tls_modid;
Packit Service 82fcde
#endif
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case R_SH_TLS_DTPOFF32:
Packit Service 82fcde
#ifndef RTLD_BOOTSTRAP
Packit Service 82fcde
	  /* During relocation all TLS symbols are defined and used.
Packit Service 82fcde
	     Therefore the offset is already correct.  */
Packit Service 82fcde
	  if (sym != NULL)
Packit Service 82fcde
	    *reloc_addr = sym->st_value;
Packit Service 82fcde
#endif
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case R_SH_TLS_TPOFF32:
Packit Service 82fcde
	  /* The offset is positive, afterward from the thread pointer.  */
Packit Service 82fcde
#ifdef RTLD_BOOTSTRAP
Packit Service 82fcde
	  *reloc_addr = map->l_tls_offset + sym->st_value + reloc->r_addend;
Packit Service 82fcde
#else
Packit Service 82fcde
	  /* We know the offset of object the symbol is contained in.
Packit Service 82fcde
	     It is a positive value which will be added to the thread
Packit Service 82fcde
	     pointer.  To get the variable position in the TLS block
Packit Service 82fcde
	     we add the offset from that of the TLS block.  */
Packit Service 82fcde
	  if (sym != NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      CHECK_STATIC_TLS (map, sym_map);
Packit Service 82fcde
	      *reloc_addr = sym_map->l_tls_offset + sym->st_value
Packit Service 82fcde
			    + reloc->r_addend;
Packit Service 82fcde
	    }
Packit Service 82fcde
#endif
Packit Service 82fcde
	  break;
Packit Service 82fcde
	case R_SH_DIR32:
Packit Service 82fcde
	  {
Packit Service 82fcde
#if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP
Packit Service 82fcde
	   /* This is defined in rtld.c, but nowhere in the static
Packit Service 82fcde
	      libc.a; make the reference weak so static programs can
Packit Service 82fcde
	      still link.  This declaration cannot be done when
Packit Service 82fcde
	      compiling rtld.c (i.e. #ifdef RTLD_BOOTSTRAP) because
Packit Service 82fcde
	      rtld.c contains the common defn for _dl_rtld_map, which
Packit Service 82fcde
	      is incompatible with a weak decl in the same file.  */
Packit Service 82fcde
# ifndef SHARED
Packit Service 82fcde
	    weak_extern (_dl_rtld_map);
Packit Service 82fcde
# endif
Packit Service 82fcde
	    if (map == &GL(dl_rtld_map))
Packit Service 82fcde
	      /* Undo the relocation done here during bootstrapping.
Packit Service 82fcde
		 Now we will relocate it anew, possibly using a
Packit Service 82fcde
		 binding found in the user program or a loaded library
Packit Service 82fcde
		 rather than the dynamic linker's built-in definitions
Packit Service 82fcde
		 used while loading those libraries.  */
Packit Service 82fcde
	      value -= SYMBOL_ADDRESS (map, refsym, true) + reloc->r_addend;
Packit Service 82fcde
#endif
Packit Service 82fcde
	    COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
Packit Service 82fcde
				 (int) reloc_addr_arg & 3);
Packit Service 82fcde
	    break;
Packit Service 82fcde
	  }
Packit Service 82fcde
	case R_SH_REL32:
Packit Service 82fcde
	  value = (value - (Elf32_Addr) reloc_addr);
Packit Service 82fcde
	  COPY_UNALIGNED_WORD (&value, reloc_addr_arg,
Packit Service 82fcde
			       (int) reloc_addr_arg & 3);
Packit Service 82fcde
	  break;
Packit Service 82fcde
	default:
Packit Service 82fcde
	  _dl_reloc_bad_type (map, r_type, 0);
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
auto inline void
Packit Service 82fcde
__attribute__ ((always_inline))
Packit Service 82fcde
elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Packit Service 82fcde
			   void *const reloc_addr_arg)
Packit Service 82fcde
{
Packit Service 82fcde
  Elf32_Addr value;
Packit Service 82fcde
Packit Service 82fcde
  if (reloc->r_addend)
Packit Service 82fcde
    value = l_addr + reloc->r_addend;
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      COPY_UNALIGNED_WORD (reloc_addr_arg, &value, (int) reloc_addr_arg & 3);
Packit Service 82fcde
      value += l_addr;
Packit Service 82fcde
    }
Packit Service 82fcde
  COPY_UNALIGNED_WORD (&value, reloc_addr_arg, (int) reloc_addr_arg & 3);
Packit Service 82fcde
Packit Service 82fcde
#undef COPY_UNALIGNED_WORD
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
auto inline void
Packit Service 82fcde
__attribute__ ((always_inline))
Packit Service 82fcde
elf_machine_lazy_rel (struct link_map *map,
Packit Service 82fcde
		      Elf32_Addr l_addr, const Elf32_Rela *reloc,
Packit Service 82fcde
		      int skip_ifunc)
Packit Service 82fcde
{
Packit Service 82fcde
  Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset);
Packit Service 82fcde
  /* Check for unexpected PLT reloc type.  */
Packit Service 82fcde
  if (ELF32_R_TYPE (reloc->r_info) == R_SH_JMP_SLOT)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (__builtin_expect (map->l_mach.plt, 0) == 0)
Packit Service 82fcde
	*reloc_addr += l_addr;
Packit Service 82fcde
      else
Packit Service 82fcde
	*reloc_addr =
Packit Service 82fcde
	  map->l_mach.plt
Packit Service 82fcde
	  + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 7;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#endif /* RESOLVE_MAP */