[PATCH] ARM EABI: fix 64-bit syscall's arguments decoding

Kirill A. Shutemov kirill at shutemov.name
Tue May 24 21:30:54 UTC 2011


ARM OABI and ARM EABI have different function parameters passing rules.
With EABI, 64-bit function parameters passed in registers are aligned to
an even-numbered register instead of using the next available pair. [1]
This rule also applies to syscall's arguments.

strace is not aware about this difference. This patch fixes it.
Five syscalls affected.

[1] http://lkml.org/lkml/2006/1/12/175

Signed-off-by: Kirill A. Shutemov <kirill at shutemov.name>
Reported-by: Damir Shayhutdinov <damir at altlinux.org>
---
 file.c                 |   22 +++++++++++++++++++---
 io.c                   |    6 ++++++
 linux/arm/syscallent.h |   10 +++++-----
 3 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/file.c b/file.c
index 346f1e7..fc18123 100644
--- a/file.c
+++ b/file.c
@@ -612,6 +612,14 @@ sys_llseek(struct tcb *tcp)
 	return 0;
 }
 
+/* With ARM EABI, 64-bit arguments will be aligned to an _even_ numbered
+   register. */
+#if defined(__ARM_EABI__)
+#define READAHEAD_OFFSET_ARG 2
+#else
+#define READAHEAD_OFFSET_ARG 1
+#endif
+
 int
 sys_readahead(struct tcb *tcp)
 {
@@ -619,7 +627,7 @@ sys_readahead(struct tcb *tcp)
 		int argn;
 		printfd(tcp, tcp->u_arg[0]);
 		tprintf(", ");
-		argn = printllval(tcp, "%lld", 1);
+		argn = printllval(tcp, "%lld", READAHEAD_OFFSET_ARG);
 		tprintf(", %ld", tcp->u_arg[argn]);
 	}
 	return 0;
@@ -656,13 +664,21 @@ sys_truncate(struct tcb *tcp)
 }
 #endif
 
+/* With ARM EABI, 64-bit arguments will be aligned to an _even_ numbered
+   register. */
+#if defined(__ARM_EABI__)
+#define FTRUNCATE64_OFFSET_ARG 2
+#else
+#define FTRUNCATE64_OFFSET_ARG 1
+#endif
+
 #if _LFS64_LARGEFILE || HAVE_LONG_LONG_OFF_T
 int
 sys_truncate64(struct tcb *tcp)
 {
 	if (entering(tcp)) {
 		printpath(tcp, tcp->u_arg[0]);
-		printllval(tcp, ", %llu", 1);
+		printllval(tcp, ", %llu", FTRUNCATE64_OFFSET_ARG);
 	}
 	return 0;
 }
@@ -687,7 +703,7 @@ sys_ftruncate64(struct tcb *tcp)
 	if (entering(tcp)) {
 		printfd(tcp, tcp->u_arg[0]);
 		tprintf(", ");
-		printllval(tcp, "%llu", 1);
+		printllval(tcp, "%llu", FTRUNCATE64_OFFSET_ARG);
 	}
 	return 0;
 }
diff --git a/io.c b/io.c
index 3f8757c..cd2efca 100644
--- a/io.c
+++ b/io.c
@@ -273,6 +273,12 @@ sys_sendfile(struct tcb *tcp)
    was changed late in the 2.4 series (around 2.4.20).  */
 #if defined(SH)
 #define PREAD_OFFSET_ARG 4
+
+/* With ARM EABI, 64-bit arguments will be aligned to an _even_ numbered
+   register. */
+#elif defined(__ARM_EABI__)
+#define PREAD_OFFSET_ARG 4
+
 #else
 #define PREAD_OFFSET_ARG 3
 #endif
diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h
index b914ca0..7268878 100644
--- a/linux/arm/syscallent.h
+++ b/linux/arm/syscallent.h
@@ -209,8 +209,8 @@
 	{ 3,	TS,	sys_rt_sigqueueinfo,    "rt_sigqueueinfo"}, /* 178 */
 	{ 2,	TS,	sys_rt_sigsuspend,	"rt_sigsuspend"	}, /* 179 */
 
-	{ 5,	TF,	sys_pread,		"pread"		}, /* 180 */
-	{ 5,	TF,	sys_pwrite,		"pwrite"	}, /* 181 */
+	{ 6,	TF,	sys_pread,		"pread"		}, /* 180 */
+	{ 6,	TF,	sys_pwrite,		"pwrite"	}, /* 181 */
 	{ 3,	TF,	sys_chown,		"chown"		}, /* 182 */
 	{ 2,	TF,	sys_getcwd,		"getcwd"	}, /* 183 */
 	{ 2,	0,	sys_capget,		"capget"	}, /* 184 */
@@ -222,8 +222,8 @@
 	{ 0,	TP,	sys_vfork,		"vfork"		}, /* 190 */
 	{ 2,	0,	sys_getrlimit,		"getrlimit"	}, /* 191 */
 	{ 6,	TD,	sys_mmap,		"mmap2"		}, /* 192 */
-	{ 3,	TF,	sys_truncate64,		"truncate64"	}, /* 193 */
-	{ 3,	TF,	sys_ftruncate64,	"ftruncate64"	}, /* 194 */
+	{ 4,	TF,	sys_truncate64,		"truncate64"	}, /* 193 */
+	{ 4,	TF,	sys_ftruncate64,	"ftruncate64"	}, /* 194 */
 	{ 2,	TF,	sys_stat64,		"stat64"	}, /* 195 */
 	{ 2,	TF,	sys_lstat64,		"lstat64"	}, /* 196 */
 	{ 2,	TF,	sys_fstat64,		"fstat64"	}, /* 197 */
@@ -255,7 +255,7 @@
 	{ 5,	0,	printargs,		"SYS_222"	}, /* 222 */
 	{ 5,	0,	printargs,		"SYS_223"	}, /* 223 */
 	{ 0,	0,	printargs,		"gettid"	}, /* 224 */
-	{ 4,	0,	sys_readahead,		"readahead"	}, /* 225 */
+	{ 5,	0,	sys_readahead,		"readahead"	}, /* 225 */
 	{ 5,	TF,	sys_setxattr,		"setxattr"	}, /* 226 */
 	{ 5,	TF,	sys_setxattr,		"lsetxattr"	}, /* 227 */
 	{ 5,	0,	sys_fsetxattr,		"fsetxattr"	}, /* 228 */
-- 
1.7.4.5





More information about the Strace-devel mailing list