This patch implements reading the directory information for source
files in the dwarf3 reader.
Basically, the change consists in replacing in the DiInlLoc struct
      const HChar* filename;     /* caller source filename */
by
      UInt   fndn_ix;            /* index in di->fndnpool of caller source
                                    dirname/filename */

A similar change is done in  DiVariable struct, as the
read_filename_Table code is shared between the inline info reader
and the varinfo reader.
Note however that outputting dirname in variable description
is not done. Unclear if that is desired or not.
It should be trivially doable however.
Replacing filename by fndn_ix implies a bunch of semi-mechanical
changes.

The code to read the directory names is in the new function
static
XArray* read_dirname_xa (struct _DebugInfo* di, const HChar *compdir,
                         Cursor *c,
                         Bool td3 )

Note that readdwarf.c and readdwarf3.c have significant duplicated
logic. Would be nice to integrate these 2 dwarf readers in one
single reader. This function is directly inspired from
an equivalent piece of code in readdwarf.c.

Modified memcheck/tests/varinfo5.vgtest to test the dirname appears
in the inlined functions.


Impact on memory is neglectable (a few Kb on a big executable).



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14245 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c
index e5114b6..9afbf73 100644
--- a/coregrind/m_debuginfo/debuginfo.c
+++ b/coregrind/m_debuginfo/debuginfo.c
@@ -1914,18 +1914,14 @@
    DebugInfo* si;
    Word       locno;
    UInt       fndn_ix;
-   FnDn*      fndn;
 
    search_all_loctabs ( a, &si, &locno );
    if (si == NULL) 
       return False;
    fndn_ix = ML_(fndn_ix) (si, locno);
-   if (fndn_ix == 0)
-      VG_(strncpy_safely)(filename, "???", n_filename);
-   else {
-      fndn = VG_(indexEltNumber) (si->fndnpool, fndn_ix);
-      VG_(strncpy_safely)(filename, fndn->filename, n_filename);
-   }
+   VG_(strncpy_safely)(filename,
+                       ML_(fndn_ix2filename) (si, fndn_ix),
+                       n_filename);
    return True;
 }
 
@@ -1954,7 +1950,6 @@
    DebugInfo* si;
    Word       locno;
    UInt       fndn_ix;
-   FnDn*      fndn = NULL;
 
    vg_assert( (dirname == NULL && dirname_available == NULL)
               ||
@@ -1970,26 +1965,18 @@
    }
 
    fndn_ix = ML_(fndn_ix)(si, locno);
-   if (fndn_ix == 0)
-      VG_(strncpy_safely)(filename, "???", n_filename);
-   else {
-      fndn = VG_(indexEltNumber) (si->fndnpool, fndn_ix);
-      VG_(strncpy_safely)(filename, fndn->filename, n_filename);
-   }
+   VG_(strncpy_safely)(filename,
+                       ML_(fndn_ix2filename) (si, fndn_ix),
+                       n_filename);
    *lineno = si->loctab[locno].lineno;
 
    if (dirname) {
       /* caller wants directory info too .. */
       vg_assert(n_dirname > 0);
-      if (fndn_ix != 0 && fndn->dirname) {
-         /* .. and we have some */
-         *dirname_available = True;
-         VG_(strncpy_safely)(dirname, fndn->dirname, n_dirname);
-      } else {
-         /* .. but we don't have any */
-         *dirname_available = False;
-         *dirname = 0;
-      }
+      VG_(strncpy_safely)(dirname,
+                          ML_(fndn_ix2dirname) (si, fndn_ix),
+                          n_dirname);
+      *dirname_available = *dirname != 0;
    }
 
    return True;
@@ -2172,11 +2159,21 @@
          ? & iipc->di->inltab[iipc->cur_inltab]
          : NULL;
       vg_assert (cur_inl);
-      // The filename and lineno for the inlined fn caller is in cur_inl.
-      VG_(snprintf) (buf_srcloc, BUF_LEN, "%s", cur_inl->filename);
-      lineno = cur_inl->lineno;
 
       know_dirinfo = False;
+      // The fndn_ix and lineno for the caller of the inlined fn is in cur_inl.
+      if (cur_inl->fndn_ix == 0) {
+         VG_(snprintf) (buf_srcloc, BUF_LEN, "???");
+      } else {
+         FnDn *fndn = VG_(indexEltNumber) (iipc->di->fndnpool,
+                                           cur_inl->fndn_ix);
+         if (fndn->dirname) {
+            VG_(snprintf) (buf_dirname, BUF_LEN, "%s", fndn->dirname);
+            know_dirinfo = True;
+         }
+         VG_(snprintf) (buf_srcloc, BUF_LEN, "%s", fndn->filename);
+      }
+      lineno = cur_inl->lineno;
       know_srcloc = True;
    }
          
@@ -3071,6 +3068,7 @@
 static void format_message ( /*MOD*/XArray* /* of HChar */ dn1,
                              /*MOD*/XArray* /* of HChar */ dn2,
                              Addr     data_addr,
+                             DebugInfo* di,
                              DiVariable* var,
                              PtrdiffT var_offset,
                              PtrdiffT residual_offset,
@@ -3084,6 +3082,9 @@
    const HChar* ro_plural = residual_offset == 1 ? "" : "s";
    const HChar* basetag   = "auxwhat"; /* a constant */
    HChar tagL[32], tagR[32], xagL[32], xagR[32];
+   const HChar *fileName = ML_(fndn_ix2filename)(di, var->fndn_ix);
+   // fileName will be "???" if var->fndn_ix == 0.
+   // fileName will only be used if have_descr is True.
 
    if (frameNo < -1) {
       vg_assert(0); /* Not allowed */
@@ -3100,7 +3101,7 @@
    vg_assert(var && var->name);
    have_descr = VG_(sizeXA)(described) > 0
                 && *(UChar*)VG_(indexXA)(described,0) != '\0';
-   have_srcloc = var->fileName && var->lineNo > 0;
+   have_srcloc = var->fndn_ix > 0 && var->lineNo > 0;
 
    tagL[0] = tagR[0] = xagL[0] = xagR[0] = 0;
    if (xml) {
@@ -3158,12 +3159,12 @@
          TXTL( dn2 );
          p2XA( dn2,
                "declared at %pS:%d, in frame #%d of thread %d",
-               var->fileName, var->lineNo, frameNo, (Int)tid );
+               fileName, var->lineNo, frameNo, (Int)tid );
          TXTR( dn2 );
          // FIXME: also do <dir>
          p2XA( dn2,
                " <file>%pS</file> <line>%d</line> ", 
-               var->fileName, var->lineNo );
+               fileName, var->lineNo );
          XAGR( dn2 );
       } else {
          p2XA( dn1,
@@ -3171,7 +3172,7 @@
                data_addr, var_offset, vo_plural, var->name );
          p2XA( dn2,
                "declared at %s:%d, in frame #%d of thread %d",
-               var->fileName, var->lineNo, frameNo, (Int)tid );
+               fileName, var->lineNo, frameNo, (Int)tid );
       }
    }
    else
@@ -3215,12 +3216,12 @@
          TXTL( dn2 );
          p2XA( dn2,
                "declared at %pS:%d, in frame #%d of thread %d",
-               var->fileName, var->lineNo, frameNo, (Int)tid );
+               fileName, var->lineNo, frameNo, (Int)tid );
          TXTR( dn2 );
          // FIXME: also do <dir>
          p2XA( dn2,
                " <file>%pS</file> <line>%d</line> ",
-               var->fileName, var->lineNo );
+               fileName, var->lineNo );
          XAGR( dn2 );
       } else {
          p2XA( dn1,
@@ -3229,7 +3230,7 @@
                (HChar*)(VG_(indexXA)(described,0)) );
          p2XA( dn2,
                "declared at %s:%d, in frame #%d of thread %d",
-               var->fileName, var->lineNo, frameNo, (Int)tid );
+               fileName, var->lineNo, frameNo, (Int)tid );
       }
    }
    else
@@ -3266,12 +3267,12 @@
          TXTL( dn2 );
          p2XA( dn2,
                "declared at %pS:%d",
-               var->fileName, var->lineNo);
+               fileName, var->lineNo);
          TXTR( dn2 );
          // FIXME: also do <dir>
          p2XA( dn2,
                " <file>%pS</file> <line>%d</line> ",
-               var->fileName, var->lineNo );
+               fileName, var->lineNo );
          XAGR( dn2 );
       } else {
          p2XA( dn1,
@@ -3279,7 +3280,7 @@
                data_addr, var_offset, vo_plural, var->name );
          p2XA( dn2,
                "declared at %s:%d",
-               var->fileName, var->lineNo);
+               fileName, var->lineNo);
       }
    }
    else
@@ -3323,12 +3324,12 @@
          TXTL( dn2 );
          p2XA( dn2,
                "a global variable declared at %pS:%d",
-               var->fileName, var->lineNo);
+               fileName, var->lineNo);
          TXTR( dn2 );
          // FIXME: also do <dir>
          p2XA( dn2,
                " <file>%pS</file> <line>%d</line> ",
-               var->fileName, var->lineNo );
+               fileName, var->lineNo );
          XAGR( dn2 );
       } else {
          p2XA( dn1,
@@ -3337,7 +3338,7 @@
                (HChar*)(VG_(indexXA)(described,0)) );
          p2XA( dn2,
                "a global variable declared at %s:%d",
-               var->fileName, var->lineNo);
+               fileName, var->lineNo);
       }
    }
    else 
@@ -3472,7 +3473,7 @@
                                                     di->admin_tyents, 
                                                     var->typeR, offset );
             format_message( dname1, dname2,
-                            data_addr, var, offset, residual_offset,
+                            data_addr, di, var, offset, residual_offset,
                             described, frameNo, tid );
             VG_(deleteXA)( described );
             return True;
@@ -3580,7 +3581,7 @@
                                                     di->admin_tyents,
                                                     var->typeR, offset );
             format_message( dname1, dname2,
-                            data_addr, var, offset, residual_offset,
+                            data_addr, di, var, offset, residual_offset,
                             described, -1/*frameNo*/,
                             VG_INVALID_THREADID );
             VG_(deleteXA)( described );
@@ -4031,8 +4032,8 @@
             tl_assert(var->name);
             tl_assert(di->soname);
             if (0) VG_(printf)("XXXX %s %s %d\n", var->name,
-                                var->fileName?(HChar*)var->fileName
-                                             :"??",var->lineNo);
+                               ML_(fndn_ix2filename)(di, var->fndn_ix),
+                               var->lineNo);
             VG_(memset)(&gb, 0, sizeof(gb));
             gb.addr  = res.word;
             gb.szB   = (SizeT)mul.ul;
diff --git a/coregrind/m_debuginfo/priv_storage.h b/coregrind/m_debuginfo/priv_storage.h
index 30491ec..b79587f 100644
--- a/coregrind/m_debuginfo/priv_storage.h
+++ b/coregrind/m_debuginfo/priv_storage.h
@@ -141,9 +141,9 @@
       Addr   addr_hi;            /* highest address following the inlined fn */
       /* Word 3 */
       const HChar* inlinedfn;    /* inlined function name */
-      /* Word 4 */
-      const HChar* filename;     /* caller source filename */
-      /* Word 5 */
+      /* Word 4 and 5 */
+      UInt   fndn_ix;            /* index in di->fndnpool of caller source
+                                    dirname/filename */
       UInt   lineno:LINENO_BITS; /* caller line number */
       UShort level:LEVEL_BITS;   /* level of inlining */
    }
@@ -480,8 +480,8 @@
       UWord  typeR; /* a cuOff */
       GExpr* gexpr; /* on DebugInfo.gexprs list */
       GExpr* fbGX;  /* SHARED. */
-      HChar* fileName; /* where declared; may be NULL. in
-                          DebugInfo.strpool */
+      UInt   fndn_ix; /* where declared; may be zero. index
+                         in DebugInfo.fndnpool */
       Int    lineNo;   /* where declared; may be zero. */
    }
    DiVariable;
@@ -994,6 +994,16 @@
                           const HChar* filename, 
                           const HChar* dirname);  /* NULL is allowable */
 
+/* Returns the filename of the fndn pair identified by fndn_ix.
+   Returns "???" if fndn_ix is 0. */
+extern const HChar* ML_(fndn_ix2filename) (struct _DebugInfo* di,
+                                           UInt fndn_ix);
+
+/* Returns the dirname of the fndn pair identified by fndn_ix.
+   Returns "" if fndn_ix is 0 or fndn->dirname is NULL. */
+extern const HChar* ML_(fndn_ix2dirname) (struct _DebugInfo* di,
+                                          UInt fndn_ix);
+
 /* Returns the fndn_ix for the LineInfo locno in di->loctab.
    0 if filename/dirname are unknown. */
 extern UInt ML_(fndn_ix) (struct _DebugInfo* di, Word locno);
@@ -1010,15 +1020,17 @@
    A call to the below means that inlinedfn code has been
    inlined, resulting in code from [addr_lo, addr_hi[.
    Note that addr_hi is excluded, i.e. is not part of the inlined code.
-   The call that caused this inlining is in filename/lineno (dirname
-   is not recorded).
+   fndn_ix and lineno identifies the location of the call that caused
+   this inlining.
+   fndn_ix is an index in di->fndnpool, allocated using  ML_(addFnDn).
+   Give a 0 index for an unknown filename/dirname pair.
    In case of nested inlining, a small level indicates the call
    is closer to main that a call with a higher level. */
 extern
 void ML_(addInlInfo) ( struct _DebugInfo* di, 
                        Addr addr_lo, Addr addr_hi,
                        const HChar* inlinedfn,
-                       const HChar* filename, 
+                       UInt fndn_ix,
                        Int lineno, UShort level);
 
 /* Add a CFI summary record.  The supplied DiCfSI_m is copied. */
@@ -1047,9 +1059,11 @@
                          UWord  typeR, /* a cuOff */
                          GExpr* gexpr,
                          GExpr* fbGX, /* SHARED. */
-                         HChar* fileName, /* where decl'd - may be NULL */
+                         UInt   fndn_ix, /* where decl'd - may be zero */
                          Int    lineNo, /* where decl'd - may be zero */
                          Bool   show );
+/* Note: fndn_ix identifies a filename/dirname pair similarly to
+   ML_(addInlInfo) and ML_(addLineInfo). */
 
 /* Canonicalise the tables held by 'di', in preparation for use.  Call
    this after finishing adding entries to these tables. */
diff --git a/coregrind/m_debuginfo/readdwarf.c b/coregrind/m_debuginfo/readdwarf.c
index ef88cfa..9a07696 100644
--- a/coregrind/m_debuginfo/readdwarf.c
+++ b/coregrind/m_debuginfo/readdwarf.c
@@ -508,10 +508,10 @@
       }
       VG_(printf)("\n");
    }
-
-   /* Read the contents of the Directory table.  */
+   /* skip over "standard_opcode_lengths" */
    data = ML_(cur_plus)(standard_opcodes, info.li_opcode_base - 1);
 
+   /* Read the contents of the Directory table.  */
    if (di->ddump_line)
       VG_(printf)(" The Directory Table%s\n", 
                   ML_(cur_read_UChar)(data) == 0 ? " is empty." : ":" );
diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c
index c5234a1..d43dfc2 100644
--- a/coregrind/m_debuginfo/readdwarf3.c
+++ b/coregrind/m_debuginfo/readdwarf3.c
@@ -1574,7 +1574,7 @@
       GExpr*  gexpr; /* for this variable */
       GExpr*  fbGX;  /* to find the frame base of the enclosing fn, if
                         any */
-      HChar*  fName; /* declaring file name, or NULL */
+      UInt    fndn_ix; /* declaring file/dirname index in fndnpool, or 0 */
       Int     fLine; /* declaring file line number, or zero */
       /* offset in .debug_info, so that abstract instances can be
          found to satisfy references from concrete instances. */
@@ -1610,9 +1610,9 @@
       Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
       GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
                                          expr, else NULL */
-      /* The file name table.  Is a mapping from integer index to the
-         (permanent) copy of the string in in DebugInfo's .strpool. */
-      XArray* /* of UChar* */ filenameTable;
+      /* The fndn_ix file name/dirname table.  Is a mapping from dwarf
+         integer index to the index in di->fndnpool. */
+      XArray* /* of UInt* */ fndn_ix_Table;
    }
    D3VarParser;
 
@@ -1733,9 +1733,92 @@
    return gexpr;
 }
 
+/* Returns an xarray* of directory names (indexed by the dwarf dirname
+   integer).
+   If 'compdir' is NULL, entry [0] will be set to "."
+   otherwise entry [0] is set to compdir.
+   Entry [0] basically means "the current directory of the compilation",
+   whatever that means, according to the DWARF3 spec.
+   FIXME??? readdwarf3.c/readdwarf.c have a lot of duplicated code */
+static
+XArray* read_dirname_xa (struct _DebugInfo* di, const HChar *compdir,
+                         Cursor *c,
+                         Bool td3 )
+{
+   XArray*        dirname_xa;   /* xarray of HChar* dirname */
+   const HChar*   dirname;
+   UInt           compdir_len = 0;
+
+   dirname_xa = VG_(newXA) (ML_(dinfo_zalloc), "di.rdxa.1", ML_(dinfo_free),
+                            sizeof(HChar*) );
+
+   if (compdir == NULL) {
+      dirname = ".";
+      compdir_len = 0;
+   } else {
+      dirname = compdir;
+      compdir_len = VG_(strlen)(compdir);
+   }
+   VG_(addToXA) (dirname_xa, &dirname);
+
+   TRACE_D3(" The Directory Table%s\n", 
+            peek_UChar(c) == 0 ? " is empty." : ":" );
+
+   while (peek_UChar(c) != 0) {
+
+#     define NBUF 4096
+      static HChar buf[NBUF];
+      DiCursor cur = get_AsciiZ(c);
+      HChar* data_str = ML_(cur_read_strdup)( cur, "dirname_xa.1" );
+      TRACE_D3("  %s\n", data_str);
+
+      /* If data_str[0] is '/', then 'data' is an absolute path and we
+         don't mess with it.  Otherwise, if we can, construct the
+         path 'compdir' ++ "/" ++ 'data'. */
+
+      if (data_str[0] != '/' 
+          /* not an absolute path */
+          && compdir
+          /* actually got something sensible for compdir */
+          && compdir_len
+             + VG_(strlen)(data_str) + 5/*paranoia*/ < NBUF
+          /* it's short enough to concatenate */) 
+      {
+         buf[0] = 0;
+         VG_(strcat)(buf, compdir);
+         VG_(strcat)(buf, "/");
+         VG_(strcat)(buf, data_str);
+         vg_assert(VG_(strlen)(buf) < NBUF);
+         dirname = ML_(addStr)(di,buf,-1);
+         VG_(addToXA) (dirname_xa, &dirname);
+         if (0) VG_(printf)("rel path  %s\n", buf);
+      } else {
+         /* just use 'data'. */
+         dirname = ML_(addStr)(di,data_str,-1);
+         VG_(addToXA) (dirname_xa, &dirname);
+         if (0) VG_(printf)("abs path  %s\n", data_str);
+      }
+
+      ML_(dinfo_free)(data_str);
+
+#     undef NBUF
+   }
+
+   TRACE_D3 ("\n");
+
+   if (get_UChar (c) != 0) {
+      ML_(symerr)(NULL, True,
+                  "could not get NUL at end of DWARF directory table");
+      VG_(deleteXA)(dirname_xa);
+      return NULL;
+   }
+
+   return dirname_xa;
+}
 
 static 
-void read_filename_table( /*MOD*/XArray* /* of UChar* */ filenameTable,
+void read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table,
+                          HChar* compdir,
                           CUConst* cc, ULong debug_line_offset,
                           Bool td3 )
 {
@@ -1745,8 +1828,12 @@
    UShort version;
    UChar  opcode_base;
    HChar* str;
+   XArray* dirname_xa;   /* xarray of HChar* dirname */
+   ULong  dir_xa_ix;     /* Index in dirname_xa, as read from dwarf info. */
+   HChar* dirname;
+   UInt   fndn_ix;
 
-   vg_assert(filenameTable && cc && cc->barf);
+   vg_assert(fndn_ix_Table && cc && cc->barf);
    if (!ML_(sli_is_valid)(cc->escn_debug_line)
        || cc->escn_debug_line.szB <= debug_line_offset) {
       cc->barf("read_filename_table: .debug_line is missing?");
@@ -1774,29 +1861,34 @@
    for (i = 1; i < (Word)opcode_base; i++)
      (void)get_UChar( &c );
 
-   /* skip over the directory names table */
-   while (peek_UChar(&c) != 0) {
-     (void)get_AsciiZ(&c);
-   }
-   (void)get_UChar(&c); /* skip terminating zero */
+   dirname_xa = read_dirname_xa(cc->di, compdir, &c, td3);
 
    /* Read and record the file names table */
-   vg_assert( VG_(sizeXA)( filenameTable ) == 0 );
+   vg_assert( VG_(sizeXA)( fndn_ix_Table ) == 0 );
    /* Add a dummy index-zero entry.  DWARF3 numbers its files
       from 1, for some reason. */
-   str = ML_(addStr)( cc->di, "<unknown_file>", -1 );
-   VG_(addToXA)( filenameTable, &str );
+   fndn_ix = ML_(addFnDn) ( cc->di, "<unknown_file>", NULL );
+   VG_(addToXA)( fndn_ix_Table, &fndn_ix );
    while (peek_UChar(&c) != 0) {
       DiCursor cur = get_AsciiZ(&c);
       str = ML_(addStrFromCursor)( cc->di, cur );
-      TRACE_D3("  read_filename_table: %ld %s\n",
-               VG_(sizeXA)(filenameTable), str);
-      VG_(addToXA)( filenameTable, &str );
-      (void)get_ULEB128( &c ); /* skip directory index # */
+      dir_xa_ix = get_ULEB128( &c );
+      if (dirname_xa != NULL 
+          && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa))
+         dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix );
+      else
+         dirname = NULL;
+      fndn_ix = ML_(addFnDn)( cc->di, str, dirname);
+      TRACE_D3("  read_filename_table: %ld fndn_ix %d %s %s\n",
+               VG_(sizeXA)(fndn_ix_Table), fndn_ix, 
+               dirname, str);
+      VG_(addToXA)( fndn_ix_Table, &fndn_ix );
       (void)get_ULEB128( &c ); /* skip last mod time */
       (void)get_ULEB128( &c ); /* file size */
    }
    /* We're done!  The rest of it is not interesting. */
+   if (dirname_xa != NULL)
+      VG_(deleteXA)(dirname_xa);
 }
 
 /* setup_cu_svma to be called when a cu is found at level 0,
@@ -1955,6 +2047,7 @@
       Addr ip_lo    = 0;
       Addr ip_hi1   = 0;
       Addr rangeoff = 0;
+      HChar *compdir = NULL;
       nf_i = 0;
       while (True) {
          DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
@@ -1976,8 +2069,17 @@
             rangeoff   = cts.u.val;
             have_range = True;
          }
+         if (attr == DW_AT_comp_dir) {
+            if (cts.szB >= 0)
+               cc->barf("parse_var_DIE compdir: expecting indirect string");
+            HChar *str = ML_(cur_read_strdup)( cts.u.cur,
+                                               "parse_var_DIE.compdir" );
+            compdir = ML_(addStr)(cc->di, str, -1);
+            ML_(dinfo_free) (str);
+         }
          if (attr == DW_AT_stmt_list && cts.szB > 0) {
-            read_filename_table( parser->filenameTable, cc, cts.u.val, td3 );
+            read_filename_table( parser->fndn_ix_Table, compdir,
+                                 cc, cts.u.val, td3 );
          }
       }
       if (have_lo && have_hi1 && hiIsRelative)
@@ -2133,7 +2235,7 @@
       Int    n_attrs     = 0;
       UWord  abs_ori     = (UWord)D3_INVALID_CUOFF;
       Int    lineNo      = 0;
-      HChar* fileName    = NULL;
+      UInt   fndn_ix     = 0;
       nf_i = 0;
       while (True) {
          DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
@@ -2169,12 +2271,11 @@
          if (attr == DW_AT_decl_file && cts.szB > 0) {
             Int ftabIx = (Int)cts.u.val;
             if (ftabIx >= 1
-                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
-               fileName = *(HChar**)
-                          VG_(indexXA)( parser->filenameTable, ftabIx );
-               vg_assert(fileName);
+                && ftabIx < VG_(sizeXA)( parser->fndn_ix_Table )) {
+               fndn_ix = *(UInt*)VG_(indexXA)( parser->fndn_ix_Table, ftabIx );
             }
-            if (0) VG_(printf)("XXX filename = %s\n", fileName);
+            if (0) VG_(printf)("XXX filename fndn_ix = %d %s\n", fndn_ix,
+                               ML_(fndn_ix2filename) (cc->di, fndn_ix));
          }
       }
       if (!global && dtag == DW_TAG_variable && level == 1) {
@@ -2190,7 +2291,7 @@
          (1) has location and type    -> completed
          (2) has type only            -> is an abstract instance
          (3) has location and abs_ori -> is a concrete instance
-         Name, filename and line number are all optional frills.
+         Name, fndn_ix and line number are all optional frills.
       */
       if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF) 
            /* 2 */ || (typeR != D3_INVALID_CUOFF)
@@ -2262,7 +2363,7 @@
          tv->typeR  = typeR;
          tv->gexpr  = gexpr;
          tv->fbGX   = fbGX;
-         tv->fName  = fileName;
+         tv->fndn_ix= fndn_ix;
          tv->fLine  = lineNo;
          tv->dioff  = posn;
          tv->absOri = abs_ori;
@@ -2398,9 +2499,9 @@
 
 typedef
    struct {
-      /* The file name table.  Is a mapping from integer index to the
-         (permanent) copy of the string in DebugInfo's .strchunks. */
-      XArray* /* of UChar* */ filenameTable;
+      /* The fndn_ix file name/dirname table.  Is a mapping from dwarf
+         integer index to the index in di->fndnpool. */
+      XArray* /* of UInt* */ fndn_ix_Table;
       UWord sibling; // sibling of the last read DIE (if it has a sibling).
    }
    D3InlParser;
@@ -2503,6 +2604,7 @@
    if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit) {
       Bool have_lo    = False;
       Addr ip_lo    = 0;
+      HChar *compdir = NULL;
 
       nf_i = 0;
       while (True) {
@@ -2515,8 +2617,17 @@
             ip_lo   = cts.u.val;
             have_lo = True;
          }
+         if (attr == DW_AT_comp_dir) {
+            if (cts.szB >= 0)
+               cc->barf("parse_inl_DIE compdir: expecting indirect string");
+            HChar *str = ML_(cur_read_strdup)( cts.u.cur,
+                                               "parse_inl_DIE.compdir" );
+            compdir = ML_(addStr)(cc->di, str, -1);
+            ML_(dinfo_free) (str);
+         }
          if (attr == DW_AT_stmt_list && cts.szB > 0) {
-            read_filename_table( parser->filenameTable, cc, cts.u.val, td3 );
+            read_filename_table( parser->fndn_ix_Table, compdir,
+                                 cc, cts.u.val, td3 );
          }
          if (attr == DW_AT_sibling && cts.szB > 0) {
             parser->sibling = cts.u.val;
@@ -2534,7 +2645,7 @@
       Addr   ip_lo      = 0;
       Addr   ip_hi1     = 0;
       Addr   rangeoff   = 0;
-      HChar* caller_filename = NULL;
+      UInt   caller_fndn_ix = 0;
       Int caller_lineno = 0;
       Int inlinedfn_abstract_origin = 0;
 
@@ -2548,12 +2659,12 @@
          if (attr == DW_AT_call_file && cts.szB > 0) {
             Int ftabIx = (Int)cts.u.val;
             if (ftabIx >= 1
-                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
-               caller_filename = *(HChar**)
-                          VG_(indexXA)( parser->filenameTable, ftabIx );
-               vg_assert(caller_filename);
+                && ftabIx < VG_(sizeXA)( parser->fndn_ix_Table )) {
+               caller_fndn_ix = *(UInt*)
+                          VG_(indexXA)( parser->fndn_ix_Table, ftabIx );
             }
-            if (0) VG_(printf)("XXX caller_filename = %s\n", caller_filename);
+            if (0) VG_(printf)("XXX caller_fndn_ix = %d %s\n", caller_fndn_ix,
+                               ML_(fndn_ix2filename) (cc->di, caller_fndn_ix));
          }  
          if (attr == DW_AT_call_line && cts.szB > 0) {
             caller_lineno = cts.u.val;
@@ -2599,7 +2710,7 @@
             ML_(addInlInfo) (cc->di,
                              ip_lo, ip_hi1, 
                              get_inlFnName (inlinedfn_abstract_origin, cc, td3),
-                             caller_filename,
+                             caller_fndn_ix,
                              caller_lineno, level);
          }
       } else if (have_range) {
@@ -2624,7 +2735,7 @@
                              // while ML_(addInlInfo) expects last bound not
                              // included.
                              inlfnname,
-                             caller_filename,
+                             caller_fndn_ix,
                              caller_lineno, level);
          }
          VG_(deleteXA)( ranges );
@@ -4514,28 +4625,28 @@
                            unitary_range_list(0UL, ~0UL),
                            -1, False/*isFunc*/, NULL/*fbGX*/ );
 
-            /* And set up the file name table.  When we come across the top
+            /* And set up the fndn_ix_Table.  When we come across the top
                level DIE for this CU (which is what the next call to
                read_DIE should process) we will copy all the file names out
                of the .debug_line img area and use this table to look up the
                copies when we later see filename numbers in DW_TAG_variables
                etc. */
-            vg_assert(!varparser.filenameTable );
-            varparser.filenameTable 
+            vg_assert(!varparser.fndn_ix_Table );
+            varparser.fndn_ix_Table 
                = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5var",
                              ML_(dinfo_free),
-                             sizeof(UChar*) );
-            vg_assert(varparser.filenameTable);
+                             sizeof(UInt) );
+            vg_assert(varparser.fndn_ix_Table);
          }
 
          if (VG_(clo_read_inline_info)) {
-            /* filename table for the inlined call parser */
-            vg_assert(!inlparser.filenameTable );
-            inlparser.filenameTable 
+            /* fndn_ix_Table for the inlined call parser */
+            vg_assert(!inlparser.fndn_ix_Table );
+            inlparser.fndn_ix_Table 
                = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5inl",
                              ML_(dinfo_free),
-                             sizeof(UChar*) );
-            vg_assert(inlparser.filenameTable);
+                             sizeof(UInt) );
+            vg_assert(inlparser.fndn_ix_Table);
          }
 
          /* Now read the one-and-only top-level DIE for this CU. */
@@ -4588,14 +4699,14 @@
          }
 
          if (VG_(clo_read_var_info)) {
-            vg_assert(varparser.filenameTable );
-            VG_(deleteXA)( varparser.filenameTable );
-            varparser.filenameTable = NULL;
+            vg_assert(varparser.fndn_ix_Table );
+            VG_(deleteXA)( varparser.fndn_ix_Table );
+            varparser.fndn_ix_Table = NULL;
          }
          if (VG_(clo_read_inline_info)) {
-            vg_assert(inlparser.filenameTable );
-            VG_(deleteXA)( inlparser.filenameTable );
-            inlparser.filenameTable = NULL;
+            vg_assert(inlparser.fndn_ix_Table );
+            VG_(deleteXA)( inlparser.fndn_ix_Table );
+            inlparser.fndn_ix_Table = NULL;
          }
          clear_CUConst(&cc);
 
@@ -4750,8 +4861,9 @@
             } else {
                VG_(printf)("  FrB=none\n");
             }
-            VG_(printf)("  declared at: %s:%d\n",
-                        varp->fName ? varp->fName : "NULL",
+            VG_(printf)("  declared at: %d %s:%d\n",
+                        varp->fndn_ix,
+                        ML_(fndn_ix2filename) (di, varp->fndn_ix),
                         varp->fLine );
             if (varp->absOri != (UWord)D3_INVALID_CUOFF)
                VG_(printf)("  abstract origin: <%lx>\n", varp->absOri);
@@ -4798,8 +4910,8 @@
                varp->typeR = varAI->typeR;
             if (varAI->name && !varp->name)
                varp->name = varAI->name;
-            if (varAI->fName && !varp->fName)
-               varp->fName = varAI->fName;
+            if (varAI->fndn_ix && !varp->fndn_ix)
+               varp->fndn_ix = varAI->fndn_ix;
             if (varAI->fLine > 0 && varp->fLine == 0)
                varp->fLine = varAI->fLine;
          }
@@ -4891,7 +5003,7 @@
                      pcMin, pcMax,
                      varp->name,  varp->typeR,
                      varp->gexpr, varp->fbGX,
-                     varp->fName, varp->fLine, td3 
+                     varp->fndn_ix, varp->fLine, td3 
               );
            }
          }
@@ -4921,7 +5033,7 @@
       ML_(dinfo_free)( tyents_to_keep_cache );
       tyents_to_keep_cache = NULL;
 
-      vg_assert( varparser.filenameTable == NULL );
+      vg_assert( varparser.fndn_ix_Table == NULL );
 
       /* And the signatured type hash.  */
       VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );
diff --git a/coregrind/m_debuginfo/storage.c b/coregrind/m_debuginfo/storage.c
index 5abe0fb..705331c 100644
--- a/coregrind/m_debuginfo/storage.c
+++ b/coregrind/m_debuginfo/storage.c
@@ -271,6 +271,33 @@
    return fndn_ix;
 }
 
+const HChar* ML_(fndn_ix2filename) (struct _DebugInfo* di,
+                                    UInt fndn_ix)
+{
+   FnDn *fndn;
+   if (fndn_ix == 0)
+      return "???";
+   else {
+      fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix);
+      return fndn->filename;
+   }
+}
+
+const HChar* ML_(fndn_ix2dirname) (struct _DebugInfo* di,
+                                   UInt fndn_ix)
+{
+   FnDn *fndn;
+   if (fndn_ix == 0)
+      return "";
+   else {
+      fndn = VG_(indexEltNumber) (di->fndnpool, fndn_ix);
+      if (fndn->dirname)
+         return fndn->dirname;
+      else
+         return "";
+   }
+}
+
 /* Add a string to the string table of a DebugInfo, by copying the
    string from the given DiCursor.  Measures the length of the string
    itself. */
@@ -581,7 +608,7 @@
 void ML_(addInlInfo) ( struct _DebugInfo* di, 
                        Addr addr_lo, Addr addr_hi,
                        const HChar* inlinedfn,
-                       const HChar* filename, 
+                       UInt fndn_ix,
                        Int lineno, UShort level)
 {
    DiInlLoc inl;
@@ -618,15 +645,16 @@
    inl.addr_hi   = addr_hi;
    inl.inlinedfn = inlinedfn;
    // caller:
-   inl.filename  = filename;
+   inl.fndn_ix   = fndn_ix;
    inl.lineno    = lineno;
    inl.level     = level;
 
    if (0) VG_(message)
              (Vg_DebugMsg, 
               "addInlInfo: fn %s inlined as addr_lo %#lx,addr_hi %#lx,"
-              "caller %s:%d\n",
-              inlinedfn, addr_lo, addr_hi, filename, lineno);
+              "caller fndn_ix %d %s:%d\n",
+              inlinedfn, addr_lo, addr_hi, fndn_ix,
+              ML_(fndn_ix2filename) (di, fndn_ix), lineno);
 
    addInl ( di, &inl );
 }
@@ -1125,8 +1153,8 @@
                   UWord  typeR, /* a cuOff */
                   GExpr* gexpr,
                   GExpr* fbGX,
-                  HChar* fileName, /* where decl'd - may be NULL.
-                                      in di's .strpool */
+                  UInt   fndn_ix, /* where decl'd - may be zero.
+                                     index in in di's .fndnpool */
                   Int    lineNo, /* where decl'd - may be zero */
                   Bool   show )
 {
@@ -1260,7 +1288,7 @@
    var.typeR    = typeR;
    var.gexpr    = gexpr;
    var.fbGX     = fbGX;
-   var.fileName = fileName;
+   var.fndn_ix  = fndn_ix;
    var.lineNo   = lineNo;
 
    all = aMin == (Addr)0 && aMax == ~(Addr)0;
diff --git a/memcheck/tests/varinfo5.stderr.exp b/memcheck/tests/varinfo5.stderr.exp
index 8edc97e..4d29266 100644
--- a/memcheck/tests/varinfo5.stderr.exp
+++ b/memcheck/tests/varinfo5.stderr.exp
@@ -1,191 +1,191 @@
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: varinfo1_main (varinfo5so.c:52)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:52)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is 1 bytes inside a block of size 3 alloc'd
-   at 0x........: malloc (vg_replace_malloc.c:...)
-   by 0x........: varinfo1_main (varinfo5so.c:50)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: malloc (coregrind/vg_replace_malloc.c:...)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:50)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: varinfo1_main (varinfo5so.c:55)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:55)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global var "global_u1"
  declared at varinfo5so.c:38
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: varinfo1_main (varinfo5so.c:56)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:56)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global var "global_i1"
  declared at varinfo5so.c:40
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: varinfo1_main (varinfo5so.c:57)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:57)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global_u2[3],
  a global variable declared at varinfo5so.c:42
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: varinfo1_main (varinfo5so.c:58)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:58)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global_i2[7],
  a global variable declared at varinfo5so.c:44
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: varinfo1_main (varinfo5so.c:59)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:59)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside local var "local"
  declared at varinfo5so.c:49, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo2 (varinfo5so.c:71)
-   by 0x........: varinfo2_main (varinfo5so.c:81)
-   by 0x........: varinfo5_main (varinfo5so.c:155)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo2 (memcheck/tests/varinfo5so.c:71)
+   by 0x........: varinfo2_main (memcheck/tests/varinfo5so.c:81)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:155)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside var[7],
  declared at varinfo5so.c:69, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo2 (varinfo5so.c:73)
-   by 0x........: varinfo2_main (varinfo5so.c:81)
-   by 0x........: varinfo5_main (varinfo5so.c:155)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo2 (memcheck/tests/varinfo5so.c:73)
+   by 0x........: varinfo2_main (memcheck/tests/varinfo5so.c:81)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:155)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 2 bytes inside var.bar,
  declared at varinfo5so.c:72, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo2 (varinfo5so.c:76)
-   by 0x........: varinfo2_main (varinfo5so.c:81)
-   by 0x........: varinfo5_main (varinfo5so.c:155)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo2 (memcheck/tests/varinfo5so.c:76)
+   by 0x........: varinfo2_main (memcheck/tests/varinfo5so.c:81)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:155)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 1 byte inside local var "var"
  declared at varinfo5so.c:67, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo3 (varinfo5so.c:106)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:106)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside static_global_def[1],
  a global variable declared at varinfo5so.c:87
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo3 (varinfo5so.c:107)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:107)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_global_def[2],
  a global variable declared at varinfo5so.c:88
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo3 (varinfo5so.c:108)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:108)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside static_global_undef[3],
  a global variable declared at varinfo5so.c:89
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: foo3 (varinfo5so.c:109)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:109)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_global_undef[4],
  a global variable declared at varinfo5so.c:90
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: bar3 (varinfo5so.c:94)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:94)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is 5 bytes inside data symbol "static_local_def.XXXX"
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: bar3 (varinfo5so.c:95)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:95)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_local_def[6],
  declared at varinfo5so.c:103, in frame #2 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: bar3 (varinfo5so.c:96)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:96)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is 7 bytes inside data symbol "static_local_undef.XXXX"
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: bar3 (varinfo5so.c:97)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:97)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_local_undef[8],
  declared at varinfo5so.c:105, in frame #2 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: blah4 (varinfo5so.c:137)
-   by 0x........: varinfo4_main (varinfo5so.c:146)
-   by 0x........: varinfo5_main (varinfo5so.c:157)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: blah4 (memcheck/tests/varinfo5so.c:137)
+   by 0x........: varinfo4_main (memcheck/tests/varinfo5so.c:146)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:157)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 1 byte inside a[3].xyzzy[21].c1,
  declared at varinfo5so.c:135, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: blah4 (varinfo5so.c:138)
-   by 0x........: varinfo4_main (varinfo5so.c:146)
-   by 0x........: varinfo5_main (varinfo5so.c:157)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: blah4 (memcheck/tests/varinfo5so.c:138)
+   by 0x........: varinfo4_main (memcheck/tests/varinfo5so.c:146)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:157)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside a[5].bong,
  declared at varinfo5so.c:135, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: blah4 (varinfo5so.c:139)
-   by 0x........: varinfo4_main (varinfo5so.c:146)
-   by 0x........: varinfo5_main (varinfo5so.c:157)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: blah4 (memcheck/tests/varinfo5so.c:139)
+   by 0x........: varinfo4_main (memcheck/tests/varinfo5so.c:146)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:157)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 1 byte inside a[3].xyzzy[21].c2[2],
  declared at varinfo5so.c:135, in frame #1 of thread 1
 
 answer is 0
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:29)
-   by 0x........: fun_c (varinfo5so.c:164)
-   by 0x........: fun_b (varinfo5so.c:168)
-   by 0x........: fun_a (varinfo5so.c:172)
-   by 0x........: inlinetest (varinfo5so.c:178)
-   by 0x........: varinfo5_main (varinfo5so.c:158)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:29)
+   by 0x........: fun_c (memcheck/tests/varinfo5so.c:164)
+   by 0x........: fun_b (memcheck/tests/varinfo5so.c:168)
+   by 0x........: fun_a (memcheck/tests/varinfo5so.c:172)
+   by 0x........: inlinetest (memcheck/tests/varinfo5so.c:178)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:158)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is on thread 1's stack
  in frame #1, created by varinfo5_main (varinfo5so.c:153)
 
diff --git a/memcheck/tests/varinfo5.stderr.exp-ppc64 b/memcheck/tests/varinfo5.stderr.exp-ppc64
index f5ebf0b..dae4136 100644
--- a/memcheck/tests/varinfo5.stderr.exp-ppc64
+++ b/memcheck/tests/varinfo5.stderr.exp-ppc64
@@ -1,180 +1,191 @@
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: varinfo1_main (varinfo5so.c:52)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:52)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is 1 bytes inside a block of size 3 alloc'd
-   at 0x........: malloc (vg_replace_malloc.c:...)
-   by 0x........: varinfo1_main (varinfo5so.c:50)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: malloc (coregrind/vg_replace_malloc.c:...)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:50)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: varinfo1_main (varinfo5so.c:55)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:55)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global var "global_u1"
  declared at varinfo5so.c:38
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: varinfo1_main (varinfo5so.c:56)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:56)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global var "global_i1"
  declared at varinfo5so.c:40
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: varinfo1_main (varinfo5so.c:57)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:57)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global_u2[3],
  a global variable declared at varinfo5so.c:42
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: varinfo1_main (varinfo5so.c:58)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:58)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside global_i2[7],
  a global variable declared at varinfo5so.c:44
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: varinfo1_main (varinfo5so.c:59)
-   by 0x........: varinfo5_main (varinfo5so.c:154)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: varinfo1_main (memcheck/tests/varinfo5so.c:59)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:154)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside local var "local"
  declared at varinfo5so.c:49, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo2 (varinfo5so.c:71)
-   by 0x........: varinfo2_main (varinfo5so.c:81)
-   by 0x........: varinfo5_main (varinfo5so.c:155)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo2 (memcheck/tests/varinfo5so.c:71)
+   by 0x........: varinfo2_main (memcheck/tests/varinfo5so.c:81)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:155)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside var[7],
  declared at varinfo5so.c:69, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo2 (varinfo5so.c:73)
-   by 0x........: varinfo2_main (varinfo5so.c:81)
-   by 0x........: varinfo5_main (varinfo5so.c:155)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo2 (memcheck/tests/varinfo5so.c:73)
+   by 0x........: varinfo2_main (memcheck/tests/varinfo5so.c:81)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:155)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 2 bytes inside var.bar,
  declared at varinfo5so.c:72, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo2 (varinfo5so.c:76)
-   by 0x........: varinfo2_main (varinfo5so.c:81)
-   by 0x........: varinfo5_main (varinfo5so.c:155)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo2 (memcheck/tests/varinfo5so.c:76)
+   by 0x........: varinfo2_main (memcheck/tests/varinfo5so.c:81)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:155)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 1 byte inside local var "var"
  declared at varinfo5so.c:67, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo3 (varinfo5so.c:106)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:106)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside static_global_def[1],
  a global variable declared at varinfo5so.c:87
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo3 (varinfo5so.c:107)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:107)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_global_def[2],
  a global variable declared at varinfo5so.c:88
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo3 (varinfo5so.c:108)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:108)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside static_global_undef[3],
  a global variable declared at varinfo5so.c:89
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: foo3 (varinfo5so.c:109)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:109)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_global_undef[4],
  a global variable declared at varinfo5so.c:90
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: bar3 (varinfo5so.c:94)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:94)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is 5 bytes inside data symbol "static_local_def.XXXX"
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: bar3 (varinfo5so.c:95)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:95)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_local_def[6],
  declared at varinfo5so.c:103, in frame #2 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: bar3 (varinfo5so.c:96)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:96)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Address 0x........ is 7 bytes inside data symbol "static_local_undef.XXXX"
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: bar3 (varinfo5so.c:97)
-   by 0x........: foo3 (varinfo5so.c:110)
-   by 0x........: varinfo3_main (varinfo5so.c:118)
-   by 0x........: varinfo5_main (varinfo5so.c:156)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: bar3 (memcheck/tests/varinfo5so.c:97)
+   by 0x........: foo3 (memcheck/tests/varinfo5so.c:110)
+   by 0x........: varinfo3_main (memcheck/tests/varinfo5so.c:118)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:156)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside nonstatic_local_undef[8],
  declared at varinfo5so.c:105, in frame #2 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: blah4 (varinfo5so.c:137)
-   by 0x........: varinfo4_main (varinfo5so.c:146)
-   by 0x........: varinfo5_main (varinfo5so.c:157)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: blah4 (memcheck/tests/varinfo5so.c:137)
+   by 0x........: varinfo4_main (memcheck/tests/varinfo5so.c:146)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:157)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 1 byte inside a[3].xyzzy[21].c1,
  declared at varinfo5so.c:135, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: blah4 (varinfo5so.c:138)
-   by 0x........: varinfo4_main (varinfo5so.c:146)
-   by 0x........: varinfo5_main (varinfo5so.c:157)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: blah4 (memcheck/tests/varinfo5so.c:138)
+   by 0x........: varinfo4_main (memcheck/tests/varinfo5so.c:146)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:157)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 0 bytes inside a[5].bong,
  declared at varinfo5so.c:135, in frame #1 of thread 1
 
 Uninitialised byte(s) found during client check request
-   at 0x........: croak (varinfo5so.c:30)
-   by 0x........: blah4 (varinfo5so.c:139)
-   by 0x........: varinfo4_main (varinfo5so.c:146)
-   by 0x........: varinfo5_main (varinfo5so.c:157)
-   by 0x........: main (varinfo5.c:5)
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: blah4 (memcheck/tests/varinfo5so.c:139)
+   by 0x........: varinfo4_main (memcheck/tests/varinfo5so.c:146)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:157)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
  Location 0x........ is 1 byte inside a[3].xyzzy[21].c2[2],
  declared at varinfo5so.c:135, in frame #1 of thread 1
 
 answer is 0
+Uninitialised byte(s) found during client check request
+   at 0x........: croak (memcheck/tests/varinfo5so.c:30)
+   by 0x........: fun_c (memcheck/tests/varinfo5so.c:164)
+   by 0x........: fun_b (memcheck/tests/varinfo5so.c:168)
+   by 0x........: fun_a (memcheck/tests/varinfo5so.c:172)
+   by 0x........: inlinetest (memcheck/tests/varinfo5so.c:178)
+   by 0x........: varinfo5_main (memcheck/tests/varinfo5so.c:158)
+   by 0x........: main (memcheck/tests/varinfo5.c:5)
+ Address 0x........ is on thread 1's stack
+ in frame #1, created by varinfo5_main (varinfo5so.c:153)
+
diff --git a/memcheck/tests/varinfo5.vgtest b/memcheck/tests/varinfo5.vgtest
index 79c4a72..8cf00eb 100644
--- a/memcheck/tests/varinfo5.vgtest
+++ b/memcheck/tests/varinfo5.vgtest
@@ -1,3 +1,3 @@
 prog: varinfo5
-vgopts: --read-var-info=yes --read-inline-info=yes -q
+vgopts: --fullpath-after=${PWD}/ --read-var-info=yes --read-inline-info=yes -q
 stderr_filter: filter_varinfo3