Bug 338615 suppress glibc 2.20 optimized strcmp implementation for ARMv7.

Add an add_hardwired_spec for strcmp in VG_(redir_initialise) for
ld-linux.so.3 and ld-linux-armhf.so.3 to use a simple strcmp
implementation in m_trampoline.S (compiled from the trivial .c code
to asm with gcc like the other implementations in that file).

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14374 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index 2078d00..ca9973e 100644
--- a/NEWS
+++ b/NEWS
@@ -216,6 +216,7 @@
 338205  configure.ac and check for -Wno-tautological-compare
 338445  amd64 vbit-test fails with unknown opcodes used by arm64 VEX
 338499  --sim-hints parsing broken due to wrong order in tokens
+338615  suppress glibc 2.20 optimized strcmp implementation for ARMv7
 n-i-bz  Fix KVM_CREATE_IRQCHIP ioctl handling
 n-i-bz  s390x: Fix memory corruption for multithreaded applications
 n-i-bz  vex arm->IR: allow PC as basereg in some LDRD cases
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index 1fb3df2..374b796 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -1388,6 +1388,17 @@
          (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
          complain_about_stripped_glibc_ldso
       );
+      /* strcmp */
+      add_hardwired_spec(
+         "ld-linux.so.3", "strcmp",
+         (Addr)&VG_(arm_linux_REDIR_FOR_strcmp),
+         complain_about_stripped_glibc_ldso
+      );
+      add_hardwired_spec(
+         "ld-linux-armhf.so.3", "strcmp",
+         (Addr)&VG_(arm_linux_REDIR_FOR_strcmp),
+         complain_about_stripped_glibc_ldso
+      );
    }
 
 #  elif defined(VGP_arm64_linux)
diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S
index 2394100..81a1b1e 100644
--- a/coregrind/m_trampoline.S
+++ b/coregrind/m_trampoline.S
@@ -700,6 +700,22 @@
 	ldmfd	sp!, {r4, r5, pc}
 	UD2_4
 
+.global VG_(arm_linux_REDIR_FOR_strcmp)
+VG_(arm_linux_REDIR_FOR_strcmp):
+.L64:
+	ldrb	r3, [r0], #1	@ zero_extendqisi2
+	ldrb	r2, [r1], #1	@ zero_extendqisi2
+	cmp	r3, #0
+	beq	.L67
+	cmp	r3, r2
+	beq	.L64
+	rsb	r0, r2, r3
+	bx	lr
+.L67:
+	rsb	r0, r2, #0
+	bx	lr
+	UD2_4
+
 .global VG_(trampoline_stuff_end)
 VG_(trampoline_stuff_end):
 
diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h
index b4c056b..51dbc13 100644
--- a/coregrind/pub_core_trampoline.h
+++ b/coregrind/pub_core_trampoline.h
@@ -101,6 +101,7 @@
 extern UInt  VG_(arm_linux_REDIR_FOR_strlen)( void* );
 //extern void* VG_(arm_linux_REDIR_FOR_index) ( void*, Int );
 extern void* VG_(arm_linux_REDIR_FOR_memcpy)( void*, void*, Int );
+extern void* VG_(arm_linux_REDIR_FOR_strcmp)( void*, void* );
 #endif
 
 #if defined(VGP_arm64_linux)