summary refs log tree commit diff
diff options
context:
space:
mode:
authorRajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>2016-07-05 21:20:41 +0530
committerRajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>2016-07-05 21:20:41 +0530
commit30e4cc5413f72c2c728a544389da0c48500d9904 (patch)
tree261f08774100bfd10af7e10ab04c49b238343f89
parent2918b0d0ecbf781400577d63aed7eaa4498dad91 (diff)
downloadglibc-30e4cc5413f72c2c728a544389da0c48500d9904.tar.gz
glibc-30e4cc5413f72c2c728a544389da0c48500d9904.tar.xz
glibc-30e4cc5413f72c2c728a544389da0c48500d9904.zip
powerpc: Fix return code of strcasecmp for unaligned inputs
If the input values are unaligned and if there are null characters in the
memory before the starting address of the input values, strcasecmp
gives incorrect return code. Fixed it by adding mask the bits that
are not part of the string.
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/powerpc/powerpc64/power8/strcasecmp.S17
2 files changed, 20 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 66627f1fb5..cc875c5120 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2016-07-05  Rajalakshmi Srinivasaraghavan  <raji@linux.vnet.ibm.com>
+
+	[BZ #20327]
+	* sysdeps/powerpc/powerpc64/power8/strcasecmp.S: Mask bits that
+	are not part of the string.
+
 2016-07-05  Adhemerval Zanella  <adhemerval.zanella@linaro.org>
 
 	* nptl/tst-cancel4-common.c (do_test): Add temporary fifo creation.
diff --git a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S
index 63f62171d9..c83dc524e8 100644
--- a/sysdeps/powerpc/powerpc64/power8/strcasecmp.S
+++ b/sysdeps/powerpc/powerpc64/power8/strcasecmp.S
@@ -40,11 +40,20 @@
 	vsel	v5, v7, v5, v8; \
 	vcmpequb.	v7, v5, v4;
 
-/* Get 16 bytes for unaligned case.  */
+/*
+ * Get 16 bytes for unaligned case.
+ * reg1: Vector to hold next 16 bytes.
+ * reg2: Address to read from.
+ * reg3: Permute control vector.
+ * v8: Tmp vector used to mask unwanted bytes.
+ * v9: Tmp vector,0 when null is found on first 16 bytes
+ */
 #ifdef __LITTLE_ENDIAN__
 #define GET16BYTES(reg1, reg2, reg3) \
 	lvx	reg1, 0, reg2; \
-	vcmpequb.	v8, v0, reg1; \
+	vspltisb	v8, -1; \
+	vperm	v8, v8, reg1, reg3; \
+	vcmpequb.	v8, v0, v8; \
 	beq	cr6, 1f; \
 	vspltisb	v9, 0; \
 	b	2f; \
@@ -57,7 +66,9 @@
 #else
 #define GET16BYTES(reg1, reg2, reg3) \
 	lvx	reg1, 0, reg2; \
-	vcmpequb.	v8, v0, reg1; \
+	vspltisb	 v8, -1; \
+	vperm	v8, reg1, v8,  reg3; \
+	vcmpequb.	v8, v0, v8; \
 	beq	cr6, 1f; \
 	vspltisb	v9, 0; \
 	b	2f; \