summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
Diffstat (limited to 'libexec')
-rw-r--r--libexec/ld.so/alpha/ldasm.S38
-rw-r--r--libexec/ld.so/alpha/rtld_machine.c31
2 files changed, 50 insertions, 19 deletions
diff --git a/libexec/ld.so/alpha/ldasm.S b/libexec/ld.so/alpha/ldasm.S
index c6917ff2e26..c4d5bd15a4d 100644
--- a/libexec/ld.so/alpha/ldasm.S
+++ b/libexec/ld.so/alpha/ldasm.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldasm.S,v 1.11 2002/12/18 19:20:01 drahn Exp $ */
+/* $OpenBSD: ldasm.S,v 1.12 2003/01/17 20:41:07 drahn Exp $ */
/*
* Copyright (c) 2001 Niklas Hallqvist
@@ -69,26 +69,28 @@
/* Not really a leaf... but we are special. */
LEAF_NOPROFILE(_dl_start, 0)
.set noreorder
- lda sp, (-8 - ((AUX_entry) * 8))(sp)
br pv, L1
L1:
LDGP(pv)
- ldiq t2, L1
- subq pv, t2, t2
- lda t0, _GLOBAL_OFFSET_TABLE_
- addq t0, t2, t0
- lda t1, _DYNAMIC
- addq t1, t2, t1
-L2: cmpult t0, t1, t3
- beq t3, L3
- ldq t3, 0(t0)
- addq t3, t2, t3
- stq t3, 0(t0)
- lda t0, 8(t0)
- br L2
-L3:
- mov a0, s0
- mov t2, s1 /* relocation displacement */
+
+ mov a0, s0 /* save arg */
+
+ /* relocate ourself. */
+ br s2, L2 /* get our PC */
+L2: ldiq s3, L2 /* get where the linker thought we were */
+
+ subq s2, s3, s2
+ mov s2, a1
+ lda t5, _DYNAMIC
+ addq s2, t5, a0
+
+ bsr ra, _reloc_alpha_got
+
+ /* allocate stack */
+ lda sp, (-8 - ((AUX_entry) * 8))(sp)
+
+ mov s0, a0
+ mov s2, s1 /* relocation displacement */
ldq a2, 0(a0) /* argc */
lda a3, 8(a0) /* argv */
mov a3, s3
diff --git a/libexec/ld.so/alpha/rtld_machine.c b/libexec/ld.so/alpha/rtld_machine.c
index 7c5792ba723..e9c67279577 100644
--- a/libexec/ld.so/alpha/rtld_machine.c
+++ b/libexec/ld.so/alpha/rtld_machine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtld_machine.c,v 1.19 2003/01/16 19:56:37 drahn Exp $ */
+/* $OpenBSD: rtld_machine.c,v 1.20 2003/01/17 20:41:07 drahn Exp $ */
/*
* Copyright (c) 1999 Dale Rahn
@@ -297,3 +297,32 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
_dl_mprotect((void*)object->plt_addr, object->plt_size,
PROT_READ|PROT_EXEC);
}
+
+/* relocate the GOT early */
+
+void
+_reloc_alpha_got(dynp, relocbase)
+ Elf_Dyn *dynp;
+ Elf_Addr relocbase;
+{
+ const Elf_RelA *rela = 0, *relalim;
+ Elf_Addr relasz = 0;
+ Elf_Addr *where;
+
+ for (; dynp->d_tag != DT_NULL; dynp++) {
+ switch (dynp->d_tag) {
+ case DT_RELA:
+ rela = (const Elf_RelA *)(relocbase + dynp->d_un.d_ptr);
+ break;
+ case DT_RELASZ:
+ relasz = dynp->d_un.d_val;
+ break;
+ }
+ }
+ relalim = (const Elf_RelA *)((caddr_t)rela + relasz);
+ for (; rela < relalim; rela++) {
+ where = (Elf_Addr *)(relocbase + rela->r_offset);
+ /* XXX For some reason I see a few GLOB_DAT relocs here. */
+ *where += (Elf_Addr)relocbase;
+ }
+}