From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32726 invoked by alias); 4 Mar 2013 23:33:09 -0000 Received: (qmail 32716 invoked by uid 22791); 4 Mar 2013 23:33:08 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from toast.topped-with-meat.com (HELO topped-with-meat.com) (204.197.218.159) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 04 Mar 2013 23:33:03 +0000 Received: by topped-with-meat.com (Postfix, from userid 5281) id 7D40A2C08B; Mon, 4 Mar 2013 15:33:02 -0800 (PST) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit From: Roland McGrath to: libc-ports@sourceware.org Subject: [PATCH roland/arm-avoid-pc] ARM_BX_ALIGN_LOG2 Message-Id: <20130304233302.7D40A2C08B@topped-with-meat.com> Date: Mon, 04 Mar 2013 23:33:00 -0000 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=LYSvtFvi c=1 sm=1 tr=0 a=WkljmVdYkabdwxfqvArNOQ==:117 a=14OXPxybAAAA:8 a=uhDOp3YjA3IA:10 a=Z6MIti7PxpgA:10 a=kj9zAlcOel0A:10 a=hOe2yjtxAAAA:8 a=_WG08a5xAUcA:10 a=zzha5f-aZVcb3yJgKj0A:9 a=CjuIK1q_8ugA:10 X-IsSubscribed: yes Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org X-SW-Source: 2013-03/txt/msg00026.txt.bz2 This is on top of the ARM_ALWAYS_BX patch, which is on the same branch. Tested on armv7l-linux-gnueabihf: no changes to the object code. Tested the new code by locally hacking arm-features.h to define ARM_ALWAYS_BX and ARM_BX_ALIGN_LOG2=4, and verifying no failures in 'make check subdirs=string'. I didn't actually test ARM_BX_ALIGN_LOG2=4 without ARM_ALWAYS_BX, which is a configuration that will probably never be used (but I wrote this code to support it)--it's pretty easy to tell by inspection that it's equivalent to what I did test. Thanks, Roland ports/ChangeLog.arm * sysdeps/arm/arm-features.h (ARM_BX_ALIGN_LOG2): New macro. * sysdeps/arm/memcpy.S: Respect ARM_BX_ALIGN_LOG2. * sysdeps/arm/memmove.S: Likewise. --- a/ports/sysdeps/arm/arm-features.h +++ b/ports/sysdeps/arm/arm-features.h @@ -40,4 +40,12 @@ that instructions using pc as a destination register must never be used, so a "bx" (or "blx") instruction is always required. */ +/* The log2 of the minimum alignment required for an address that + is the target of a computed branch (i.e. a "bx" instruction). + A more-specific arm-features.h file may define this to set a more + stringent requirement. */ +#ifndef ARM_BX_ALIGN_LOG2 +# define ARM_BX_ALIGN_LOG2 2 +#endif + #endif /* arm-features.h */ --- a/ports/sysdeps/arm/memcpy.S +++ b/ports/sysdeps/arm/memcpy.S @@ -90,9 +90,9 @@ ENTRY(memcpy) CALGN( adr r4, 6f ) CALGN( subs r2, r2, r3 ) @ C gets set #ifndef ARM_ALWAYS_BX - CALGN( add pc, r4, ip ) + CALGN( add pc, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)) #else - CALGN( add r4, r4, ip ) + CALGN( add r4, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)) CALGN( bx r4 ) #endif @@ -114,38 +114,55 @@ ENTRY(memcpy) 5: ands ip, r2, #28 rsb ip, ip, #32 #ifndef ARM_ALWAYS_BX - addne pc, pc, ip @ C is always clear here + /* C is always clear here. */ + addne pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) b 7f #else beq 7f push {r10} cfi_adjust_cfa_offset (4) - add r10, pc, ip + add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) bx r10 #endif + .p2align ARM_BX_ALIGN_LOG2 6: nop + .p2align ARM_BX_ALIGN_LOG2 ldr r3, [r1], #4 + .p2align ARM_BX_ALIGN_LOG2 ldr r4, [r1], #4 + .p2align ARM_BX_ALIGN_LOG2 ldr r5, [r1], #4 + .p2align ARM_BX_ALIGN_LOG2 ldr r6, [r1], #4 + .p2align ARM_BX_ALIGN_LOG2 ldr r7, [r1], #4 + .p2align ARM_BX_ALIGN_LOG2 ldr r8, [r1], #4 + .p2align ARM_BX_ALIGN_LOG2 ldr lr, [r1], #4 #ifndef ARM_ALWAYS_BX - add pc, pc, ip + add pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) nop #else - add r10, pc, ip + add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) bx r10 #endif + .p2align ARM_BX_ALIGN_LOG2 nop + .p2align ARM_BX_ALIGN_LOG2 str r3, [r0], #4 + .p2align ARM_BX_ALIGN_LOG2 str r4, [r0], #4 + .p2align ARM_BX_ALIGN_LOG2 str r5, [r0], #4 + .p2align ARM_BX_ALIGN_LOG2 str r6, [r0], #4 + .p2align ARM_BX_ALIGN_LOG2 str r7, [r0], #4 + .p2align ARM_BX_ALIGN_LOG2 str r8, [r0], #4 + .p2align ARM_BX_ALIGN_LOG2 str lr, [r0], #4 #ifdef ARM_ALWAYS_BX --- a/ports/sysdeps/arm/memmove.S +++ b/ports/sysdeps/arm/memmove.S @@ -106,9 +106,9 @@ ENTRY(memmove) CALGN( adr r4, 6f ) CALGN( subs r2, r2, ip ) @ C is set here #ifndef ARM_ALWAYS_BX - CALGN( add pc, r4, ip ) + CALGN( add pc, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)) #else - CALGN( add r4, r4, ip ) + CALGN( add r4, r4, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)) CALGN( bx r4 ) #endif @@ -130,38 +130,55 @@ ENTRY(memmove) 5: ands ip, r2, #28 rsb ip, ip, #32 #ifndef ARM_ALWAYS_BX - addne pc, pc, ip @ C is always clear here + /* C is always clear here. */ + addne pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) b 7f #else beq 7f push {r10} cfi_adjust_cfa_offset (4) - add r10, pc, ip + add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) bx r10 #endif + .p2align ARM_BX_ALIGN_LOG2 6: nop + .p2align ARM_BX_ALIGN_LOG2 ldr r3, [r1, #-4]! + .p2align ARM_BX_ALIGN_LOG2 ldr r4, [r1, #-4]! + .p2align ARM_BX_ALIGN_LOG2 ldr r5, [r1, #-4]! + .p2align ARM_BX_ALIGN_LOG2 ldr r6, [r1, #-4]! + .p2align ARM_BX_ALIGN_LOG2 ldr r7, [r1, #-4]! + .p2align ARM_BX_ALIGN_LOG2 ldr r8, [r1, #-4]! + .p2align ARM_BX_ALIGN_LOG2 ldr lr, [r1, #-4]! #ifndef ARM_ALWAYS_BX - add pc, pc, ip + add pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) nop #else - add r10, pc, ip + add r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2) bx r10 #endif + .p2align ARM_BX_ALIGN_LOG2 nop + .p2align ARM_BX_ALIGN_LOG2 str r3, [r0, #-4]! + .p2align ARM_BX_ALIGN_LOG2 str r4, [r0, #-4]! + .p2align ARM_BX_ALIGN_LOG2 str r5, [r0, #-4]! + .p2align ARM_BX_ALIGN_LOG2 str r6, [r0, #-4]! + .p2align ARM_BX_ALIGN_LOG2 str r7, [r0, #-4]! + .p2align ARM_BX_ALIGN_LOG2 str r8, [r0, #-4]! + .p2align ARM_BX_ALIGN_LOG2 str lr, [r0, #-4]! #ifdef ARM_ALWAYS_BX