root / linux-user / strace.c @ 9e0b74a4
History | View | Annotate | Download (33.3 kB)
1 |
#include <stdio.h> |
---|---|
2 |
#include <errno.h> |
3 |
#include <sys/ipc.h> |
4 |
#include <sys/msg.h> |
5 |
#include <sys/sem.h> |
6 |
#include <sys/shm.h> |
7 |
#include <sys/select.h> |
8 |
#include <sys/types.h> |
9 |
#include <sys/mount.h> |
10 |
#include <sys/mman.h> |
11 |
#include <unistd.h> |
12 |
#include "qemu.h" |
13 |
|
14 |
int do_strace=0; |
15 |
|
16 |
struct syscallname {
|
17 |
int nr;
|
18 |
const char *name; |
19 |
const char *format; |
20 |
void (*call)(const struct syscallname *, |
21 |
abi_long, abi_long, abi_long, |
22 |
abi_long, abi_long, abi_long); |
23 |
void (*result)(const struct syscallname *, abi_long); |
24 |
}; |
25 |
|
26 |
#ifdef __GNUC__
|
27 |
/*
|
28 |
* It is possible that target doesn't have syscall that uses
|
29 |
* following flags but we don't want the compiler to warn
|
30 |
* us about them being unused. Same applies to utility print
|
31 |
* functions. It is ok to keep them while not used.
|
32 |
*/
|
33 |
#define UNUSED __attribute__ ((unused))
|
34 |
#else
|
35 |
#define UNUSED
|
36 |
#endif
|
37 |
|
38 |
/*
|
39 |
* Structure used to translate flag values into strings. This is
|
40 |
* similar that is in the actual strace tool.
|
41 |
*/
|
42 |
struct flags {
|
43 |
abi_long f_value; /* flag */
|
44 |
const char *f_string; /* stringified flag */ |
45 |
}; |
46 |
|
47 |
/* common flags for all architectures */
|
48 |
#define FLAG_GENERIC(name) { name, #name } |
49 |
/* target specific flags (syscall_defs.h has TARGET_<flag>) */
|
50 |
#define FLAG_TARGET(name) { TARGET_ ## name, #name } |
51 |
/* end of flags array */
|
52 |
#define FLAG_END { 0, NULL } |
53 |
|
54 |
UNUSED static const char *get_comma(int); |
55 |
UNUSED static void print_pointer(abi_long, int); |
56 |
UNUSED static void print_flags(const struct flags *, abi_long, int); |
57 |
UNUSED static void print_at_dirfd(abi_long, int); |
58 |
UNUSED static void print_file_mode(abi_long, int); |
59 |
UNUSED static void print_open_flags(abi_long, int); |
60 |
UNUSED static void print_syscall_prologue(const struct syscallname *); |
61 |
UNUSED static void print_syscall_epilogue(const struct syscallname *); |
62 |
UNUSED static void print_string(abi_long, int); |
63 |
UNUSED static void print_raw_param(const char *, abi_long, int); |
64 |
UNUSED static void print_timeval(abi_ulong, int); |
65 |
UNUSED static void print_number(abi_long, int); |
66 |
|
67 |
/*
|
68 |
* Utility functions
|
69 |
*/
|
70 |
static void |
71 |
print_ipc_cmd(int cmd)
|
72 |
{ |
73 |
#define output_cmd(val) \
|
74 |
if( cmd == val ) { \
|
75 |
gemu_log(#val); \
|
76 |
return; \
|
77 |
} |
78 |
|
79 |
cmd &= 0xff;
|
80 |
|
81 |
/* General IPC commands */
|
82 |
output_cmd( IPC_RMID ); |
83 |
output_cmd( IPC_SET ); |
84 |
output_cmd( IPC_STAT ); |
85 |
output_cmd( IPC_INFO ); |
86 |
/* msgctl() commands */
|
87 |
#ifdef __USER_MISC
|
88 |
output_cmd( MSG_STAT ); |
89 |
output_cmd( MSG_INFO ); |
90 |
#endif
|
91 |
/* shmctl() commands */
|
92 |
output_cmd( SHM_LOCK ); |
93 |
output_cmd( SHM_UNLOCK ); |
94 |
output_cmd( SHM_STAT ); |
95 |
output_cmd( SHM_INFO ); |
96 |
/* semctl() commands */
|
97 |
output_cmd( GETPID ); |
98 |
output_cmd( GETVAL ); |
99 |
output_cmd( GETALL ); |
100 |
output_cmd( GETNCNT ); |
101 |
output_cmd( GETZCNT ); |
102 |
output_cmd( SETVAL ); |
103 |
output_cmd( SETALL ); |
104 |
output_cmd( SEM_STAT ); |
105 |
output_cmd( SEM_INFO ); |
106 |
output_cmd( IPC_RMID ); |
107 |
output_cmd( IPC_RMID ); |
108 |
output_cmd( IPC_RMID ); |
109 |
output_cmd( IPC_RMID ); |
110 |
output_cmd( IPC_RMID ); |
111 |
output_cmd( IPC_RMID ); |
112 |
output_cmd( IPC_RMID ); |
113 |
output_cmd( IPC_RMID ); |
114 |
output_cmd( IPC_RMID ); |
115 |
|
116 |
/* Some value we don't recognize */
|
117 |
gemu_log("%d",cmd);
|
118 |
} |
119 |
|
120 |
#ifdef TARGET_NR__newselect
|
121 |
static void |
122 |
print_fdset(int n, abi_ulong target_fds_addr)
|
123 |
{ |
124 |
int i;
|
125 |
|
126 |
gemu_log("[");
|
127 |
if( target_fds_addr ) {
|
128 |
abi_long *target_fds; |
129 |
|
130 |
target_fds = lock_user(VERIFY_READ, |
131 |
target_fds_addr, |
132 |
sizeof(*target_fds)*(n / TARGET_ABI_BITS + 1), |
133 |
1);
|
134 |
|
135 |
if (!target_fds)
|
136 |
return;
|
137 |
|
138 |
for (i=n; i>=0; i--) { |
139 |
if ((tswapl(target_fds[i / TARGET_ABI_BITS]) >> (i & (TARGET_ABI_BITS - 1))) & 1) |
140 |
gemu_log("%d,", i );
|
141 |
} |
142 |
unlock_user(target_fds, target_fds_addr, 0);
|
143 |
} |
144 |
gemu_log("]");
|
145 |
} |
146 |
#endif
|
147 |
|
148 |
/*
|
149 |
* Sysycall specific output functions
|
150 |
*/
|
151 |
|
152 |
/* select */
|
153 |
#ifdef TARGET_NR__newselect
|
154 |
static long newselect_arg1 = 0; |
155 |
static long newselect_arg2 = 0; |
156 |
static long newselect_arg3 = 0; |
157 |
static long newselect_arg4 = 0; |
158 |
static long newselect_arg5 = 0; |
159 |
|
160 |
static void |
161 |
print_newselect(const struct syscallname *name, |
162 |
abi_long arg1, abi_long arg2, abi_long arg3, |
163 |
abi_long arg4, abi_long arg5, abi_long arg6) |
164 |
{ |
165 |
gemu_log("%s(" TARGET_ABI_FMT_ld ",", name->name, arg1); |
166 |
print_fdset(arg1, arg2); |
167 |
gemu_log(",");
|
168 |
print_fdset(arg1, arg3); |
169 |
gemu_log(",");
|
170 |
print_fdset(arg1, arg4); |
171 |
gemu_log(",");
|
172 |
print_timeval(arg5, 1);
|
173 |
gemu_log(")");
|
174 |
|
175 |
/* save for use in the return output function below */
|
176 |
newselect_arg1=arg1; |
177 |
newselect_arg2=arg2; |
178 |
newselect_arg3=arg3; |
179 |
newselect_arg4=arg4; |
180 |
newselect_arg5=arg5; |
181 |
} |
182 |
#endif
|
183 |
|
184 |
#ifdef TARGET_NR_semctl
|
185 |
static void |
186 |
print_semctl(const struct syscallname *name, |
187 |
abi_long arg1, abi_long arg2, abi_long arg3, |
188 |
abi_long arg4, abi_long arg5, abi_long arg6) |
189 |
{ |
190 |
gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", name->name, arg1, arg2); |
191 |
print_ipc_cmd(arg3); |
192 |
gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4); |
193 |
} |
194 |
#endif
|
195 |
|
196 |
static void |
197 |
print_execve(const struct syscallname *name, |
198 |
abi_long arg1, abi_long arg2, abi_long arg3, |
199 |
abi_long arg4, abi_long arg5, abi_long arg6) |
200 |
{ |
201 |
abi_ulong arg_ptr_addr; |
202 |
char *s;
|
203 |
|
204 |
if (!(s = lock_user_string(arg1)))
|
205 |
return;
|
206 |
gemu_log("%s(\"%s\",{", name->name, s);
|
207 |
unlock_user(s, arg1, 0);
|
208 |
|
209 |
for (arg_ptr_addr = arg2; ; arg_ptr_addr += sizeof(abi_ulong)) { |
210 |
abi_ulong *arg_ptr, arg_addr; |
211 |
|
212 |
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); |
213 |
if (!arg_ptr)
|
214 |
return;
|
215 |
arg_addr = tswapl(*arg_ptr); |
216 |
unlock_user(arg_ptr, arg_ptr_addr, 0);
|
217 |
if (!arg_addr)
|
218 |
break;
|
219 |
if ((s = lock_user_string(arg_addr))) {
|
220 |
gemu_log("\"%s\",", s);
|
221 |
unlock_user(s, arg_addr, 0);
|
222 |
} |
223 |
} |
224 |
|
225 |
gemu_log("NULL})");
|
226 |
} |
227 |
|
228 |
#ifdef TARGET_NR_ipc
|
229 |
static void |
230 |
print_ipc(const struct syscallname *name, |
231 |
abi_long arg1, abi_long arg2, abi_long arg3, |
232 |
abi_long arg4, abi_long arg5, abi_long arg6) |
233 |
{ |
234 |
switch(arg1) {
|
235 |
case IPCOP_semctl:
|
236 |
gemu_log("semctl(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ",", arg1, arg2); |
237 |
print_ipc_cmd(arg3); |
238 |
gemu_log(",0x" TARGET_ABI_FMT_lx ")", arg4); |
239 |
break;
|
240 |
default:
|
241 |
gemu_log("%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")", |
242 |
name->name, arg1, arg2, arg3, arg4); |
243 |
} |
244 |
} |
245 |
#endif
|
246 |
|
247 |
/*
|
248 |
* Variants for the return value output function
|
249 |
*/
|
250 |
|
251 |
static void |
252 |
print_syscall_ret_addr(const struct syscallname *name, abi_long ret) |
253 |
{ |
254 |
if( ret == -1 ) { |
255 |
gemu_log(" = -1 errno=%d (%s)\n", errno, target_strerror(errno));
|
256 |
} else {
|
257 |
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret); |
258 |
} |
259 |
} |
260 |
|
261 |
#if 0 /* currently unused */
|
262 |
static void
|
263 |
print_syscall_ret_raw(struct syscallname *name, abi_long ret)
|
264 |
{
|
265 |
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
|
266 |
}
|
267 |
#endif
|
268 |
|
269 |
#ifdef TARGET_NR__newselect
|
270 |
static void |
271 |
print_syscall_ret_newselect(const struct syscallname *name, abi_long ret) |
272 |
{ |
273 |
gemu_log(" = 0x" TARGET_ABI_FMT_lx " (", ret); |
274 |
print_fdset(newselect_arg1,newselect_arg2); |
275 |
gemu_log(",");
|
276 |
print_fdset(newselect_arg1,newselect_arg3); |
277 |
gemu_log(",");
|
278 |
print_fdset(newselect_arg1,newselect_arg4); |
279 |
gemu_log(",");
|
280 |
print_timeval(newselect_arg5, 1);
|
281 |
gemu_log(")\n");
|
282 |
} |
283 |
#endif
|
284 |
|
285 |
UNUSED static struct flags access_flags[] = { |
286 |
FLAG_GENERIC(F_OK), |
287 |
FLAG_GENERIC(R_OK), |
288 |
FLAG_GENERIC(W_OK), |
289 |
FLAG_GENERIC(X_OK), |
290 |
FLAG_END, |
291 |
}; |
292 |
|
293 |
UNUSED static struct flags at_file_flags[] = { |
294 |
#ifdef AT_EACCESS
|
295 |
FLAG_GENERIC(AT_EACCESS), |
296 |
#endif
|
297 |
#ifdef AT_SYMLINK_NOFOLLOW
|
298 |
FLAG_GENERIC(AT_SYMLINK_NOFOLLOW), |
299 |
#endif
|
300 |
FLAG_END, |
301 |
}; |
302 |
|
303 |
UNUSED static struct flags unlinkat_flags[] = { |
304 |
#ifdef AT_REMOVEDIR
|
305 |
FLAG_GENERIC(AT_REMOVEDIR), |
306 |
#endif
|
307 |
FLAG_END, |
308 |
}; |
309 |
|
310 |
UNUSED static struct flags mode_flags[] = { |
311 |
FLAG_GENERIC(S_IFSOCK), |
312 |
FLAG_GENERIC(S_IFLNK), |
313 |
FLAG_GENERIC(S_IFREG), |
314 |
FLAG_GENERIC(S_IFBLK), |
315 |
FLAG_GENERIC(S_IFDIR), |
316 |
FLAG_GENERIC(S_IFCHR), |
317 |
FLAG_GENERIC(S_IFIFO), |
318 |
FLAG_END, |
319 |
}; |
320 |
|
321 |
UNUSED static struct flags open_access_flags[] = { |
322 |
FLAG_TARGET(O_RDONLY), |
323 |
FLAG_TARGET(O_WRONLY), |
324 |
FLAG_TARGET(O_RDWR), |
325 |
FLAG_END, |
326 |
}; |
327 |
|
328 |
UNUSED static struct flags open_flags[] = { |
329 |
FLAG_TARGET(O_APPEND), |
330 |
FLAG_TARGET(O_CREAT), |
331 |
FLAG_TARGET(O_DIRECTORY), |
332 |
FLAG_TARGET(O_EXCL), |
333 |
FLAG_TARGET(O_LARGEFILE), |
334 |
FLAG_TARGET(O_NOCTTY), |
335 |
FLAG_TARGET(O_NOFOLLOW), |
336 |
FLAG_TARGET(O_NONBLOCK), /* also O_NDELAY */
|
337 |
FLAG_TARGET(O_SYNC), |
338 |
FLAG_TARGET(O_TRUNC), |
339 |
#ifdef O_DIRECT
|
340 |
FLAG_TARGET(O_DIRECT), |
341 |
#endif
|
342 |
FLAG_END, |
343 |
}; |
344 |
|
345 |
UNUSED static struct flags mount_flags[] = { |
346 |
#ifdef MS_BIND
|
347 |
FLAG_GENERIC(MS_BIND), |
348 |
#endif
|
349 |
#ifdef MS_DIRSYNC
|
350 |
FLAG_GENERIC(MS_DIRSYNC), |
351 |
#endif
|
352 |
FLAG_GENERIC(MS_MANDLOCK), |
353 |
#ifdef MS_MOVE
|
354 |
FLAG_GENERIC(MS_MOVE), |
355 |
#endif
|
356 |
FLAG_GENERIC(MS_NOATIME), |
357 |
FLAG_GENERIC(MS_NODEV), |
358 |
FLAG_GENERIC(MS_NODIRATIME), |
359 |
FLAG_GENERIC(MS_NOEXEC), |
360 |
FLAG_GENERIC(MS_NOSUID), |
361 |
FLAG_GENERIC(MS_RDONLY), |
362 |
#ifdef MS_RELATIME
|
363 |
FLAG_GENERIC(MS_RELATIME), |
364 |
#endif
|
365 |
FLAG_GENERIC(MS_REMOUNT), |
366 |
FLAG_GENERIC(MS_SYNCHRONOUS), |
367 |
FLAG_END, |
368 |
}; |
369 |
|
370 |
UNUSED static struct flags umount2_flags[] = { |
371 |
#ifdef MNT_FORCE
|
372 |
FLAG_GENERIC(MNT_FORCE), |
373 |
#endif
|
374 |
#ifdef MNT_DETACH
|
375 |
FLAG_GENERIC(MNT_DETACH), |
376 |
#endif
|
377 |
#ifdef MNT_EXPIRE
|
378 |
FLAG_GENERIC(MNT_EXPIRE), |
379 |
#endif
|
380 |
FLAG_END, |
381 |
}; |
382 |
|
383 |
UNUSED static struct flags mmap_prot_flags[] = { |
384 |
FLAG_GENERIC(PROT_NONE), |
385 |
FLAG_GENERIC(PROT_EXEC), |
386 |
FLAG_GENERIC(PROT_READ), |
387 |
FLAG_GENERIC(PROT_WRITE), |
388 |
FLAG_TARGET(PROT_SEM), |
389 |
FLAG_GENERIC(PROT_GROWSDOWN), |
390 |
FLAG_GENERIC(PROT_GROWSUP), |
391 |
FLAG_END, |
392 |
}; |
393 |
|
394 |
UNUSED static struct flags mmap_flags[] = { |
395 |
FLAG_TARGET(MAP_SHARED), |
396 |
FLAG_TARGET(MAP_PRIVATE), |
397 |
FLAG_TARGET(MAP_ANONYMOUS), |
398 |
FLAG_TARGET(MAP_DENYWRITE), |
399 |
FLAG_TARGET(MAP_FIXED), |
400 |
FLAG_TARGET(MAP_GROWSDOWN), |
401 |
#ifdef MAP_LOCKED
|
402 |
FLAG_TARGET(MAP_LOCKED), |
403 |
#endif
|
404 |
#ifdef MAP_NONBLOCK
|
405 |
FLAG_TARGET(MAP_NONBLOCK), |
406 |
#endif
|
407 |
FLAG_TARGET(MAP_NORESERVE), |
408 |
#ifdef MAP_POPULATE
|
409 |
FLAG_TARGET(MAP_POPULATE), |
410 |
#endif
|
411 |
FLAG_END, |
412 |
}; |
413 |
|
414 |
UNUSED static struct flags fcntl_flags[] = { |
415 |
FLAG_TARGET(F_DUPFD), |
416 |
FLAG_TARGET(F_GETFD), |
417 |
FLAG_TARGET(F_SETFD), |
418 |
FLAG_TARGET(F_GETFL), |
419 |
FLAG_TARGET(F_SETFL), |
420 |
FLAG_TARGET(F_GETLK), |
421 |
FLAG_TARGET(F_SETLK), |
422 |
FLAG_TARGET(F_SETLKW), |
423 |
FLAG_END, |
424 |
}; |
425 |
|
426 |
/*
|
427 |
* print_xxx utility functions. These are used to print syscall
|
428 |
* parameters in certain format. All of these have parameter
|
429 |
* named 'last'. This parameter is used to add comma to output
|
430 |
* when last == 0.
|
431 |
*/
|
432 |
|
433 |
static const char * |
434 |
get_comma(int last)
|
435 |
{ |
436 |
return ((last) ? "" : ","); |
437 |
} |
438 |
|
439 |
static void |
440 |
print_flags(const struct flags *f, abi_long tflags, int last) |
441 |
{ |
442 |
const char *sep = ""; |
443 |
int flags;
|
444 |
int n;
|
445 |
|
446 |
flags = (int)tswap32(tflags);
|
447 |
|
448 |
if ((flags == 0) && (f->f_value == 0)) { |
449 |
gemu_log("%s%s", f->f_string, get_comma(last));
|
450 |
return;
|
451 |
} |
452 |
for (n = 0; f->f_string != NULL; f++) { |
453 |
if ((f->f_value != 0) && ((flags & f->f_value) == f->f_value)) { |
454 |
gemu_log("%s%s", sep, f->f_string);
|
455 |
flags &= ~f->f_value; |
456 |
sep = "|";
|
457 |
n++; |
458 |
} |
459 |
} |
460 |
|
461 |
if (n > 0) { |
462 |
/* print rest of the flags as numeric */
|
463 |
if (flags != 0) { |
464 |
gemu_log("%s%#x%s", sep, flags, get_comma(last));
|
465 |
} else {
|
466 |
gemu_log("%s", get_comma(last));
|
467 |
} |
468 |
} else {
|
469 |
/* no string version of flags found, print them in hex then */
|
470 |
gemu_log("%#x%s", flags, get_comma(last));
|
471 |
} |
472 |
} |
473 |
|
474 |
static void |
475 |
print_at_dirfd(abi_long tdirfd, int last)
|
476 |
{ |
477 |
int dirfd = tswap32(tdirfd);
|
478 |
|
479 |
#ifdef AT_FDCWD
|
480 |
if (dirfd == AT_FDCWD) {
|
481 |
gemu_log("AT_FDCWD%s", get_comma(last));
|
482 |
return;
|
483 |
} |
484 |
#endif
|
485 |
gemu_log("%d%s", dirfd, get_comma(last));
|
486 |
} |
487 |
|
488 |
static void |
489 |
print_file_mode(abi_long tmode, int last)
|
490 |
{ |
491 |
const char *sep = ""; |
492 |
const struct flags *m; |
493 |
mode_t mode = (mode_t)tswap32(tmode); |
494 |
|
495 |
for (m = &mode_flags[0]; m->f_string != NULL; m++) { |
496 |
if ((m->f_value & mode) == m->f_value) {
|
497 |
gemu_log("%s%s", m->f_string, sep);
|
498 |
sep = "|";
|
499 |
mode &= ~m->f_value; |
500 |
break;
|
501 |
} |
502 |
} |
503 |
|
504 |
mode &= ~S_IFMT; |
505 |
/* print rest of the mode as octal */
|
506 |
if (mode != 0) |
507 |
gemu_log("%s%#o", sep, mode);
|
508 |
|
509 |
gemu_log("%s", get_comma(last));
|
510 |
} |
511 |
|
512 |
static void |
513 |
print_open_flags(abi_long tflags, int last)
|
514 |
{ |
515 |
int flags = tswap32(tflags);
|
516 |
|
517 |
print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1);
|
518 |
flags &= ~TARGET_O_ACCMODE; |
519 |
if (flags == 0) { |
520 |
gemu_log("%s", get_comma(last));
|
521 |
return;
|
522 |
} |
523 |
gemu_log("|");
|
524 |
print_flags(open_flags, flags, last); |
525 |
} |
526 |
|
527 |
static void |
528 |
print_syscall_prologue(const struct syscallname *sc) |
529 |
{ |
530 |
gemu_log("%s(", sc->name);
|
531 |
} |
532 |
|
533 |
/*ARGSUSED*/
|
534 |
static void |
535 |
print_syscall_epilogue(const struct syscallname *sc) |
536 |
{ |
537 |
(void)sc;
|
538 |
gemu_log(")");
|
539 |
} |
540 |
|
541 |
static void |
542 |
print_string(abi_long addr, int last)
|
543 |
{ |
544 |
char *s;
|
545 |
|
546 |
if ((s = lock_user_string(addr)) != NULL) { |
547 |
gemu_log("\"%s\"%s", s, get_comma(last));
|
548 |
unlock_user(s, addr, 0);
|
549 |
} else {
|
550 |
/* can't get string out of it, so print it as pointer */
|
551 |
print_pointer(addr, last); |
552 |
} |
553 |
} |
554 |
|
555 |
/*
|
556 |
* Prints out raw parameter using given format. Caller needs
|
557 |
* to do byte swapping if needed.
|
558 |
*/
|
559 |
static void |
560 |
print_raw_param(const char *fmt, abi_long param, int last) |
561 |
{ |
562 |
char format[64]; |
563 |
|
564 |
(void) snprintf(format, sizeof (format), "%s%s", fmt, get_comma(last)); |
565 |
gemu_log(format, param); |
566 |
} |
567 |
|
568 |
static void |
569 |
print_pointer(abi_long p, int last)
|
570 |
{ |
571 |
if (p == 0) |
572 |
gemu_log("NULL%s", get_comma(last));
|
573 |
else
|
574 |
gemu_log("0x" TARGET_ABI_FMT_lx "%s", p, get_comma(last)); |
575 |
} |
576 |
|
577 |
/*
|
578 |
* Reads 32-bit (int) number from guest address space from
|
579 |
* address 'addr' and prints it.
|
580 |
*/
|
581 |
static void |
582 |
print_number(abi_long addr, int last)
|
583 |
{ |
584 |
if (addr == 0) { |
585 |
gemu_log("NULL%s", get_comma(last));
|
586 |
} else {
|
587 |
int num;
|
588 |
|
589 |
get_user_s32(num, addr); |
590 |
gemu_log("[%d]%s", num, get_comma(last));
|
591 |
} |
592 |
} |
593 |
|
594 |
static void |
595 |
print_timeval(abi_ulong tv_addr, int last)
|
596 |
{ |
597 |
if( tv_addr ) {
|
598 |
struct target_timeval *tv;
|
599 |
|
600 |
tv = lock_user(VERIFY_READ, tv_addr, sizeof(*tv), 1); |
601 |
if (!tv)
|
602 |
return;
|
603 |
gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}%s", |
604 |
tv->tv_sec, tv->tv_usec, get_comma(last)); |
605 |
unlock_user(tv, tv_addr, 0);
|
606 |
} else
|
607 |
gemu_log("NULL%s", get_comma(last));
|
608 |
} |
609 |
|
610 |
#undef UNUSED
|
611 |
|
612 |
#ifdef TARGET_NR_accept
|
613 |
static void |
614 |
print_accept(const struct syscallname *name, |
615 |
abi_long arg0, abi_long arg1, abi_long arg2, |
616 |
abi_long arg3, abi_long arg4, abi_long arg5) |
617 |
{ |
618 |
print_syscall_prologue(name); |
619 |
print_raw_param("%d", tswap32(arg0), 0); |
620 |
print_pointer(arg1, 0);
|
621 |
print_number(arg2, 1);
|
622 |
print_syscall_epilogue(name); |
623 |
} |
624 |
#endif
|
625 |
|
626 |
#ifdef TARGET_NR_access
|
627 |
static void |
628 |
print_access(const struct syscallname *name, |
629 |
abi_long arg0, abi_long arg1, abi_long arg2, |
630 |
abi_long arg3, abi_long arg4, abi_long arg5) |
631 |
{ |
632 |
print_syscall_prologue(name); |
633 |
print_string(arg0, 0);
|
634 |
print_flags(access_flags, arg1, 1);
|
635 |
print_syscall_epilogue(name); |
636 |
} |
637 |
#endif
|
638 |
|
639 |
#ifdef TARGET_NR_brk
|
640 |
static void |
641 |
print_brk(const struct syscallname *name, |
642 |
abi_long arg0, abi_long arg1, abi_long arg2, |
643 |
abi_long arg3, abi_long arg4, abi_long arg5) |
644 |
{ |
645 |
print_syscall_prologue(name); |
646 |
print_pointer(arg0, 1);
|
647 |
print_syscall_epilogue(name); |
648 |
} |
649 |
#endif
|
650 |
|
651 |
#ifdef TARGET_NR_chdir
|
652 |
static void |
653 |
print_chdir(const struct syscallname *name, |
654 |
abi_long arg0, abi_long arg1, abi_long arg2, |
655 |
abi_long arg3, abi_long arg4, abi_long arg5) |
656 |
{ |
657 |
print_syscall_prologue(name); |
658 |
print_string(arg0, 1);
|
659 |
print_syscall_epilogue(name); |
660 |
} |
661 |
#endif
|
662 |
|
663 |
#ifdef TARGET_NR_chmod
|
664 |
static void |
665 |
print_chmod(const struct syscallname *name, |
666 |
abi_long arg0, abi_long arg1, abi_long arg2, |
667 |
abi_long arg3, abi_long arg4, abi_long arg5) |
668 |
{ |
669 |
print_syscall_prologue(name); |
670 |
print_string(arg0, 0);
|
671 |
print_file_mode(arg1, 1);
|
672 |
print_syscall_epilogue(name); |
673 |
} |
674 |
#endif
|
675 |
|
676 |
#ifdef TARGET_NR_creat
|
677 |
static void |
678 |
print_creat(const struct syscallname *name, |
679 |
abi_long arg0, abi_long arg1, abi_long arg2, |
680 |
abi_long arg3, abi_long arg4, abi_long arg5) |
681 |
{ |
682 |
print_syscall_prologue(name); |
683 |
print_string(arg0, 0);
|
684 |
print_file_mode(arg1, 1);
|
685 |
print_syscall_epilogue(name); |
686 |
} |
687 |
#endif
|
688 |
|
689 |
#ifdef TARGET_NR_execv
|
690 |
static void |
691 |
print_execv(const struct syscallname *name, |
692 |
abi_long arg0, abi_long arg1, abi_long arg2, |
693 |
abi_long arg3, abi_long arg4, abi_long arg5) |
694 |
{ |
695 |
print_syscall_prologue(name); |
696 |
print_string(arg0, 0);
|
697 |
print_raw_param("0x" TARGET_ABI_FMT_lx, tswapl(arg1), 1); |
698 |
print_syscall_epilogue(name); |
699 |
} |
700 |
#endif
|
701 |
|
702 |
#ifdef TARGET_NR_faccessat
|
703 |
static void |
704 |
print_faccessat(const struct syscallname *name, |
705 |
abi_long arg0, abi_long arg1, abi_long arg2, |
706 |
abi_long arg3, abi_long arg4, abi_long arg5) |
707 |
{ |
708 |
print_syscall_prologue(name); |
709 |
print_at_dirfd(arg0, 0);
|
710 |
print_string(arg1, 0);
|
711 |
print_flags(access_flags, arg2, 0);
|
712 |
print_flags(at_file_flags, arg3, 1);
|
713 |
print_syscall_epilogue(name); |
714 |
} |
715 |
#endif
|
716 |
|
717 |
#ifdef TARGET_NR_fchmodat
|
718 |
static void |
719 |
print_fchmodat(const struct syscallname *name, |
720 |
abi_long arg0, abi_long arg1, abi_long arg2, |
721 |
abi_long arg3, abi_long arg4, abi_long arg5) |
722 |
{ |
723 |
print_syscall_prologue(name); |
724 |
print_at_dirfd(arg0, 0);
|
725 |
print_string(arg1, 0);
|
726 |
print_file_mode(arg2, 0);
|
727 |
print_flags(at_file_flags, arg3, 1);
|
728 |
print_syscall_epilogue(name); |
729 |
} |
730 |
#endif
|
731 |
|
732 |
#ifdef TARGET_NR_fchownat
|
733 |
static void |
734 |
print_fchownat(const struct syscallname *name, |
735 |
abi_long arg0, abi_long arg1, abi_long arg2, |
736 |
abi_long arg3, abi_long arg4, abi_long arg5) |
737 |
{ |
738 |
print_syscall_prologue(name); |
739 |
print_at_dirfd(arg0, 0);
|
740 |
print_string(arg1, 0);
|
741 |
#ifdef USE_UID16
|
742 |
print_raw_param("%d", tswap16(arg2), 0); |
743 |
print_raw_param("%d", tswap16(arg3), 0); |
744 |
#else
|
745 |
print_raw_param("%d", tswap32(arg2), 0); |
746 |
print_raw_param("%d", tswap32(arg3), 0); |
747 |
#endif
|
748 |
print_flags(at_file_flags, arg4, 1);
|
749 |
print_syscall_epilogue(name); |
750 |
} |
751 |
#endif
|
752 |
|
753 |
#if defined(TARGET_NR_fcntl) || defined(TARGET_NR_fcntl64)
|
754 |
static void |
755 |
print_fcntl(const struct syscallname *name, |
756 |
abi_long arg0, abi_long arg1, abi_long arg2, |
757 |
abi_long arg3, abi_long arg4, abi_long arg5) |
758 |
{ |
759 |
print_syscall_prologue(name); |
760 |
print_raw_param("%d", tswap32(arg0), 0); |
761 |
print_flags(fcntl_flags, arg1, 0);
|
762 |
/*
|
763 |
* TODO: check flags and print following argument only
|
764 |
* when needed.
|
765 |
*/
|
766 |
print_pointer(arg2, 1);
|
767 |
print_syscall_epilogue(name); |
768 |
} |
769 |
#define print_fcntl64 print_fcntl
|
770 |
#endif
|
771 |
|
772 |
|
773 |
#ifdef TARGET_NR_futimesat
|
774 |
static void |
775 |
print_futimesat(const struct syscallname *name, |
776 |
abi_long arg0, abi_long arg1, abi_long arg2, |
777 |
abi_long arg3, abi_long arg4, abi_long arg5) |
778 |
{ |
779 |
print_syscall_prologue(name); |
780 |
print_at_dirfd(arg0, 0);
|
781 |
print_string(arg1, 0);
|
782 |
print_timeval(arg2, 0);
|
783 |
print_timeval(arg2 + sizeof (struct target_timeval), 1); |
784 |
print_syscall_epilogue(name); |
785 |
} |
786 |
#endif
|
787 |
|
788 |
#ifdef TARGET_NR_link
|
789 |
static void |
790 |
print_link(const struct syscallname *name, |
791 |
abi_long arg0, abi_long arg1, abi_long arg2, |
792 |
abi_long arg3, abi_long arg4, abi_long arg5) |
793 |
{ |
794 |
print_syscall_prologue(name); |
795 |
print_string(arg0, 0);
|
796 |
print_string(arg1, 1);
|
797 |
print_syscall_epilogue(name); |
798 |
} |
799 |
#endif
|
800 |
|
801 |
#ifdef TARGET_NR_linkat
|
802 |
static void |
803 |
print_linkat(const struct syscallname *name, |
804 |
abi_long arg0, abi_long arg1, abi_long arg2, |
805 |
abi_long arg3, abi_long arg4, abi_long arg5) |
806 |
{ |
807 |
print_syscall_prologue(name); |
808 |
print_at_dirfd(arg0, 0);
|
809 |
print_string(arg1, 0);
|
810 |
print_at_dirfd(arg2, 0);
|
811 |
print_string(arg3, 0);
|
812 |
print_flags(at_file_flags, arg4, 1);
|
813 |
print_syscall_epilogue(name); |
814 |
} |
815 |
#endif
|
816 |
|
817 |
#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
|
818 |
defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) |
819 |
static void |
820 |
print_stat(const struct syscallname *name, |
821 |
abi_long arg0, abi_long arg1, abi_long arg2, |
822 |
abi_long arg3, abi_long arg4, abi_long arg5) |
823 |
{ |
824 |
print_syscall_prologue(name); |
825 |
print_string(arg0, 0);
|
826 |
print_pointer(arg1, 1);
|
827 |
print_syscall_epilogue(name); |
828 |
} |
829 |
#define print_lstat print_stat
|
830 |
#define print_stat64 print_stat
|
831 |
#define print_lstat64 print_stat
|
832 |
#endif
|
833 |
|
834 |
#if defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
|
835 |
static void |
836 |
print_fstat(const struct syscallname *name, |
837 |
abi_long arg0, abi_long arg1, abi_long arg2, |
838 |
abi_long arg3, abi_long arg4, abi_long arg5) |
839 |
{ |
840 |
print_syscall_prologue(name); |
841 |
print_raw_param("%d", tswap32(arg0), 0); |
842 |
print_pointer(arg1, 1);
|
843 |
print_syscall_epilogue(name); |
844 |
} |
845 |
#define print_fstat64 print_fstat
|
846 |
#endif
|
847 |
|
848 |
#ifdef TARGET_NR_mkdir
|
849 |
static void |
850 |
print_mkdir(const struct syscallname *name, |
851 |
abi_long arg0, abi_long arg1, abi_long arg2, |
852 |
abi_long arg3, abi_long arg4, abi_long arg5) |
853 |
{ |
854 |
print_syscall_prologue(name); |
855 |
print_string(arg0, 0);
|
856 |
print_file_mode(arg1, 1);
|
857 |
print_syscall_epilogue(name); |
858 |
} |
859 |
#endif
|
860 |
|
861 |
#ifdef TARGET_NR_mkdirat
|
862 |
static void |
863 |
print_mkdirat(const struct syscallname *name, |
864 |
abi_long arg0, abi_long arg1, abi_long arg2, |
865 |
abi_long arg3, abi_long arg4, abi_long arg5) |
866 |
{ |
867 |
print_syscall_prologue(name); |
868 |
print_at_dirfd(arg0, 0);
|
869 |
print_string(arg1, 0);
|
870 |
print_file_mode(arg2, 1);
|
871 |
print_syscall_epilogue(name); |
872 |
} |
873 |
#endif
|
874 |
|
875 |
#ifdef TARGET_NR_mknod
|
876 |
static void |
877 |
print_mknod(const struct syscallname *name, |
878 |
abi_long arg0, abi_long arg1, abi_long arg2, |
879 |
abi_long arg3, abi_long arg4, abi_long arg5) |
880 |
{ |
881 |
int hasdev = (tswapl(arg1) & (S_IFCHR|S_IFBLK));
|
882 |
|
883 |
print_syscall_prologue(name); |
884 |
print_string(arg0, 0);
|
885 |
print_file_mode(arg1, (hasdev == 0));
|
886 |
if (hasdev) {
|
887 |
print_raw_param("makedev(%d", major(tswapl(arg2)), 0); |
888 |
print_raw_param("%d)", minor(tswapl(arg2)), 1); |
889 |
} |
890 |
print_syscall_epilogue(name); |
891 |
} |
892 |
#endif
|
893 |
|
894 |
#ifdef TARGET_NR_mknodat
|
895 |
static void |
896 |
print_mknodat(const struct syscallname *name, |
897 |
abi_long arg0, abi_long arg1, abi_long arg2, |
898 |
abi_long arg3, abi_long arg4, abi_long arg5) |
899 |
{ |
900 |
int hasdev = (tswapl(arg2) & (S_IFCHR|S_IFBLK));
|
901 |
|
902 |
print_syscall_prologue(name); |
903 |
print_at_dirfd(arg0, 0);
|
904 |
print_string(arg1, 0);
|
905 |
print_file_mode(arg2, (hasdev == 0));
|
906 |
if (hasdev) {
|
907 |
print_raw_param("makedev(%d", major(tswapl(arg3)), 0); |
908 |
print_raw_param("%d)", minor(tswapl(arg3)), 1); |
909 |
} |
910 |
print_syscall_epilogue(name); |
911 |
} |
912 |
#endif
|
913 |
|
914 |
#ifdef TARGET_NR_mq_open
|
915 |
static void |
916 |
print_mq_open(const struct syscallname *name, |
917 |
abi_long arg0, abi_long arg1, abi_long arg2, |
918 |
abi_long arg3, abi_long arg4, abi_long arg5) |
919 |
{ |
920 |
int is_creat = (tswapl(arg1) & TARGET_O_CREAT);
|
921 |
|
922 |
print_syscall_prologue(name); |
923 |
print_string(arg0, 0);
|
924 |
print_open_flags(arg1, (is_creat == 0));
|
925 |
if (is_creat) {
|
926 |
print_file_mode(arg2, 0);
|
927 |
print_pointer(arg3, 1);
|
928 |
} |
929 |
print_syscall_epilogue(name); |
930 |
} |
931 |
#endif
|
932 |
|
933 |
#ifdef TARGET_NR_open
|
934 |
static void |
935 |
print_open(const struct syscallname *name, |
936 |
abi_long arg0, abi_long arg1, abi_long arg2, |
937 |
abi_long arg3, abi_long arg4, abi_long arg5) |
938 |
{ |
939 |
int is_creat = (tswap32(arg1) & TARGET_O_CREAT);
|
940 |
|
941 |
print_syscall_prologue(name); |
942 |
print_string(arg0, 0);
|
943 |
print_open_flags(arg1, (is_creat == 0));
|
944 |
if (is_creat)
|
945 |
print_file_mode(arg2, 1);
|
946 |
print_syscall_epilogue(name); |
947 |
} |
948 |
#endif
|
949 |
|
950 |
#ifdef TARGET_NR_openat
|
951 |
static void |
952 |
print_openat(const struct syscallname *name, |
953 |
abi_long arg0, abi_long arg1, abi_long arg2, |
954 |
abi_long arg3, abi_long arg4, abi_long arg5) |
955 |
{ |
956 |
int is_creat = (tswap32(arg2) & TARGET_O_CREAT);
|
957 |
|
958 |
print_syscall_prologue(name); |
959 |
print_at_dirfd(arg0, 0);
|
960 |
print_string(arg1, 0);
|
961 |
print_open_flags(arg2, (is_creat == 0));
|
962 |
if (is_creat)
|
963 |
print_file_mode(arg3, 1);
|
964 |
print_syscall_epilogue(name); |
965 |
} |
966 |
#endif
|
967 |
|
968 |
#ifdef TARGET_NR_mq_unlink
|
969 |
static void |
970 |
print_mq_unlink(const struct syscallname *name, |
971 |
abi_long arg0, abi_long arg1, abi_long arg2, |
972 |
abi_long arg3, abi_long arg4, abi_long arg5) |
973 |
{ |
974 |
print_syscall_prologue(name); |
975 |
print_string(arg0, 1);
|
976 |
print_syscall_epilogue(name); |
977 |
} |
978 |
#endif
|
979 |
|
980 |
#if defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)
|
981 |
static void |
982 |
print_fstatat64(const struct syscallname *name, |
983 |
abi_long arg0, abi_long arg1, abi_long arg2, |
984 |
abi_long arg3, abi_long arg4, abi_long arg5) |
985 |
{ |
986 |
print_syscall_prologue(name); |
987 |
print_at_dirfd(arg0, 0);
|
988 |
print_string(arg1, 0);
|
989 |
print_pointer(arg2, 0);
|
990 |
print_flags(at_file_flags, arg3, 1);
|
991 |
print_syscall_epilogue(name); |
992 |
} |
993 |
#define print_newfstatat print_fstatat64
|
994 |
#endif
|
995 |
|
996 |
#ifdef TARGET_NR_readlink
|
997 |
static void |
998 |
print_readlink(const struct syscallname *name, |
999 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1000 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1001 |
{ |
1002 |
print_syscall_prologue(name); |
1003 |
print_string(arg0, 0);
|
1004 |
print_pointer(arg1, 0);
|
1005 |
print_raw_param("%u", tswapl(arg2), 1); |
1006 |
print_syscall_epilogue(name); |
1007 |
} |
1008 |
#endif
|
1009 |
|
1010 |
#ifdef TARGET_NR_readlinkat
|
1011 |
static void |
1012 |
print_readlinkat(const struct syscallname *name, |
1013 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1014 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1015 |
{ |
1016 |
print_syscall_prologue(name); |
1017 |
print_at_dirfd(arg0, 0);
|
1018 |
print_string(arg1, 0);
|
1019 |
print_pointer(arg2, 0);
|
1020 |
print_raw_param("%u", tswapl(arg3), 1); |
1021 |
print_syscall_epilogue(name); |
1022 |
} |
1023 |
#endif
|
1024 |
|
1025 |
#ifdef TARGET_NR_rename
|
1026 |
static void |
1027 |
print_rename(const struct syscallname *name, |
1028 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1029 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1030 |
{ |
1031 |
print_syscall_prologue(name); |
1032 |
print_string(arg0, 0);
|
1033 |
print_string(arg1, 1);
|
1034 |
print_syscall_epilogue(name); |
1035 |
} |
1036 |
#endif
|
1037 |
|
1038 |
#ifdef TARGET_NR_renameat
|
1039 |
static void |
1040 |
print_renameat(const struct syscallname *name, |
1041 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1042 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1043 |
{ |
1044 |
print_syscall_prologue(name); |
1045 |
print_at_dirfd(arg0, 0);
|
1046 |
print_string(arg1, 0);
|
1047 |
print_at_dirfd(arg2, 0);
|
1048 |
print_string(arg3, 1);
|
1049 |
print_syscall_epilogue(name); |
1050 |
} |
1051 |
#endif
|
1052 |
|
1053 |
#ifdef TARGET_NR_statfs
|
1054 |
static void |
1055 |
print_statfs(const struct syscallname *name, |
1056 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1057 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1058 |
{ |
1059 |
print_syscall_prologue(name); |
1060 |
print_string(arg0, 0);
|
1061 |
print_pointer(arg1, 1);
|
1062 |
print_syscall_epilogue(name); |
1063 |
} |
1064 |
#define print_statfs64 print_statfs
|
1065 |
#endif
|
1066 |
|
1067 |
#ifdef TARGET_NR_symlink
|
1068 |
static void |
1069 |
print_symlink(const struct syscallname *name, |
1070 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1071 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1072 |
{ |
1073 |
print_syscall_prologue(name); |
1074 |
print_string(arg0, 0);
|
1075 |
print_string(arg1, 1);
|
1076 |
print_syscall_epilogue(name); |
1077 |
} |
1078 |
#endif
|
1079 |
|
1080 |
#ifdef TARGET_NR_symlinkat
|
1081 |
static void |
1082 |
print_symlinkat(const struct syscallname *name, |
1083 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1084 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1085 |
{ |
1086 |
print_syscall_prologue(name); |
1087 |
print_string(arg0, 0);
|
1088 |
print_at_dirfd(arg1, 0);
|
1089 |
print_string(arg2, 1);
|
1090 |
print_syscall_epilogue(name); |
1091 |
} |
1092 |
#endif
|
1093 |
|
1094 |
#ifdef TARGET_NR_mount
|
1095 |
static void |
1096 |
print_mount(const struct syscallname *name, |
1097 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1098 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1099 |
{ |
1100 |
print_syscall_prologue(name); |
1101 |
print_string(arg0, 0);
|
1102 |
print_string(arg1, 0);
|
1103 |
print_string(arg2, 0);
|
1104 |
print_flags(mount_flags, arg3, 0);
|
1105 |
print_pointer(arg4, 1);
|
1106 |
print_syscall_epilogue(name); |
1107 |
} |
1108 |
#endif
|
1109 |
|
1110 |
#ifdef TARGET_NR_umount
|
1111 |
static void |
1112 |
print_umount(const struct syscallname *name, |
1113 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1114 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1115 |
{ |
1116 |
print_syscall_prologue(name); |
1117 |
print_string(arg0, 1);
|
1118 |
print_syscall_epilogue(name); |
1119 |
} |
1120 |
#endif
|
1121 |
|
1122 |
#ifdef TARGET_NR_umount2
|
1123 |
static void |
1124 |
print_umount2(const struct syscallname *name, |
1125 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1126 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1127 |
{ |
1128 |
print_syscall_prologue(name); |
1129 |
print_string(arg0, 0);
|
1130 |
print_flags(umount2_flags, arg1, 1);
|
1131 |
print_syscall_epilogue(name); |
1132 |
} |
1133 |
#endif
|
1134 |
|
1135 |
#ifdef TARGET_NR_unlink
|
1136 |
static void |
1137 |
print_unlink(const struct syscallname *name, |
1138 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1139 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1140 |
{ |
1141 |
print_syscall_prologue(name); |
1142 |
print_string(arg0, 1);
|
1143 |
print_syscall_epilogue(name); |
1144 |
} |
1145 |
#endif
|
1146 |
|
1147 |
#ifdef TARGET_NR_unlinkat
|
1148 |
static void |
1149 |
print_unlinkat(const struct syscallname *name, |
1150 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1151 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1152 |
{ |
1153 |
print_syscall_prologue(name); |
1154 |
print_at_dirfd(arg0, 0);
|
1155 |
print_string(arg1, 0);
|
1156 |
print_flags(unlinkat_flags, arg2, 1);
|
1157 |
print_syscall_epilogue(name); |
1158 |
} |
1159 |
#endif
|
1160 |
|
1161 |
#ifdef TARGET_NR_utime
|
1162 |
static void |
1163 |
print_utime(const struct syscallname *name, |
1164 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1165 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1166 |
{ |
1167 |
print_syscall_prologue(name); |
1168 |
print_string(arg0, 0);
|
1169 |
print_pointer(arg1, 1);
|
1170 |
print_syscall_epilogue(name); |
1171 |
} |
1172 |
#endif
|
1173 |
|
1174 |
#ifdef TARGET_NR_utimes
|
1175 |
static void |
1176 |
print_utimes(const struct syscallname *name, |
1177 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1178 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1179 |
{ |
1180 |
print_syscall_prologue(name); |
1181 |
print_string(arg0, 0);
|
1182 |
print_pointer(arg1, 1);
|
1183 |
print_syscall_epilogue(name); |
1184 |
} |
1185 |
#endif
|
1186 |
|
1187 |
#ifdef TARGET_NR_utimensat
|
1188 |
static void |
1189 |
print_utimensat(const struct syscallname *name, |
1190 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1191 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1192 |
{ |
1193 |
print_syscall_prologue(name); |
1194 |
print_at_dirfd(arg0, 0);
|
1195 |
print_string(arg1, 0);
|
1196 |
print_pointer(arg2, 0);
|
1197 |
print_flags(at_file_flags, arg3, 1);
|
1198 |
print_syscall_epilogue(name); |
1199 |
} |
1200 |
#endif
|
1201 |
|
1202 |
#ifdef TARGET_NR_mmap
|
1203 |
static void |
1204 |
print_mmap(const struct syscallname *name, |
1205 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1206 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1207 |
{ |
1208 |
print_syscall_prologue(name); |
1209 |
print_pointer(arg0, 0);
|
1210 |
print_raw_param("%d", tswapl(arg1), 0); |
1211 |
print_flags(mmap_prot_flags, arg2, 0);
|
1212 |
print_flags(mmap_flags, arg3, 0);
|
1213 |
print_raw_param("%d", tswapl(arg4), 0); |
1214 |
print_raw_param("%#x", tswapl(arg5), 1); |
1215 |
print_syscall_epilogue(name); |
1216 |
} |
1217 |
#define print_mmap2 print_mmap
|
1218 |
#endif
|
1219 |
|
1220 |
#ifdef TARGET_NR_mprotect
|
1221 |
static void |
1222 |
print_mprotect(const struct syscallname *name, |
1223 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1224 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1225 |
{ |
1226 |
print_syscall_prologue(name); |
1227 |
print_pointer(arg0, 0);
|
1228 |
print_raw_param("%d", tswapl(arg1), 0); |
1229 |
print_flags(mmap_prot_flags, arg2, 1);
|
1230 |
print_syscall_epilogue(name); |
1231 |
} |
1232 |
#endif
|
1233 |
|
1234 |
#ifdef TARGET_NR_munmap
|
1235 |
static void |
1236 |
print_munmap(const struct syscallname *name, |
1237 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1238 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1239 |
{ |
1240 |
print_syscall_prologue(name); |
1241 |
print_pointer(arg0, 0);
|
1242 |
print_raw_param("%d", tswapl(arg1), 1); |
1243 |
print_syscall_epilogue(name); |
1244 |
} |
1245 |
#endif
|
1246 |
|
1247 |
#ifdef TARGET_NR_futex
|
1248 |
static void print_futex_op(abi_long tflag, int last) |
1249 |
{ |
1250 |
#define print_op(val) \
|
1251 |
if( cmd == val ) { \
|
1252 |
gemu_log(#val); \
|
1253 |
return; \
|
1254 |
} |
1255 |
|
1256 |
int cmd = (int)tswap32(tflag); |
1257 |
#ifdef FUTEX_PRIVATE_FLAG
|
1258 |
if (cmd & FUTEX_PRIVATE_FLAG) {
|
1259 |
gemu_log("FUTEX_PRIVATE_FLAG|");
|
1260 |
cmd &= ~FUTEX_PRIVATE_FLAG; |
1261 |
} |
1262 |
#endif
|
1263 |
print_op(FUTEX_WAIT) |
1264 |
print_op(FUTEX_WAKE) |
1265 |
print_op(FUTEX_FD) |
1266 |
print_op(FUTEX_REQUEUE) |
1267 |
print_op(FUTEX_CMP_REQUEUE) |
1268 |
print_op(FUTEX_WAKE_OP) |
1269 |
print_op(FUTEX_LOCK_PI) |
1270 |
print_op(FUTEX_UNLOCK_PI) |
1271 |
print_op(FUTEX_TRYLOCK_PI) |
1272 |
#ifdef FUTEX_WAIT_BITSET
|
1273 |
print_op(FUTEX_WAIT_BITSET) |
1274 |
#endif
|
1275 |
#ifdef FUTEX_WAKE_BITSET
|
1276 |
print_op(FUTEX_WAKE_BITSET) |
1277 |
#endif
|
1278 |
/* unknown values */
|
1279 |
gemu_log("%d",cmd);
|
1280 |
} |
1281 |
|
1282 |
static void |
1283 |
print_futex(const struct syscallname *name, |
1284 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1285 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1286 |
{ |
1287 |
print_syscall_prologue(name); |
1288 |
print_pointer(arg0, 0);
|
1289 |
print_futex_op(arg1, 0);
|
1290 |
print_raw_param(",%d", tswapl(arg2), 0); |
1291 |
print_pointer(arg3, 0); /* struct timespec */ |
1292 |
print_pointer(arg4, 0);
|
1293 |
print_raw_param("%d", tswapl(arg4), 1); |
1294 |
print_syscall_epilogue(name); |
1295 |
} |
1296 |
#endif
|
1297 |
|
1298 |
/*
|
1299 |
* An array of all of the syscalls we know about
|
1300 |
*/
|
1301 |
|
1302 |
static const struct syscallname scnames[] = { |
1303 |
#include "strace.list" |
1304 |
}; |
1305 |
|
1306 |
static int nsyscalls = ARRAY_SIZE(scnames); |
1307 |
|
1308 |
/*
|
1309 |
* The public interface to this module.
|
1310 |
*/
|
1311 |
void
|
1312 |
print_syscall(int num,
|
1313 |
abi_long arg1, abi_long arg2, abi_long arg3, |
1314 |
abi_long arg4, abi_long arg5, abi_long arg6) |
1315 |
{ |
1316 |
int i;
|
1317 |
const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ")"; |
1318 |
|
1319 |
gemu_log("%d ", getpid() );
|
1320 |
|
1321 |
for(i=0;i<nsyscalls;i++) |
1322 |
if( scnames[i].nr == num ) {
|
1323 |
if( scnames[i].call != NULL ) { |
1324 |
scnames[i].call(&scnames[i],arg1,arg2,arg3,arg4,arg5,arg6); |
1325 |
} else {
|
1326 |
/* XXX: this format system is broken because it uses
|
1327 |
host types and host pointers for strings */
|
1328 |
if( scnames[i].format != NULL ) |
1329 |
format = scnames[i].format; |
1330 |
gemu_log(format,scnames[i].name, arg1,arg2,arg3,arg4,arg5,arg6); |
1331 |
} |
1332 |
return;
|
1333 |
} |
1334 |
gemu_log("Unknown syscall %d\n", num);
|
1335 |
} |
1336 |
|
1337 |
|
1338 |
void
|
1339 |
print_syscall_ret(int num, abi_long ret)
|
1340 |
{ |
1341 |
int i;
|
1342 |
|
1343 |
for(i=0;i<nsyscalls;i++) |
1344 |
if( scnames[i].nr == num ) {
|
1345 |
if( scnames[i].result != NULL ) { |
1346 |
scnames[i].result(&scnames[i],ret); |
1347 |
} else {
|
1348 |
if( ret < 0 ) { |
1349 |
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, target_strerror(-ret)); |
1350 |
} else {
|
1351 |
gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret); |
1352 |
} |
1353 |
} |
1354 |
break;
|
1355 |
} |
1356 |
} |