Incorrect preadv/pwritev argument parsing on ARM EABI

Dmitry V. Levin ldv at altlinux.org
Thu Apr 17 10:01:54 UTC 2014


On Thu, Apr 17, 2014 at 02:16:31AM -0700, Dima Kogan wrote:
> Dmitry V. Levin <ldv at altlinux.org> writes:
> 
> > On Wed, Apr 16, 2014 at 11:19:06PM -0700, Dima Kogan wrote:
> >> Dima Kogan <dima at secretsauce.net> writes:
> >> > Dmitry V. Levin <ldv at altlinux.org> writes:
> >> >
> >> OK. Never mind on the llseek, actually. I was testing lseek, NOT llseek,
> >> which is why it looked odd. The patch I attached earlier can be fixed
> >> with some #ifdefs probably. I should be pretty trivial. Is it useful for
> >> me to do it, or do you want to?
> >
> > If the result is going to be as complex as printllval without alignment,
> > it worth extending printllval instead of reinventing the wheel.
> 
> Currently printllval assumes register alignment, which (on ARM at least)
> should be done for some syscalls (like pread) but not others (like
> preadv). To make printllval work here, it'd need to take an extra
> argument to indicate whether alignment should happen or not. That
> function is already full of logic, so I was thinking instead something
> of printing the preadv/pwritev pos like this:
> 
> #ifdef 64bit
>   printllval(tcp, "%llu", PREAD_OFFSET_ARG);
> #else
>  tprintf("%llu", LONG_LONG(tcp->u_arg[3], tcp->u_arg[4]));
> #endif
> 
> Here "64bit" would be replaced by something that's defined if we can
> pass 64-bit args in a single register. I don't know about all the
> platforms that printllval() checks, so I can't say if this "64bit" check
> would be complicated or not. Looking at printllval(), it looks like it's
> possible to have sizeof(long)==8, but still pass syscall args in 32-bit
> pieces. Do you know the details about all the cases?

There are platforms that support multiple personalities.
For example, x86 personality on x86_64.

Here is a stripped down printllval, I don't see a simpler way to implement this:

#if SIZEOF_LONG > 4 && SIZEOF_LONG == SIZEOF_LONG_LONG
# if SUPPORTED_PERSONALITIES > 1
	if (current_wordsize > 4)
# endif
		tprintf(format, tcp->u_arg[arg_no]);
# if SUPPORTED_PERSONALITIES > 1
	else
		tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
# endif /* SUPPORTED_PERSONALITIES */
#elif SIZEOF_LONG > 4
#  error Unsupported configuration: SIZEOF_LONG > 4 && SIZEOF_LONG_LONG > SIZEOF_LONG
#elif defined LINUX_MIPSN32
	tprintf(format, tcp->ext_arg[arg_no]);
#elif defined X32
	if (current_personality == 0)
		tprintf(format, tcp->ext_arg[arg_no]);
	else
		tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
#else
	tprintf(format, LONG_LONG(tcp->u_arg[arg_no], tcp->u_arg[arg_no + 1]));
#endif


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20140417/32eafab9/attachment.bin>


More information about the Strace-devel mailing list