Back to index

glibc  2.9
Defines | Functions | Variables
dl-machine.h File Reference
#include <string.h>
#include <sys/param.h>
#include <ldsodefs.h>
#include <tls.h>

Go to the source code of this file.

Defines

#define ELF_MACHINE_NAME   "sparc"
#define VALIDX(tag)
#define OPCODE_NOP   0x01000000 /* nop */
#define OPCODE_CALL   0x40000000 /* call ?; add PC-rel word address */
#define OPCODE_SETHI_G1   0x03000000 /* sethi ?, %g1; add value>>10 */
#define OPCODE_JMP_G1   0x81c06000 /* jmp %g1+?; add lo 10 bits of value */
#define OPCODE_SAVE_SP   0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */
#define OPCODE_BA   0x30800000 /* b,a ?; add PC-rel word address */
#define LOAD_PIC_REG(PIC_REG)
#define elf_machine_type_class(type)
#define ELF_MACHINE_JMP_SLOT   R_SPARC_JMP_SLOT
#define ELF_MACHINE_NO_REL   1
#define ELF_MACHINE_PLTREL_OVERLAP   1
#define DL_STACK_END(cookie)   ((void *) (((long) (cookie)) - (22 - 6) * 4))
#define RTLD_START   __asm__ ("\ .text\n\ .globl _start\n\ .type _start, @function\n\ .align 32\n\_start:\n\ /* Allocate space for functions to drop their arguments. */\n\ sub %sp, 6*4, %sp\n\ /* Pass pointer to argument block to _dl_start. */\n\ call _dl_start\n\ add %sp, 22*4, %o0\n\ /* FALTHRU */\n\ .globl _dl_start_user\n\ .type _dl_start_user, @function\n\_dl_start_user:\n\ /* Load the PIC register. */\n\1: call 2f\n\ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\ add %l7, %o7, %l7\n\ /* Save the user entry point address in %l0 */\n\ mov %o0, %l0\n\ /* See if we were run as a command with the executable file name as an\n\ extra leading argument. If so, adjust the contents of the stack. */\n\ sethi %hi(_dl_skip_args), %g2\n\ or %g2, %lo(_dl_skip_args), %g2\n\ ld [%l7+%g2], %i0\n\ ld [%i0], %i0\n\ tst %i0\n\ beq 3f\n\ ld [%sp+22*4], %i5 /* load argc */\n\ /* Find out how far to shift. */\n\ sethi %hi(_dl_argv), %l3\n\ or %l3, %lo(_dl_argv), %l3\n\ ld [%l7+%l3], %l3\n\ sub %i5, %i0, %i5\n\ ld [%l3], %l4\n\ sll %i0, 2, %i2\n\ st %i5, [%sp+22*4]\n\ sub %l4, %i2, %l4\n\ add %sp, 23*4, %i1\n\ add %i1, %i2, %i2\n\ st %l4, [%l3]\n\ /* Copy down argv */\n\21: ld [%i2], %i3\n\ add %i2, 4, %i2\n\ tst %i3\n\ st %i3, [%i1]\n\ bne 21b\n\ add %i1, 4, %i1\n\ /* Copy down env */\n\22: ld [%i2], %i3\n\ add %i2, 4, %i2\n\ tst %i3\n\ st %i3, [%i1]\n\ bne 22b\n\ add %i1, 4, %i1\n\ /* Copy down auxiliary table. */\n\23: ld [%i2], %i3\n\ ld [%i2+4], %i4\n\ add %i2, 8, %i2\n\ tst %i3\n\ st %i3, [%i1]\n\ st %i4, [%i1+4]\n\ bne 23b\n\ add %i1, 8, %i1\n\ /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n\3: sethi %hi(_rtld_local), %o0\n\ add %sp, 23*4, %o2\n\ orcc %o0, %lo(_rtld_local), %o0\n\ sll %i5, 2, %o3\n\ ld [%l7+%o0], %o0\n\ add %o3, 4, %o3\n\ mov %i5, %o1\n\ add %o2, %o3, %o3\n\ call _dl_init_internal\n\ ld [%o0], %o0\n\ /* Pass our finalizer function to the user in %g1. */\n\ sethi %hi(_dl_fini), %g1\n\ or %g1, %lo(_dl_fini), %g1\n\ ld [%l7+%g1], %g1\n\ /* Jump to the user's entry point and deallocate the extra stack we got. */\n\ jmp %l0\n\ add %sp, 6*4, %sp\n\ .size _dl_start_user, . - _dl_start_user\n\ .previous");
#define ARCH_LA_PLTENTER   sparc32_gnu_pltenter
#define ARCH_LA_PLTEXIT   sparc32_gnu_pltexit

Functions

static int elf_machine_matches_host (const Elf32_Ehdr *ehdr)
static Elf32_Addr elf_machine_dynamic (void)
static Elf32_Addr elf_machine_load_address (void)
static int elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
static __attribute__ ((always_inline)) Elf32_Addr sparc_fixup_plt(const Elf32_Rela *reloc

Variables

static Elf32_Addrreloc_addr
static Elf32_Addr Elf32_Addr value
static Elf32_Addr Elf32_Addr int t

Define Documentation

#define ARCH_LA_PLTENTER   sparc32_gnu_pltenter
#define ARCH_LA_PLTEXIT   sparc32_gnu_pltexit
#define DL_STACK_END (   cookie)    ((void *) (((long) (cookie)) - (22 - 6) * 4))

Definition at line 221 of file dl-machine.h.

Definition at line 211 of file dl-machine.h.

#define ELF_MACHINE_NAME   "sparc"

Definition at line 24 of file dl-machine.h.

#define ELF_MACHINE_NO_REL   1

Definition at line 214 of file dl-machine.h.

Definition at line 217 of file dl-machine.h.

Value:

Definition at line 199 of file dl-machine.h.

#define LOAD_PIC_REG (   PIC_REG)
Value:
do {   register Elf32_Addr pc __asm("o7"); \
       __asm("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t" \
             "call 1f\n\t" \
             "add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n" \
             "1:\tadd %1, %0, %1" \
             : "=r" (pc), "=r" (PIC_REG)); \
} while (0)

Definition at line 67 of file dl-machine.h.

#define OPCODE_BA   0x30800000 /* b,a ?; add PC-rel word address */

Definition at line 42 of file dl-machine.h.

#define OPCODE_CALL   0x40000000 /* call ?; add PC-rel word address */

Definition at line 38 of file dl-machine.h.

#define OPCODE_JMP_G1   0x81c06000 /* jmp %g1+?; add lo 10 bits of value */

Definition at line 40 of file dl-machine.h.

#define OPCODE_NOP   0x01000000 /* nop */

Definition at line 37 of file dl-machine.h.

#define OPCODE_SAVE_SP   0x9de3bfa8 /* save %sp, -(16+6)*4, %sp */

Definition at line 41 of file dl-machine.h.

#define OPCODE_SETHI_G1   0x03000000 /* sethi ?, %g1; add value>>10 */

Definition at line 39 of file dl-machine.h.

#define RTLD_START   __asm__ ("\ .text\n\ .globl _start\n\ .type _start, @function\n\ .align 32\n\_start:\n\ /* Allocate space for functions to drop their arguments. */\n\ sub %sp, 6*4, %sp\n\ /* Pass pointer to argument block to _dl_start. */\n\ call _dl_start\n\ add %sp, 22*4, %o0\n\ /* FALTHRU */\n\ .globl _dl_start_user\n\ .type _dl_start_user, @function\n\_dl_start_user:\n\ /* Load the PIC register. */\n\1: call 2f\n\ sethi %hi(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\2: or %l7, %lo(_GLOBAL_OFFSET_TABLE_-(1b-.)), %l7\n\ add %l7, %o7, %l7\n\ /* Save the user entry point address in %l0 */\n\ mov %o0, %l0\n\ /* See if we were run as a command with the executable file name as an\n\ extra leading argument. If so, adjust the contents of the stack. */\n\ sethi %hi(_dl_skip_args), %g2\n\ or %g2, %lo(_dl_skip_args), %g2\n\ ld [%l7+%g2], %i0\n\ ld [%i0], %i0\n\ tst %i0\n\ beq 3f\n\ ld [%sp+22*4], %i5 /* load argc */\n\ /* Find out how far to shift. */\n\ sethi %hi(_dl_argv), %l3\n\ or %l3, %lo(_dl_argv), %l3\n\ ld [%l7+%l3], %l3\n\ sub %i5, %i0, %i5\n\ ld [%l3], %l4\n\ sll %i0, 2, %i2\n\ st %i5, [%sp+22*4]\n\ sub %l4, %i2, %l4\n\ add %sp, 23*4, %i1\n\ add %i1, %i2, %i2\n\ st %l4, [%l3]\n\ /* Copy down argv */\n\21: ld [%i2], %i3\n\ add %i2, 4, %i2\n\ tst %i3\n\ st %i3, [%i1]\n\ bne 21b\n\ add %i1, 4, %i1\n\ /* Copy down env */\n\22: ld [%i2], %i3\n\ add %i2, 4, %i2\n\ tst %i3\n\ st %i3, [%i1]\n\ bne 22b\n\ add %i1, 4, %i1\n\ /* Copy down auxiliary table. */\n\23: ld [%i2], %i3\n\ ld [%i2+4], %i4\n\ add %i2, 8, %i2\n\ tst %i3\n\ st %i3, [%i1]\n\ st %i4, [%i1+4]\n\ bne 23b\n\ add %i1, 8, %i1\n\ /* %o0 = _dl_loaded, %o1 = argc, %o2 = argv, %o3 = envp. */\n\3: sethi %hi(_rtld_local), %o0\n\ add %sp, 23*4, %o2\n\ orcc %o0, %lo(_rtld_local), %o0\n\ sll %i5, 2, %o3\n\ ld [%l7+%o0], %o0\n\ add %o3, 4, %o3\n\ mov %i5, %o1\n\ add %o2, %o3, %o3\n\ call _dl_init_internal\n\ ld [%o0], %o0\n\ /* Pass our finalizer function to the user in %g1. */\n\ sethi %hi(_dl_fini), %g1\n\ or %g1, %lo(_dl_fini), %g1\n\ ld [%l7+%g1], %g1\n\ /* Jump to the user's entry point and deallocate the extra stack we got. */\n\ jmp %l0\n\ add %sp, 6*4, %sp\n\ .size _dl_start_user, . - _dl_start_user\n\ .previous");

Definition at line 228 of file dl-machine.h.

#define VALIDX (   tag)
Value:

Definition at line 32 of file dl-machine.h.


Function Documentation

static __attribute__ ( (always_inline)  ) const [inline, static]
static Elf32_Addr elf_machine_dynamic ( void  ) [inline, static]

Definition at line 80 of file dl-machine.h.

{
  register Elf32_Addr *got asm ("%l7");

  LOAD_PIC_REG (got);

  return *got;
}
static Elf32_Addr elf_machine_load_address ( void  ) [inline, static]

Definition at line 91 of file dl-machine.h.

{
  register Elf32_Addr *pc __asm ("%o7"), *got __asm ("%l7");

  __asm ("sethi %%hi(_GLOBAL_OFFSET_TABLE_-4), %1\n\t"
        "call 1f\n\t"
        " add %1, %%lo(_GLOBAL_OFFSET_TABLE_+4), %1\n\t"
        "call _DYNAMIC\n\t"
        "call _GLOBAL_OFFSET_TABLE_\n"
        "1:\tadd %1, %0, %1\n\t" : "=r" (pc), "=r" (got));

  /* got is now l_addr + _GLOBAL_OFFSET_TABLE_
     *got is _DYNAMIC
     pc[2]*4 is l_addr + _DYNAMIC - (long)pc - 8
     pc[3]*4 is l_addr + _GLOBAL_OFFSET_TABLE_ - (long)pc - 12  */
  return (Elf32_Addr) got - *got + (pc[2] - pc[3]) * 4 - 4;
}
static int elf_machine_matches_host ( const Elf32_Ehdr ehdr) [inline, static]

Definition at line 46 of file dl-machine.h.

{
  if (ehdr->e_machine == EM_SPARC)
    return 1;
  else if (ehdr->e_machine == EM_SPARC32PLUS)
    {
      /* XXX The following is wrong!  Dave Miller rejected to implement it
        correctly.  If this causes problems shoot *him*!  */
#ifdef SHARED
      return GLRO(dl_hwcap) & GLRO(dl_hwcap_mask) & HWCAP_SPARC_V9;
#else
      return GLRO(dl_hwcap) & HWCAP_SPARC_V9;
#endif
    }
  else
    return 0;
}
static int elf_machine_runtime_setup ( struct link_map l,
int  lazy,
int  profile 
) [inline, static]

Definition at line 113 of file dl-machine.h.

{
  Elf32_Addr *plt;
  extern void _dl_runtime_resolve (Elf32_Word);
  extern void _dl_runtime_profile (Elf32_Word);

  if (l->l_info[DT_JMPREL] && lazy)
    {
      Elf32_Addr rfunc;

      /* The entries for functions in the PLT have not yet been filled in.
        Their initial contents will arrange when called to set the high 22
        bits of %g1 with an offset into the .rela.plt section and jump to
        the beginning of the PLT.  */
      plt = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
      if (__builtin_expect(profile, 0))
       {
         rfunc = (Elf32_Addr) &_dl_runtime_profile;

         if (GLRO(dl_profile) != NULL
             && _dl_name_match_p (GLRO(dl_profile), l))
           GL(dl_profile_map) = l;
       }
      else
       {
         rfunc = (Elf32_Addr) &_dl_runtime_resolve;
       }

      /* The beginning of the PLT does:

              sethi %hi(_dl_runtime_{resolve,profile}), %g2
        pltpc:       jmpl %g2 + %lo(_dl_runtime_{resolve,profile}), %g2
               nop
              .word MAP

         The PC value (pltpc) saved in %g2 by the jmpl points near the
        location where we store the link_map pointer for this object.  */

      plt[0] = 0x05000000 | ((rfunc >> 10) & 0x003fffff);
      plt[1] = 0x85c0a000 | (rfunc & 0x3ff);
      plt[2] = OPCODE_NOP;  /* Fill call delay slot.  */
      plt[3] = (Elf32_Addr) l;
      if (__builtin_expect (l->l_info[VALIDX(DT_GNU_PRELINKED)] != NULL, 0)
         || __builtin_expect (l->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL, 0))
       {
         /* Need to reinitialize .plt to undo prelinking.  */
         Elf32_Rela *rela = (Elf32_Rela *) D_PTR (l, l_info[DT_JMPREL]);
         Elf32_Rela *relaend
           = (Elf32_Rela *) ((char *) rela
                           + l->l_info[DT_PLTRELSZ]->d_un.d_val);
#if !defined RTLD_BOOTSTRAP && !defined __sparc_v9__
         /* Note that we don't mask the hwcap here, as the flush is
            essential to functionality on those cpu's that implement it.
            For sparcv9 we can assume flush is present.  */
         const int do_flush = GLRO(dl_hwcap) & HWCAP_SPARC_FLUSH;
#else
         const int do_flush = 1;
#endif

         /* prelink must ensure there are no R_SPARC_NONE relocs left
            in .rela.plt.  */
         while (rela < relaend)
           {
             *(unsigned int *) rela->r_offset
              = OPCODE_SETHI_G1 | (rela->r_offset - (Elf32_Addr) plt);
             *(unsigned int *) (rela->r_offset + 4)
              = OPCODE_BA | ((((Elf32_Addr) plt
                             - rela->r_offset - 4) >> 2) & 0x3fffff);
             if (do_flush)
              {
                __asm __volatile ("flush %0" : : "r"(rela->r_offset));
                __asm __volatile ("flush %0+4" : : "r"(rela->r_offset));
              }
             ++rela;
           }
       }
    }

  return lazy;
}

Here is the call graph for this function:


Variable Documentation

Definition at line 316 of file dl-machine.h.

Definition at line 316 of file dl-machine.h.

Definition at line 316 of file dl-machine.h.