From ba4624ee143a0c6453f7aa6bfc68d9c16c7e984c Mon Sep 17 00:00:00 2001 From: miod Date: Mon, 1 Jun 2015 19:02:11 +0000 Subject: [PATCH] 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. --- lib/libc/arch/alpha/gen/divrem.m4 | 53 +++++++++++++++++++++++++++---- 1 file 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 -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 -- 2.20.1