diff options
Diffstat (limited to 'sysdeps/alpha/dl-machine.h')
-rw-r--r-- | sysdeps/alpha/dl-machine.h | 344 |
1 files changed, 173 insertions, 171 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h index 8986ed7d58..b900b769ee 100644 --- a/sysdeps/alpha/dl-machine.h +++ b/sysdeps/alpha/dl-machine.h @@ -18,14 +18,16 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* This was written in the absense of an ABI -- don't expect +/* This was written in the absence of an ABI -- don't expect it to remain unchanged. */ +#ifndef dl_machine_h +#define dl_machine_h 1 + #define ELF_MACHINE_NAME "alpha" #include <assert.h> #include <string.h> -#include <link.h> /* Return nonzero iff E_MACHINE is compatible with the running host. */ @@ -35,7 +37,6 @@ elf_machine_matches_host (Elf64_Word e_machine) return e_machine == EM_ALPHA; } - /* Return the run-time address of the _GLOBAL_OFFSET_TABLE_. Must be inlined in a function which uses global data. */ static inline Elf64_Addr * @@ -45,7 +46,6 @@ elf_machine_got (void) return (Elf64_Addr *)(gp - 0x8000); } - /* Return the run-time load address of the shared object. */ static inline Elf64_Addr elf_machine_load_address (void) @@ -78,6 +78,164 @@ elf_machine_load_address (void) return dot + 4 + zero_disp; } +/* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +static inline void +elf_machine_runtime_setup (struct link_map *l, int lazy) +{ + Elf64_Addr plt; + extern void _dl_runtime_resolve (void); + + if (l->l_info[DT_JMPREL] && lazy) + { + /* The GOT entries for the functions in the PLT have not been + filled in yet. Their initial contents are directed to the + PLT which arranges for the dynamic linker to be called. */ + plt = l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr; + + /* This function will be called to perform the relocation. */ + *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve; + + /* Identify this shared object */ + *(Elf64_Addr *)(plt + 24) = (Elf64_Addr) l; + } +} + +/* This code is used in dl-runtime.c to call the `fixup' function + and then redirect to the address it returns. */ +#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ( \ +"/* Trampoline for _dl_runtime_resolver */ + .globl _dl_runtime_resolve + .ent _dl_runtime_resolve +_dl_runtime_resolve: + lda $sp, -168($sp) + .frame $sp, 168, $26 + /* Preserve all registers that C normally doesn't. */ + stq $26, 0($sp) + stq $0, 8($sp) + stq $1, 16($sp) + stq $2, 24($sp) + stq $3, 32($sp) + stq $4, 40($sp) + stq $5, 48($sp) + stq $6, 56($sp) + stq $7, 64($sp) + stq $8, 72($sp) + stq $16, 80($sp) + stq $17, 88($sp) + stq $18, 96($sp) + stq $19, 104($sp) + stq $20, 112($sp) + stq $21, 120($sp) + stq $22, 128($sp) + stq $23, 136($sp) + stq $24, 144($sp) + stq $25, 152($sp) + stq $29, 160($sp) + .mask 0x27ff01ff, -168 + /* Set up our $gp */ + br $gp, .+4 + ldgp $gp, 0($gp) + .prologue 1 + /* Set up the arguments for _dl_runtime_resolve. */ + /* $16 = link_map out of plt0 */ + ldq $16, 8($27) + /* $17 = offset of reloc entry */ + mov $28, $17 + /* Do the fixup */ + bsr $26, fixup..ng + /* Move the destination address to a safe place. */ + mov $0, $27 + /* Restore program registers. */ + ldq $26, 0($sp) + ldq $0, 8($sp) + ldq $1, 16($sp) + ldq $2, 24($sp) + ldq $3, 32($sp) + ldq $4, 40($sp) + ldq $5, 48($sp) + ldq $6, 56($sp) + ldq $7, 64($sp) + ldq $8, 72($sp) + ldq $16, 80($sp) + ldq $17, 88($sp) + ldq $18, 96($sp) + ldq $19, 104($sp) + ldq $20, 112($sp) + ldq $21, 120($sp) + ldq $22, 128($sp) + ldq $23, 136($sp) + ldq $24, 144($sp) + ldq $25, 152($sp) + ldq $29, 160($sp) + /* Clean up and turn control to the destination */ + lda $sp, 168($sp) + jmp $31, ($27) + .end _dl_runtime_resolve"); + +/* The PLT uses Elf_Rel relocs. */ +#define elf_machine_relplt elf_machine_rela + +/* Mask identifying addresses reserved for the user program, + where the dynamic linker should not map anything. */ +/* FIXME */ +#define ELF_MACHINE_USER_ADDRESS_MASK (~0x1FFFFFFFFUL) + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. */ + +#define RTLD_START asm ("\ +.text + .globl _start + .globl _dl_start_user +_start: + br $gp,.+4 + ldgp $gp, 0($gp) + /* Pass pointer to argument block to _dl_start. */ + mov $sp, $16 + bsr $26, _dl_start..ng +_dl_start_user: + /* Save the user entry point address in s0. */ + mov $0, $9 + /* See if we were run as a command with the executable file + name as an extra leading argument. If so, adjust the stack + pointer to skip _dl_skip_args words. */ + ldl $1, _dl_skip_args + beq $1, 0f + ldq $2, 0($sp) + subq $2, $1, $2 + s8addq $1, $sp, $sp + stq $2, 0($sp) + /* Load _dl_default_scope[2] into s1 to pass to _dl_init_next. */ +0: ldq $10, _dl_default_scope+16 + /* Call _dl_init_next to return the address of an initalizer + function to run. */ +1: mov $10, $16 + jsr $26, _dl_init_next + ldgp $gp, 0($26) + beq $0, 2f + mov $0, $27 + jsr $26, ($0) + ldgp $gp, 0($26) + br 1b +2: /* Pass our finalizer function to the user in $0. */ + lda $0, _dl_fini + /* Jump to the user's entry point. */ + mov $9, $27 + jmp ($9)"); + +/* Nonzero iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. */ +#define elf_machine_pltrel_p(type) ((type) == R_ALPHA_JMP_SLOT) + +/* The alpha never uses Elf64_Rel relocations. */ +#define ELF_MACHINE_NO_REL 1 + +#endif /* !dl_machine_h */ + +#ifdef RESOLVE /* Fix up the instructions of a PLT entry to invoke the function rather than the dynamic linker. */ @@ -154,13 +312,11 @@ elf_alpha_fix_plt(struct link_map *l, static inline void elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, - const Elf64_Sym *sym, - Elf64_Addr (*resolve) (const Elf64_Sym **ref, - Elf64_Addr reloc_addr, - int noplt)) + const Elf64_Sym *sym) { - Elf64_Addr *const reloc_addr = (void *)(map->l_addr + reloc->r_offset); - unsigned long r_info = ELF64_R_TYPE (reloc->r_info); + Elf64_Addr * const reloc_addr = (void *)(map->l_addr + reloc->r_offset); + unsigned long const r_info = ELF64_R_TYPE (reloc->r_info); + #ifndef RTLD_BOOTSTRAP /* This is defined in rtld.c, but nowhere in the static libc.a; make the reference weak so static programs can still link. This declaration @@ -175,8 +331,8 @@ elf_machine_rela (struct link_map *map, if (r_info == R_ALPHA_RELATIVE) { - /* Already done in dynamic linker. */ #ifndef RTLD_BOOTSTRAP + /* Already done in dynamic linker. */ if (map != &_dl_rtld_map) #endif *reloc_addr += map->l_addr; @@ -187,12 +343,8 @@ elf_machine_rela (struct link_map *map, { Elf64_Addr loadbase, sym_value; -#ifndef RTLD_BOOTSTRAP - loadbase = (*resolve)(&sym, (Elf64_Addr)reloc_addr, - r_info == R_ALPHA_JMP_SLOT); -#else - loadbase = map->l_addr; -#endif + loadbase = RESOLVE (&sym, (Elf64_Addr)reloc_addr, + r_info == R_ALPHA_JMP_SLOT); sym_value = sym ? loadbase + sym->st_value : 0; if (r_info == R_ALPHA_GLOB_DAT) @@ -233,8 +385,8 @@ elf_machine_rela (struct link_map *map, static inline void elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc) { - Elf64_Addr *const reloc_addr = (void *)(map->l_addr + reloc->r_offset); - unsigned long r_info = ELF64_R_TYPE (reloc->r_info); + Elf64_Addr * const reloc_addr = (void *)(map->l_addr + reloc->r_offset); + unsigned long const r_info = ELF64_R_TYPE (reloc->r_info); if (r_info == R_ALPHA_JMP_SLOT) { @@ -243,159 +395,9 @@ elf_machine_lazy_rel (struct link_map *map, const Elf64_Rela *reloc) *reloc_addr += map->l_addr; } else if (r_info == R_ALPHA_NONE) - ; + return; else assert (! "unexpected PLT reloc type"); } -/* The alpha never uses Elf_Rel relocations. */ -#define ELF_MACHINE_NO_REL 1 - - -/* Set up the loaded object described by L so its unrelocated PLT - entries will jump to the on-demand fixup code in dl-runtime.c. */ - -static inline void -elf_machine_runtime_setup (struct link_map *l, int lazy) -{ - Elf64_Addr plt; - extern void _dl_runtime_resolve (void); - - if (l->l_info[DT_JMPREL] && lazy) - { - /* The GOT entries for the functions in the PLT have not been - filled in yet. Their initial contents are directed to the - PLT which arranges for the dynamic linker to be called. */ - plt = l->l_addr + l->l_info[DT_PLTGOT]->d_un.d_ptr; - - /* This function will be called to perform the relocation. */ - *(Elf64_Addr *)(plt + 16) = (Elf64_Addr) &_dl_runtime_resolve; - - /* Identify this shared object */ - *(Elf64_Addr *)(plt + 24) = (Elf64_Addr) l; - } -} - -/* This code is used in dl-runtime.c to call the `fixup' function - and then redirect to the address it returns. */ -#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ( \ -"/* Trampoline for _dl_runtime_resolver */ - .globl _dl_runtime_resolve - .ent _dl_runtime_resolve -_dl_runtime_resolve: - lda $sp, -168($sp) - .frame $sp, 168, $26 - /* Preserve all registers that C normally doesn't. */ - stq $26, 0($sp) - stq $0, 8($sp) - stq $1, 16($sp) - stq $2, 24($sp) - stq $3, 32($sp) - stq $4, 40($sp) - stq $5, 48($sp) - stq $6, 56($sp) - stq $7, 64($sp) - stq $8, 72($sp) - stq $16, 80($sp) - stq $17, 88($sp) - stq $18, 96($sp) - stq $19, 104($sp) - stq $20, 112($sp) - stq $21, 120($sp) - stq $22, 128($sp) - stq $23, 136($sp) - stq $24, 144($sp) - stq $25, 152($sp) - stq $29, 160($sp) - .mask 0x27ff01ff, -168 - /* Set up our $gp */ - br $gp, .+4 - ldgp $gp, 0($gp) - .prologue 1 - /* Set up the arguments for _dl_runtime_resolve. */ - /* $16 = link_map out of plt0 */ - ldq $16, 8($27) - /* $17 = offset of reloc entry */ - mov $28, $17 - /* Do the fixup */ - bsr $26, fixup..ng - /* Move the destination address to a safe place. */ - mov $0, $27 - /* Restore program registers. */ - ldq $26, 0($sp) - ldq $0, 8($sp) - ldq $1, 16($sp) - ldq $2, 24($sp) - ldq $3, 32($sp) - ldq $4, 40($sp) - ldq $5, 48($sp) - ldq $6, 56($sp) - ldq $7, 64($sp) - ldq $8, 72($sp) - ldq $16, 80($sp) - ldq $17, 88($sp) - ldq $18, 96($sp) - ldq $19, 104($sp) - ldq $20, 112($sp) - ldq $21, 120($sp) - ldq $22, 128($sp) - ldq $23, 136($sp) - ldq $24, 144($sp) - ldq $25, 152($sp) - ldq $29, 160($sp) - /* Clean up and turn control to the destination */ - lda $sp, 168($sp) - jmp $31, ($27) - .end _dl_runtime_resolve"); - -/* The PLT uses Elf_Rel relocs. */ -#define elf_machine_relplt elf_machine_rela - -/* Mask identifying addresses reserved for the user program, - where the dynamic linker should not map anything. */ -/* FIXME */ -#define ELF_MACHINE_USER_ADDRESS_MASK (~0x1FFFFFFFFUL) - -/* Initial entry point code for the dynamic linker. - The C function `_dl_start' is the real entry point; - its return value is the user program's entry point. */ - -#define RTLD_START asm ("\ -.text - .globl _start - .globl _dl_start_user -_start: - br $gp,.+4 - ldgp $gp, 0($gp) - /* Pass pointer to argument block to _dl_start. */ - mov $sp, $16 - bsr $26, _dl_start..ng -_dl_start_user: - /* Save the user entry point address in s0. */ - mov $0, $9 - /* See if we were run as a command with the executable file - name as an extra leading argument. If so, adjust the stack - pointer to skip _dl_skip_args words. */ - ldl $1, _dl_skip_args - beq $1, 0f - ldq $2, 0($sp) - subq $2, $1, $2 - s8addq $1, $sp, $sp - stq $2, 0($sp) - /* Load _dl_default_scope[2] into s1 to pass to _dl_init_next. */ -0: ldq $10, _dl_default_scope+16 - /* Call _dl_init_next to return the address of an initalizer - function to run. */ -1: mov $10, $16 - jsr $26, _dl_init_next - ldgp $gp, 0($26) - beq $0, 2f - mov $0, $27 - jsr $26, ($0) - ldgp $gp, 0($26) - br 1b -2: /* Pass our finalizer function to the user in $0. */ - lda $0, _dl_fini - /* Jump to the user's entry point. */ - mov $9, $27 - jmp ($9)"); +#endif /* RESOLVE */ |