Message ID | 1407170739-12237-4-git-send-email-tommusta@gmail.com |
---|---|
State | New |
Headers | show |
On 4 August 2014 17:45, Tom Musta <tommusta@gmail.com> wrote: > The semun union used in the semctl system call contains both an int (val) and > pointers. In cross-endian situations on 64 bit targets, the target memory > must be byte swapped, otherwise the wrong 32 bits are used for the val > field. > > Signed-off-by: Tom Musta <tommusta@gmail.com> > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 229c482..fb03e96 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -2647,9 +2647,14 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd, > switch( cmd ) { > case GETVAL: > case SETVAL: > +#if TARGET_ABI_BITS == 64 > + /* In 64 bit cross endian situations, we will erroneously pick up > + * the wrong half of the union for the "val" element. To rectify > + * this, the entire structure is byteswaped. */ "byteswapped". > + target_su.buf = tswapal(target_su.buf); > +#endif This feels weird; surely there's a way of phrasing this that doesn't require an #ifdef on TARGET_ABI_BITS? > arg.val = tswap32(target_su.val); > ret = get_errno(semctl(semid, semnum, cmd, arg)); > - target_su.val = tswap32(arg.val); This deleted line isn't mentioned in the commit message... > break; > case GETALL: > case SETALL: thanks -- PMM
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 229c482..fb03e96 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2647,9 +2647,14 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd, switch( cmd ) { case GETVAL: case SETVAL: +#if TARGET_ABI_BITS == 64 + /* In 64 bit cross endian situations, we will erroneously pick up + * the wrong half of the union for the "val" element. To rectify + * this, the entire structure is byteswaped. */ + target_su.buf = tswapal(target_su.buf); +#endif arg.val = tswap32(target_su.val); ret = get_errno(semctl(semid, semnum, cmd, arg)); - target_su.val = tswap32(arg.val); break; case GETALL: case SETALL:
The semun union used in the semctl system call contains both an int (val) and pointers. In cross-endian situations on 64 bit targets, the target memory must be byte swapped, otherwise the wrong 32 bits are used for the val field. Signed-off-by: Tom Musta <tommusta@gmail.com>