Replace strlen, index, strcmp in the AArch64 ld.so.  (Why does it have
the soname "ld-linux-aarch64.so.1" and not "ld-linux.so.3" like all
the rest?)


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13858 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index 1453b0b..69d0f37 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -1323,21 +1323,26 @@
    /* If we're using memcheck, use these intercepts right from
       the start, otherwise ld.so makes a lot of noise. */
    if (0==VG_(strcmp)("Memcheck", VG_(details).name)) {
-   //   add_hardwired_spec(
-   //      "ld-linux.so.3", "strlen",
-   //      (Addr)&VG_(arm_linux_REDIR_FOR_strlen),
-   //      complain_about_stripped_glibc_ldso
-   //   );
-   //   //add_hardwired_spec(
-   //   //   "ld-linux.so.3", "index",
-   //   //   (Addr)&VG_(arm_linux_REDIR_FOR_index),
-   //   //   NULL 
-   //   //);
-   //   add_hardwired_spec(
-   //      "ld-linux.so.3", "memcpy",
-   //      (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
-   //      complain_about_stripped_glibc_ldso
-   //   );
+      add_hardwired_spec(
+         "ld-linux-aarch64.so.1", "strlen",
+         (Addr)&VG_(arm64_linux_REDIR_FOR_strlen),
+         complain_about_stripped_glibc_ldso
+      );
+      add_hardwired_spec(
+         "ld-linux-aarch64.so.1", "index",
+         (Addr)&VG_(arm64_linux_REDIR_FOR_index),
+         NULL 
+      );
+      add_hardwired_spec(
+         "ld-linux-aarch64.so.1", "strcmp",
+         (Addr)&VG_(arm64_linux_REDIR_FOR_strcmp),
+         NULL 
+      );
+      //add_hardwired_spec(
+      //   "ld-linux.so.3", "memcpy",
+      //   (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
+      //   complain_about_stripped_glibc_ldso
+      //);
    }
 
 #  elif defined(VGP_x86_darwin)
diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S
index 475133f..a1c4dec 100644
--- a/coregrind/m_trampoline.S
+++ b/coregrind/m_trampoline.S
@@ -706,6 +706,67 @@
 .size VG_(arm64_linux_SUBST_FOR_rt_sigreturn), \
         .-VG_(arm64_linux_SUBST_FOR_rt_sigreturn)
 
+.global VG_(arm64_linux_REDIR_FOR_strlen)
+.type   VG_(arm64_linux_REDIR_FOR_strlen),#function
+VG_(arm64_linux_REDIR_FOR_strlen):
+	mov	x2, x0
+	ldrb	w0, [x0]
+	cbz	w0, .L5
+	mov	x0, 0
+.L4:
+	add	x0, x0, 1
+	ldrb	w1, [x2,x0]
+	cbnz	w1, .L4
+	ret
+.L5:
+	mov	x0, 0
+	ret
+.size VG_(arm64_linux_REDIR_FOR_strlen), .-VG_(arm64_linux_REDIR_FOR_strlen)
+
+.global VG_(arm64_linux_REDIR_FOR_index)
+.type   VG_(arm64_linux_REDIR_FOR_index),#function
+VG_(arm64_linux_REDIR_FOR_index):
+        ldrb    w2, [x0]
+        uxtb    w1, w1
+        cmp     w2, w1
+        beq     .L11
+.L13:
+        cbz     w2, .L16
+        ldrb    w2, [x0,1]!
+        cmp     w2, w1
+        bne     .L13
+.L11:
+        ret
+.L16:
+        mov     x0, 0
+        ret
+.size VG_(arm64_linux_REDIR_FOR_index), .-VG_(arm64_linux_REDIR_FOR_index)
+
+.global VG_(arm64_linux_REDIR_FOR_strcmp)
+.type   VG_(arm64_linux_REDIR_FOR_strcmp),#function
+VG_(arm64_linux_REDIR_FOR_strcmp):
+        ldrb    w2, [x0]
+        ldrb    w3, [x1]
+        cmp     w2, w3
+        bcc     .L22
+.L21:
+        bhi     .L25
+        cbz     w2, .L26
+        ldrb    w2, [x0,1]!
+        ldrb    w3, [x1,1]!
+        cmp     w2, w3
+        bcs     .L21
+.L22:
+        mov     x0, -1
+        ret
+.L25:
+        mov     x0, 1
+        ret
+.L26:
+        mov     x0, 0
+        ret
+.size VG_(arm64_linux_REDIR_FOR_strcmp), .-VG_(arm64_linux_REDIR_FOR_strcmp)
+
 .global VG_(trampoline_stuff_end)
 VG_(trampoline_stuff_end):
 
diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h
index 39baac6..755f8b9 100644
--- a/coregrind/pub_core_trampoline.h
+++ b/coregrind/pub_core_trampoline.h
@@ -105,6 +105,9 @@
 
 #if defined(VGP_arm64_linux)
 extern Addr  VG_(arm64_linux_SUBST_FOR_rt_sigreturn);
+extern ULong VG_(arm64_linux_REDIR_FOR_strlen)( void* );
+extern void* VG_(arm64_linux_REDIR_FOR_index) ( void*, Long );
+extern Long  VG_(arm64_linux_REDIR_FOR_strcmp)( void*, void* );
 #endif
 
 #if defined(VGP_x86_darwin)