Back to index

glibc  2.9
Defines | Functions | Variables
dl-trampoline.c File Reference
#include <sysdep.h>
#include <link.h>
#include <elf.h>
#include <ldsodefs.h>
#include <dl-machine.h>

Go to the source code of this file.

Defines

#define VERSYMIDX(sym)   (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
#define ELF_DL_FRAME_SIZE   40
#define ELF_DL_SAVE_ARG_REGS   "\ sw $15, 36($29)\n \ sw $4, 16($29)\n \ sw $5, 20($29)\n \ sw $6, 24($29)\n \ sw $7, 28($29)\n \"
#define ELF_DL_RESTORE_ARG_REGS   "\ lw $31, 36($29)\n \ lw $4, 16($29)\n \ lw $5, 20($29)\n \ lw $6, 24($29)\n \ lw $7, 28($29)\n \"
#define ELF_DL_PLT_FRAME_SIZE   48
#define ELF_DL_PLT_SAVE_ARG_REGS   ELF_DL_SAVE_ARG_REGS "\ sw $2, 40($29)\n \ sw $3, 44($29)\n \"
#define ELF_DL_PLT_RESTORE_ARG_REGS   ELF_DL_RESTORE_ARG_REGS "\ lw $2, 40($29)\n \ lw $3, 44($29)\n \"
#define IFABIO32(X)   X
#define IFNEWABI(X)

Functions

static struct link_mapelf_machine_runtime_link_map (ElfW(Addr) gpreg, ElfW(Addr) stub_pc)
static ElfW (Addr)
 asm ("\n\ .text\n\ .align 2\n\ .globl _dl_runtime_resolve\n\ .type _dl_runtime_resolve,@function\n\ .ent _dl_runtime_resolve\n\ _dl_runtime_resolve:\n\ .frame $29, "STRINGXP(ELF_DL_FRAME_SIZE)", $31\n\ .set noreorder\n\ # Save GP.\n\ move $3, $28\n\ # Save arguments and sp value in stack.\n\ "STRINGXP(PTR_SUBIU)" $29, "STRINGXP(ELF_DL_FRAME_SIZE)"\n\ # Modify t9 ($25) so as to point .cpload instruction.\n\ "IFABIO32(STRINGXP(PTR_ADDIU)" $25, 12\n")"\ # Compute GP.\n\ "STRINGXP(SETUP_GP)"\n\ "STRINGXV(SETUP_GP64(0, _dl_runtime_resolve))"\n\ .set reorder\n\ # Save slot call pc.\n\ move $2, $31\n\ "IFABIO32(STRINGXP(CPRESTORE(32)))"\n\ "ELF_DL_SAVE_ARG_REGS"\ move $4, $24\n\ move $5, $15\n\ move $6, $3\n\ move $7, $2\n\ jal __dl_runtime_resolve\n\ "ELF_DL_RESTORE_ARG_REGS"\ "STRINGXP(RESTORE_GP64)"\n\ "STRINGXP(PTR_ADDIU)" $29, "STRINGXP(ELF_DL_FRAME_SIZE)"\n\ move $25, $2\n\ jr $25\n\ .end _dl_runtime_resolve\n\ .previous\n\ ")
 asm ("\n\ .text\n\ .align 2\n\ .globl _dl_runtime_pltresolve\n\ .type _dl_runtime_pltresolve,@function\n\ .ent _dl_runtime_pltresolve\n\ _dl_runtime_pltresolve:\n\ .frame $29, "STRINGXP(ELF_DL_PLT_FRAME_SIZE)", $31\n\ .set noreorder\n\ # Save arguments and sp value in stack.\n\ "STRINGXP(PTR_SUBIU)" $29, "STRINGXP(ELF_DL_PLT_FRAME_SIZE)"\n\ "IFABIO32(STRINGXP(PTR_L)" $13, "STRINGXP(PTRSIZE)"($28)")"\n\ "IFNEWABI(STRINGXP(PTR_L)" $13, "STRINGXP(PTRSIZE)"($14)")"\n\ # Modify t9 ($25) so as to point .cpload instruction.\n\ "IFABIO32(STRINGXP(PTR_ADDIU)" $25, 12\n")"\ # Compute GP.\n\ "STRINGXP(SETUP_GP)"\n\ "STRINGXV(SETUP_GP64(0, _dl_runtime_pltresolve))"\n\ .set reorder\n\ "IFABIO32(STRINGXP(CPRESTORE(32)))"\n\ "ELF_DL_PLT_SAVE_ARG_REGS"\ move $4, $13\n\ sll $5, $24, "STRINGXP(PTRLOG)" + 1\n\ jal _dl_fixup\n\ move $25, $2\n\ "ELF_DL_PLT_RESTORE_ARG_REGS"\ "STRINGXP(RESTORE_GP64)"\n\ "STRINGXP(PTR_ADDIU)" $29, "STRINGXP(ELF_DL_PLT_FRAME_SIZE)"\n\ jr $25\n\ .end _dl_runtime_pltresolve\n\ .previous\n\ ")

Variables

int _dl_mips_gnu_objects = 1

Define Documentation

#define ELF_DL_FRAME_SIZE   40

Definition at line 185 of file dl-trampoline.c.

#define ELF_DL_PLT_FRAME_SIZE   48

Definition at line 205 of file dl-trampoline.c.

#define ELF_DL_PLT_RESTORE_ARG_REGS   ELF_DL_RESTORE_ARG_REGS "\ lw $2, 40($29)\n \ lw $3, 44($29)\n \"

Definition at line 213 of file dl-trampoline.c.

#define ELF_DL_PLT_SAVE_ARG_REGS   ELF_DL_SAVE_ARG_REGS "\ sw $2, 40($29)\n \ sw $3, 44($29)\n \"

Definition at line 207 of file dl-trampoline.c.

#define ELF_DL_RESTORE_ARG_REGS   "\ lw $31, 36($29)\n \ lw $4, 16($29)\n \ lw $5, 20($29)\n \ lw $6, 24($29)\n \ lw $7, 28($29)\n \"

Definition at line 195 of file dl-trampoline.c.

#define ELF_DL_SAVE_ARG_REGS   "\ sw $15, 36($29)\n \ sw $4, 16($29)\n \ sw $5, 20($29)\n \ sw $6, 24($29)\n \ sw $7, 28($29)\n \"

Definition at line 187 of file dl-trampoline.c.

#define IFABIO32 (   X)    X

Definition at line 219 of file dl-trampoline.c.

#define IFNEWABI (   X)

Definition at line 220 of file dl-trampoline.c.

#define VERSYMIDX (   sym)    (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))

Definition at line 115 of file dl-trampoline.c.


Function Documentation

asm ( "\n\ .text\n\ .align 2\n\ .globl _dl_runtime_resolve\n\ .type  _dl_runtime_resolve,
@function\n\.ent _dl_runtime_resolve\n\_dl_runtime_resolve:\n\.frame $  29,
"STRINGXP(ELF_DL_FRAME_SIZE)"  ,
$31\n\.set noreorder\n\#Save GP.\n\move $  3,
$28\n\#Save arguments and sp value in stack.\n\"STRINGXP(PTR_SUBIU)"$  29,
"STRINGXP(ELF_DL_FRAME_SIZE)"\n\#Modify t9($25) so as to point.cpload instruction.\n\"IFABIO32(STRINGXP(PTR_ADDIU)"$25, 12\n")"\#Compute GP.\n\"STRINGXP(SETUP_GP)"\n\"STRINGXV(SETUP_GP64(0, _dl_runtime_resolve))"\n\.set reorder\n\#Save slot call pc.\n\move $  2,
$31\n\"IFABIO32(STRINGXP(CPRESTORE(32)))"\n\"ELF_DL_SAVE_ARG_REGS"\move $  4,
$24\n\move $  5,
$15\n\move $  6,
$3\n\move $  7,
$2\n\jal __dl_runtime_resolve\n\"ELF_DL_RESTORE_ARG_REGS"\"STRINGXP(RESTORE_GP64)"\n\"STRINGXP(PTR_ADDIU)"$  29,
"STRINGXP(ELF_DL_FRAME_SIZE)"\n\move $  25,
$2\n\jr $25\n\.end _dl_runtime_resolve\n\.previous\n\"   
)
asm ( "\n\ .text\n\ .align 2\n\ .globl _dl_runtime_pltresolve\n\ .type  _dl_runtime_pltresolve,
@function\n\.ent _dl_runtime_pltresolve\n\_dl_runtime_pltresolve:\n\.frame $  29,
"STRINGXP(ELF_DL_PLT_FRAME_SIZE)"  ,
$31\n\.set noreorder\n\#Save arguments and sp value in stack.\n\"STRINGXP(PTR_SUBIU)"$  29,
"STRINGXP(ELF_DL_PLT_FRAME_SIZE)"\n\"IFABIO32(STRINGXP(PTR_L)"$13,"STRINGXP(PTRSIZE)"($28)")"\n\"IFNEWABI(STRINGXP(PTR_L)"$13,"STRINGXP(PTRSIZE)"($14)")"\n\#Modify t9($25) so as to point.cpload instruction.\n\"IFABIO32(STRINGXP(PTR_ADDIU)"$25, 12\n")"\#Compute GP.\n\"STRINGXP(SETUP_GP)"\n\"STRINGXV(SETUP_GP64(0, _dl_runtime_pltresolve))"\n\.set reorder\n\"IFABIO32(STRINGXP(CPRESTORE(32)))"\n\"ELF_DL_PLT_SAVE_ARG_REGS"\move $  4,
$13\n\sll $  5,
24,
"STRINGXP(PTRLOG)"+1\n\jal _dl_fixup\n\move $  25,
$2\n\"ELF_DL_PLT_RESTORE_ARG_REGS"\"STRINGXP(RESTORE_GP64)"\n\"STRINGXP(PTR_ADDIU)"$  29,
"STRINGXP(ELF_DL_PLT_FRAME_SIZE)"\n\jr $25\n\.end _dl_runtime_pltresolve\n\.previous\n\"   
)
static struct link_map* elf_machine_runtime_link_map ( ElfW(Addr)  gpreg,
ElfW(Addr)  stub_pc 
) [static, read]

Definition at line 32 of file dl-trampoline.c.

{
  extern int _dl_mips_gnu_objects;

  /* got[1] is reserved to keep its link map address for the shared
     object generated by the gnu linker.  If all are such objects, we
     can find the link map from current GPREG simply.  If not so, get
     the link map for caller's object containing STUB_PC.  */

  if (_dl_mips_gnu_objects)
    {
      ElfW(Addr) *got = elf_mips_got_from_gpreg (gpreg);
      ElfW(Word) g1;

      g1 = ((ElfW(Word) *) got)[1];

      if ((g1 & ELF_MIPS_GNU_GOT1_MASK) != 0)
       {
         struct link_map *l =
           (struct link_map *) (g1 & ~ELF_MIPS_GNU_GOT1_MASK);
         ElfW(Addr) base, limit;
         const ElfW(Phdr) *p = l->l_phdr;
         ElfW(Half) this, nent = l->l_phnum;

         /* For the common case of a stub being called from the containing
            object, STUB_PC will point to somewhere within the object that
            is described by the link map fetched via got[1].  Otherwise we
            have to scan all maps.  */
         for (this = 0; this < nent; this++)
           {
             if (p[this].p_type == PT_LOAD)
              {
                base = p[this].p_vaddr + l->l_addr;
                limit = base + p[this].p_memsz;
                if (stub_pc >= base && stub_pc < limit)
                  return l;
              }
           }
       }
    }

    struct link_map *l;
    Lmid_t nsid;

    for (nsid = 0; nsid < DL_NNS; ++nsid)
      for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
       {
         ElfW(Addr) base, limit;
         const ElfW(Phdr) *p = l->l_phdr;
         ElfW(Half) this, nent = l->l_phnum;

         for (this = 0; this < nent; ++this)
           {
             if (p[this].p_type == PT_LOAD)
              {
                base = p[this].p_vaddr + l->l_addr;
                limit = base + p[this].p_memsz;
                if (stub_pc >= base && stub_pc < limit)
                  return l;
              }
           }
       }

  _dl_signal_error (0, NULL, NULL, "cannot find runtime link map");
  return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static ElfW ( Addr  ) [static]

Definition at line 118 of file dl-trampoline.c.

{
  struct link_map *l = elf_machine_runtime_link_map (old_gpreg, stub_pc);
  const ElfW(Sym) *const symtab
    = (const ElfW(Sym) *) D_PTR (l, l_info[DT_SYMTAB]);
  const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
  ElfW(Addr) *got
    = (ElfW(Addr) *) D_PTR (l, l_info[DT_PLTGOT]);
  const ElfW(Word) local_gotno
    = (const ElfW(Word)) l->l_info[DT_MIPS (LOCAL_GOTNO)]->d_un.d_val;
  const ElfW(Word) gotsym
    = (const ElfW(Word)) l->l_info[DT_MIPS (GOTSYM)]->d_un.d_val;
  const ElfW(Sym) *sym = &symtab[sym_index];
  struct link_map *sym_map;
  ElfW(Addr) value;

  /* FIXME: The symbol versioning stuff is not tested yet.  */
  if (__builtin_expect (ELFW(ST_VISIBILITY) (sym->st_other), 0) == 0)
    {
      switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
       {
       default:
         {
           const ElfW(Half) *vernum =
             (const void *) D_PTR (l, l_info[VERSYMIDX (DT_VERSYM)]);
           ElfW(Half) ndx = vernum[sym_index] & 0x7fff;
           const struct r_found_version *version = &l->l_versions[ndx];

           if (version->hash != 0)
             {
              sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l,
                                          &sym, l->l_scope, version,
                                          ELF_RTYPE_CLASS_PLT, 0, 0);
              break;
             }
           /* Fall through.  */
         }
       case 0:
         sym_map = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym,
                                    l->l_scope, 0, ELF_RTYPE_CLASS_PLT,
                                    DL_LOOKUP_ADD_DEPENDENCY, 0);
       }

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

  /* Apply the relocation with that value.  */
  *(got + local_gotno + sym_index - gotsym) = value;

  return value;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 113 of file dl-trampoline.c.