From af856e3a857599bc2d2c2577a8064339778253b0 Mon Sep 17 00:00:00 2001 From: kettenis Date: Thu, 16 Jul 2020 21:18:09 +0000 Subject: Make lazy binding work. Committing on behalf of drahn@ who is a bit busy. --- libexec/ld.so/powerpc64/ldasm.S | 19 ++++++++++--------- libexec/ld.so/powerpc64/rtld_machine.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) (limited to 'libexec') diff --git a/libexec/ld.so/powerpc64/ldasm.S b/libexec/ld.so/powerpc64/ldasm.S index 5ed5c5ace27..f88031bc9bf 100644 --- a/libexec/ld.so/powerpc64/ldasm.S +++ b/libexec/ld.so/powerpc64/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.2 2020/06/28 17:58:40 drahn Exp $ */ +/* $OpenBSD: ldasm.S,v 1.3 2020/07/16 21:18:09 kettenis Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -89,9 +89,10 @@ _dl_start: END(_dl_start) ENTRY(_dl_bind_start) - mflr %r0 - std %r0,16(%r1) # save lr - std %r2,24(%r1) # save toc + # r0 contains offset, do not overwrite + # r2 ld.so toc is loaded on entry to this function. + mflr %r12 + std %r12,16(%r1) # save lr stdu 1,-104(%r1) @@ -102,11 +103,11 @@ ENTRY(_dl_bind_start) std %r7,64(%r1) std %r8,72(%r1) std %r9,80(%r1) - std %r10,96(%r1) + std %r10,88(%r1) - mr %r3,%r12 # obj - mr %r4,%r11 # reloff - bl _dl_bind # _rtld_bind(obj, reloff) + mr %r3,%r11 # obj + mr %r4,%r0 # relidx + bl _dl_bind # _rtld_bind(obj, relidx) mtctr %r3 mr %r12, %r3 @@ -117,7 +118,7 @@ ENTRY(_dl_bind_start) ld %r7,64(%r1) ld %r8,72(%r1) ld %r9,80(%r1) - ld %r10,96(%r1) + ld %r10,88(%r1) addi %r1,%r1,104 diff --git a/libexec/ld.so/powerpc64/rtld_machine.c b/libexec/ld.so/powerpc64/rtld_machine.c index 4ea228e1fe9..08562960410 100644 --- a/libexec/ld.so/powerpc64/rtld_machine.c +++ b/libexec/ld.so/powerpc64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.2 2020/06/28 20:52:05 drahn Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.3 2020/07/16 21:18:09 kettenis Exp $ */ /* * Copyright (c) 1999 Dale Rahn @@ -272,13 +272,35 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (object->Dyn.info[DT_PLTREL] != DT_RELA) return 0; - fails = _dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ); + if (!lazy) { + fails = _dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ); + } else { + Elf_Addr *plt; + int numplt, i; + + /* Relocate processor-specific tags. */ + object->Dyn.info[DT_PROC(DT_PPC64_GLINK)] += object->obj_base; + + if (object->Dyn.info[DT_PLTREL] != DT_RELA) + _dl_die(" bad relocation type PLTREL not RELA"); + + plt = (Elf_Addr *) + (Elf_RelA *)(object->Dyn.info[DT_PLTGOT]); + numplt = object->Dyn.info[DT_PLTRELSZ] / sizeof(Elf_RelA); + plt[0] = (uint64_t)_dl_bind_start; + plt[1] = (uint64_t)object; + // offset 2 as first two entries are rtld parameters + for (i = 2; i < numplt+2; i++) { + plt[i] = object->Dyn.info[DT_PROC(DT_PPC64_GLINK)] + + i*4 + 24; + } + } return fails; } Elf_Addr -_dl_bind(elf_object_t *object, int reloff) +_dl_bind(elf_object_t *object, int relidx) { const Elf_Sym *sym; struct sym_res sr; @@ -291,7 +313,7 @@ _dl_bind(elf_object_t *object, int reloff) Elf_Addr newval; } buf; - relas = (Elf_RelA *)(object->Dyn.info[DT_JMPREL] + reloff); + relas = ((Elf_RelA *)object->Dyn.info[DT_JMPREL]) + relidx; sym = object->dyn.symtab; sym += ELF_R_SYM(relas->r_info); @@ -308,7 +330,7 @@ _dl_bind(elf_object_t *object, int reloff) return buf.newval; plttable = (Elf_Addr *)(Elf_RelA *)(object->Dyn.info[DT_PLTGOT]); - buf.param.kb_addr = &plttable[ reloff / sizeof(Elf_RelA) ]; + buf.param.kb_addr = &plttable[relidx + 2]; buf.param.kb_size = sizeof(Elf_Addr); { -- cgit v1.2.3-59-g8ed1b