~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to bsd-user/strace.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

Show diffs side-by-side

added added

removed removed

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