Blame sysdeps/generic/dl-machine.h

Packit 6c4009
/* Machine-dependent ELF dynamic relocation inline functions.  Stub version.
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#define ELF_MACHINE_NAME "stub"
Packit 6c4009
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <link.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return nonzero iff ELF header is compatible with the running host.  */
Packit 6c4009
static inline int
Packit 6c4009
elf_machine_matches_host (const Elf32_Ehdr *ehdr)
Packit 6c4009
{
Packit 6c4009
  switch (ehdr->e_machine)
Packit 6c4009
    {
Packit 6c4009
    default:
Packit 6c4009
      return 0;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return the link-time address of _DYNAMIC.  */
Packit 6c4009
static inline Elf32_Addr
Packit 6c4009
elf_machine_dynamic (void)
Packit 6c4009
{
Packit 6c4009
#error "Damn, no _DYNAMIC"
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return the run-time load address of the shared object.  */
Packit 6c4009
static inline Elf32_Addr
Packit 6c4009
elf_machine_load_address (void)
Packit 6c4009
{
Packit 6c4009
#error "Where am I?"
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Fixup a PLT entry to bounce directly to the function at VALUE.  */
Packit 6c4009
Packit 6c4009
static inline ElfW(Addr)
Packit 6c4009
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
Packit 6c4009
		       const ElfW(Sym) *refsym, const ElfW(Sym) *sym,
Packit 6c4009
		       const ElfW(Rel) *reloc,
Packit 6c4009
		       ElfW(Addr) *reloc_addr, ElfW(Addr) value)
Packit 6c4009
{
Packit 6c4009
  return *reloc_addr = value;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
Packit 6c4009
   LOADADDR is the load address of the object; INFO is an array indexed
Packit 6c4009
   by DT_* of the .dynamic section info.  */
Packit 6c4009
Packit 6c4009
auto inline void
Packit 6c4009
__attribute__ ((always_inline))
Packit 6c4009
elf_machine_rel (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
Packit 6c4009
		 const Elf32_Rel *reloc, const Elf32_Sym *sym,
Packit 6c4009
		 Elf32_Addr (*resolve) (const Elf32_Sym **ref,
Packit 6c4009
					Elf32_Addr reloc_addr,
Packit 6c4009
					int noplt))
Packit 6c4009
{
Packit 6c4009
  Elf32_Addr *const reloc_addr = (Elf32_Addr *) reloc->r_offset;
Packit 6c4009
  Elf32_Addr loadbase;
Packit 6c4009
Packit 6c4009
  switch (ELF32_R_TYPE (reloc->r_info))
Packit 6c4009
    {
Packit 6c4009
    case R_MACHINE_COPY:
Packit 6c4009
      loadbase = (*resolve) (&sym, (Elf32_Addr) reloc_addr, 0);
Packit 6c4009
      memcpy (reloc_addr, (void *) (loadbase + sym->st_value), sym->st_size);
Packit 6c4009
      break;
Packit 6c4009
    default:
Packit 6c4009
      _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 0);
Packit 6c4009
      break;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
auto inline Elf32_Addr
Packit 6c4009
__attribute__ ((always_inline))
Packit 6c4009
elf_machine_rela (Elf32_Addr loadaddr, Elf32_Dyn *info[DT_NUM],
Packit 6c4009
		  const Elf32_Rel *reloc, const Elf32_Sym *sym,
Packit 6c4009
		  Elf32_Addr (*resolve) (const Elf32_Sym **ref,
Packit 6c4009
					 Elf32_Addr reloc_addr,
Packit 6c4009
					 int noplt))
Packit 6c4009
{
Packit 6c4009
  _dl_signal_error (0, "Elf32_Rela relocation requested -- unused on "
Packit 6c4009
		    NULL, ELF_MACHINE_NAME);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Set up the loaded object described by L so its unrelocated PLT
Packit 6c4009
   entries will jump to the on-demand fixup code in dl-runtime.c.  */
Packit 6c4009
Packit 6c4009
static inline int
Packit 6c4009
elf_machine_runtime_setup (struct link_map *l, int lazy)
Packit 6c4009
{
Packit 6c4009
  extern void _dl_runtime_resolve (Elf32_Word);
Packit 6c4009
Packit 6c4009
  if (lazy)
Packit 6c4009
    {
Packit 6c4009
      /* The GOT entries for functions in the PLT have not yet been filled
Packit 6c4009
         in.  Their initial contents will arrange when called to push an
Packit 6c4009
         offset into the .rel.plt section, push _GLOBAL_OFFSET_TABLE_[1],
Packit 6c4009
         and then jump to _GLOBAL_OFFSET_TABLE[2].  */
Packit 6c4009
      Elf32_Addr *got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
Packit 6c4009
      got[1] = (Elf32_Addr) l;	/* Identify this shared object.  */
Packit 6c4009
Packit 6c4009
      /* This function will get called to fix up the GOT entry indicated by
Packit 6c4009
         the offset on the stack, and then jump to the resolved address.  */
Packit 6c4009
      got[2] = (Elf32_Addr) &_dl_runtime_resolve;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return lazy;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Initial entry point code for the dynamic linker.
Packit 6c4009
   The C function `_dl_start' is the real entry point;
Packit 6c4009
   its return value is the user program's entry point.  */
Packit 6c4009
Packit 6c4009
#define RTLD_START #error need some startup code