Ejemplo n.º 1
0
void
_dl_relocate_static_pie (void)
{
  struct link_map *main_map = _dl_get_dl_main_map ();

# define STATIC_PIE_BOOTSTRAP
# define BOOTSTRAP_MAP (main_map)
# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
# include "dynamic-link.h"

  /* Figure out the run-time load address of static PIE.  */
  main_map->l_addr = elf_machine_load_address ();

  /* Read our own dynamic section and fill in the info array.  */
  main_map->l_ld = ((void *) main_map->l_addr + elf_machine_dynamic ());
  elf_get_dynamic_info (main_map, NULL);

# ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
  ELF_MACHINE_BEFORE_RTLD_RELOC (main_map->l_info);
# endif

  /* Relocate ourselves so we can do normal function calls and
     data access using the global offset table.  */
  ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0);
  main_map->l_relocated = 1;

  /* Initialize _r_debug.  */
  struct r_debug *r = _dl_debug_initialize (0, LM_ID_BASE);
  r->r_state = RT_CONSISTENT;

  /* Set up debugging before the debugger is notified for the first
     time.  */
# ifdef ELF_MACHINE_DEBUG_SETUP
  /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way.  */
  ELF_MACHINE_DEBUG_SETUP (main_map, r);
# else
  if (main_map->l_info[DT_DEBUG] != NULL)
    /* There is a DT_DEBUG entry in the dynamic section.  Fill it in
       with the run-time address of the r_debug structure  */
    main_map->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
# endif
}
Ejemplo n.º 2
0
void
_dl_relocate_object (struct link_map *l, struct link_map *scope[], int lazy)
{
  if (l->l_relocated)
    return;

  if (l->l_info[DT_TEXTREL])
    {
      /* Bletch.  We must make read-only segments writable
	 long enough to relocate them.  */
      const ElfW(Phdr) *ph;
      for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
	if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
	  {
	    caddr_t mapstart = ((caddr_t) l->l_addr +
				(ph->p_vaddr & ~(_dl_pagesize - 1)));
	    caddr_t mapend = ((caddr_t) l->l_addr +
			      ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
			       & ~(_dl_pagesize - 1)));
	    if (__mprotect (mapstart, mapend - mapstart,
			    PROT_READ|PROT_WRITE) < 0)
	      _dl_signal_error (errno, l->l_name,
				"cannot make segment writable for relocation");
	  }
    }

  {
    /* Do the actual relocation of the object's GOT and other data.  */

    const char *strtab		/* String table object symbols.  */
      = ((void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);

    /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
#define RESOLVE(ref, flags) \
    (_dl_lookup_symbol (strtab + (*ref)->st_name, ref, scope, \
			l->l_name, flags))

#include "dynamic-link.h"
    ELF_DYNAMIC_RELOCATE (l, lazy);
  }

  /* Set up the PLT so its unrelocated entries will jump to
     _dl_runtime_resolve (dl-runtime.c), which will relocate them.  */
  elf_machine_runtime_setup (l, lazy);

  /* Mark the object so we know ths work has been done.  */
  l->l_relocated = 1;

  if (l->l_info[DT_TEXTREL])
    {
      /* Undo the protection change we made before relocating.  */
      const ElfW(Phdr) *ph;
      for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
	if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
	  {
	    caddr_t mapstart = ((caddr_t) l->l_addr +
				(ph->p_vaddr & ~(_dl_pagesize - 1)));
	    caddr_t mapend = ((caddr_t) l->l_addr +
			      ((ph->p_vaddr + ph->p_memsz + _dl_pagesize - 1)
			       & ~(_dl_pagesize - 1)));
	    int prot = 0;
	    if (ph->p_flags & PF_R)
	      prot |= PROT_READ;
	    if (ph->p_flags & PF_X)
	      prot |= PROT_EXEC;
	    if (__mprotect (mapstart, mapend - mapstart, prot) < 0)
	      _dl_signal_error (errno, l->l_name,
				"can't restore segment prot after reloc");
	  }
    }
}