diff options
author | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2008-08-19 07:03:04 +0000 |
---|---|---|
committer | sewardj <sewardj@a5019735-40e9-0310-863c-91ae7b9d1cf9> | 2008-08-19 07:03:04 +0000 |
commit | ec61b6509566cf36ab3968d69226cecf177cb0fe (patch) | |
tree | 3ea7d6e3548c366debd565ca33e140abcf08a5e4 /include/pub_tool_libcfile.h | |
parent | 419060073e7943846cc9e0bcdcb25258d90da2dc (diff) | |
download | valgrind-ec61b6509566cf36ab3968d69226cecf177cb0fe.tar.gz |
Presently, Valgrind (non-client) code that wants to use the stat
family of syscalls is impossible to write in a way that's portable and
correct. On some targets (eg x86-linux) you need to do sys_stat64 and
receive the results in a 'struct vki_stat64'. But on other targets
(eg amd64-linux) neither sys_stat64 nor 'struct vki_stat64' exist.
This commit adds a new type, 'struct vg_stat', which contains 64 bit
fields in all the right places, and makes VG_(stat) and VG_(fstat) use
it. This means callers to the two functions no longer need to worry
about the is-it-64-bit-clean-or-not question, since these routines
reformat the received data into a'struct vg_stat'. Kind of like what
glibc must have been doing for decades.
This (indirectly) fixes a bug on x86-linux, in which m_debuginfo would
sometimes fail to read debug info, due to VG_(di_notify_mmap) using
VG_(stat) (hence sys_stat) on the file, which failed, and when in fact
it should have used sys_stat64. Bug reported and tracked down by
Marc-Oliver Straub.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@8522 a5019735-40e9-0310-863c-91ae7b9d1cf9
Diffstat (limited to 'include/pub_tool_libcfile.h')
-rw-r--r-- | include/pub_tool_libcfile.h | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/include/pub_tool_libcfile.h b/include/pub_tool_libcfile.h index 9e3274b35..81710d4d9 100644 --- a/include/pub_tool_libcfile.h +++ b/include/pub_tool_libcfile.h @@ -37,6 +37,32 @@ /* To use this file you must first include pub_tool_vki.h. */ +/* Note that VG_(stat) and VG_(fstat) write to a 'struct vg_stat*' and + not a 'struct vki_stat*' or a 'struct vki_stat64*'. 'struct + vg_stat*' is not the same as either of the vki_ versions. No + specific vki_stat{,64} kernel structure will work and is + consistently available on different architectures on Linux, so we + have to use this 'struct vg_stat' impedance-matching type + instead. */ +struct vg_stat { + ULong st_dev; + ULong st_ino; + ULong st_nlink; + UInt st_mode; + UInt st_uid; + UInt st_gid; + ULong st_rdev; + Long st_size; + ULong st_blksize; + ULong st_blocks; + ULong st_atime; + ULong st_atime_nsec; + ULong st_mtime; + ULong st_mtime_nsec; + ULong st_ctime; + ULong st_ctime_nsec; +}; + extern SysRes VG_(open) ( const Char* pathname, Int flags, Int mode ); extern void VG_(close) ( Int fd ); extern Int VG_(read) ( Int fd, void* buf, Int count); @@ -44,8 +70,8 @@ extern Int VG_(write) ( Int fd, const void* buf, Int count); extern Int VG_(pipe) ( Int fd[2] ); extern OffT VG_(lseek) ( Int fd, OffT offset, Int whence ); -extern SysRes VG_(stat) ( Char* file_name, struct vki_stat* buf ); -extern Int VG_(fstat) ( Int fd, struct vki_stat* buf ); +extern SysRes VG_(stat) ( Char* file_name, struct vg_stat* buf ); +extern Int VG_(fstat) ( Int fd, struct vg_stat* buf ); extern SysRes VG_(dup) ( Int oldfd ); extern Int VG_(rename) ( Char* old_name, Char* new_name ); extern Int VG_(unlink) ( Char* file_name ); |