And with this third cumulative patch, `valgrind --trace-children=yes
loffice` also works.

Jeff
Description: Fix /proc/self/exe handling on kfreebsd
 Because /proc/self/fd/# is not a symlink, the normal strategy of redirecing
 readlink(/proc/self/exe) to readlink(/proc/self/fd/cl_exec_fd) will not work
 on freebsd.
 .
 Instead, record the executable path at the same time the executable fd is
 recorded, and use that instead of calling an underlying readlink or readlinkat.
 .
 Also, add linux-compatible names in readlinkat.
 .
 This allows loffice to start.  Before it didn't, with one of the failing steps
 being:
 /usr/lib/libreoffice/program/../ure-link/bin/javaldx \
   -env:INIFILENAME=vnd.sun.star.pathname:/usr/lib/libreoffice/program/redirectrc
 which would fail to load a library it searched for relative to the executab.e
Author: Jeff Epler <jep...@unpythonic.net>
Bug-Debian: http://bugs.debian.org/702729

--- valgrind-3.8.1.orig/coregrind/m_clientstate.c
+++ valgrind-3.8.1/coregrind/m_clientstate.c
@@ -60,6 +60,7 @@ Addr  VG_(brk_limit)   = 0;       /* cur
 
 /* A fd which refers to the client executable. */
 Int VG_(cl_exec_fd) = -1;
+HChar* VG_(cl_exec_path)[4096];
 
 /* A fd which refers to the fake /proc/<pid>/cmdline in /tmp. */
 Int VG_(cl_cmdline_fd) = -1;
--- valgrind-3.8.1.orig/coregrind/pub_core_clientstate.h
+++ valgrind-3.8.1/coregrind/pub_core_clientstate.h
@@ -55,6 +55,7 @@ extern Addr  VG_(brk_limit);	 // current
 
 /* A fd which refers to the client executable. */
 extern Int VG_(cl_exec_fd);
+extern HChar VG_(cl_exec_path)[4096];
 
 /* A fd which refers to the fake /proc/<pid>/cmdline in /tmp.  The
    idea is: make up the /proc/<pid>/cmdline file the client would
--- valgrind-3.8.1.orig/coregrind/m_syswrap/syswrap-generic.c
+++ valgrind-3.8.1/coregrind/m_syswrap/syswrap-generic.c
@@ -3809,7 +3809,7 @@ PRE(sys_readlink)
    PRE_MEM_WRITE( "readlink(buf)", ARG2,ARG3 );
 
    {
-#if defined(VGO_linux)
+#if defined(VGO_linux) || defined(VGO_freebsd)
       /*
        * Handle the case where readlink is looking at /proc/self/exe or
        * /proc/<pid>/exe.
@@ -3821,9 +3821,15 @@ PRE(sys_readlink)
           (VG_STREQ(arg1s, name) || VG_STREQ(arg1s, "/proc/self/exe"))
          )
       {
+#if defined(VGO_freebsd)
+         SET_STATUS_Success( VG_(strlen)(VG_(cl_exec_path)) );
+         if(RES < ARG3) SET_STATUS_Success( ARG3 );
+         VG_(memcpy)((char*)ARG2, VG_(cl_exec_path), (size_t)RES);
+#else
          VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
          SET_STATUS_from_SysRes( VG_(do_syscall3)(saved, (UWord)name, 
                                                          ARG2, ARG3));
+#endif
       } else
 #endif // defined(VGO_linux)
       {
--- valgrind-3.8.1.orig/coregrind/m_syswrap/syswrap-freebsd.c
+++ valgrind-3.8.1/coregrind/m_syswrap/syswrap-freebsd.c
@@ -3073,7 +3073,7 @@ PRE(sys_symlinkat)
 
 PRE(sys_readlinkat)
 {
-   HChar name[25];
+   HChar name[25], name2[25];
    Word  saved = SYSNO;
 
    PRINT("sys_readlinkat ( %ld, %#lx(%s), %#lx, %llu )", ARG1,ARG2,(char*)ARG2,ARG3,(ULong)ARG4);
@@ -3087,12 +3087,15 @@ PRE(sys_readlinkat)
     * /proc/<pid>/file.
     */
    VG_(sprintf)(name, "/proc/%d/file", VG_(getpid)());
+   VG_(sprintf)(name2, "/proc/%d/exe", VG_(getpid)());
    if (ML_(safe_to_deref)((void*)ARG2, 1)
        && (VG_(strcmp)((Char *)ARG2, name) == 0
-           || VG_(strcmp)((Char *)ARG2, "/proc/curproc/file") == 0)) {
-      VG_(sprintf)(name, "/proc/self/fd/%d", VG_(cl_exec_fd));
-      SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, (UWord)name,
-                                                      ARG3, ARG4));
+           || VG_(strcmp)((Char *)ARG2, name2) == 0
+           || VG_(strcmp)((Char *)ARG2, "/proc/curproc/file") == 0
+           || VG_(strcmp)((Char *)ARG2, "/proc/self/exe") == 0)) {
+      SET_STATUS_Success( VG_(strlen)(VG_(cl_exec_path)) );
+      if(RES < ARG3) SET_STATUS_Success( ARG3 );
+      VG_(memcpy)((char*)ARG2, VG_(cl_exec_path), (size_t)RES);
    } else {
       /* Normal case */
       SET_STATUS_from_SysRes( VG_(do_syscall4)(saved, ARG1, ARG2, ARG3, ARG4));
--- valgrind-3.8.1.orig/coregrind/m_initimg/initimg-freebsd.c
+++ valgrind-3.8.1/coregrind/m_initimg/initimg-freebsd.c
@@ -96,7 +96,10 @@ static void load_client ( /*OUT*/ExeInfo
       executable.  This is needed for attaching to GDB. */
    res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
    if (!sr_isError(res))
+   {
+      VG_(snprintf)(VG_(cl_exec_path), sizeof(VG_(cl_exec_path)), "%s", exe_name);
       VG_(cl_exec_fd) = sr_Res(res);
+   }
 
    /* Copy necessary bits of 'info' that were filled in */
    *client_ip  = info->init_ip;

Attachment: signature.asc
Description: Digital signature

Reply via email to