Back to index

glibc  2.9
Defines | Functions
dl-runtime.c File Reference
#include <alloca.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <ldsodefs.h>
#include <sysdep-cancel.h>
#include "dynamic-link.h"
#include <tls.h>
#include <stdio.h>

Go to the source code of this file.


#define IN_DL_RUNTIME   1 /* This can be tested in dl-machine.h. */
#define PLTREL   ElfW(Rela)


DL_FIXUP_VALUE_TYPE __attribute ((noinline))
void ARCH_FIXUP_ATTRIBUTE _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_offset, const void *inregs, void *outregs)

Define Documentation

Definition at line 46 of file dl-runtime.c.

#define IN_DL_RUNTIME   1 /* This can be tested in dl-machine.h. */

Definition at line 20 of file dl-runtime.c.

#define PLTREL   ElfW(Rela)

Definition at line 34 of file dl-runtime.c.

Function Documentation

static int __attribute ( (noinline)  )

Definition at line 59 of file dl-runtime.c.

  const ElfW(Sym) *const symtab
    = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);

  const PLTREL *const reloc
    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
  const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
  void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
  lookup_t result;

  /* Sanity check that we're really looking at a PLT relocation.  */
  assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);

   /* Look up the target symbol.  If the normal lookup rules are not
      used don't look in the global scope.  */
  if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
      const struct r_found_version *version = NULL;

      if (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
         const ElfW(Half) *vernum =
           (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
         ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)] & 0x7fff;
         version = &l->l_versions[ndx];
         if (version->hash == 0)
           version = NULL;

      /* We need to keep the scope around so do some locking.  This is
        not necessary for objects which cannot be unloaded or when
        we are not using any threads (yet).  */
      int flags = DL_LOOKUP_ADD_DEPENDENCY;
         flags |= DL_LOOKUP_GSCOPE_LOCK;

      result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
                                version, ELF_RTYPE_CLASS_PLT, flags, NULL);

      /* We are done with the global scope.  */

      /* Currently result contains the base load address (or link map)
        of the object that defines sym.  Now add in the symbol
        offset.  */
      value = DL_FIXUP_MAKE_VALUE (result,
                               sym ? (LOOKUP_VALUE_ADDRESS (result)
                                     + sym->st_value) : 0);
      /* We already found the symbol.  The module (and therefore its load
        address) is also known.  */
      value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + sym->st_value);
      result = l;

  /* And now perhaps the relocation addend.  */
  value = elf_machine_plt_value (l, reloc, value);

  /* Finally, fix up the plt itself.  */
  if (__builtin_expect (GLRO(dl_bind_not), 0))
    return value;

  return elf_machine_fixup_plt (l, result, reloc, rel_addr, value);

Here is the call graph for this function:

void ARCH_FIXUP_ATTRIBUTE _dl_call_pltexit ( struct link_map l,
ElfW(Word)  reloc_offset,
const void *  inregs,
void *  outregs 

Definition at line 406 of file dl-runtime.c.

#ifdef SHARED
  /* This is the address in the array where we store the result of previous
     relocations.  */
  // XXX Maybe the bound information must be stored on the stack since
  // XXX with bind_not a new value could have been stored in the meantime.
  struct reloc_result *reloc_result
    = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
  ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
                     + reloc_result->boundndx);

  /* Set up the sym parameter.  */
  ElfW(Sym) sym = *defsym;

  /* Get the symbol name.  */
  const char *strtab = (const void *) D_PTR (reloc_result->bound,
  const char *symname = strtab + sym.st_name;

  struct audit_ifaces *afct = GLRO(dl_audit);
  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
      if (afct->ARCH_LA_PLTEXIT != NULL
         && (reloc_result->enterexit
             & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
         afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
                             inregs, outregs, symname);

      afct = afct->next;