This is the mail archive of the mailing list for the systemtap project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tapsets/18597] long_arg() doesn't correctly handle negative values in 32-on-64 environment

--- Comment #5 from David Smith <dsmith at redhat dot com> ---
(In reply to David Smith from comment #4)
> If this code wasn't needed before, why is it needed now?

I've figured this out. This code is needed because stp_arg() (which long_arg()
calls) had a bug. The bug was that in some circumstances, longlong_arg() would
return a 64-bit value (from 1 register) when called on a 32-bit process.
longlong_arg()/stp_arg() was designed to do the following:

If we're in a 32-bit compat process, then you can't put a 64-bit value in 1
register. Instead, you have to break the 64-bit value up and put it in 2
registers. This is why longlong_arg() had code in it like this:

-       if (probing_32bit_app()) {
-               lowbits = _stp_arg(argnum, 0, 1)
-               highbits = _stp_arg(argnum+1, 0, 1)
-               return ((highbits << 32) | lowbits)

However, this code doesn't really work correctly on a 64-bit OS. Let me give an
example. Here's pread() and the x86_64 compat function for pread(). The 'pos'
argument (or the combination of 'poslo' and 'poshi' arguments) is a 64-bit

ssize_t sys_pread64(unsigned int fd, char __user *buf, size_t count, loff_t

asmlinkage long sys32_pread(unsigned int fd, char __user *ubuf, u32 count,
                            u32 poslo, u32 poshi)
        return sys_pread64(fd, ubuf, count,
                         ((loff_t)AA(poshi) << 32) | AA(poslo));

If we're probing a compat function, we'd never call longlong_arg(), we'd do the
same thing that the wrapper function is doing - call ulong_arg() on arguments 4
and 5 and slam the values together. Since probing_32bit_app() never returned
true, the supposed 32-bit code in longlong_arg() was never getting called.

Your patch has to add lots of "compat" probes because as a side effect of
fixing the negative value problem it "broke" longlong_arg() returning a 64-bit
value from 1 register even when in a 32-bit process (which shouldn't have
worked in the first place).

I've been struggling with the right way to fix this. I went down the same path
you tried, and ended up about in the same place. Then I decided to try a
different path.

What if we decided that if you call longlong_arg() on a 64-bit OS on a 32-bit
process you really *want* a 64-bit value from 1 register? In some ways this
makes sense and it matches our old behavior. My theory here is that you know
what you are doing and if you call longlong_arg() on a 32-bit process you must
be in the true 64-bit function at this point.

I'm testing this now and it works well on everything but ppc64. I'm unsure of
what is going on there.

You are receiving this mail because:
You are the assignee for the bug.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]