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.

Defines

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

Functions

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;
  DL_FIXUP_VALUE_TYPE value;

  /* 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;
      if (!RTLD_SINGLE_THREAD_P)
       {
         THREAD_GSCOPE_SET_FLAG ();
         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.  */
      if (!RTLD_SINGLE_THREAD_P)
       THREAD_GSCOPE_RESET_FLAG ();

      /* 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);
    }
  else
    {
      /* 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,
                                       l_info[DT_SYMTAB])
                     + 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,
                                        l_info[DT_STRTAB]);
  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,
                             &l->l_audit[cnt].cookie,
                             &reloc_result->bound->l_audit[cnt].cookie,
                             inregs, outregs, symname);
       }

      afct = afct->next;
    }
#endif
}