x32: fix decoding of flags argument of preadv2 and pwritev2 syscalls
x32 is the only linux architecture where preadv2 and pwritev2 syscalls take 5 arguments instead of 6. * io.c (PREADV2_PWRITEV2_FLAGS_ARG_NO): New macro. (SYS_FUNC(preadv2), SYS_FUNC(pwritev2)): Use it. * linux/x32/syscallent.h (preadv2, pwritev2): Change nargs to 5. * NEWS: Mention this fix. * tests/preadv2-pwritev2.c (main): Fix invocation of preadv2 and pwritev2 syscalls on x32.
This commit is contained in:
parent
7519e54937
commit
f7b9a6ac63
3
NEWS
3
NEWS
@ -4,6 +4,9 @@ Noteworthy changes in release ?.?? (????-??-??)
|
||||
* Improvements
|
||||
* Enhanced decoding of sched_setattr syscall.
|
||||
|
||||
* Bug fixes
|
||||
* Fixed decoding of flags argument of preadv2 and pwritev2 syscalls on x32.
|
||||
|
||||
Noteworthy changes in release 4.16 (2017-02-14)
|
||||
===============================================
|
||||
|
||||
|
27
io.c
27
io.c
@ -224,11 +224,6 @@ SYS_FUNC(preadv)
|
||||
return do_preadv(tcp, -1);
|
||||
}
|
||||
|
||||
SYS_FUNC(preadv2)
|
||||
{
|
||||
return do_preadv(tcp, 5);
|
||||
}
|
||||
|
||||
static int
|
||||
do_pwritev(struct tcb *tcp, const int flags_arg)
|
||||
{
|
||||
@ -253,9 +248,29 @@ SYS_FUNC(pwritev)
|
||||
return do_pwritev(tcp, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* x32 is the only architecture where preadv2 takes 5 arguments
|
||||
* instead of 6, see preadv64v2 in kernel sources.
|
||||
* Likewise, x32 is the only architecture where pwritev2 takes 5 arguments
|
||||
* instead of 6, see pwritev64v2 in kernel sources.
|
||||
*/
|
||||
|
||||
#if defined X86_64
|
||||
# define PREADV2_PWRITEV2_FLAGS_ARG_NO (current_personality == 2 ? 4 : 5)
|
||||
#elif defined X32
|
||||
# define PREADV2_PWRITEV2_FLAGS_ARG_NO (current_personality == 0 ? 4 : 5)
|
||||
#else
|
||||
# define PREADV2_PWRITEV2_FLAGS_ARG_NO 5
|
||||
#endif
|
||||
|
||||
SYS_FUNC(preadv2)
|
||||
{
|
||||
return do_preadv(tcp, PREADV2_PWRITEV2_FLAGS_ARG_NO);
|
||||
}
|
||||
|
||||
SYS_FUNC(pwritev2)
|
||||
{
|
||||
return do_pwritev(tcp, 5);
|
||||
return do_pwritev(tcp, PREADV2_PWRITEV2_FLAGS_ARG_NO);
|
||||
}
|
||||
|
||||
#include "xlat/splice_flags.h"
|
||||
|
@ -369,5 +369,5 @@
|
||||
[543] = { 2, CST|TM, SEN(io_setup), "io_setup" },
|
||||
[544] = { 3, CST, SEN(io_submit), "io_submit" },
|
||||
[545] = { 5, CST|TD|TF|TP|SE|SI, SEN(execveat), "execveat" },
|
||||
[546] = { 6, TD, SEN(preadv2), "preadv2" },
|
||||
[547] = { 6, TD, SEN(pwritev2), "pwritev2" },
|
||||
[546] = { 5, TD, SEN(preadv2), "preadv2" },
|
||||
[547] = { 5, TD, SEN(pwritev2), "pwritev2" },
|
||||
|
@ -181,26 +181,45 @@ int
|
||||
main(void)
|
||||
{
|
||||
const kernel_ulong_t vlen = (kernel_ulong_t) 0xfac1fed2dad3bef4ULL;
|
||||
const unsigned long long pos = 0xfac5fed6dad7bef8;
|
||||
const unsigned long long pos = 0x7ac5fed6dad7bef8;
|
||||
const kernel_ulong_t pos_l = (kernel_ulong_t) pos;
|
||||
const kernel_ulong_t pos_h =
|
||||
(sizeof(kernel_ulong_t) == sizeof(long long)) ?
|
||||
(kernel_ulong_t) 0xbadc0deddeadbeefULL : 0xfac5fed6UL;
|
||||
int test_dumpio = 1;
|
||||
long rc;
|
||||
int test_dumpio;
|
||||
|
||||
tprintf("%s", "");
|
||||
|
||||
syscall(__NR_preadv2, -1, NULL, vlen, pos_l, pos_h, 1);
|
||||
if (ENOSYS == errno)
|
||||
test_dumpio = 0;
|
||||
tprintf("preadv2(-1, NULL, %lu, %lld, RWF_HIPRI) = -1 %s (%m)\n",
|
||||
(unsigned long) vlen, pos, errno2name());
|
||||
#if defined __x86_64__ && defined __ILP32__
|
||||
/*
|
||||
* x32 is the only architecture where preadv2 takes 5 arguments,
|
||||
* see preadv64v2 in kernel sources.
|
||||
*/
|
||||
rc = syscall(__NR_preadv2, -1, NULL, vlen, pos_l, 1);
|
||||
#else
|
||||
const kernel_ulong_t pos_h =
|
||||
(sizeof(pos_l) == sizeof(pos)) ?
|
||||
(kernel_ulong_t) 0xbadc0deddeadbeefULL :
|
||||
(kernel_ulong_t) (pos >> 32);
|
||||
rc = syscall(__NR_preadv2, -1, NULL, vlen, pos_l, pos_h, 1);
|
||||
#endif
|
||||
if (rc != -1 || (ENOSYS != errno && EBADF != errno))
|
||||
perror_msg_and_fail("preadv2");
|
||||
test_dumpio = EBADF == errno;
|
||||
tprintf("preadv2(-1, NULL, %lu, %lld, RWF_HIPRI) = %s\n",
|
||||
(unsigned long) vlen, pos, sprintrc(rc));
|
||||
|
||||
syscall(__NR_pwritev2, -1, NULL, vlen, pos_l, pos_h, 1);
|
||||
if (ENOSYS == errno)
|
||||
test_dumpio = 0;
|
||||
tprintf("pwritev2(-1, NULL, %lu, %lld, RWF_HIPRI) = -1 %s (%m)\n",
|
||||
(unsigned long) vlen, pos, errno2name());
|
||||
#if defined __x86_64__ && defined __ILP32__
|
||||
/*
|
||||
* x32 is the only architecture where pwritev2 takes 5 arguments,
|
||||
* see pwritev64v2 in kernel sources.
|
||||
*/
|
||||
rc = syscall(__NR_pwritev2, -1, NULL, vlen, pos_l, 1);
|
||||
#else
|
||||
rc = syscall(__NR_pwritev2, -1, NULL, vlen, pos_l, pos_h, 1);
|
||||
#endif
|
||||
if (rc != -1 || (ENOSYS != errno && EBADF != errno))
|
||||
perror_msg_and_fail("pwritev2");
|
||||
tprintf("pwritev2(-1, NULL, %lu, %lld, RWF_HIPRI) = %s\n",
|
||||
(unsigned long) vlen, pos, sprintrc(rc));
|
||||
|
||||
if (test_dumpio)
|
||||
dumpio();
|
||||
|
Loading…
x
Reference in New Issue
Block a user