diff options
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/ld.so/alpha/ldasm.S | 38 | ||||
-rw-r--r-- | libexec/ld.so/alpha/rtld_machine.c | 31 |
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; + } +} |