Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/libexec/ld.elf_so/arch/vax Once we know the bound routine, r...
details: https://anonhg.NetBSD.org/src/rev/febee5979dbb
branches: trunk
changeset: 327861:febee5979dbb
user: matt <matt%NetBSD.org@localhost>
date: Wed Mar 19 02:39:22 2014 +0000
description:
Once we know the bound routine, rebuilt a new callframe that can be unwound
properly.
diffstat:
libexec/ld.elf_so/arch/vax/rtld_start.S | 110 +++++++++++++++++++++++++------
1 files changed, 87 insertions(+), 23 deletions(-)
diffs (127 lines):
diff -r 289f3a7a868f -r febee5979dbb libexec/ld.elf_so/arch/vax/rtld_start.S
--- a/libexec/ld.elf_so/arch/vax/rtld_start.S Wed Mar 19 01:24:32 2014 +0000
+++ b/libexec/ld.elf_so/arch/vax/rtld_start.S Wed Mar 19 02:39:22 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld_start.S,v 1.17 2014/03/18 23:43:38 matt Exp $ */
+/* $NetBSD: rtld_start.S,v 1.18 2014/03/19 02:39:22 matt Exp $ */
/*
* Copyright 1996 Matt Thomas <matt%3am-software.com@localhost>
@@ -64,31 +64,95 @@
* hence the `optimization' to avoid the callg opportunistically.
*/
ALTENTRY(_rtld_bind_start)
- .cfi_startproc
- .cfi_def_cfa 13, 60
- .cfi_offset 16, -56
- .cfi_offset 12, -52
- .cfi_offset 13, -48
- .cfi_offset 15, -44
- .cfi_offset 2, -40
- .cfi_offset 3, -36
- .cfi_offset 4, -32
- .cfi_offset 5, -28
- .cfi_offset 6, -24
- .cfi_offset 7, -20
- .cfi_offset 8, -16
- .cfi_offset 9, -12
- .cfi_offset 10, -8
- .cfi_offset 11, -4
+ movab -64(%sp),%sp /* reserve some space */
pushr $0x3f /* save R0-R5 */
- movq 24(%sp),%r0 /* get addresses of plt.got & reloc index */
+ movq -8(%fp),%r0 /* get addresses of plt.got & reloc index */
pushl (%r1) /* push relocation index */
pushl %r0 /* push address of obj entry */
calls $2,_rtld_bind
- movl %r0,28(%sp) /* save return address onto stack */
+
+ movl %r0,%r3 /* save routine address */
+ extzv $0,$12,(%r0),%r1 /* get entry mask */
+ extzv $0,$12,6(%fp),%r2 /* get saved mask */
+ cmpw %r1,%r2 /* compare them */
+ bneq 12f /* if they are different, rebuild */
+ movl %r0,-4(%fp) /* save routine address */
+ popr $0x3f /* pop registers */
+ movab 68(%sp),%sp /* restore sp */
+ rsb /* and jump to it */
+
+ /*
+ * We need to rebuild the callframe. Save the current one in case
+ * we might overwrite it.
+ */
+12: movq 4(%fp),-(%sp) /* save PSW and AP */
+ movq 12(%fp),-(%sp) /* save FP and return address */
+ /*
+ * Find out where this this call frame ends.
+ */
+ movl %ap,%r0 /* get past callframe and registers */
+ bbs $29,4(%fp),22f /* calls is easy, it's where AP is */
+ /*
+ * Callg not so much
+ */
+ movab 20(%fp),%r0 /* past fixed callframe */
+ tstw %r2 /* no saved registers? */
+ beql 22f /* none, so we are done. */
+ movl $11,%r4 /* start with register 11 */
+20: bbc %r4,%r2,21f /* save this register? */
+ addl2 $4,%r0 /* yes, adjust for saved register */
+21: sobgeq %r4,20b /* try next register */
+
+22:
+ /*
+ * First "push" the caller saved registers (if there any that
+ * need to saved.)
+ */
+ tstw %r1 /* if there are no registers to save */
+ beql 1f /* just push the callframe */
+ cmpw %r1,$63 /* if there are no caller-saved registers */
+ blequ 5f /* skip them */
+ bbc $11,%r1,10f /* does it need to be saved? */
+ movl %r11,-(%r0)
+10: bbc $10,%r1,9f /* does it need to be saved? */
+ movl %r10,-(%r0)
+9: bbc $9,%r1,8f /* does it need to be saved? */
+ movl %r9,-(%r0)
+8: bbc $8,%r1,7f /* does it need to be saved? */
+ movl %r8,-(%r0)
+7: bbc $7,%r1,6f /* does it need to be saved? */
+ movl %r7,-(%r0)
+6: bbc $6,%r1,5f /* does it need to be saved? */
+ movl %r6,-(%r0)
+5:
+ /*
+ * r0-r5 are not normally preserved so we should be done.
+ */
+ cmpw %r1,$63
+ bgtru 1f
+ /*
+ * For some reason, we have to preserve these.
+ */
+ movab 16(%sp),%r2
+ bbc $5,%r1,4f /* does it need to be saved? */
+ movl 20(%r2),-(%r0)
+4: bbc $4,%r1,3f /* does it need to be saved? */
+ movl 16(%r2),-(%r0)
+3: bbc $3,%r1,2f /* does it need to be saved? */
+ movl 12(%r2),-(%r0)
+2: bbc $2,%r1,1f /* does it need to be saved? */
+ movl 8(%r2),-(%r0)
+
+ /*
+ * Now we save the fixed part of the callframe.
+ */
+1: clrl %r4 /* clear condition handler slot */
+ movq (%sp)+,-(%r0) /* move FP and PC into place */
+ movq (%sp)+,-(%r0) /* move PSW/save-mask/etc + AP into place */
+ movq %r3,-(%r0) /* move routine address + cond handle slot */
+ addl3 $4,%r0,%fp /* get start of new callframe */
+ insv $0,$12,%r1,6(%fp) /* insert new saved mask */
popr $0x3f /* restore R0-R5 (cond flags not modified) */
- addl2 $4,%sp
- callg (%ap),*(%sp)+ /* return value from _rtld_bind() == actual */
- ret
- .cfi_endproc
+ subl3 $4,%fp,%sp /* sp needs to be equal to fp */
+ rsb /* and jmp to the routine */
END(_rtld_bind_start)
Home |
Main Index |
Thread Index |
Old Index