Use fstat64 to work out the size of a file if it is available as it
copes with a wider range of filesystems than the old fstat call.

Fixes bug #130020.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5979 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index be0d75f..e3318e6 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -821,7 +821,6 @@
    Addr          dimage = 0;
    UInt          n_dimage = 0;
    OffT          offset_dimage = 0;
-   struct vki_stat stat_buf;
 
    oimage = (Addr)NULL;
    if (VG_(clo_verbosity) > 1 || VG_(clo_trace_redir))
@@ -832,19 +831,19 @@
       line number info out of it.  It will be munmapped immediately
       thereafter; it is only aboard transiently. */
 
-   fd = VG_(stat)(si->filename, &stat_buf);
-   if (fd.isError) {
-      ML_(symerr)("Can't stat .so/.exe (to determine its size)?!");
-      return False;
-   }
-   n_oimage = stat_buf.st_size;
-
    fd = VG_(open)(si->filename, VKI_O_RDONLY, 0);
    if (fd.isError) {
       ML_(symerr)("Can't open .so/.exe to read symbols?!");
       return False;
    }
 
+   n_oimage = VG_(fsize)(fd.val);
+   if (n_oimage < 0) {
+      ML_(symerr)("Can't stat .so/.exe (to determine its size)?!");
+      VG_(close)(fd.val);
+      return False;
+   }
+
    sres = VG_(am_mmap_file_float_valgrind)
              ( n_oimage, VKI_PROT_READ, fd.val, 0 );
 
diff --git a/coregrind/m_libcfile.c b/coregrind/m_libcfile.c
index 82e2972..f84a1c2 100644
--- a/coregrind/m_libcfile.c
+++ b/coregrind/m_libcfile.c
@@ -133,8 +133,13 @@
 
 Int VG_(fsize) ( Int fd )
 {
+#ifdef __NR_fstat64
+   struct vki_stat64 buf;
+   SysRes res = VG_(do_syscall2)(__NR_fstat64, fd, (UWord)&buf);
+#else
    struct vki_stat buf;
    SysRes res = VG_(do_syscall2)(__NR_fstat, fd, (UWord)&buf);
+#endif
    return res.isError ? (-1) : buf.st_size;
 }