]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Reinstating a heavily modified version of r10402. This is to do
authorJulian Seward <jseward@acm.org>
Sun, 2 Aug 2009 12:21:31 +0000 (12:21 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 2 Aug 2009 12:21:31 +0000 (12:21 +0000)
with #190429.

This patch (originally from Jakub Jelinek) makes the redir of strlen
in ld.so on amd64-linux ld.so mandatory, but only for glibc 2.10 and
above.  For glibc-2.2 (our earliest supported version) to glibc-2.9
it is still optional.

Also, makes more verbose, the message that is printed if a mandatory
ld.so redirection on Linux cannot be set up.

Is believed to fix #190429.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10689

coregrind/m_redir.c
coregrind/m_trampoline.S
coregrind/pub_core_trampoline.h

index a63a556a6bd4361fb48d276577c683801b6386a3..fd7d046ce510a3f74a6203db16b30c85d055d8a6 100644 (file)
@@ -223,8 +223,8 @@ typedef
       HChar* from_fnpatt;  /* from fnname pattern  */
       Addr   to_addr;      /* where redirecting to */
       Bool   isWrap;       /* wrap or replacement? */
-      const HChar* mandatory; /* non-NULL ==> abort V and print the
-                              string if from_sopatt is loaded but
+      HChar** mandatory;   /* non-NULL ==> abort V and print the
+                              strings if from_sopatt is loaded but
                               from_fnpatt cannot be found */
       /* VARIABLE PARTS -- used transiently whilst processing redirections */
       Bool   mark; /* set if spec requires further processing */
@@ -555,6 +555,7 @@ void generate_and_add_actives (
          break;
    }
    if (sp) {
+      HChar** strp;
       HChar* v = "valgrind:  ";
       vg_assert(sp->mark);
       vg_assert(!sp->done);
@@ -581,8 +582,11 @@ void generate_and_add_actives (
       v, VG_(DebugInfo_get_soname)(di));
       VG_(printf)(
       "%s\n", v);
-      VG_(printf)(
-      "%s%s\n", v, sp->mandatory);
+
+      for (strp = sp->mandatory; *strp; strp++)
+         VG_(printf)(
+         "%s%s\n", v, *strp);
+
       VG_(printf)(
       "%s\n", v);
       VG_(printf)(
@@ -809,7 +813,7 @@ static void add_hardwired_active ( Addr from, Addr to )
 __attribute__((unused)) /* not used on all platforms */
 static void add_hardwired_spec ( HChar* sopatt, HChar* fnpatt, 
                                  Addr   to_addr,
-                                 const HChar* const mandatory )
+                                 HChar** mandatory )
 {
    Spec* spec = dinfo_zalloc("redir.ahs.1", sizeof(Spec));
    vg_assert(spec);
@@ -838,6 +842,18 @@ static void add_hardwired_spec ( HChar* sopatt, HChar* fnpatt,
 }
 
 
+__attribute__((unused)) /* not used on all platforms */
+static const HChar* complain_about_stripped_glibc_ldso[]
+= { "Possible fixes: (1, short term): install glibc's debuginfo",
+    "package on this machine.  (2, longer term): ask the packagers",
+    "for your Linux distribution to please in future ship a non-",
+    "stripped ld.so (or whatever the dynamic linker .so is called)",
+    "that exports the above-named function using the standard",
+    "calling conventions for this platform.",
+    NULL
+  };
+
+
 /* Initialise the redir system, and create the initial Spec list and
    for amd64-linux a couple of permanent active mappings.  The initial
    Specs are not converted into Actives yet, on the (checked)
@@ -880,11 +896,26 @@ void VG_(redir_initialise) ( void )
       (Addr)&VG_(amd64_linux_REDIR_FOR_vtime) 
    );
 
-#  elif defined(VGP_ppc32_linux)
-   {
-   static const HChar croakage[]
-     = "Possible fix: install glibc's debuginfo package on this machine.";
+   /* 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-x86-64.so.2", "strlen",
+         (Addr)&VG_(amd64_linux_REDIR_FOR_strlen),
+#        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)
+         NULL
+#        else
+         /* for glibc-2.10 and later, this is mandatory - can't sanely
+            continue without it */
+         complain_about_stripped_glibc_ldso
+#        endif
+      );   
+   }
+
+#  elif defined(VGP_ppc32_linux)
    /* 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)) {
@@ -893,7 +924,7 @@ void VG_(redir_initialise) ( void )
       add_hardwired_spec(
          "ld.so.1", "strlen",
          (Addr)&VG_(ppc32_linux_REDIR_FOR_strlen),
-         croakage
+         complain_about_stripped_glibc_ldso
       );   
       add_hardwired_spec(
          "ld.so.1", "strcmp",
@@ -908,13 +939,8 @@ void VG_(redir_initialise) ( void )
          /* glibc-2.6.1 (openSUSE 10.3, ppc32) seems fine without it */
       );
    }
-   }
 
 #  elif defined(VGP_ppc64_linux)
-   {
-   static const HChar croakage[]
-     = "Possible fix: install glibc's debuginfo package on this machine.";
-
    /* 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)) {
@@ -923,7 +949,7 @@ void VG_(redir_initialise) ( void )
       add_hardwired_spec(
          "ld64.so.1", "strlen",
          (Addr)VG_(fnptr_to_fnentry)( &VG_(ppc64_linux_REDIR_FOR_strlen) ),
-         croakage
+         complain_about_stripped_glibc_ldso
       );
 
       add_hardwired_spec(
@@ -933,7 +959,6 @@ void VG_(redir_initialise) ( void )
          /* glibc-2.5 (FC6, ppc64) seems fine without it */
       );
    }
-   }
 
 #  elif defined(VGP_ppc32_aix5)
    /* nothing so far */
@@ -955,11 +980,11 @@ void VG_(redir_initialise) ( void )
                          (Addr)&VG_(darwin_REDIR_FOR_strcpy), NULL);
       add_hardwired_spec("dyld", "strlcat",
                          (Addr)&VG_(darwin_REDIR_FOR_strlcat), NULL);
-#if defined(VGP_amd64_darwin)
+#     if defined(VGP_amd64_darwin)
       // DDD: #warning fixme rdar://6166275
       add_hardwired_spec("dyld", "arc4random",
                          (Addr)&VG_(darwin_REDIR_FOR_arc4random), NULL);
-#endif
+#     endif
    }
 
 #  else
index 8b3487ef9fcdc37bdcf72a25194342c8a072c4ed..256666bdf40ea4d6891c785aeefed455ad5dc7bc 100644 (file)
@@ -168,7 +168,29 @@ VG_(amd64_linux_REDIR_FOR_vtime):
 .LfnE3:
 .size VG_(amd64_linux_REDIR_FOR_vtime), .-.LfnB3
 
-/* A CIE for the above two functions, followed by their FDEs */
+/* 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_(amd64_linux_REDIR_FOR_strlen)
+.type   VG_(amd64_linux_REDIR_FOR_strlen), @function
+VG_(amd64_linux_REDIR_FOR_strlen):
+.LfnB4:
+       xorl    %eax, %eax
+       cmpb    $0, (%rdi)
+       movq    %rdi, %rdx
+       je      .L41
+.L40:  addq    $1, %rdx
+       cmpb    $0, (%rdx)
+       jne     .L40
+       movq    %rdx, %rax
+       subq    %rdi, %rax
+.L41:  ret
+.LfnE4:
+.size VG_(amd64_linux_REDIR_FOR_strlen), .-VG_(amd64_linux_REDIR_FOR_strlen)
+
+
+/* A CIE for the above three functions, followed by their FDEs */
        .section .eh_frame,"a",@progbits
 .Lframe1:
         .long   .LEcie1-.LScie1
@@ -206,6 +228,15 @@ VG_(amd64_linux_REDIR_FOR_vtime):
         .uleb128 0x0
         .align 8
 .LEfde3:
+.LSfde4:
+        .long   .LEfde4-.LASfde4
+.LASfde4:
+        .long   .LASfde4-.Lframe1
+        .long   .LfnB4
+        .long   .LfnE4-.LfnB4
+        .uleb128 0x0
+        .align 8
+.LEfde4:
        .previous
 
 .global VG_(trampoline_stuff_end)
index c8c652074448e4877b5546a261da8d56d2825ef4..31c591cb94913d212c4e6b52c12eeb5128a67fdb 100644 (file)
@@ -66,6 +66,7 @@ extern Char* VG_(x86_linux_REDIR_FOR_index) ( const Char*, Int );
 extern void VG_(amd64_linux_SUBST_FOR_rt_sigreturn);
 extern void VG_(amd64_linux_REDIR_FOR_vgettimeofday);
 extern void VG_(amd64_linux_REDIR_FOR_vtime);
+extern UInt VG_(amd64_linux_REDIR_FOR_strlen)( void* );
 #endif
 
 #if defined(VGP_ppc32_linux)