Bug 1356 - extracting values from user int * params
Summary: extracting values from user int * params
Status: RESOLVED DUPLICATE of bug 1295
Alias: None
Product: systemtap
Classification: Unclassified
Component: translator (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Frank Ch. Eigler
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-19 20:42 UTC by Kevin Stafford
Modified: 2005-09-20 22:32 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kevin Stafford 2005-09-19 20:42:16 UTC
Here is a signiture for a function that I would like to write a tapset for:

asmlinkage long sys_stime(time_t __user *tptr)

I would like to extract and export the value of tptr. This does not work:

function get_uint(ptr)%{
        unsigned long g = (unsigned long)THIS->ptr;
        unsigned long val;
        get_user(val, (time_t *) g);
        THIS->__retvalue = (long long) val;
%} 

Produces error: incompatible types in assignment.

Much like user_string, it would be great to have a user_int. This may also
depend on the fix to bug #1295.

Thanks.
Comment 1 Kevin Stafford 2005-09-19 21:54:48 UTC
Here is another example:

asmlinkage long sys_settimeofday(struct timeval __user *tv ..., )

where timeval is defined as:

struct timeval {
    time_t         tv_sec;   /* seconds */
    suseconds_t    tv_usec;  /* microseconds */
};

probe kernel.syscall.settimeofday = 
    kernel.function("sys_settimeofday"){
          tv_sec = $tv->tv_sec
          tv_usec = $tv->tv_usec
    }

Access to the 2 exported fields from struct timeval produce bogus results. 
Comment 2 Frank Ch. Eigler 2005-09-20 19:02:00 UTC
For the first example, please specify what program produces that error.  Note
that you're not declaring the get_uint type explicitly, so perhaps the
translator was led to believe that get_uint returns a string.

A generic user_int() function wouldn't exactly help here, since you are not
dereferencing plain user int*, but a user struct foo*.  One may need hand-made
wrapper functions like your get_uint for such user-side structures.

For the settimeofday example, please describe a test that invokes settimeofday().
Comment 3 Kevin Stafford 2005-09-20 20:36:41 UTC
Here is some more analysis:

Consider this C code:
__________________________________________
#include <time.h>
int main (void) {
        time_t t = 44;
        stime(&t);
}
__________________________________________
...& this probe script:
__________________________________________
%{ #include <asm/uaccess.h> %}

function get_uint:long(ptr:long) %{
        unsigned long g = (unsigned long) THIS->ptr;
        unsigned long val = 0;
        get_user(val, (time_t *) g);
        THIS->__retvalue = val;
%}

probe kernel.function("sys_stime") {
        print("Addr of $tptr: ".string($tptr)."\n");
        print("Converted: ".string(get_uint($tptr))."\n");
}
__________________________________________
...and this (condensed) jprobes module:
__________________________________________
/* extract the val from the pointer */
int get_uint(time_t __user *ptr)
{
        unsigned long g = (unsigned long) ptr;
        unsigned long val = 0;
        get_user(val, (time_t *) g);
        return val;
}
/* this is my jprobe handler */
asmlinkage long jdo_stime(time_t __user *tptr)
{
        printk("Addr of $tptr: %d\n",tptr);
        printk("Converted: %d\n",get_uint(tptr));
        jprobe_return();
        return 0;
}
__________________________________________

Here is the output of the script when I run the C program:

Addr of $tptr: 25
Converted: 0

And here is the output of the kprobes module:

Addr of $tptr: -1075403996
Converted: 44
_________________________________________________

sys_stime and sys_settimeofday are essentially the same
function with different args. The module places a single
jprobe (basically a kprobe that gives access to args) on
"sys_stime". The module behaves as expected. The probe
script is (what I think should be) the functional equiv-
alent of the kprobes module. However the args are not 
matching up with what I see from the jprobes handler. Thus,
I think this may be a bug in the translator.

Please let me know your thoughts on this.

Thanks.



Comment 4 Frank Ch. Eigler 2005-09-20 22:32:58 UTC
This now seems to be another instance of bug# 1295.

FWIW, using the .statement() syntax to refer to a place a few lines down the
function makes the $tptr value resolve properly.  (I used the "tv.tv_nsec = 0"
line.)  You may need to make similar approximations in your syscall tapset until
we get the general debuginfo situation corrected.


*** This bug has been marked as a duplicate of 1295 ***