aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/alpha/dl-machine.h
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/alpha/dl-machine.h')
-rw-r--r--sysdeps/alpha/dl-machine.h71
1 files changed, 49 insertions, 22 deletions
diff --git a/sysdeps/alpha/dl-machine.h b/sysdeps/alpha/dl-machine.h
index ad79ef669c..b16e1c884c 100644
--- a/sysdeps/alpha/dl-machine.h
+++ b/sysdeps/alpha/dl-machine.h
@@ -289,37 +289,64 @@ _dl_start_user:
/* Store the highest stack address. */
stq $30, __libc_stack_end
/* 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. */
+ name as an extra leading argument. */
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_main_searchlist into s1 to pass to _dl_init_next. */
-0: ldq $10, _dl_main_searchlist
- /* Call _dl_init_next to return the address of an initializer
- 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: /* Clear the startup flag. */
- stl $31, _dl_starting_up
+ beq $1, $fixup_stack
+$fixup_stack_ret:
+ /* The special initializer gets called with the stack just
+ as the application's entry point will see it; it can
+ switch stacks if it moves these contents over. */
+" RTLD_START_SPECIAL_INIT "
+ /* Call _dl_init(_dl_loaded, argc, argv, envp) to run initializers. */
+ ldq $16, _dl_loaded
+ ldq $17, 0($sp)
+ lda $18, 8($sp)
+ s8addq $17, 8, $19
+ addq $19, $18, $19
+ jsr $26, _dl_init
/* 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)
+$fixup_stack:
+ /* Adjust the stack pointer to skip _dl_skip_args words. This
+ involves copying everything down, since the stack pointer must
+ always be 16-byte aligned. */
+ ldq $2, 0($sp)
+ subq $2, $1, $2
+ mov $sp, $4
+ s8addq $2, $sp, $3
+ stq $2, 0($sp)
+ /* Copy down argv. */
+0: ldq $5, 8($3)
+ addq $4, 8, $4
+ addq $3, 8, $3
+ stq $5, 0($4)
+ bne $5, 0b
+ /* Copy down envp. */
+1: ldq $5, 8($3)
+ addq $4, 8, $4
+ addq $3, 8, $3
+ stq $5, 0($4)
+ bne $5, 1b
+ /* Copy down auxiliary table. */
+2: ldq $5, 8($3)
+ ldq $6, 16($3)
+ addq $4, 16, $4
+ addq $3, 16, $3
+ stq $5, -8($4)
+ stq $6, 0($4)
+ bne $5, 2b
+ br $fixup_stack_ret
.end _dl_start_user
.set noat
.previous");
+#ifndef RTLD_START_SPECIAL_INIT
+#define RTLD_START_SPECIAL_INIT /* nothing */
+#endif
+
/* Nonzero iff TYPE describes relocation of a PLT entry, so
PLT entries should not be allowed to define the value. */
#define elf_machine_lookup_noplt_p(type) ((type) == R_ALPHA_JMP_SLOT)
@@ -350,7 +377,7 @@ elf_machine_fixup_plt(struct link_map *l, const Elf64_Rela *reloc,
/* Recover the PLT entry address by calculating reloc's index into the
.rela.plt, and finding that entry in the .plt. */
rela_plt = (void *) D_PTR (l, l_info[DT_JMPREL]);
- plte = (void *) (D_PTR (l, [DT_PLTGOT]) + 32);
+ plte = (void *) (D_PTR (l, l_info[DT_PLTGOT]) + 32);
plte += 3 * (reloc - rela_plt);
/* Find the displacement from the plt entry to the function. */