diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2015-06-01 19:02:12 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2015-06-01 19:02:12 +0000 |
commit | 44fa1dccdea3d69e80a3e4e3dbe581b1fca2da28 (patch) | |
tree | dcd3b5b7d3b50b6adc05efb9beb726003c4715d3 /lib/libc | |
parent | 4d6f487258a174e9bcb3d164f4cd1c9514278342 (diff) |
Since the __{div,rem}{l,q}{,u} special libc entry points use a specific
calling convention which conflicts over t11 usage with the secureplt
calling convention, force these symbols to be `notype' rather `function', so
that the linker will not attempt to use plt relocations for them in the
absence of explicit relocation information.
Note that these symbols are still public and still callable with the old plt
convention, so existing binaries will still work with an updated libc, and
no libc version change is necessary.
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/arch/alpha/gen/divrem.m4 | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/lib/libc/arch/alpha/gen/divrem.m4 b/lib/libc/arch/alpha/gen/divrem.m4 index 94ec9201379..cb3501075ca 100644 --- a/lib/libc/arch/alpha/gen/divrem.m4 +++ b/lib/libc/arch/alpha/gen/divrem.m4 @@ -1,4 +1,4 @@ -/* $OpenBSD: divrem.m4,v 1.4 2003/03/01 00:19:08 miod Exp $ */ +/* $OpenBSD: divrem.m4,v 1.5 2015/06/01 19:02:11 miod Exp $ */ /* $NetBSD: divrem.m4,v 1.7 1996/10/17 03:08:04 cgd Exp $ */ /* @@ -57,16 +57,41 @@ ifelse(S, `true', `define(NEG, `t4')') #include <machine/asm.h> -LEAF(NAME, 0) /* XXX */ +/* + * These functions use t11 as an input, which makes them incompatible with + * the secureplt calling sequence. The compiler knows about this, and will + * ask for a call through a got relocation. But this can only work if the + * linker omits creating a plt entry for the symbol. In order to achieve + * this, we need to declare it as `notype' instead of `function', which + * means that LEAF(NAME, 0) can't be used as it uses .ent which forces the + * `function' type. + */ + .globl NAME + .type NAME, @notype + .usepv NAME, no + + .cfi_startproc + .cfi_return_column ra +NAME: + MCOUNT lda sp, -64(sp) + .cfi_def_cfa_offset 64 stq BIT, 0(sp) + .cfi_rel_offset BIT, 0 stq I, 8(sp) + .cfi_rel_offset I, 8 stq CC, 16(sp) + .cfi_rel_offset CC, 16 stq T_0, 24(sp) -ifelse(S, `true', -` stq NEG, 32(sp)') + .cfi_rel_offset T_0, 24 +ifelse(S, `true',`dnl + stq NEG, 32(sp) + .cfi_rel_offset NEG, 32 +')dnl stq A, 40(sp) + .cfi_rel_offset A, 40 stq B, 48(sp) + .cfi_rel_offset B, 48 mov zero, RESULT /* Initialize result to zero */ ifelse(S, `true', @@ -177,14 +202,23 @@ ifelse(S, `true', ') ldq BIT, 0(sp) + .cfi_restore BIT ldq I, 8(sp) + .cfi_restore I ldq CC, 16(sp) + .cfi_restore CC ldq T_0, 24(sp) -ifelse(S, `true', -` ldq NEG, 32(sp)') + .cfi_restore T_0 +ifelse(S, `true',`dnl + ldq NEG, 32(sp) + .cfi_restore NEG +')dnl ldq A, 40(sp) + .cfi_restore A ldq B, 48(sp) + .cfi_restore B lda sp, 64(sp) + .cfi_def_cfa_offset 0 ret zero, (t9), 1 Ldotrap: @@ -195,4 +229,9 @@ ifelse(OP, `div', ') br zero, Lret_result -END(NAME) +/* + * For the reasons stated above, we can not use END(NAME) either, as it + * expands to .end which requires a matching .ent. + */ + .cfi_endproc + .size NAME, . - NAME |