root / linux-user / strace.c @ b53d44e5
History | View | Annotate | Download (33.2 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_END, |
389 |
}; |
390 |
|
391 |
UNUSED static struct flags mmap_flags[] = { |
392 |
FLAG_TARGET(MAP_SHARED), |
393 |
FLAG_TARGET(MAP_PRIVATE), |
394 |
FLAG_TARGET(MAP_ANONYMOUS), |
395 |
FLAG_TARGET(MAP_DENYWRITE), |
396 |
FLAG_TARGET(MAP_FIXED), |
397 |
FLAG_TARGET(MAP_GROWSDOWN), |
398 |
#ifdef MAP_LOCKED
|
399 |
FLAG_TARGET(MAP_LOCKED), |
400 |
#endif
|
401 |
#ifdef MAP_NONBLOCK
|
402 |
FLAG_TARGET(MAP_NONBLOCK), |
403 |
#endif
|
404 |
FLAG_TARGET(MAP_NORESERVE), |
405 |
#ifdef MAP_POPULATE
|
406 |
FLAG_TARGET(MAP_POPULATE), |
407 |
#endif
|
408 |
FLAG_END, |
409 |
}; |
410 |
|
411 |
UNUSED static struct flags fcntl_flags[] = { |
412 |
FLAG_TARGET(F_DUPFD), |
413 |
FLAG_TARGET(F_GETFD), |
414 |
FLAG_TARGET(F_SETFD), |
415 |
FLAG_TARGET(F_GETFL), |
416 |
FLAG_TARGET(F_SETFL), |
417 |
FLAG_TARGET(F_GETLK), |
418 |
FLAG_TARGET(F_SETLK), |
419 |
FLAG_TARGET(F_SETLKW), |
420 |
FLAG_END, |
421 |
}; |
422 |
|
423 |
/*
|
424 |
* print_xxx utility functions. These are used to print syscall
|
425 |
* parameters in certain format. All of these have parameter
|
426 |
* named 'last'. This parameter is used to add comma to output
|
427 |
* when last == 0.
|
428 |
*/
|
429 |
|
430 |
static const char * |
431 |
get_comma(int last)
|
432 |
{ |
433 |
return ((last) ? "" : ","); |
434 |
} |
435 |
|
436 |
static void |
437 |
print_flags(const struct flags *f, abi_long tflags, int last) |
438 |
{ |
439 |
const char *sep = ""; |
440 |
int flags;
|
441 |
int n;
|
442 |
|
443 |
flags = (int)tswap32(tflags);
|
444 |
|
445 |
if ((flags == 0) && (f->f_value == 0)) { |
446 |
gemu_log("%s%s", f->f_string, get_comma(last));
|
447 |
return;
|
448 |
} |
449 |
for (n = 0; f->f_string != NULL; f++) { |
450 |
if ((f->f_value != 0) && ((flags & f->f_value) == f->f_value)) { |
451 |
gemu_log("%s%s", sep, f->f_string);
|
452 |
flags &= ~f->f_value; |
453 |
sep = "|";
|
454 |
n++; |
455 |
} |
456 |
} |
457 |
|
458 |
if (n > 0) { |
459 |
/* print rest of the flags as numeric */
|
460 |
if (flags != 0) { |
461 |
gemu_log("%s%#x%s", sep, flags, get_comma(last));
|
462 |
} else {
|
463 |
gemu_log("%s", get_comma(last));
|
464 |
} |
465 |
} else {
|
466 |
/* no string version of flags found, print them in hex then */
|
467 |
gemu_log("%#x%s", flags, get_comma(last));
|
468 |
} |
469 |
} |
470 |
|
471 |
static void |
472 |
print_at_dirfd(abi_long tdirfd, int last)
|
473 |
{ |
474 |
int dirfd = tswap32(tdirfd);
|
475 |
|
476 |
#ifdef AT_FDCWD
|
477 |
if (dirfd == AT_FDCWD) {
|
478 |
gemu_log("AT_FDCWD%s", get_comma(last));
|
479 |
return;
|
480 |
} |
481 |
#endif
|
482 |
gemu_log("%d%s", dirfd, get_comma(last));
|
483 |
} |
484 |
|
485 |
static void |
486 |
print_file_mode(abi_long tmode, int last)
|
487 |
{ |
488 |
const char *sep = ""; |
489 |
const struct flags *m; |
490 |
mode_t mode = (mode_t)tswap32(tmode); |
491 |
|
492 |
for (m = &mode_flags[0]; m->f_string != NULL; m++) { |
493 |
if ((m->f_value & mode) == m->f_value) {
|
494 |
gemu_log("%s%s", m->f_string, sep);
|
495 |
sep = "|";
|
496 |
mode &= ~m->f_value; |
497 |
break;
|
498 |
} |
499 |
} |
500 |
|
501 |
mode &= ~S_IFMT; |
502 |
/* print rest of the mode as octal */
|
503 |
if (mode != 0) |
504 |
gemu_log("%s%#o", sep, mode);
|
505 |
|
506 |
gemu_log("%s", get_comma(last));
|
507 |
} |
508 |
|
509 |
static void |
510 |
print_open_flags(abi_long tflags, int last)
|
511 |
{ |
512 |
int flags = tswap32(tflags);
|
513 |
|
514 |
print_flags(open_access_flags, flags & TARGET_O_ACCMODE, 1);
|
515 |
flags &= ~TARGET_O_ACCMODE; |
516 |
if (flags == 0) { |
517 |
gemu_log("%s", get_comma(last));
|
518 |
return;
|
519 |
} |
520 |
gemu_log("|");
|
521 |
print_flags(open_flags, flags, last); |
522 |
} |
523 |
|
524 |
static void |
525 |
print_syscall_prologue(const struct syscallname *sc) |
526 |
{ |
527 |
gemu_log("%s(", sc->name);
|
528 |
} |
529 |
|
530 |
/*ARGSUSED*/
|
531 |
static void |
532 |
print_syscall_epilogue(const struct syscallname *sc) |
533 |
{ |
534 |
(void)sc;
|
535 |
gemu_log(")");
|
536 |
} |
537 |
|
538 |
static void |
539 |
print_string(abi_long addr, int last)
|
540 |
{ |
541 |
char *s;
|
542 |
|
543 |
if ((s = lock_user_string(addr)) != NULL) { |
544 |
gemu_log("\"%s\"%s", s, get_comma(last));
|
545 |
unlock_user(s, addr, 0);
|
546 |
} else {
|
547 |
/* can't get string out of it, so print it as pointer */
|
548 |
print_pointer(addr, last); |
549 |
} |
550 |
} |
551 |
|
552 |
/*
|
553 |
* Prints out raw parameter using given format. Caller needs
|
554 |
* to do byte swapping if needed.
|
555 |
*/
|
556 |
static void |
557 |
print_raw_param(const char *fmt, abi_long param, int last) |
558 |
{ |
559 |
char format[64]; |
560 |
|
561 |
(void) snprintf(format, sizeof (format), "%s%s", fmt, get_comma(last)); |
562 |
gemu_log(format, param); |
563 |
} |
564 |
|
565 |
static void |
566 |
print_pointer(abi_long p, int last)
|
567 |
{ |
568 |
if (p == 0) |
569 |
gemu_log("NULL%s", get_comma(last));
|
570 |
else
|
571 |
gemu_log("0x" TARGET_ABI_FMT_lx "%s", p, get_comma(last)); |
572 |
} |
573 |
|
574 |
/*
|
575 |
* Reads 32-bit (int) number from guest address space from
|
576 |
* address 'addr' and prints it.
|
577 |
*/
|
578 |
static void |
579 |
print_number(abi_long addr, int last)
|
580 |
{ |
581 |
if (addr == 0) { |
582 |
gemu_log("NULL%s", get_comma(last));
|
583 |
} else {
|
584 |
int num;
|
585 |
|
586 |
get_user_s32(num, addr); |
587 |
gemu_log("[%d]%s", num, get_comma(last));
|
588 |
} |
589 |
} |
590 |
|
591 |
static void |
592 |
print_timeval(abi_ulong tv_addr, int last)
|
593 |
{ |
594 |
if( tv_addr ) {
|
595 |
struct target_timeval *tv;
|
596 |
|
597 |
tv = lock_user(VERIFY_READ, tv_addr, sizeof(*tv), 1); |
598 |
if (!tv)
|
599 |
return;
|
600 |
gemu_log("{" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "}%s", |
601 |
tv->tv_sec, tv->tv_usec, get_comma(last)); |
602 |
unlock_user(tv, tv_addr, 0);
|
603 |
} else
|
604 |
gemu_log("NULL%s", get_comma(last));
|
605 |
} |
606 |
|
607 |
#undef UNUSED
|
608 |
|
609 |
#ifdef TARGET_NR_accept
|
610 |
static void |
611 |
print_accept(const struct syscallname *name, |
612 |
abi_long arg0, abi_long arg1, abi_long arg2, |
613 |
abi_long arg3, abi_long arg4, abi_long arg5) |
614 |
{ |
615 |
print_syscall_prologue(name); |
616 |
print_raw_param("%d", tswap32(arg0), 0); |
617 |
print_pointer(arg1, 0);
|
618 |
print_number(arg2, 1);
|
619 |
print_syscall_epilogue(name); |
620 |
} |
621 |
#endif
|
622 |
|
623 |
#ifdef TARGET_NR_access
|
624 |
static void |
625 |
print_access(const struct syscallname *name, |
626 |
abi_long arg0, abi_long arg1, abi_long arg2, |
627 |
abi_long arg3, abi_long arg4, abi_long arg5) |
628 |
{ |
629 |
print_syscall_prologue(name); |
630 |
print_string(arg0, 0);
|
631 |
print_flags(access_flags, arg1, 1);
|
632 |
print_syscall_epilogue(name); |
633 |
} |
634 |
#endif
|
635 |
|
636 |
#ifdef TARGET_NR_brk
|
637 |
static void |
638 |
print_brk(const struct syscallname *name, |
639 |
abi_long arg0, abi_long arg1, abi_long arg2, |
640 |
abi_long arg3, abi_long arg4, abi_long arg5) |
641 |
{ |
642 |
print_syscall_prologue(name); |
643 |
print_pointer(arg0, 1);
|
644 |
print_syscall_epilogue(name); |
645 |
} |
646 |
#endif
|
647 |
|
648 |
#ifdef TARGET_NR_chdir
|
649 |
static void |
650 |
print_chdir(const struct syscallname *name, |
651 |
abi_long arg0, abi_long arg1, abi_long arg2, |
652 |
abi_long arg3, abi_long arg4, abi_long arg5) |
653 |
{ |
654 |
print_syscall_prologue(name); |
655 |
print_string(arg0, 1);
|
656 |
print_syscall_epilogue(name); |
657 |
} |
658 |
#endif
|
659 |
|
660 |
#ifdef TARGET_NR_chmod
|
661 |
static void |
662 |
print_chmod(const struct syscallname *name, |
663 |
abi_long arg0, abi_long arg1, abi_long arg2, |
664 |
abi_long arg3, abi_long arg4, abi_long arg5) |
665 |
{ |
666 |
print_syscall_prologue(name); |
667 |
print_string(arg0, 0);
|
668 |
print_file_mode(arg1, 1);
|
669 |
print_syscall_epilogue(name); |
670 |
} |
671 |
#endif
|
672 |
|
673 |
#ifdef TARGET_NR_creat
|
674 |
static void |
675 |
print_creat(const struct syscallname *name, |
676 |
abi_long arg0, abi_long arg1, abi_long arg2, |
677 |
abi_long arg3, abi_long arg4, abi_long arg5) |
678 |
{ |
679 |
print_syscall_prologue(name); |
680 |
print_string(arg0, 0);
|
681 |
print_file_mode(arg1, 1);
|
682 |
print_syscall_epilogue(name); |
683 |
} |
684 |
#endif
|
685 |
|
686 |
#ifdef TARGET_NR_execv
|
687 |
static void |
688 |
print_execv(const struct syscallname *name, |
689 |
abi_long arg0, abi_long arg1, abi_long arg2, |
690 |
abi_long arg3, abi_long arg4, abi_long arg5) |
691 |
{ |
692 |
print_syscall_prologue(name); |
693 |
print_string(arg0, 0);
|
694 |
print_raw_param("0x" TARGET_ABI_FMT_lx, tswapl(arg1), 1); |
695 |
print_syscall_epilogue(name); |
696 |
} |
697 |
#endif
|
698 |
|
699 |
#ifdef TARGET_NR_faccessat
|
700 |
static void |
701 |
print_faccessat(const struct syscallname *name, |
702 |
abi_long arg0, abi_long arg1, abi_long arg2, |
703 |
abi_long arg3, abi_long arg4, abi_long arg5) |
704 |
{ |
705 |
print_syscall_prologue(name); |
706 |
print_at_dirfd(arg0, 0);
|
707 |
print_string(arg1, 0);
|
708 |
print_flags(access_flags, arg2, 0);
|
709 |
print_flags(at_file_flags, arg3, 1);
|
710 |
print_syscall_epilogue(name); |
711 |
} |
712 |
#endif
|
713 |
|
714 |
#ifdef TARGET_NR_fchmodat
|
715 |
static void |
716 |
print_fchmodat(const struct syscallname *name, |
717 |
abi_long arg0, abi_long arg1, abi_long arg2, |
718 |
abi_long arg3, abi_long arg4, abi_long arg5) |
719 |
{ |
720 |
print_syscall_prologue(name); |
721 |
print_at_dirfd(arg0, 0);
|
722 |
print_string(arg1, 0);
|
723 |
print_file_mode(arg2, 0);
|
724 |
print_flags(at_file_flags, arg3, 1);
|
725 |
print_syscall_epilogue(name); |
726 |
} |
727 |
#endif
|
728 |
|
729 |
#ifdef TARGET_NR_fchownat
|
730 |
static void |
731 |
print_fchownat(const struct syscallname *name, |
732 |
abi_long arg0, abi_long arg1, abi_long arg2, |
733 |
abi_long arg3, abi_long arg4, abi_long arg5) |
734 |
{ |
735 |
print_syscall_prologue(name); |
736 |
print_at_dirfd(arg0, 0);
|
737 |
print_string(arg1, 0);
|
738 |
#ifdef USE_UID16
|
739 |
print_raw_param("%d", tswap16(arg2), 0); |
740 |
print_raw_param("%d", tswap16(arg3), 0); |
741 |
#else
|
742 |
print_raw_param("%d", tswap32(arg2), 0); |
743 |
print_raw_param("%d", tswap32(arg3), 0); |
744 |
#endif
|
745 |
print_flags(at_file_flags, arg4, 1);
|
746 |
print_syscall_epilogue(name); |
747 |
} |
748 |
#endif
|
749 |
|
750 |
#if defined(TARGET_NR_fcntl) || defined(TARGET_NR_fcntl64)
|
751 |
static void |
752 |
print_fcntl(const struct syscallname *name, |
753 |
abi_long arg0, abi_long arg1, abi_long arg2, |
754 |
abi_long arg3, abi_long arg4, abi_long arg5) |
755 |
{ |
756 |
print_syscall_prologue(name); |
757 |
print_raw_param("%d", tswap32(arg0), 0); |
758 |
print_flags(fcntl_flags, arg1, 0);
|
759 |
/*
|
760 |
* TODO: check flags and print following argument only
|
761 |
* when needed.
|
762 |
*/
|
763 |
print_pointer(arg2, 1);
|
764 |
print_syscall_epilogue(name); |
765 |
} |
766 |
#define print_fcntl64 print_fcntl
|
767 |
#endif
|
768 |
|
769 |
|
770 |
#ifdef TARGET_NR_futimesat
|
771 |
static void |
772 |
print_futimesat(const struct syscallname *name, |
773 |
abi_long arg0, abi_long arg1, abi_long arg2, |
774 |
abi_long arg3, abi_long arg4, abi_long arg5) |
775 |
{ |
776 |
print_syscall_prologue(name); |
777 |
print_at_dirfd(arg0, 0);
|
778 |
print_string(arg1, 0);
|
779 |
print_timeval(arg2, 0);
|
780 |
print_timeval(arg2 + sizeof (struct target_timeval), 1); |
781 |
print_syscall_epilogue(name); |
782 |
} |
783 |
#endif
|
784 |
|
785 |
#ifdef TARGET_NR_link
|
786 |
static void |
787 |
print_link(const struct syscallname *name, |
788 |
abi_long arg0, abi_long arg1, abi_long arg2, |
789 |
abi_long arg3, abi_long arg4, abi_long arg5) |
790 |
{ |
791 |
print_syscall_prologue(name); |
792 |
print_string(arg0, 0);
|
793 |
print_string(arg1, 1);
|
794 |
print_syscall_epilogue(name); |
795 |
} |
796 |
#endif
|
797 |
|
798 |
#ifdef TARGET_NR_linkat
|
799 |
static void |
800 |
print_linkat(const struct syscallname *name, |
801 |
abi_long arg0, abi_long arg1, abi_long arg2, |
802 |
abi_long arg3, abi_long arg4, abi_long arg5) |
803 |
{ |
804 |
print_syscall_prologue(name); |
805 |
print_at_dirfd(arg0, 0);
|
806 |
print_string(arg1, 0);
|
807 |
print_at_dirfd(arg2, 0);
|
808 |
print_string(arg3, 0);
|
809 |
print_flags(at_file_flags, arg4, 1);
|
810 |
print_syscall_epilogue(name); |
811 |
} |
812 |
#endif
|
813 |
|
814 |
#if defined(TARGET_NR_stat) || defined(TARGET_NR_stat64) || \
|
815 |
defined(TARGET_NR_lstat) || defined(TARGET_NR_lstat64) |
816 |
static void |
817 |
print_stat(const struct syscallname *name, |
818 |
abi_long arg0, abi_long arg1, abi_long arg2, |
819 |
abi_long arg3, abi_long arg4, abi_long arg5) |
820 |
{ |
821 |
print_syscall_prologue(name); |
822 |
print_string(arg0, 0);
|
823 |
print_pointer(arg1, 1);
|
824 |
print_syscall_epilogue(name); |
825 |
} |
826 |
#define print_lstat print_stat
|
827 |
#define print_stat64 print_stat
|
828 |
#define print_lstat64 print_stat
|
829 |
#endif
|
830 |
|
831 |
#if defined(TARGET_NR_fstat) || defined(TARGET_NR_fstat64)
|
832 |
static void |
833 |
print_fstat(const struct syscallname *name, |
834 |
abi_long arg0, abi_long arg1, abi_long arg2, |
835 |
abi_long arg3, abi_long arg4, abi_long arg5) |
836 |
{ |
837 |
print_syscall_prologue(name); |
838 |
print_raw_param("%d", tswap32(arg0), 0); |
839 |
print_pointer(arg1, 1);
|
840 |
print_syscall_epilogue(name); |
841 |
} |
842 |
#define print_fstat64 print_fstat
|
843 |
#endif
|
844 |
|
845 |
#ifdef TARGET_NR_mkdir
|
846 |
static void |
847 |
print_mkdir(const struct syscallname *name, |
848 |
abi_long arg0, abi_long arg1, abi_long arg2, |
849 |
abi_long arg3, abi_long arg4, abi_long arg5) |
850 |
{ |
851 |
print_syscall_prologue(name); |
852 |
print_string(arg0, 0);
|
853 |
print_file_mode(arg1, 1);
|
854 |
print_syscall_epilogue(name); |
855 |
} |
856 |
#endif
|
857 |
|
858 |
#ifdef TARGET_NR_mkdirat
|
859 |
static void |
860 |
print_mkdirat(const struct syscallname *name, |
861 |
abi_long arg0, abi_long arg1, abi_long arg2, |
862 |
abi_long arg3, abi_long arg4, abi_long arg5) |
863 |
{ |
864 |
print_syscall_prologue(name); |
865 |
print_at_dirfd(arg0, 0);
|
866 |
print_string(arg1, 0);
|
867 |
print_file_mode(arg2, 1);
|
868 |
print_syscall_epilogue(name); |
869 |
} |
870 |
#endif
|
871 |
|
872 |
#ifdef TARGET_NR_mknod
|
873 |
static void |
874 |
print_mknod(const struct syscallname *name, |
875 |
abi_long arg0, abi_long arg1, abi_long arg2, |
876 |
abi_long arg3, abi_long arg4, abi_long arg5) |
877 |
{ |
878 |
int hasdev = (tswapl(arg1) & (S_IFCHR|S_IFBLK));
|
879 |
|
880 |
print_syscall_prologue(name); |
881 |
print_string(arg0, 0);
|
882 |
print_file_mode(arg1, (hasdev == 0));
|
883 |
if (hasdev) {
|
884 |
print_raw_param("makedev(%d", major(tswapl(arg2)), 0); |
885 |
print_raw_param("%d)", minor(tswapl(arg2)), 1); |
886 |
} |
887 |
print_syscall_epilogue(name); |
888 |
} |
889 |
#endif
|
890 |
|
891 |
#ifdef TARGET_NR_mknodat
|
892 |
static void |
893 |
print_mknodat(const struct syscallname *name, |
894 |
abi_long arg0, abi_long arg1, abi_long arg2, |
895 |
abi_long arg3, abi_long arg4, abi_long arg5) |
896 |
{ |
897 |
int hasdev = (tswapl(arg2) & (S_IFCHR|S_IFBLK));
|
898 |
|
899 |
print_syscall_prologue(name); |
900 |
print_at_dirfd(arg0, 0);
|
901 |
print_string(arg1, 0);
|
902 |
print_file_mode(arg2, (hasdev == 0));
|
903 |
if (hasdev) {
|
904 |
print_raw_param("makedev(%d", major(tswapl(arg3)), 0); |
905 |
print_raw_param("%d)", minor(tswapl(arg3)), 1); |
906 |
} |
907 |
print_syscall_epilogue(name); |
908 |
} |
909 |
#endif
|
910 |
|
911 |
#ifdef TARGET_NR_mq_open
|
912 |
static void |
913 |
print_mq_open(const struct syscallname *name, |
914 |
abi_long arg0, abi_long arg1, abi_long arg2, |
915 |
abi_long arg3, abi_long arg4, abi_long arg5) |
916 |
{ |
917 |
int is_creat = (tswapl(arg1) & TARGET_O_CREAT);
|
918 |
|
919 |
print_syscall_prologue(name); |
920 |
print_string(arg0, 0);
|
921 |
print_open_flags(arg1, (is_creat == 0));
|
922 |
if (is_creat) {
|
923 |
print_file_mode(arg2, 0);
|
924 |
print_pointer(arg3, 1);
|
925 |
} |
926 |
print_syscall_epilogue(name); |
927 |
} |
928 |
#endif
|
929 |
|
930 |
#ifdef TARGET_NR_open
|
931 |
static void |
932 |
print_open(const struct syscallname *name, |
933 |
abi_long arg0, abi_long arg1, abi_long arg2, |
934 |
abi_long arg3, abi_long arg4, abi_long arg5) |
935 |
{ |
936 |
int is_creat = (tswap32(arg1) & TARGET_O_CREAT);
|
937 |
|
938 |
print_syscall_prologue(name); |
939 |
print_string(arg0, 0);
|
940 |
print_open_flags(arg1, (is_creat == 0));
|
941 |
if (is_creat)
|
942 |
print_file_mode(arg2, 1);
|
943 |
print_syscall_epilogue(name); |
944 |
} |
945 |
#endif
|
946 |
|
947 |
#ifdef TARGET_NR_openat
|
948 |
static void |
949 |
print_openat(const struct syscallname *name, |
950 |
abi_long arg0, abi_long arg1, abi_long arg2, |
951 |
abi_long arg3, abi_long arg4, abi_long arg5) |
952 |
{ |
953 |
int is_creat = (tswap32(arg2) & TARGET_O_CREAT);
|
954 |
|
955 |
print_syscall_prologue(name); |
956 |
print_at_dirfd(arg0, 0);
|
957 |
print_string(arg1, 0);
|
958 |
print_open_flags(arg2, (is_creat == 0));
|
959 |
if (is_creat)
|
960 |
print_file_mode(arg3, 1);
|
961 |
print_syscall_epilogue(name); |
962 |
} |
963 |
#endif
|
964 |
|
965 |
#ifdef TARGET_NR_mq_unlink
|
966 |
static void |
967 |
print_mq_unlink(const struct syscallname *name, |
968 |
abi_long arg0, abi_long arg1, abi_long arg2, |
969 |
abi_long arg3, abi_long arg4, abi_long arg5) |
970 |
{ |
971 |
print_syscall_prologue(name); |
972 |
print_string(arg0, 1);
|
973 |
print_syscall_epilogue(name); |
974 |
} |
975 |
#endif
|
976 |
|
977 |
#if defined(TARGET_NR_fstatat64) || defined(TARGET_NR_newfstatat)
|
978 |
static void |
979 |
print_fstatat64(const struct syscallname *name, |
980 |
abi_long arg0, abi_long arg1, abi_long arg2, |
981 |
abi_long arg3, abi_long arg4, abi_long arg5) |
982 |
{ |
983 |
print_syscall_prologue(name); |
984 |
print_at_dirfd(arg0, 0);
|
985 |
print_string(arg1, 0);
|
986 |
print_pointer(arg2, 0);
|
987 |
print_flags(at_file_flags, arg3, 1);
|
988 |
print_syscall_epilogue(name); |
989 |
} |
990 |
#define print_newfstatat print_fstatat64
|
991 |
#endif
|
992 |
|
993 |
#ifdef TARGET_NR_readlink
|
994 |
static void |
995 |
print_readlink(const struct syscallname *name, |
996 |
abi_long arg0, abi_long arg1, abi_long arg2, |
997 |
abi_long arg3, abi_long arg4, abi_long arg5) |
998 |
{ |
999 |
print_syscall_prologue(name); |
1000 |
print_string(arg0, 0);
|
1001 |
print_pointer(arg1, 0);
|
1002 |
print_raw_param("%u", tswapl(arg2), 1); |
1003 |
print_syscall_epilogue(name); |
1004 |
} |
1005 |
#endif
|
1006 |
|
1007 |
#ifdef TARGET_NR_readlinkat
|
1008 |
static void |
1009 |
print_readlinkat(const struct syscallname *name, |
1010 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1011 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1012 |
{ |
1013 |
print_syscall_prologue(name); |
1014 |
print_at_dirfd(arg0, 0);
|
1015 |
print_string(arg1, 0);
|
1016 |
print_pointer(arg2, 0);
|
1017 |
print_raw_param("%u", tswapl(arg3), 1); |
1018 |
print_syscall_epilogue(name); |
1019 |
} |
1020 |
#endif
|
1021 |
|
1022 |
#ifdef TARGET_NR_rename
|
1023 |
static void |
1024 |
print_rename(const struct syscallname *name, |
1025 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1026 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1027 |
{ |
1028 |
print_syscall_prologue(name); |
1029 |
print_string(arg0, 0);
|
1030 |
print_string(arg1, 1);
|
1031 |
print_syscall_epilogue(name); |
1032 |
} |
1033 |
#endif
|
1034 |
|
1035 |
#ifdef TARGET_NR_renameat
|
1036 |
static void |
1037 |
print_renameat(const struct syscallname *name, |
1038 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1039 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1040 |
{ |
1041 |
print_syscall_prologue(name); |
1042 |
print_at_dirfd(arg0, 0);
|
1043 |
print_string(arg1, 0);
|
1044 |
print_at_dirfd(arg2, 0);
|
1045 |
print_string(arg3, 1);
|
1046 |
print_syscall_epilogue(name); |
1047 |
} |
1048 |
#endif
|
1049 |
|
1050 |
#ifdef TARGET_NR_statfs
|
1051 |
static void |
1052 |
print_statfs(const struct syscallname *name, |
1053 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1054 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1055 |
{ |
1056 |
print_syscall_prologue(name); |
1057 |
print_string(arg0, 0);
|
1058 |
print_pointer(arg1, 1);
|
1059 |
print_syscall_epilogue(name); |
1060 |
} |
1061 |
#define print_statfs64 print_statfs
|
1062 |
#endif
|
1063 |
|
1064 |
#ifdef TARGET_NR_symlink
|
1065 |
static void |
1066 |
print_symlink(const struct syscallname *name, |
1067 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1068 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1069 |
{ |
1070 |
print_syscall_prologue(name); |
1071 |
print_string(arg0, 0);
|
1072 |
print_string(arg1, 1);
|
1073 |
print_syscall_epilogue(name); |
1074 |
} |
1075 |
#endif
|
1076 |
|
1077 |
#ifdef TARGET_NR_symlinkat
|
1078 |
static void |
1079 |
print_symlinkat(const struct syscallname *name, |
1080 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1081 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1082 |
{ |
1083 |
print_syscall_prologue(name); |
1084 |
print_string(arg0, 0);
|
1085 |
print_at_dirfd(arg1, 0);
|
1086 |
print_string(arg2, 1);
|
1087 |
print_syscall_epilogue(name); |
1088 |
} |
1089 |
#endif
|
1090 |
|
1091 |
#ifdef TARGET_NR_mount
|
1092 |
static void |
1093 |
print_mount(const struct syscallname *name, |
1094 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1095 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1096 |
{ |
1097 |
print_syscall_prologue(name); |
1098 |
print_string(arg0, 0);
|
1099 |
print_string(arg1, 0);
|
1100 |
print_string(arg2, 0);
|
1101 |
print_flags(mount_flags, arg3, 0);
|
1102 |
print_pointer(arg4, 1);
|
1103 |
print_syscall_epilogue(name); |
1104 |
} |
1105 |
#endif
|
1106 |
|
1107 |
#ifdef TARGET_NR_umount
|
1108 |
static void |
1109 |
print_umount(const struct syscallname *name, |
1110 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1111 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1112 |
{ |
1113 |
print_syscall_prologue(name); |
1114 |
print_string(arg0, 1);
|
1115 |
print_syscall_epilogue(name); |
1116 |
} |
1117 |
#endif
|
1118 |
|
1119 |
#ifdef TARGET_NR_umount2
|
1120 |
static void |
1121 |
print_umount2(const struct syscallname *name, |
1122 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1123 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1124 |
{ |
1125 |
print_syscall_prologue(name); |
1126 |
print_string(arg0, 0);
|
1127 |
print_flags(umount2_flags, arg1, 1);
|
1128 |
print_syscall_epilogue(name); |
1129 |
} |
1130 |
#endif
|
1131 |
|
1132 |
#ifdef TARGET_NR_unlink
|
1133 |
static void |
1134 |
print_unlink(const struct syscallname *name, |
1135 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1136 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1137 |
{ |
1138 |
print_syscall_prologue(name); |
1139 |
print_string(arg0, 1);
|
1140 |
print_syscall_epilogue(name); |
1141 |
} |
1142 |
#endif
|
1143 |
|
1144 |
#ifdef TARGET_NR_unlinkat
|
1145 |
static void |
1146 |
print_unlinkat(const struct syscallname *name, |
1147 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1148 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1149 |
{ |
1150 |
print_syscall_prologue(name); |
1151 |
print_at_dirfd(arg0, 0);
|
1152 |
print_string(arg1, 0);
|
1153 |
print_flags(unlinkat_flags, arg2, 1);
|
1154 |
print_syscall_epilogue(name); |
1155 |
} |
1156 |
#endif
|
1157 |
|
1158 |
#ifdef TARGET_NR_utime
|
1159 |
static void |
1160 |
print_utime(const struct syscallname *name, |
1161 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1162 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1163 |
{ |
1164 |
print_syscall_prologue(name); |
1165 |
print_string(arg0, 0);
|
1166 |
print_pointer(arg1, 1);
|
1167 |
print_syscall_epilogue(name); |
1168 |
} |
1169 |
#endif
|
1170 |
|
1171 |
#ifdef TARGET_NR_utimes
|
1172 |
static void |
1173 |
print_utimes(const struct syscallname *name, |
1174 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1175 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1176 |
{ |
1177 |
print_syscall_prologue(name); |
1178 |
print_string(arg0, 0);
|
1179 |
print_pointer(arg1, 1);
|
1180 |
print_syscall_epilogue(name); |
1181 |
} |
1182 |
#endif
|
1183 |
|
1184 |
#ifdef TARGET_NR_utimensat
|
1185 |
static void |
1186 |
print_utimensat(const struct syscallname *name, |
1187 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1188 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1189 |
{ |
1190 |
print_syscall_prologue(name); |
1191 |
print_at_dirfd(arg0, 0);
|
1192 |
print_string(arg1, 0);
|
1193 |
print_pointer(arg2, 0);
|
1194 |
print_flags(at_file_flags, arg3, 1);
|
1195 |
print_syscall_epilogue(name); |
1196 |
} |
1197 |
#endif
|
1198 |
|
1199 |
#ifdef TARGET_NR_mmap
|
1200 |
static void |
1201 |
print_mmap(const struct syscallname *name, |
1202 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1203 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1204 |
{ |
1205 |
print_syscall_prologue(name); |
1206 |
print_pointer(arg0, 0);
|
1207 |
print_raw_param("%d", tswapl(arg1), 0); |
1208 |
print_flags(mmap_prot_flags, arg2, 0);
|
1209 |
print_flags(mmap_flags, arg3, 0);
|
1210 |
print_raw_param("%d", tswapl(arg4), 0); |
1211 |
print_raw_param("%#x", tswapl(arg5), 1); |
1212 |
print_syscall_epilogue(name); |
1213 |
} |
1214 |
#define print_mmap2 print_mmap
|
1215 |
#endif
|
1216 |
|
1217 |
#ifdef TARGET_NR_mprotect
|
1218 |
static void |
1219 |
print_mprotect(const struct syscallname *name, |
1220 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1221 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1222 |
{ |
1223 |
print_syscall_prologue(name); |
1224 |
print_pointer(arg0, 0);
|
1225 |
print_raw_param("%d", tswapl(arg1), 0); |
1226 |
print_flags(mmap_prot_flags, arg2, 1);
|
1227 |
print_syscall_epilogue(name); |
1228 |
} |
1229 |
#endif
|
1230 |
|
1231 |
#ifdef TARGET_NR_munmap
|
1232 |
static void |
1233 |
print_munmap(const struct syscallname *name, |
1234 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1235 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1236 |
{ |
1237 |
print_syscall_prologue(name); |
1238 |
print_pointer(arg0, 0);
|
1239 |
print_raw_param("%d", tswapl(arg1), 1); |
1240 |
print_syscall_epilogue(name); |
1241 |
} |
1242 |
#endif
|
1243 |
|
1244 |
#ifdef TARGET_NR_futex
|
1245 |
static void print_futex_op(abi_long tflag, int last) |
1246 |
{ |
1247 |
#define print_op(val) \
|
1248 |
if( cmd == val ) { \
|
1249 |
gemu_log(#val); \
|
1250 |
return; \
|
1251 |
} |
1252 |
|
1253 |
int cmd = (int)tswap32(tflag); |
1254 |
#ifdef FUTEX_PRIVATE_FLAG
|
1255 |
if (cmd == FUTEX_PRIVATE_FLAG)
|
1256 |
gemu_log("FUTEX_PRIVATE_FLAG|");
|
1257 |
#endif
|
1258 |
print_op(FUTEX_WAIT) |
1259 |
print_op(FUTEX_WAKE) |
1260 |
print_op(FUTEX_FD) |
1261 |
print_op(FUTEX_REQUEUE) |
1262 |
print_op(FUTEX_CMP_REQUEUE) |
1263 |
print_op(FUTEX_WAKE_OP) |
1264 |
print_op(FUTEX_LOCK_PI) |
1265 |
print_op(FUTEX_UNLOCK_PI) |
1266 |
print_op(FUTEX_TRYLOCK_PI) |
1267 |
#ifdef FUTEX_WAIT_BITSET
|
1268 |
print_op(FUTEX_WAIT_BITSET) |
1269 |
#endif
|
1270 |
#ifdef FUTEX_WAKE_BITSET
|
1271 |
print_op(FUTEX_WAKE_BITSET) |
1272 |
#endif
|
1273 |
/* unknown values */
|
1274 |
gemu_log("%d",cmd);
|
1275 |
} |
1276 |
|
1277 |
static void |
1278 |
print_futex(const struct syscallname *name, |
1279 |
abi_long arg0, abi_long arg1, abi_long arg2, |
1280 |
abi_long arg3, abi_long arg4, abi_long arg5) |
1281 |
{ |
1282 |
print_syscall_prologue(name); |
1283 |
print_pointer(arg0, 0);
|
1284 |
print_futex_op(arg1, 0);
|
1285 |
print_raw_param(",%d", tswapl(arg2), 0); |
1286 |
print_pointer(arg3, 0); /* struct timespec */ |
1287 |
print_pointer(arg4, 0);
|
1288 |
print_raw_param("%d", tswapl(arg4), 1); |
1289 |
print_syscall_epilogue(name); |
1290 |
} |
1291 |
#endif
|
1292 |
|
1293 |
/*
|
1294 |
* An array of all of the syscalls we know about
|
1295 |
*/
|
1296 |
|
1297 |
static const struct syscallname scnames[] = { |
1298 |
#include "strace.list" |
1299 |
}; |
1300 |
|
1301 |
static int nsyscalls = ARRAY_SIZE(scnames); |
1302 |
|
1303 |
/*
|
1304 |
* The public interface to this module.
|
1305 |
*/
|
1306 |
void
|
1307 |
print_syscall(int num,
|
1308 |
abi_long arg1, abi_long arg2, abi_long arg3, |
1309 |
abi_long arg4, abi_long arg5, abi_long arg6) |
1310 |
{ |
1311 |
int i;
|
1312 |
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 ")"; |
1313 |
|
1314 |
gemu_log("%d ", getpid() );
|
1315 |
|
1316 |
for(i=0;i<nsyscalls;i++) |
1317 |
if( scnames[i].nr == num ) {
|
1318 |
if( scnames[i].call != NULL ) { |
1319 |
scnames[i].call(&scnames[i],arg1,arg2,arg3,arg4,arg5,arg6); |
1320 |
} else {
|
1321 |
/* XXX: this format system is broken because it uses
|
1322 |
host types and host pointers for strings */
|
1323 |
if( scnames[i].format != NULL ) |
1324 |
format = scnames[i].format; |
1325 |
gemu_log(format,scnames[i].name, arg1,arg2,arg3,arg4,arg5,arg6); |
1326 |
} |
1327 |
return;
|
1328 |
} |
1329 |
gemu_log("Unknown syscall %d\n", num);
|
1330 |
} |
1331 |
|
1332 |
|
1333 |
void
|
1334 |
print_syscall_ret(int num, abi_long ret)
|
1335 |
{ |
1336 |
int i;
|
1337 |
|
1338 |
for(i=0;i<nsyscalls;i++) |
1339 |
if( scnames[i].nr == num ) {
|
1340 |
if( scnames[i].result != NULL ) { |
1341 |
scnames[i].result(&scnames[i],ret); |
1342 |
} else {
|
1343 |
if( ret < 0 ) { |
1344 |
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, target_strerror(-ret)); |
1345 |
} else {
|
1346 |
gemu_log(" = " TARGET_ABI_FMT_ld "\n", ret); |
1347 |
} |
1348 |
} |
1349 |
break;
|
1350 |
} |
1351 |
} |