From: Julian Seward Date: Mon, 28 Mar 2011 08:22:55 +0000 (+0000) Subject: Intercept strlen in ld.so on x86. Fixes #266961. X-Git-Tag: svn/VALGRIND_3_7_0~566 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc53563392f7b7b53623908084f608ff3ac310ee;p=thirdparty%2Fvalgrind.git Intercept strlen in ld.so on x86. Fixes #266961. (Jakub Jelinek, jakub@redhat.com) git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11668 --- diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index 065b61aa07..b45b03ece0 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -924,20 +924,23 @@ void VG_(redir_initialise) ( void ) /* If we're using memcheck, use this intercept right from the start, otherwise ld.so (glibc-2.3.5) makes a lot of noise. */ if (0==VG_(strcmp)("Memcheck", VG_(details).name)) { + const HChar** mandatory; +# if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \ + || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \ + || defined(GLIBC_2_8) || defined(GLIBC_2_9) \ + || defined(GLIBC_2_10) || defined(GLIBC_2_11) + mandatory = NULL; +# else + /* for glibc-2.12 and later, this is mandatory - can't sanely + continue without it */ + mandatory = complain_about_stripped_glibc_ldso; +# endif add_hardwired_spec( "ld-linux.so.2", "index", - (Addr)&VG_(x86_linux_REDIR_FOR_index), -# if defined(GLIBC_2_2) || defined(GLIBC_2_3) || defined(GLIBC_2_4) \ - || defined(GLIBC_2_5) || defined(GLIBC_2_6) || defined(GLIBC_2_7) \ - || defined(GLIBC_2_8) || defined(GLIBC_2_9) \ - || defined(GLIBC_2_10) || defined(GLIBC_2_11) - NULL -# else - /* for glibc-2.12 and later, this is mandatory - can't sanely - continue without it */ - complain_about_stripped_glibc_ldso -# endif - ); + (Addr)&VG_(x86_linux_REDIR_FOR_index), mandatory); + add_hardwired_spec( + "ld-linux.so.2", "strlen", + (Addr)&VG_(x86_linux_REDIR_FOR_strlen), mandatory); } # elif defined(VGP_amd64_linux) diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S index 0fdcf9e83f..eefdbfce0a 100644 --- a/coregrind/m_trampoline.S +++ b/coregrind/m_trampoline.S @@ -112,6 +112,27 @@ VG_(x86_linux_REDIR_FOR_index): ret .size VG_(x86_linux_REDIR_FOR_index), .-VG_(x86_linux_REDIR_FOR_index) +/* There's no particular reason that this needs to be handwritten + assembly, but since that's what this file contains, here's a + simple strlen implementation (written in C and compiled by gcc.) +*/ +.global VG_(x86_linux_REDIR_FOR_strlen) +.type VG_(x86_linux_REDIR_FOR_strlen), @function +VG_(x86_linux_REDIR_FOR_strlen): + pushl %ebp + movl %esp, %ebp + movl 8(%ebp), %edx + movl %edx, %eax + jmp 2f +1: incl %eax +2: cmpb $0, (%eax) + jne 1b + subl %edx, %eax + popl %ebp + ret +.size VG_(x86_linux_REDIR_FOR_strlen), .-VG_(x86_linux_REDIR_FOR_strlen) + + .global VG_(trampoline_stuff_end) VG_(trampoline_stuff_end): diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h index 5eafcbbf7d..aee983c1b7 100644 --- a/coregrind/pub_core_trampoline.h +++ b/coregrind/pub_core_trampoline.h @@ -60,6 +60,7 @@ extern Addr VG_(trampoline_stuff_end); extern Addr VG_(x86_linux_SUBST_FOR_sigreturn); extern Addr VG_(x86_linux_SUBST_FOR_rt_sigreturn); extern Char* VG_(x86_linux_REDIR_FOR_index) ( const Char*, Int ); +extern UInt VG_(x86_linux_REDIR_FOR_strlen)( void* ); #endif #if defined(VGP_amd64_linux)