From: Kirill A. S. <ki...@sh...> - 2011-05-24 22:08:23
|
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 <ki...@sh...> Reported-by: Damir Shayhutdinov <da...@al...> --- 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 |
From: Andreas S. <sc...@re...> - 2011-05-25 07:12:49
|
"Kirill A. Shutemov" <kir...@pu...> writes: > 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. Please take a look at printllval. Andreas. -- Andreas Schwab, sc...@re... GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." |
From: Dmitry V. L. <ld...@al...> - 2011-05-28 20:53:07
|
On Wed, May 25, 2011 at 09:12:39AM +0200, Andreas Schwab wrote: > "Kirill A. Shutemov" <kir...@pu...> writes: > > > 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. > > Please take a look at printllval. Please have a look at the second edition of this fix: * linux/arm/syscallent.h (pread, pwrite, truncate64, ftruncate64, readahead, preadv, pwritev): Fix number of arguments. * util.c (printllval): Align 64bit argument to 64bit boundary on __ARM_EABI__. diff --git a/linux/arm/syscallent.h b/linux/arm/syscallent.h index 784b986..5969900 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 */ @@ -391,8 +391,8 @@ { 3, TD, sys_dup3, "dup3" }, /* 358 */ { 2, TD, sys_pipe2, "pipe2" }, /* 359 */ { 1, TD, sys_inotify_init1, "inotify_init1" }, /* 360 */ - { 5, TD, sys_preadv, "preadv" }, /* 361 */ - { 5, TD, sys_pwritev, "pwritev" }, /* 362 */ + { 6, TD, sys_preadv, "preadv" }, /* 361 */ + { 6, TD, sys_pwritev, "pwritev" }, /* 362 */ { 4, TP|TS, printargs, "rt_tgsigqueueinfo"}, /* 363 */ { 5, TD, printargs, "perf_event_open"}, /* 364 */ { 5, TN, sys_recvmmsg, "recvmmsg" }, /* 365 */ diff --git a/util.c b/util.c index 8704a46..a6c91ab 100644 --- a/util.c +++ b/util.c @@ -252,7 +252,8 @@ printllval(struct tcb *tcp, const char *format, int llarg) { # if defined(FREEBSD) \ || (defined(LINUX) && defined(POWERPC) && !defined(POWERPC64)) \ - || defined (LINUX_MIPSO32) + || defined(LINUX_MIPSO32) \ + || defined(__ARM_EABI__) /* Align 64bit argument to 64bit boundary. */ if (llarg % 2) llarg++; # endif -- ldv |