Statistics
| Branch: | Revision:

root / bsd-user / strace.c @ 753d11f2

History | View | Annotate | Download (5.1 kB)

1 84778508 blueswir1
#include <stdio.h>
2 84778508 blueswir1
#include <errno.h>
3 84778508 blueswir1
#include <sys/select.h>
4 84778508 blueswir1
#include <sys/types.h>
5 84778508 blueswir1
#include <unistd.h>
6 84778508 blueswir1
#include <sys/syscall.h>
7 84778508 blueswir1
#include "qemu.h"
8 84778508 blueswir1
9 84778508 blueswir1
int do_strace=0;
10 84778508 blueswir1
11 84778508 blueswir1
struct syscallname {
12 84778508 blueswir1
    int nr;
13 84778508 blueswir1
    const char *name;
14 84778508 blueswir1
    const char *format;
15 84778508 blueswir1
    void (*call)(const struct syscallname *,
16 84778508 blueswir1
                 abi_long, abi_long, abi_long,
17 84778508 blueswir1
                 abi_long, abi_long, abi_long);
18 84778508 blueswir1
    void (*result)(const struct syscallname *, abi_long);
19 84778508 blueswir1
};
20 84778508 blueswir1
21 84778508 blueswir1
/*
22 84778508 blueswir1
 * Utility functions
23 84778508 blueswir1
 */
24 84778508 blueswir1
25 84778508 blueswir1
static void
26 84778508 blueswir1
print_execve(const struct syscallname *name,
27 84778508 blueswir1
             abi_long arg1, abi_long arg2, abi_long arg3,
28 84778508 blueswir1
             abi_long arg4, abi_long arg5, abi_long arg6)
29 84778508 blueswir1
{
30 84778508 blueswir1
    abi_ulong arg_ptr_addr;
31 84778508 blueswir1
    char *s;
32 84778508 blueswir1
33 84778508 blueswir1
    if (!(s = lock_user_string(arg1)))
34 84778508 blueswir1
        return;
35 84778508 blueswir1
    gemu_log("%s(\"%s\",{", name->name, s);
36 84778508 blueswir1
    unlock_user(s, arg1, 0);
37 84778508 blueswir1
38 84778508 blueswir1
    for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) {
39 18c9a9c3 Christoph Egger
        abi_ulong *arg_ptr, arg_addr;
40 84778508 blueswir1
41 84778508 blueswir1
        arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
42 84778508 blueswir1
        if (!arg_ptr)
43 84778508 blueswir1
            return;
44 84778508 blueswir1
        arg_addr = tswapl(*arg_ptr);
45 84778508 blueswir1
        unlock_user(arg_ptr, arg_ptr_addr, 0);
46 84778508 blueswir1
        if (!arg_addr)
47 84778508 blueswir1
            break;
48 84778508 blueswir1
        if ((s = lock_user_string(arg_addr))) {
49 84778508 blueswir1
            gemu_log("\"%s\",", s);
50 18c9a9c3 Christoph Egger
            unlock_user(s, arg_addr, 0);
51 84778508 blueswir1
        }
52 84778508 blueswir1
    }
53 84778508 blueswir1
54 84778508 blueswir1
    gemu_log("NULL})");
55 84778508 blueswir1
}
56 84778508 blueswir1
57 84778508 blueswir1
/*
58 84778508 blueswir1
 * Variants for the return value output function
59 84778508 blueswir1
 */
60 84778508 blueswir1
61 84778508 blueswir1
static void
62 84778508 blueswir1
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
63 84778508 blueswir1
{
64 84778508 blueswir1
if( ret == -1 ) {
65 84778508 blueswir1
        gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
66 84778508 blueswir1
    } else {
67 84778508 blueswir1
        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
68 84778508 blueswir1
    }
69 84778508 blueswir1
}
70 84778508 blueswir1
71 84778508 blueswir1
#if 0 /* currently unused */
72 84778508 blueswir1
static void
73 84778508 blueswir1
print_syscall_ret_raw(struct syscallname *name, abi_long ret)
74 84778508 blueswir1
{
75 84778508 blueswir1
        gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
76 84778508 blueswir1
}
77 84778508 blueswir1
#endif
78 84778508 blueswir1
79 84778508 blueswir1
/*
80 84778508 blueswir1
 * An array of all of the syscalls we know about
81 84778508 blueswir1
 */
82 84778508 blueswir1
83 84778508 blueswir1
static const struct syscallname freebsd_scnames[] = {
84 84778508 blueswir1
#include "freebsd/strace.list"
85 84778508 blueswir1
};
86 84778508 blueswir1
static const struct syscallname netbsd_scnames[] = {
87 84778508 blueswir1
#include "netbsd/strace.list"
88 84778508 blueswir1
};
89 84778508 blueswir1
static const struct syscallname openbsd_scnames[] = {
90 84778508 blueswir1
#include "openbsd/strace.list"
91 84778508 blueswir1
};
92 84778508 blueswir1
93 84778508 blueswir1
static void
94 84778508 blueswir1
print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
95 84778508 blueswir1
              abi_long arg1, abi_long arg2, abi_long arg3,
96 84778508 blueswir1
              abi_long arg4, abi_long arg5, abi_long arg6)
97 84778508 blueswir1
{
98 84778508 blueswir1
    unsigned int i;
99 84778508 blueswir1
    const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
100 84778508 blueswir1
        TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
101 84778508 blueswir1
        TARGET_ABI_FMT_ld ")";
102 84778508 blueswir1
103 84778508 blueswir1
    gemu_log("%d ", getpid() );
104 84778508 blueswir1
105 84778508 blueswir1
    for (i = 0; i < nscnames; i++)
106 84778508 blueswir1
        if (scnames[i].nr == num) {
107 84778508 blueswir1
            if (scnames[i].call != NULL) {
108 84778508 blueswir1
                scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
109 84778508 blueswir1
                                arg6);
110 84778508 blueswir1
            } else {
111 84778508 blueswir1
                /* XXX: this format system is broken because it uses
112 84778508 blueswir1
                   host types and host pointers for strings */
113 84778508 blueswir1
                if (scnames[i].format != NULL)
114 84778508 blueswir1
                    format = scnames[i].format;
115 84778508 blueswir1
                gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4,
116 84778508 blueswir1
                         arg5, arg6);
117 84778508 blueswir1
            }
118 84778508 blueswir1
            return;
119 84778508 blueswir1
        }
120 84778508 blueswir1
    gemu_log("Unknown syscall %d\n", num);
121 84778508 blueswir1
}
122 84778508 blueswir1
123 84778508 blueswir1
static void
124 84778508 blueswir1
print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
125 84778508 blueswir1
                  unsigned int nscnames)
126 84778508 blueswir1
{
127 84778508 blueswir1
    unsigned int i;
128 84778508 blueswir1
129 84778508 blueswir1
    for (i = 0; i < nscnames; i++)
130 84778508 blueswir1
        if (scnames[i].nr == num) {
131 84778508 blueswir1
            if (scnames[i].result != NULL) {
132 84778508 blueswir1
                scnames[i].result(&scnames[i], ret);
133 84778508 blueswir1
            } else {
134 84778508 blueswir1
                if( ret < 0 ) {
135 84778508 blueswir1
                    gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
136 84778508 blueswir1
                             strerror(-ret));
137 84778508 blueswir1
                } else {
138 84778508 blueswir1
                    gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret);
139 84778508 blueswir1
                }
140 84778508 blueswir1
            }
141 84778508 blueswir1
            break;
142 84778508 blueswir1
        }
143 84778508 blueswir1
}
144 84778508 blueswir1
145 84778508 blueswir1
/*
146 84778508 blueswir1
 * The public interface to this module.
147 84778508 blueswir1
 */
148 84778508 blueswir1
void
149 84778508 blueswir1
print_freebsd_syscall(int num,
150 84778508 blueswir1
                      abi_long arg1, abi_long arg2, abi_long arg3,
151 84778508 blueswir1
                      abi_long arg4, abi_long arg5, abi_long arg6)
152 84778508 blueswir1
{
153 84778508 blueswir1
    print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
154 84778508 blueswir1
                  arg1, arg2, arg3, arg4, arg5, arg6);
155 84778508 blueswir1
}
156 84778508 blueswir1
157 84778508 blueswir1
void
158 84778508 blueswir1
print_freebsd_syscall_ret(int num, abi_long ret)
159 84778508 blueswir1
{
160 84778508 blueswir1
    print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
161 84778508 blueswir1
}
162 84778508 blueswir1
163 84778508 blueswir1
void
164 84778508 blueswir1
print_netbsd_syscall(int num,
165 84778508 blueswir1
                      abi_long arg1, abi_long arg2, abi_long arg3,
166 84778508 blueswir1
                      abi_long arg4, abi_long arg5, abi_long arg6)
167 84778508 blueswir1
{
168 84778508 blueswir1
    print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
169 84778508 blueswir1
                  arg1, arg2, arg3, arg4, arg5, arg6);
170 84778508 blueswir1
}
171 84778508 blueswir1
172 84778508 blueswir1
void
173 84778508 blueswir1
print_netbsd_syscall_ret(int num, abi_long ret)
174 84778508 blueswir1
{
175 84778508 blueswir1
    print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
176 84778508 blueswir1
}
177 84778508 blueswir1
178 84778508 blueswir1
void
179 84778508 blueswir1
print_openbsd_syscall(int num,
180 84778508 blueswir1
                      abi_long arg1, abi_long arg2, abi_long arg3,
181 84778508 blueswir1
                      abi_long arg4, abi_long arg5, abi_long arg6)
182 84778508 blueswir1
{
183 84778508 blueswir1
    print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames),
184 84778508 blueswir1
                  arg1, arg2, arg3, arg4, arg5, arg6);
185 84778508 blueswir1
}
186 84778508 blueswir1
187 84778508 blueswir1
void
188 84778508 blueswir1
print_openbsd_syscall_ret(int num, abi_long ret)
189 84778508 blueswir1
{
190 84778508 blueswir1
    print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
191 84778508 blueswir1
}