Make lazy binding work on riscv64.
authorkettenis <kettenis@openbsd.org>
Sat, 26 Jun 2021 14:50:25 +0000 (14:50 +0000)
committerkettenis <kettenis@openbsd.org>
Sat, 26 Jun 2021 14:50:25 +0000 (14:50 +0000)
prompted by deraadt@

libexec/ld.so/riscv64/ldasm.S
libexec/ld.so/riscv64/rtld_machine.c

index d51e82c..8decd9a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ldasm.S,v 1.2 2021/05/16 16:00:50 drahn Exp $ */
+/*     $OpenBSD: ldasm.S,v 1.3 2021/06/26 14:50:25 kettenis Exp $ */
 
 /*
  * Copyright (c) 2016,2021 Dale Rahn <drahn@openbsd.org>
@@ -74,65 +74,44 @@ END(_dl_start)
 
 ENTRY(_dl_bind_start)
        /*
-        * x16 is pointer to pltgot[2]
-        * x17 is available as scratch register
-        * return address and pointer to pltgot entry for this
-        * relocation are on the stack
+        * t0 is the "link map"
+        * t1 is the .got.plt offset
         */
-       mv      x17, sp
 
        /* save parameter/result registers */
-       addi    sp, sp, -(16*8)  /* should be aligned well enough */
-       sd      t1, ( 2*8)(sp)
-       sd      t2, ( 3*8)(sp)
-       sd      a0, ( 4*8)(sp)
-       sd      a1, ( 5*8)(sp)
-       sd      a2, ( 6*8)(sp)
-       sd      a3, ( 7*8)(sp)
-       sd      a4, ( 8*8)(sp)
-       sd      a5, ( 9*8)(sp)
-       sd      a6, (10*8)(sp)
-       sd      a7, (11*8)(sp)
-       sd      t3, (12*8)(sp)
-       sd      t4, (13*8)(sp)
-       sd      t5, (14*8)(sp)
-       sd      t6, (15*8)(sp)
-
-       /* what about float registers !?! */
+       addi    sp, sp, -(10*8)  /* should be aligned well enough */
+       sd      ra, (9*8)(sp)
+       sd      a0, (0*8)(sp)
+       sd      a1, (1*8)(sp)
+       sd      a2, (2*8)(sp)
+       sd      a3, (3*8)(sp)
+       sd      a4, (4*8)(sp)
+       sd      a5, (5*8)(sp)
+       sd      a6, (6*8)(sp)
+       sd      a7, (7*8)(sp)
+
        /*
-        * no need to save v0-v9 as ld.so is compiled with
-        * -march=armv8-a+nofp+nosimd and therefore doesn't touch the
-        * SIMD and Floating-Point registers
+        * no need to save the FP registers as ld.so is compiled such that
+        * it doesn't touch them
         */
 
        mv      a0, t0
-       slli    a1, t1, 1
-       add     a1, a1, t1
+       srli    a1, t1, 3
        jal     _dl_bind
-       nop
        mv      t0, a0
 
-       // restore parameter/result registers
-       ld      t1, ( 2*8)(sp)
-       ld      t2, ( 3*8)(sp)
-       ld      a0, ( 4*8)(sp)
-       ld      a1, ( 5*8)(sp)
-       ld      a2, ( 6*8)(sp)
-       ld      a3, ( 7*8)(sp)
-       ld      a4, ( 8*8)(sp)
-       ld      a5, ( 9*8)(sp)
-       ld      a6, (10*8)(sp)
-       ld      a7, (11*8)(sp)
-       ld      t3, (12*8)(sp)
-       ld      t4, (13*8)(sp)
-       sd      t5, (14*8)(sp)
-       sd      t6, (15*8)(sp)
-       add     sp, sp, (16*8)
-
-       // restore LR saved by PLT stub 
-       // XXX - correct?
-       ld      ra, 16(sp)
-       add     sp, sp, 16
+       /* restore parameter/result registers */
+       ld      a0, (0*8)(sp)
+       ld      a1, (1*8)(sp)
+       ld      a2, (2*8)(sp)
+       ld      a3, (3*8)(sp)
+       ld      a4, (4*8)(sp)
+       ld      a5, (5*8)(sp)
+       ld      a6, (6*8)(sp)
+       ld      a7, (7*8)(sp)
+       ld      ra, (9*8)(sp)
+       addi    sp, sp, (10*8)
+
        jr      t0
 END(_dl_bind_start)
 
index ff37e57..39ec91b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtld_machine.c,v 1.1 2021/04/28 15:16:26 drahn Exp $ */
+/*     $OpenBSD: rtld_machine.c,v 1.2 2021/06/26 14:50:25 kettenis Exp $ */
 
 /*
  * Copyright (c) 2004,2021 Dale Rahn <drahn@openbsd.org>
@@ -241,9 +241,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
        if (object->Dyn.info[DT_PLTREL] != DT_RELA)
                return 0;
 
-       // XXX - fix and enable.
-       lazy = 0;
-
        if (!lazy) {
                fails = _dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ);
        } else {
@@ -256,8 +253,8 @@ _dl_md_reloc_got(elf_object_t *object, int lazy)
                        *where += object->obj_base;
                }
 
+               pltgot[0] = (Elf_Addr)_dl_bind_start;
                pltgot[1] = (Elf_Addr)object;
-               pltgot[2] = (Elf_Addr)_dl_bind_start;
        }
 
        return fails;
@@ -300,7 +297,7 @@ _dl_bind(elf_object_t *object, int relidx)
                register long syscall_num __asm("t0") = SYS_kbind;
                register void *arg1 __asm("a0") = &buf;
                register long  arg2 __asm("a1") = sizeof(buf);
-               register long  arg3 __asm("x2") = cookie;
+               register long  arg3 __asm("a2") = cookie;
 
                __asm volatile("ecall" : "+r" (arg1), "+r" (arg2)
                    : "r" (syscall_num), "r" (arg3)