diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-12-21 00:32:56 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2017-12-21 00:32:56 +0000 |
commit | 61ccc4e471508962325312963ad7d2dbcaf1286f (patch) | |
tree | 78ba4fa31dc251c6e91542124dee2e8deb51d57b /libexec/ld.so/aarch64 | |
parent | 2bb50981ca4440f926c98ae16b0ab431db820c43 (diff) |
Implement missing bits to support lazy binding. Note that the code
deliberately does not save the floating-point argument registers
before calling _dl_bind(). Doing so would force an FPU context switch
upon every function call through the PLT. But since we compile ld.so
with -march=armv8-a+nofp+nosimd this is safe since nothing in the _dl_bind()
codepath uses he FPU registers.
ok guenther@, drahn@
Diffstat (limited to 'libexec/ld.so/aarch64')
-rw-r--r-- | libexec/ld.so/aarch64/ldasm.S | 80 | ||||
-rw-r--r-- | libexec/ld.so/aarch64/rtld_machine.c | 4 |
2 files changed, 38 insertions, 46 deletions
diff --git a/libexec/ld.so/aarch64/ldasm.S b/libexec/ld.so/aarch64/ldasm.S index f60480d82b5..890936c2275 100644 --- a/libexec/ld.so/aarch64/ldasm.S +++ b/libexec/ld.so/aarch64/ldasm.S @@ -1,4 +1,4 @@ -/* $OpenBSD: ldasm.S,v 1.4 2017/08/27 21:59:51 deraadt Exp $ */ +/* $OpenBSD: ldasm.S,v 1.5 2017/12/21 00:32:55 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -65,50 +65,44 @@ ENTRY(_dl_start) ENTRY(_dl_bind_start) /* - * ip is pointer to got entry for this relocation - * lr is pointer to pltgot[2], which is entry -1 of got plt reloc. - * return address is on stack + * 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 */ - stp x29, x30, [sp, #-160]! - stp x0, x1, [sp,#16] - stp x2, x3, [sp,#32] - stp x4, x5, [sp,#48] - stp x6, x7, [sp,#64] - stp x8, x9, [sp,#80] - stp x10, x11, [sp,#96] - stp x12, x13, [sp,#112] - stp x14, x15, [sp,#128] - str x18, [sp,#144] - - mov x1, x16 // reladdr - - - ldp x0, x1, [sp,#16] - ldp x2, x3, [sp,#32] - ldp x4, x5, [sp,#48] - ldp x6, x7, [sp,#64] - ldp x8, x9, [sp,#80] - ldp x10, x11, [sp,#96] - ldp x12, x13, [sp,#112] - ldp x14, x15, [sp,#128] - ldr x18, [sp,#144] - ldp x29, x30, [sp], #-160 - br x16 - - -#if 0 - stmdb sp!, {r0-r4,sl,fp} - - sub r1, ip, lr /* r1 = 4 * (n + 1) */ - sub r1, r1, #4 /* r1 = 4 * n */ - mov r1, r1, lsr #2 /* r1 = n */ - - ldr r0, [lr, #-4] + mov x17, sp + + // save parameter/result registers + stp x0, x1, [sp, #-16]! + stp x2, x3, [sp, #-16]! + stp x4, x5, [sp, #-16]! + stp x6, x7, [sp, #-16]! + stp x8, xzr, [sp, #-16]! + + /* + * 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 + */ + + ldr x0, [x16, #-8] // object + ldr x2, [x17] + sub x1, x2, x16 + sub x1, x1, #8 + lsr x1, x1, #3 // relidx bl _dl_bind - mov ip, r0 - ldmia sp!, {r0-r4,sl,fp,lr} - mov pc, ip -#endif + mov x17, x0 + + // restore parameter/result registers + ldp x8, xzr, [sp], #16 + ldp x6, x7, [sp], #16 + ldp x4, x5, [sp], #16 + ldp x2, x3, [sp], #16 + ldp x0, x1, [sp], #16 + + // restore LR saved by PLT stub + ldp xzr, x30, [sp], #16 + br x17 ENTRY(_rtld_tlsdesc) ldr x0, [x0, #8] diff --git a/libexec/ld.so/aarch64/rtld_machine.c b/libexec/ld.so/aarch64/rtld_machine.c index 2316b0a9179..c7c666381c7 100644 --- a/libexec/ld.so/aarch64/rtld_machine.c +++ b/libexec/ld.so/aarch64/rtld_machine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtld_machine.c,v 1.4 2017/10/24 20:35:54 guenther Exp $ */ +/* $OpenBSD: rtld_machine.c,v 1.5 2017/12/21 00:32:55 kettenis Exp $ */ /* * Copyright (c) 2004 Dale Rahn @@ -294,8 +294,6 @@ _dl_md_reloc_got(elf_object_t *object, int lazy) if (object->traced) lazy = 1; - lazy = 0; // until support is written. - if (!lazy) { fails = _dl_md_reloc(object, DT_JMPREL, DT_PLTRELSZ); } else { |