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