about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2015-03-19 12:45:24 -0700
committerRoland McGrath <roland@hack.frob.com>2015-03-19 12:45:24 -0700
commit298e5d56dca199aea2c18ef27dd33bd82c879ee4 (patch)
treec30e0d64a0529f470c6f60ea91e73cc7a0f842d9
parentbecb26b84bfe4d3273c4e2d4e7684dfbbf7c6bcd (diff)
downloadglibc-298e5d56dca199aea2c18ef27dd33bd82c879ee4.tar.gz
glibc-298e5d56dca199aea2c18ef27dd33bd82c879ee4.tar.xz
glibc-298e5d56dca199aea2c18ef27dd33bd82c879ee4.zip
ARM: Fix memcpy & memmove for [ARM_ALWAYS_BX]
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/arm/memcpy.S16
-rw-r--r--sysdeps/arm/memmove.S16
3 files changed, 32 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index b9b3c2cda9..9d14696f7d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-19  Roland McGrath  <roland@hack.frob.com>
+
+	* sysdeps/arm/memcpy.S [ARM_ALWAYS_BX]: Fix computed-jump calculations
+	to account for alignment padding.
+	* sysdeps/arm/memmove.S: Likewise.
+
 2015-03-19  Chris Metcalf  <cmetcalf@ezchip.com>
 
 	* sysdeps/unix/sysv/linux/generic/README: New file.
diff --git a/sysdeps/arm/memcpy.S b/sysdeps/arm/memcpy.S
index 0602d992f0..3e41ea6f61 100644
--- a/sysdeps/arm/memcpy.S
+++ b/sysdeps/arm/memcpy.S
@@ -125,7 +125,12 @@ ENTRY(memcpy)
 		push	{r10}
 		cfi_adjust_cfa_offset (4)
 		cfi_rel_offset (r10, 0)
-		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+0:		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+		/* If alignment is not perfect, then there will be some
+		   padding (nop) instructions between this BX and label 6.
+		   The computation above assumed that two instructions
+		   later is exactly the right spot.  */
+		add	r10, #(6f - (0b + PC_OFS))
 		bx	r10
 #endif
 		.p2align ARM_BX_ALIGN_LOG2
@@ -156,11 +161,16 @@ ENTRY(memcpy)
 		add	pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
 		nop
 #else
-		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+0:		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+		/* If alignment is not perfect, then there will be some
+		   padding (nop) instructions between this BX and label 66.
+		   The computation above assumed that two instructions
+		   later is exactly the right spot.  */
+		add	r10, #(66f - (0b + PC_OFS))
 		bx	r10
 #endif
 		.p2align ARM_BX_ALIGN_LOG2
-		nop
+66:		nop
 		.p2align ARM_BX_ALIGN_LOG2
 		sfi_breg r0, \
 		str	r3, [\B], #4
diff --git a/sysdeps/arm/memmove.S b/sysdeps/arm/memmove.S
index f8a4eff2a4..dde877e5f3 100644
--- a/sysdeps/arm/memmove.S
+++ b/sysdeps/arm/memmove.S
@@ -141,7 +141,12 @@ ENTRY(memmove)
 		push	{r10}
 		cfi_adjust_cfa_offset (4)
 		cfi_rel_offset (r10, 0)
-		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+0:		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+		/* If alignment is not perfect, then there will be some
+		   padding (nop) instructions between this BX and label 6.
+		   The computation above assumed that two instructions
+		   later is exactly the right spot.  */
+		add	r10, #(6f - (0b + PC_OFS))
 		bx	r10
 #endif
 		.p2align ARM_BX_ALIGN_LOG2
@@ -172,11 +177,16 @@ ENTRY(memmove)
 		add	pc, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
 		nop
 #else
-		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+0:		add	r10, pc, ip, lsl #(ARM_BX_ALIGN_LOG2 - 2)
+		/* If alignment is not perfect, then there will be some
+		   padding (nop) instructions between this BX and label 66.
+		   The computation above assumed that two instructions
+		   later is exactly the right spot.  */
+		add	r10, #(66f - (0b + PC_OFS))
 		bx	r10
 #endif
 		.p2align ARM_BX_ALIGN_LOG2
-		nop
+66:		nop
 		.p2align ARM_BX_ALIGN_LOG2
 		sfi_breg r0, \
 		str	r3, [\B, #-4]!