[patch] Add stat() support for biarch i386 on x86_64
Jan Kratochvil
jan.kratochvil at redhat.com
Sun Aug 5 22:04:01 UTC 2007
Hi,
currently the stat64() syscall is not printed for i386 tracees on x86_64.
While I would expect it should affect even i386-on-ia64 it works there for me
without any patch.
/*
* Linux x86_64 has unified `struct stat' but its i386 biarch needs
* `struct stat64'. Its <asm-i386/stat.h> definition expects 32-bit `long'.
* <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
...
Testcase:
echo -e '#include <sys/stat.h>\nint main (void) { struct stat statbuf; stat ("/proc/self/exe", &statbuf); return 0; }' >/tmp/statself.c;gcc -m32 -o /tmp/statself32 /tmp/statself.c -ggdb2 -Wall;strace -v /tmp/statself32 2>&1|tail|grep ^stat
reports
stat64(0x80484f0, 0xffb990b8) = 0
while it should report
stat64("/proc/self/exe", {st_dev=makedev(8, 1), st_ino=4910638, st_mode=S_IFREG|0755, st_nlink=1, st_uid=502, st_gid=502, st_blksize=4096, st_blocks=16, st_size=6825, st_atime=2007/08/05-23:56:21, st_mtime=2007/08/05-23:56:21, st_ctime=2007/08/05-23:56:21}) = 0
Regards,
Jan
-------------- next part --------------
2007-08-05 Jan Kratochvil <jan.kratochvil at redhat.com>
* file.c: New #include <assert.h>.
(HAVE_STAT64, stat64) [LINUX && X86_64 && __GNUC__]: New definitions.
(printstat64) [HAVE_STAT64]: Assert the I386 `struct stat64' size.
(printstat64) [!HAVE_LONG_LONG]: Support the ST_SIZE printing.
Fixes RH#222275.
--- file.c 24 Jul 2007 01:57:11 -0000 1.84
+++ file.c 5 Aug 2007 21:41:33 -0000
@@ -34,6 +34,7 @@
#include "defs.h"
#include <dirent.h>
+#include <assert.h>
#ifdef LINUX
#define dirent kernel_dirent
#define dirent64 kernel_dirent64
@@ -193,6 +194,47 @@ struct stat_sparc64 {
#define sys_ftruncate64 sys_ftruncate
#endif
+/*
+ * Linux x86_64 has unified `struct stat' but its i386 biarch needs
+ * `struct stat64'. Its <asm-i386/stat.h> definition expects 32-bit `long'.
+ * <linux/include/asm-x86_64/ia32.h> is not in the public includes set.
+ * __GNUC__ is needed for the required __attribute__ below.
+ */
+#if defined LINUX && defined X86_64 && defined __GNUC__
+#define HAVE_STAT64 1 /* Ugly hack */
+struct stat64 {
+ unsigned long st_dev;
+ unsigned char __pad0[4];
+
+ unsigned int __st_ino;
+
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned int st_uid;
+ unsigned int st_gid;
+
+ unsigned long st_rdev;
+ unsigned char __pad3[4];
+
+ long st_size;
+ unsigned int st_blksize;
+
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+
+ unsigned int st_atime;
+ unsigned int st_atime_nsec;
+
+ unsigned int st_mtime;
+ unsigned int st_mtime_nsec;
+
+ unsigned int st_ctime;
+ unsigned int st_ctime_nsec;
+
+ unsigned long st_ino;
+} __attribute__((__packed__));
+#endif
+
#ifdef MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#endif
@@ -990,6 +1032,10 @@ struct tcb *tcp;
long addr;
{
struct stat64 statbuf;
+
+#if defined LINUX && (defined X86_64 || defined I386)
+ assert (sizeof (statbuf) == 96);
+#endif
#ifdef LINUXSPARC
if (current_personality == 1) {
@@ -1058,7 +1104,11 @@ long addr;
#endif /* !HAVE_STRUCT_STAT_ST_RDEV */
break;
default:
- tprintf("st_size=%llu, ", statbuf.st_size);
+#ifdef HAVE_LONG_LONG
+ tprintf("st_size=%llu, ", (unsigned long long) statbuf.st_size);
+#else
+ tprintf("st_size=%lu, ", (unsigned long) statbuf.st_size);
+#endif
break;
}
if (!abbrev(tcp)) {
More information about the Strace-devel
mailing list