1
2 /*--------------------------------------------------------------------*/
3 /*--- Handle system calls. syswrap-main.c ---*/
4 /*--------------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2017 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29 */
30
31 #include "libvex_guest_offsets.h"
32 #include "libvex_trc_values.h"
33 #include "pub_core_basics.h"
34 #include "pub_core_aspacemgr.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_vkiscnums.h"
37 #include "pub_core_threadstate.h"
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcprint.h"
41 #include "pub_core_libcproc.h" // For VG_(getpid)()
42 #include "pub_core_libcsignal.h"
43 #include "pub_core_scheduler.h" // For VG_({acquire,release}_BigLock),
44 // and VG_(vg_yield)
45 #include "pub_core_stacktrace.h" // For VG_(get_and_pp_StackTrace)()
46 #include "pub_core_tooliface.h"
47 #include "pub_core_options.h"
48 #include "pub_core_signals.h" // For VG_SIGVGKILL, VG_(poll_signals)
49 #include "pub_core_syscall.h"
50 #include "pub_core_machine.h"
51 #include "pub_core_mallocfree.h"
52 #include "pub_core_syswrap.h"
53 #include "pub_core_gdbserver.h" // VG_(gdbserver_report_syscall)
54
55 #include "priv_types_n_macros.h"
56 #include "priv_syswrap-main.h"
57
58 #if defined(VGO_darwin)
59 #include "priv_syswrap-darwin.h"
60 #endif
61
62 /* Useful info which needs to be recorded somewhere:
63 Use of registers in syscalls is:
64
65 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
66 LINUX:
67 x86 eax ebx ecx edx esi edi ebp n/a n/a eax (== NUM)
68 amd64 rax rdi rsi rdx r10 r8 r9 n/a n/a rax (== NUM)
69 ppc32 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1)
70 ppc64 r0 r3 r4 r5 r6 r7 r8 n/a n/a r3+CR0.SO (== ARG1)
71 arm r7 r0 r1 r2 r3 r4 r5 n/a n/a r0 (== ARG1)
72 mips32 v0 a0 a1 a2 a3 stack stack n/a n/a v0 (== NUM)
73 mips64 v0 a0 a1 a2 a3 a4 a5 a6 a7 v0 (== NUM)
74 arm64 x8 x0 x1 x2 x3 x4 x5 n/a n/a x0 ?? (== ARG1??)
75
76 Dragonfly:
77 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c
78 amd64 rax rdi rsi rdx rcx r8 r9 +8 +16 rdx:rax, rflags.c
79
80 On s390x the svc instruction is used for system calls. The system call
81 number is encoded in the instruction (8 bit immediate field). Since Linux
82 2.6 it is also allowed to use svc 0 with the system call number in r1.
83 This was introduced for system calls >255, but works for all. It is
84 also possible to see the svc 0 together with an EXecute instruction, that
85 fills in the immediate field.
86 s390x r1/SVC r2 r3 r4 r5 r6 r7 n/a n/a r2 (== ARG1)
87
88 NUM ARG1 ARG2 ARG3 ARG4 ARG5 ARG6 ARG7 ARG8 RESULT
89 DARWIN:
90 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c
91 amd64 rax rdi rsi rdx rcx r8 r9 +8 +16 rdx:rax, rflags.c
92
93 For x86-darwin and x86-dragonfly, "+N" denotes "in memory at N(%esp)";
94 ditto amd64-darwin/amd64-dragonfly. Apparently 0(%esp) is some kind of return address
95 (perhaps for syscalls done with "sysenter"?) I don't think it is
96 relevant for syscalls done with "int $0x80/1/2".
97
98 SOLARIS:
99 x86 eax +4 +8 +12 +16 +20 +24 +28 +32 edx:eax, eflags.c
100 amd64 rax rdi rsi rdx r10 r8 r9 +8 +16 rdx:rax, rflags.c
101
102 "+N" denotes "in memory at N(%esp)". Solaris also supports fasttrap
103 syscalls. Fasttraps do not take any parameters (except of the sysno in eax)
104 and never fail (if the sysno is valid).
105 */
106
107 /* This is the top level of the system-call handler module. All
108 system calls are channelled through here, doing two things:
109
110 * notify the tool of the events (mem/reg reads, writes) happening
111
112 * perform the syscall, usually by passing it along to the kernel
113 unmodified.
114
115 A magical piece of assembly code, do_syscall_for_client_WRK, in
116 syscall-$PLATFORM.S does the tricky bit of passing a syscall to the
117 kernel, whilst having the simulator retain control.
118 */
119
120 /* The main function is VG_(client_syscall). The simulation calls it
121 whenever a client thread wants to do a syscall. The following is a
122 sketch of what it does.
123
124 * Ensures the root thread's stack is suitably mapped. Tedious and
125 arcane. See big big comment in VG_(client_syscall).
126
127 * First, it rounds up the syscall number and args (which is a
128 platform dependent activity) and puts them in a struct ("args")
129 and also a copy in "orig_args".
130
131 The pre/post wrappers refer to these structs and so no longer
132 need magic macros to access any specific registers. This struct
133 is stored in thread-specific storage.
134
135
136 * The pre-wrapper is called, passing it a pointer to struct
137 "args".
138
139
140 * The pre-wrapper examines the args and pokes the tool
141 appropriately. It may modify the args; this is why "orig_args"
142 is also stored.
143
144 The pre-wrapper may choose to 'do' the syscall itself, and
145 concludes one of three outcomes:
146
147 Success(N) -- syscall is already complete, with success;
148 result is N
149
150 Fail(N) -- syscall is already complete, with failure;
151 error code is N
152
153 HandToKernel -- (the usual case): this needs to be given to
154 the kernel to be done, using the values in
155 the possibly-modified "args" struct.
156
157 In addition, the pre-wrapper may set some flags:
158
159 MayBlock -- only applicable when outcome==HandToKernel
160
161 PostOnFail -- only applicable when outcome==HandToKernel or Fail
162
163
164 * If the pre-outcome is HandToKernel, the syscall is duly handed
165 off to the kernel (perhaps involving some thread switchery, but
166 that's not important). This reduces the possible set of outcomes
167 to either Success(N) or Fail(N).
168
169
170 * The outcome (Success(N) or Fail(N)) is written back to the guest
171 register(s). This is platform specific:
172
173 x86: Success(N) ==> eax = N
174 Fail(N) ==> eax = -N
175
176 ditto amd64
177
178 ppc32: Success(N) ==> r3 = N, CR0.SO = 0
179 Fail(N) ==> r3 = N, CR0.SO = 1
180
181 Dragonfly:
182 x86: Success(N) ==> edx:eax = N, cc = 0
183 Fail(N) ==> edx:eax = N, cc = 1
184
185 ditto amd64
186
187 Darwin:
188 x86: Success(N) ==> edx:eax = N, cc = 0
189 Fail(N) ==> edx:eax = N, cc = 1
190
191 s390x: Success(N) ==> r2 = N
192 Fail(N) ==> r2 = -N
193
194 Solaris:
195 x86: Success(N) ==> edx:eax = N, cc = 0
196 Fail(N) ==> eax = N, cc = 1
197 Same applies for fasttraps except they never fail.
198
199 * The post wrapper is called if:
200
201 - it exists, and
202 - outcome==Success or (outcome==Fail and PostOnFail is set)
203
204 The post wrapper is passed the adulterated syscall args (struct
205 "args"), and the syscall outcome (viz, Success(N) or Fail(N)).
206
207 There are several other complications, primarily to do with
208 syscalls getting interrupted, explained in comments in the code.
209 */
210
211 /* CAVEATS for writing wrappers. It is important to follow these!
212
213 The macros defined in priv_types_n_macros.h are designed to help
214 decouple the wrapper logic from the actual representation of
215 syscall args/results, since these wrappers are designed to work on
216 multiple platforms.
217
218 Sometimes a PRE wrapper will complete the syscall itself, without
219 handing it to the kernel. It will use one of SET_STATUS_Success,
220 SET_STATUS_Failure or SET_STATUS_from_SysRes to set the return
221 value. It is critical to appreciate that use of the macro does not
222 immediately cause the underlying guest state to be updated -- that
223 is done by the driver logic in this file, when the wrapper returns.
224
225 As a result, PRE wrappers of the following form will malfunction:
226
227 PRE(fooble)
228 {
229 ... do stuff ...
230 SET_STATUS_Somehow(...)
231
232 // do something that assumes guest state is up to date
233 }
234
235 In particular, direct or indirect calls to VG_(poll_signals) after
236 setting STATUS can cause the guest state to be read (in order to
237 build signal frames). Do not do this. If you want a signal poll
238 after the syscall goes through, do "*flags |= SfPollAfter" and the
239 driver logic will do it for you.
240
241 -----------
242
243 Another critical requirement following introduction of new address
244 space manager (JRS, 20050923):
245
246 In a situation where the mappedness of memory has changed, aspacem
247 should be notified BEFORE the tool. Hence the following is
248 correct:
249
250 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
251 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
252 if (d)
253 VG_(discard_translations)(s->start, s->end+1 - s->start);
254
255 whilst this is wrong:
256
257 VG_TRACK( die_mem_munmap, s->start, s->end+1 - s->start );
258 Bool d = VG_(am_notify_munmap)(s->start, s->end+1 - s->start);
259 if (d)
260 VG_(discard_translations)(s->start, s->end+1 - s->start);
261
262 The reason is that the tool may itself ask aspacem for more shadow
263 memory as a result of the VG_TRACK call. In such a situation it is
264 critical that aspacem's segment array is up to date -- hence the
265 need to notify aspacem first.
266
267 -----------
268
269 Also .. take care to call VG_(discard_translations) whenever
270 memory with execute permissions is unmapped.
271 */
272
273
274 /* ---------------------------------------------------------------------
275 Do potentially blocking syscall for the client, and mess with
276 signal masks at the same time.
277 ------------------------------------------------------------------ */
278
279 /* Perform a syscall on behalf of a client thread, using a specific
280 signal mask. On completion, the signal mask is set to restore_mask
281 (which presumably blocks almost everything). If a signal happens
282 during the syscall, the handler should call
283 VG_(fixup_guest_state_after_syscall_interrupted) to adjust the
284 thread's context to do the right thing.
285
286 The _WRK function is handwritten assembly, implemented per-platform
287 in coregrind/m_syswrap/syscall-$PLAT.S. It has some very magic
288 properties. See comments at the top of
289 VG_(fixup_guest_state_after_syscall_interrupted) below for details.
290
291 This function (these functions) are required to return zero in case
292 of success (even if the syscall itself failed), and nonzero if the
293 sigprocmask-swizzling calls failed. We don't actually care about
294 the failure values from sigprocmask, although most of the assembly
295 implementations do attempt to return that, using the convention
296 0 for success, or 0x8000 | error-code for failure.
297 */
298 #if defined(VGO_linux)
299 extern
300 UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
301 void* guest_state,
302 const vki_sigset_t *syscall_mask,
303 const vki_sigset_t *restore_mask,
304 Word sigsetSzB );
305 #elif defined(VGO_dragonfly)
306 extern
307 UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
308 void* guest_state,
309 const vki_sigset_t *syscall_mask,
310 const vki_sigset_t *restore_mask,
311 Word sigsetSzB );
312 #elif defined(VGO_darwin)
313 extern
314 UWord ML_(do_syscall_for_client_unix_WRK)( Word syscallno,
315 void* guest_state,
316 const vki_sigset_t *syscall_mask,
317 const vki_sigset_t *restore_mask,
318 Word sigsetSzB ); /* unused */
319 extern
320 UWord ML_(do_syscall_for_client_mach_WRK)( Word syscallno,
321 void* guest_state,
322 const vki_sigset_t *syscall_mask,
323 const vki_sigset_t *restore_mask,
324 Word sigsetSzB ); /* unused */
325 extern
326 UWord ML_(do_syscall_for_client_mdep_WRK)( Word syscallno,
327 void* guest_state,
328 const vki_sigset_t *syscall_mask,
329 const vki_sigset_t *restore_mask,
330 Word sigsetSzB ); /* unused */
331 #elif defined(VGO_solaris)
332 extern
333 UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
334 void* guest_state,
335 const vki_sigset_t *syscall_mask,
336 const vki_sigset_t *restore_mask,
337 UChar *cflag);
338 UWord ML_(do_syscall_for_client_dret_WRK)( Word syscallno,
339 void* guest_state,
340 const vki_sigset_t *syscall_mask,
341 const vki_sigset_t *restore_mask,
342 UChar *cflag);
343 #else
344 # error "Unknown OS"
345 #endif
346
347
348 static
do_syscall_for_client(Int syscallno,ThreadState * tst,const vki_sigset_t * syscall_mask)349 void do_syscall_for_client ( Int syscallno,
350 ThreadState* tst,
351 const vki_sigset_t* syscall_mask )
352 {
353 vki_sigset_t saved;
354 UWord err;
355 # if defined(VGO_dragonfly)
356 Int real_syscallno;
357 # endif
358 # if defined(VGO_linux)
359 err = ML_(do_syscall_for_client_WRK)(
360 syscallno, &tst->arch.vex,
361 syscall_mask, &saved, sizeof(vki_sigset_t)
362 );
363 # elif defined(VGO_dragonfly)
364 if (tst->arch.vex.guest_SC_CLASS == VG_DRAGONFLY_SYSCALL0)
365 real_syscallno = __NR_syscall;
366 else if (tst->arch.vex.guest_SC_CLASS == VG_DRAGONFLY_SYSCALL198)
367 real_syscallno = __NR___syscall;
368 else
369 real_syscallno = syscallno;
370 err = ML_(do_syscall_for_client_WRK)(
371 real_syscallno, &tst->arch.vex,
372 syscall_mask, &saved, sizeof(vki_sigset_t)
373 );
374 # elif defined(VGO_darwin)
375 switch (VG_DARWIN_SYSNO_CLASS(syscallno)) {
376 case VG_DARWIN_SYSCALL_CLASS_UNIX:
377 err = ML_(do_syscall_for_client_unix_WRK)(
378 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
379 syscall_mask, &saved, 0/*unused:sigsetSzB*/
380 );
381 break;
382 case VG_DARWIN_SYSCALL_CLASS_MACH:
383 err = ML_(do_syscall_for_client_mach_WRK)(
384 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
385 syscall_mask, &saved, 0/*unused:sigsetSzB*/
386 );
387 break;
388 case VG_DARWIN_SYSCALL_CLASS_MDEP:
389 err = ML_(do_syscall_for_client_mdep_WRK)(
390 VG_DARWIN_SYSNO_FOR_KERNEL(syscallno), &tst->arch.vex,
391 syscall_mask, &saved, 0/*unused:sigsetSzB*/
392 );
393 break;
394 default:
395 vg_assert(0);
396 /*NOTREACHED*/
397 break;
398 }
399 # elif defined(VGO_solaris)
400 UChar cflag;
401
402 /* Fasttraps or anything else cannot go through this path. */
403 vg_assert(VG_SOLARIS_SYSNO_CLASS(syscallno)
404 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
405
406 /* If the syscall is a door_return call then it has to be handled very
407 differently. */
408 if (tst->os_state.in_door_return)
409 err = ML_(do_syscall_for_client_dret_WRK)(
410 syscallno, &tst->arch.vex,
411 syscall_mask, &saved, &cflag
412 );
413 else
414 err = ML_(do_syscall_for_client_WRK)(
415 syscallno, &tst->arch.vex,
416 syscall_mask, &saved, &cflag
417 );
418
419 /* Save the carry flag. */
420 # if defined(VGP_x86_solaris)
421 LibVEX_GuestX86_put_eflag_c(cflag, &tst->arch.vex);
422 # elif defined(VGP_amd64_solaris)
423 LibVEX_GuestAMD64_put_rflag_c(cflag, &tst->arch.vex);
424 # else
425 # error "Unknown platform"
426 # endif
427
428 # else
429 # error "Unknown OS"
430 # endif
431 vg_assert2(
432 err == 0,
433 "ML_(do_syscall_for_client_WRK): sigprocmask error %lu",
434 err & 0xFFF
435 );
436 }
437
438
439 /* ---------------------------------------------------------------------
440 Impedance matchers and misc helpers
441 ------------------------------------------------------------------ */
442
443 static
eq_SyscallArgs(SyscallArgs * a1,SyscallArgs * a2)444 Bool eq_SyscallArgs ( SyscallArgs* a1, SyscallArgs* a2 )
445 {
446 return a1->sysno == a2->sysno
447 && a1->arg1 == a2->arg1
448 && a1->arg2 == a2->arg2
449 && a1->arg3 == a2->arg3
450 && a1->arg4 == a2->arg4
451 && a1->arg5 == a2->arg5
452 && a1->arg6 == a2->arg6
453 && a1->arg7 == a2->arg7
454 && a1->arg8 == a2->arg8;
455 }
456
457 static
eq_SyscallStatus(UInt sysno,SyscallStatus * s1,SyscallStatus * s2)458 Bool eq_SyscallStatus ( UInt sysno, SyscallStatus* s1, SyscallStatus* s2 )
459 {
460 /* was: return s1->what == s2->what && sr_EQ( s1->sres, s2->sres ); */
461 if (s1->what == s2->what && sr_EQ( sysno, s1->sres, s2->sres ))
462 return True;
463 # if defined(VGO_darwin)
464 /* Darwin-specific debugging guff */
465 vg_assert(s1->what == s2->what);
466 VG_(printf)("eq_SyscallStatus:\n");
467 VG_(printf)(" {%lu %lu %u}\n", s1->sres._wLO, s1->sres._wHI, s1->sres._mode);
468 VG_(printf)(" {%lu %lu %u}\n", s2->sres._wLO, s2->sres._wHI, s2->sres._mode);
469 vg_assert(0);
470 # endif
471 return False;
472 }
473
474 /* Convert between SysRes and SyscallStatus, to the extent possible. */
475
476 static
convert_SysRes_to_SyscallStatus(SysRes res)477 SyscallStatus convert_SysRes_to_SyscallStatus ( SysRes res )
478 {
479 SyscallStatus status;
480 status.what = SsComplete;
481 status.sres = res;
482 return status;
483 }
484
485
486 /* Impedance matchers. These convert syscall arg or result data from
487 the platform-specific in-guest-state format to the canonical
488 formats, and back. */
489
490 static
getSyscallArgsFromGuestState(SyscallArgs * canonical,VexGuestArchState * gst_vanilla,UInt trc)491 void getSyscallArgsFromGuestState ( /*OUT*/SyscallArgs* canonical,
492 /*IN*/ VexGuestArchState* gst_vanilla,
493 /*IN*/ UInt trc )
494 {
495 #if defined(VGP_x86_linux)
496 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
497 canonical->sysno = gst->guest_EAX;
498 canonical->arg1 = gst->guest_EBX;
499 canonical->arg2 = gst->guest_ECX;
500 canonical->arg3 = gst->guest_EDX;
501 canonical->arg4 = gst->guest_ESI;
502 canonical->arg5 = gst->guest_EDI;
503 canonical->arg6 = gst->guest_EBP;
504 canonical->arg7 = 0;
505 canonical->arg8 = 0;
506
507 #elif defined(VGP_amd64_linux)
508 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
509 canonical->sysno = gst->guest_RAX;
510 canonical->arg1 = gst->guest_RDI;
511 canonical->arg2 = gst->guest_RSI;
512 canonical->arg3 = gst->guest_RDX;
513 canonical->arg4 = gst->guest_R10;
514 canonical->arg5 = gst->guest_R8;
515 canonical->arg6 = gst->guest_R9;
516 canonical->arg7 = 0;
517 canonical->arg8 = 0;
518
519 #elif defined(VGP_ppc32_linux)
520 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
521 canonical->sysno = gst->guest_GPR0;
522 canonical->arg1 = gst->guest_GPR3;
523 canonical->arg2 = gst->guest_GPR4;
524 canonical->arg3 = gst->guest_GPR5;
525 canonical->arg4 = gst->guest_GPR6;
526 canonical->arg5 = gst->guest_GPR7;
527 canonical->arg6 = gst->guest_GPR8;
528 canonical->arg7 = 0;
529 canonical->arg8 = 0;
530
531 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
532 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
533 canonical->sysno = gst->guest_GPR0;
534 canonical->arg1 = gst->guest_GPR3;
535 canonical->arg2 = gst->guest_GPR4;
536 canonical->arg3 = gst->guest_GPR5;
537 canonical->arg4 = gst->guest_GPR6;
538 canonical->arg5 = gst->guest_GPR7;
539 canonical->arg6 = gst->guest_GPR8;
540 canonical->arg7 = 0;
541 canonical->arg8 = 0;
542
543 #elif defined(VGP_x86_dragonfly)
544 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
545 UWord *stack = (UWord *)gst->guest_ESP;
546
547 // Dragonfly supports different calling conventions
548 switch (gst->guest_EAX) {
549 case __NR_syscall:
550 canonical->klass = VG_DRAGONFLY_SYSCALL0;
551 canonical->sysno = stack[1];
552 stack += 1;
553 break;
554 case __NR___syscall:
555 canonical->klass = VG_DRAGONFLY_SYSCALL198;
556 canonical->sysno = stack[1];
557 stack += 2;
558 break;
559 default:
560 canonical->klass = 0;
561 canonical->sysno = gst->guest_EAX;
562 break;
563 }
564 // stack[0] is a (fake) return address
565 canonical->arg1 = stack[1];
566 canonical->arg2 = stack[2];
567 canonical->arg3 = stack[3];
568 canonical->arg4 = stack[4];
569 canonical->arg5 = stack[5];
570 canonical->arg6 = stack[6];
571 canonical->arg7 = stack[7];
572 canonical->arg8 = stack[8];
573
574 #elif defined(VGP_amd64_dragonfly)
575 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
576 UWord *stack = (UWord *)gst->guest_RSP;
577
578 // Dragonfly supports different calling conventions
579 switch (gst->guest_RAX) {
580 case __NR_syscall:
581 canonical->klass = VG_DRAGONFLY_SYSCALL0;
582 canonical->sysno = gst->guest_RDI;
583 break;
584 case __NR___syscall:
585 canonical->klass = VG_DRAGONFLY_SYSCALL198;
586 canonical->sysno = gst->guest_RDI;
587 break;
588 default:
589 canonical->klass = 0;
590 canonical->sysno = gst->guest_RAX;
591 break;
592 }
593 // stack[0] is a (fake) return address
594 if (canonical->klass != VG_DRAGONFLY_SYSCALL0 && canonical->klass != VG_DRAGONFLY_SYSCALL198) {
595 // stack[0] is return address
596 canonical->arg1 = gst->guest_RDI;
597 canonical->arg2 = gst->guest_RSI;
598 canonical->arg3 = gst->guest_RDX;
599 canonical->arg4 = gst->guest_R10;
600 canonical->arg5 = gst->guest_R8;
601 canonical->arg6 = gst->guest_R9;
602 canonical->arg7 = stack[1];
603 canonical->arg8 = stack[2];
604 } else {
605 // stack[0] is return address
606 canonical->arg1 = gst->guest_RSI;
607 canonical->arg2 = gst->guest_RDX;
608 canonical->arg3 = gst->guest_R10;
609 canonical->arg4 = gst->guest_R8;
610 canonical->arg5 = gst->guest_R9;
611 canonical->arg6 = stack[1];
612 canonical->arg7 = stack[2];
613 canonical->arg8 = stack[3];
614 }
615
616 #elif defined(VGP_arm_linux)
617 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
618 canonical->sysno = gst->guest_R7;
619 canonical->arg1 = gst->guest_R0;
620 canonical->arg2 = gst->guest_R1;
621 canonical->arg3 = gst->guest_R2;
622 canonical->arg4 = gst->guest_R3;
623 canonical->arg5 = gst->guest_R4;
624 canonical->arg6 = gst->guest_R5;
625 canonical->arg7 = 0;
626 canonical->arg8 = 0;
627
628 #elif defined(VGP_arm64_linux)
629 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
630 canonical->sysno = gst->guest_X8;
631 canonical->arg1 = gst->guest_X0;
632 canonical->arg2 = gst->guest_X1;
633 canonical->arg3 = gst->guest_X2;
634 canonical->arg4 = gst->guest_X3;
635 canonical->arg5 = gst->guest_X4;
636 canonical->arg6 = gst->guest_X5;
637 canonical->arg7 = 0;
638 canonical->arg8 = 0;
639
640 #elif defined(VGP_mips32_linux)
641 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
642 canonical->sysno = gst->guest_r2; // v0
643 if (canonical->sysno == __NR_exit) {
644 canonical->arg1 = gst->guest_r4; // a0
645 canonical->arg2 = 0;
646 canonical->arg3 = 0;
647 canonical->arg4 = 0;
648 canonical->arg5 = 0;
649 canonical->arg6 = 0;
650 canonical->arg8 = 0;
651 } else if (canonical->sysno != __NR_syscall) {
652 canonical->arg1 = gst->guest_r4; // a0
653 canonical->arg2 = gst->guest_r5; // a1
654 canonical->arg3 = gst->guest_r6; // a2
655 canonical->arg4 = gst->guest_r7; // a3
656 canonical->arg5 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP)
657 canonical->arg6 = *((UInt*) (gst->guest_r29 + 20)); // 20(guest_SP)
658 canonical->arg7 = *((UInt*) (gst->guest_r29 + 24)); // 24(guest_SP)
659 canonical->arg8 = 0;
660 } else {
661 // Fixme hack handle syscall()
662 canonical->sysno = gst->guest_r4; // a0
663 canonical->arg1 = gst->guest_r5; // a1
664 canonical->arg2 = gst->guest_r6; // a2
665 canonical->arg3 = gst->guest_r7; // a3
666 canonical->arg4 = *((UInt*) (gst->guest_r29 + 16)); // 16(guest_SP/sp)
667 canonical->arg5 = *((UInt*) (gst->guest_r29 + 20)); // 20(guest_SP/sp)
668 canonical->arg6 = *((UInt*) (gst->guest_r29 + 24)); // 24(guest_SP/sp)
669 canonical->arg8 = __NR_syscall;
670 }
671
672 #elif defined(VGP_mips64_linux)
673 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
674 canonical->sysno = gst->guest_r2; // v0
675 canonical->arg1 = gst->guest_r4; // a0
676 canonical->arg2 = gst->guest_r5; // a1
677 canonical->arg3 = gst->guest_r6; // a2
678 canonical->arg4 = gst->guest_r7; // a3
679 canonical->arg5 = gst->guest_r8; // a4
680 canonical->arg6 = gst->guest_r9; // a5
681
682 #elif defined(VGP_x86_darwin)
683 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
684 UWord *stack = (UWord *)gst->guest_ESP;
685 // GrP fixme hope syscalls aren't called with really shallow stacks...
686 canonical->sysno = gst->guest_EAX;
687 if (canonical->sysno != 0) {
688 // stack[0] is return address
689 canonical->arg1 = stack[1];
690 canonical->arg2 = stack[2];
691 canonical->arg3 = stack[3];
692 canonical->arg4 = stack[4];
693 canonical->arg5 = stack[5];
694 canonical->arg6 = stack[6];
695 canonical->arg7 = stack[7];
696 canonical->arg8 = stack[8];
697 } else {
698 // GrP fixme hack handle syscall()
699 // GrP fixme what about __syscall() ?
700 // stack[0] is return address
701 // DDD: the tool can't see that the params have been shifted! Can
702 // lead to incorrect checking, I think, because the PRRAn/PSARn
703 // macros will mention the pre-shifted args.
704 canonical->sysno = stack[1];
705 vg_assert(canonical->sysno != 0);
706 canonical->arg1 = stack[2];
707 canonical->arg2 = stack[3];
708 canonical->arg3 = stack[4];
709 canonical->arg4 = stack[5];
710 canonical->arg5 = stack[6];
711 canonical->arg6 = stack[7];
712 canonical->arg7 = stack[8];
713 canonical->arg8 = stack[9];
714
715 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
716 VG_(getpid)(), /*tid,*/
717 VG_SYSNUM_STRING(canonical->sysno));
718 }
719
720 // Here we determine what kind of syscall it was by looking at the
721 // interrupt kind, and then encode the syscall number using the 64-bit
722 // encoding for Valgrind's internal use.
723 //
724 // DDD: Would it be better to stash the JMP kind into the Darwin
725 // thread state rather than passing in the trc?
726 switch (trc) {
727 case VEX_TRC_JMP_SYS_INT128:
728 // int $0x80 = Unix, 64-bit result
729 vg_assert(canonical->sysno >= 0);
730 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno);
731 break;
732 case VEX_TRC_JMP_SYS_SYSENTER:
733 // syscall = Unix, 32-bit result
734 // OR Mach, 32-bit result
735 if (canonical->sysno >= 0) {
736 // GrP fixme hack: 0xffff == I386_SYSCALL_NUMBER_MASK
737 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(canonical->sysno
738 & 0xffff);
739 } else {
740 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno);
741 }
742 break;
743 case VEX_TRC_JMP_SYS_INT129:
744 // int $0x81 = Mach, 32-bit result
745 vg_assert(canonical->sysno < 0);
746 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MACH(-canonical->sysno);
747 break;
748 case VEX_TRC_JMP_SYS_INT130:
749 // int $0x82 = mdep, 32-bit result
750 vg_assert(canonical->sysno >= 0);
751 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_MDEP(canonical->sysno);
752 break;
753 default:
754 vg_assert(0);
755 break;
756 }
757
758 #elif defined(VGP_amd64_darwin)
759 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
760 UWord *stack = (UWord *)gst->guest_RSP;
761
762 vg_assert(trc == VEX_TRC_JMP_SYS_SYSCALL);
763
764 // GrP fixme hope syscalls aren't called with really shallow stacks...
765 canonical->sysno = gst->guest_RAX;
766 if (canonical->sysno != __NR_syscall) {
767 // stack[0] is return address
768 canonical->arg1 = gst->guest_RDI;
769 canonical->arg2 = gst->guest_RSI;
770 canonical->arg3 = gst->guest_RDX;
771 canonical->arg4 = gst->guest_R10; // not rcx with syscall insn
772 canonical->arg5 = gst->guest_R8;
773 canonical->arg6 = gst->guest_R9;
774 canonical->arg7 = stack[1];
775 canonical->arg8 = stack[2];
776 } else {
777 // GrP fixme hack handle syscall()
778 // GrP fixme what about __syscall() ?
779 // stack[0] is return address
780 // DDD: the tool can't see that the params have been shifted! Can
781 // lead to incorrect checking, I think, because the PRRAn/PSARn
782 // macros will mention the pre-shifted args.
783 canonical->sysno = VG_DARWIN_SYSCALL_CONSTRUCT_UNIX(gst->guest_RDI);
784 vg_assert(canonical->sysno != __NR_syscall);
785 canonical->arg1 = gst->guest_RSI;
786 canonical->arg2 = gst->guest_RDX;
787 canonical->arg3 = gst->guest_R10; // not rcx with syscall insn
788 canonical->arg4 = gst->guest_R8;
789 canonical->arg5 = gst->guest_R9;
790 canonical->arg6 = stack[1];
791 canonical->arg7 = stack[2];
792 canonical->arg8 = stack[3];
793
794 PRINT("SYSCALL[%d,?](0) syscall(%s, ...); please stand by...\n",
795 VG_(getpid)(), /*tid,*/
796 VG_SYSNUM_STRING(canonical->sysno));
797 }
798
799 // no canonical->sysno adjustment needed
800
801 #elif defined(VGP_s390x_linux)
802 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
803 canonical->sysno = gst->guest_SYSNO;
804 canonical->arg1 = gst->guest_r2;
805 canonical->arg2 = gst->guest_r3;
806 canonical->arg3 = gst->guest_r4;
807 canonical->arg4 = gst->guest_r5;
808 canonical->arg5 = gst->guest_r6;
809 canonical->arg6 = gst->guest_r7;
810 canonical->arg7 = 0;
811 canonical->arg8 = 0;
812
813 #elif defined(VGP_x86_solaris)
814 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
815 UWord *stack = (UWord *)gst->guest_ESP;
816 canonical->sysno = gst->guest_EAX;
817 /* stack[0] is a return address. */
818 canonical->arg1 = stack[1];
819 canonical->arg2 = stack[2];
820 canonical->arg3 = stack[3];
821 canonical->arg4 = stack[4];
822 canonical->arg5 = stack[5];
823 canonical->arg6 = stack[6];
824 canonical->arg7 = stack[7];
825 canonical->arg8 = stack[8];
826
827 switch (trc) {
828 case VEX_TRC_JMP_SYS_INT145:
829 case VEX_TRC_JMP_SYS_SYSENTER:
830 case VEX_TRC_JMP_SYS_SYSCALL:
831 /* These three are not actually valid syscall instructions on Solaris.
832 Pretend for now that we handle them as normal syscalls. */
833 case VEX_TRC_JMP_SYS_INT128:
834 case VEX_TRC_JMP_SYS_INT129:
835 case VEX_TRC_JMP_SYS_INT130:
836 /* int $0x91, sysenter, syscall = normal syscall */
837 break;
838 case VEX_TRC_JMP_SYS_INT210:
839 /* int $0xD2 = fasttrap */
840 canonical->sysno
841 = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno);
842 break;
843 default:
844 vg_assert(0);
845 break;
846 }
847
848 #elif defined(VGP_amd64_solaris)
849 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
850 UWord *stack = (UWord *)gst->guest_RSP;
851 canonical->sysno = gst->guest_RAX;
852 /* stack[0] is a return address. */
853 canonical->arg1 = gst->guest_RDI;
854 canonical->arg2 = gst->guest_RSI;
855 canonical->arg3 = gst->guest_RDX;
856 canonical->arg4 = gst->guest_R10; /* Not RCX with syscall. */
857 canonical->arg5 = gst->guest_R8;
858 canonical->arg6 = gst->guest_R9;
859 canonical->arg7 = stack[1];
860 canonical->arg8 = stack[2];
861
862 switch (trc) {
863 case VEX_TRC_JMP_SYS_SYSCALL:
864 /* syscall = normal syscall */
865 break;
866 case VEX_TRC_JMP_SYS_INT210:
867 /* int $0xD2 = fasttrap */
868 canonical->sysno
869 = VG_SOLARIS_SYSCALL_CONSTRUCT_FASTTRAP(canonical->sysno);
870 break;
871 default:
872 vg_assert(0);
873 break;
874 }
875
876 #else
877 # error "getSyscallArgsFromGuestState: unknown arch"
878 #endif
879 }
880
881 static
putSyscallArgsIntoGuestState(SyscallArgs * canonical,VexGuestArchState * gst_vanilla)882 void putSyscallArgsIntoGuestState ( /*IN*/ SyscallArgs* canonical,
883 /*OUT*/VexGuestArchState* gst_vanilla )
884 {
885 #if defined(VGP_x86_linux)
886 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
887 gst->guest_EAX = canonical->sysno;
888 gst->guest_EBX = canonical->arg1;
889 gst->guest_ECX = canonical->arg2;
890 gst->guest_EDX = canonical->arg3;
891 gst->guest_ESI = canonical->arg4;
892 gst->guest_EDI = canonical->arg5;
893 gst->guest_EBP = canonical->arg6;
894
895 #elif defined(VGP_amd64_linux)
896 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
897 gst->guest_RAX = canonical->sysno;
898 gst->guest_RDI = canonical->arg1;
899 gst->guest_RSI = canonical->arg2;
900 gst->guest_RDX = canonical->arg3;
901 gst->guest_R10 = canonical->arg4;
902 gst->guest_R8 = canonical->arg5;
903 gst->guest_R9 = canonical->arg6;
904
905 #elif defined(VGP_ppc32_linux)
906 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
907 gst->guest_GPR0 = canonical->sysno;
908 gst->guest_GPR3 = canonical->arg1;
909 gst->guest_GPR4 = canonical->arg2;
910 gst->guest_GPR5 = canonical->arg3;
911 gst->guest_GPR6 = canonical->arg4;
912 gst->guest_GPR7 = canonical->arg5;
913 gst->guest_GPR8 = canonical->arg6;
914
915 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
916 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
917 gst->guest_GPR0 = canonical->sysno;
918 gst->guest_GPR3 = canonical->arg1;
919 gst->guest_GPR4 = canonical->arg2;
920 gst->guest_GPR5 = canonical->arg3;
921 gst->guest_GPR6 = canonical->arg4;
922 gst->guest_GPR7 = canonical->arg5;
923 gst->guest_GPR8 = canonical->arg6;
924
925 #elif defined(VGP_x86_dragonfly)
926 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
927 UWord *stack = (UWord *)gst->guest_ESP;
928
929 // stack[0] is a (fake) return address
930 switch (canonical->klass) {
931 case VG_DRAGONFLY_SYSCALL0:
932 gst->guest_EAX = __NR_syscall;
933 stack[1] = canonical->sysno;
934 stack++;
935 break;
936 case VG_DRAGONFLY_SYSCALL198:
937 gst->guest_EAX = __NR___syscall;
938 stack[1] = canonical->sysno;
939 stack += 2;
940 break;
941 default:
942 gst->guest_EAX = canonical->sysno;
943 break;
944 }
945 stack[1] = canonical->arg1;
946 stack[2] = canonical->arg2;
947 stack[3] = canonical->arg3;
948 stack[4] = canonical->arg4;
949 stack[5] = canonical->arg5;
950 stack[6] = canonical->arg6;
951 stack[7] = canonical->arg7;
952 stack[8] = canonical->arg8;
953
954 #elif defined(VGP_amd64_dragonfly)
955 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
956 UWord *stack = (UWord *)gst->guest_RSP;
957
958 // stack[0] is a (fake) return address
959 switch (canonical->klass) {
960 case VG_DRAGONFLY_SYSCALL0:
961 gst->guest_RAX = __NR_syscall;
962 gst->guest_RDI = canonical->sysno;
963 gst->guest_RSI = canonical->arg1;
964 gst->guest_RDX = canonical->arg2;
965 gst->guest_R10 = canonical->arg3;
966 gst->guest_R8 = canonical->arg4;
967 gst->guest_R9 = canonical->arg5;
968 stack[1] = canonical->arg6;
969 stack[2] = canonical->arg7;
970 stack[3] = canonical->arg8;
971 break;
972 case VG_DRAGONFLY_SYSCALL198:
973 gst->guest_RAX = __NR___syscall;
974 gst->guest_RDI = canonical->sysno;
975 gst->guest_RSI = canonical->arg1;
976 gst->guest_RDX = canonical->arg2;
977 gst->guest_R10 = canonical->arg3;
978 gst->guest_R8 = canonical->arg4;
979 gst->guest_R9 = canonical->arg5;
980 stack[1] = canonical->arg6;
981 stack[2] = canonical->arg7;
982 stack[3] = canonical->arg8;
983 break;
984 default:
985 gst->guest_RAX = canonical->sysno;
986 gst->guest_RDI = canonical->arg1;
987 gst->guest_RSI = canonical->arg2;
988 gst->guest_RDX = canonical->arg3;
989 gst->guest_R10 = canonical->arg4;
990 gst->guest_R8 = canonical->arg5;
991 gst->guest_R9 = canonical->arg6;
992 stack[1] = canonical->arg7;
993 stack[2] = canonical->arg8;
994 break;
995 }
996
997 #elif defined(VGP_arm_linux)
998 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
999 gst->guest_R7 = canonical->sysno;
1000 gst->guest_R0 = canonical->arg1;
1001 gst->guest_R1 = canonical->arg2;
1002 gst->guest_R2 = canonical->arg3;
1003 gst->guest_R3 = canonical->arg4;
1004 gst->guest_R4 = canonical->arg5;
1005 gst->guest_R5 = canonical->arg6;
1006
1007 #elif defined(VGP_arm64_linux)
1008 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1009 gst->guest_X8 = canonical->sysno;
1010 gst->guest_X0 = canonical->arg1;
1011 gst->guest_X1 = canonical->arg2;
1012 gst->guest_X2 = canonical->arg3;
1013 gst->guest_X3 = canonical->arg4;
1014 gst->guest_X4 = canonical->arg5;
1015 gst->guest_X5 = canonical->arg6;
1016
1017 #elif defined(VGP_x86_darwin)
1018 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1019 UWord *stack = (UWord *)gst->guest_ESP;
1020
1021 gst->guest_EAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
1022
1023 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
1024 // stack[0] is return address
1025 stack[1] = canonical->arg1;
1026 stack[2] = canonical->arg2;
1027 stack[3] = canonical->arg3;
1028 stack[4] = canonical->arg4;
1029 stack[5] = canonical->arg5;
1030 stack[6] = canonical->arg6;
1031 stack[7] = canonical->arg7;
1032 stack[8] = canonical->arg8;
1033
1034 #elif defined(VGP_amd64_darwin)
1035 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1036 UWord *stack = (UWord *)gst->guest_RSP;
1037
1038 gst->guest_RAX = VG_DARWIN_SYSNO_FOR_KERNEL(canonical->sysno);
1039 // GrP fixme? gst->guest_TEMP_EFLAG_C = 0;
1040
1041 // stack[0] is return address
1042 gst->guest_RDI = canonical->arg1;
1043 gst->guest_RSI = canonical->arg2;
1044 gst->guest_RDX = canonical->arg3;
1045 gst->guest_RCX = canonical->arg4;
1046 gst->guest_R8 = canonical->arg5;
1047 gst->guest_R9 = canonical->arg6;
1048 stack[1] = canonical->arg7;
1049 stack[2] = canonical->arg8;
1050
1051 #elif defined(VGP_s390x_linux)
1052 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
1053 gst->guest_SYSNO = canonical->sysno;
1054 gst->guest_r2 = canonical->arg1;
1055 gst->guest_r3 = canonical->arg2;
1056 gst->guest_r4 = canonical->arg3;
1057 gst->guest_r5 = canonical->arg4;
1058 gst->guest_r6 = canonical->arg5;
1059 gst->guest_r7 = canonical->arg6;
1060
1061 #elif defined(VGP_mips32_linux)
1062 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1063 if (canonical->arg8 != __NR_syscall) {
1064 gst->guest_r2 = canonical->sysno;
1065 gst->guest_r4 = canonical->arg1;
1066 gst->guest_r5 = canonical->arg2;
1067 gst->guest_r6 = canonical->arg3;
1068 gst->guest_r7 = canonical->arg4;
1069 *((UInt*) (gst->guest_r29 + 16)) = canonical->arg5; // 16(guest_GPR29/sp)
1070 *((UInt*) (gst->guest_r29 + 20)) = canonical->arg6; // 20(sp)
1071 } else {
1072 canonical->arg8 = 0;
1073 gst->guest_r2 = __NR_syscall;
1074 gst->guest_r4 = canonical->sysno;
1075 gst->guest_r5 = canonical->arg1;
1076 gst->guest_r6 = canonical->arg2;
1077 gst->guest_r7 = canonical->arg3;
1078 *((UInt*) (gst->guest_r29 + 16)) = canonical->arg4; // 16(guest_GPR29/sp)
1079 *((UInt*) (gst->guest_r29 + 20)) = canonical->arg5; // 20(sp)
1080 *((UInt*) (gst->guest_r29 + 24)) = canonical->arg6; // 24(sp)
1081 }
1082
1083 #elif defined(VGP_mips64_linux)
1084 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
1085 gst->guest_r2 = canonical->sysno;
1086 gst->guest_r4 = canonical->arg1;
1087 gst->guest_r5 = canonical->arg2;
1088 gst->guest_r6 = canonical->arg3;
1089 gst->guest_r7 = canonical->arg4;
1090 gst->guest_r8 = canonical->arg5;
1091 gst->guest_r9 = canonical->arg6;
1092
1093 #elif defined(VGP_x86_solaris)
1094 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1095 UWord *stack = (UWord *)gst->guest_ESP;
1096
1097 /* Fasttraps or anything else cannot go through this way. */
1098 vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno)
1099 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
1100 gst->guest_EAX = canonical->sysno;
1101 /* stack[0] is a return address. */
1102 stack[1] = canonical->arg1;
1103 stack[2] = canonical->arg2;
1104 stack[3] = canonical->arg3;
1105 stack[4] = canonical->arg4;
1106 stack[5] = canonical->arg5;
1107 stack[6] = canonical->arg6;
1108 stack[7] = canonical->arg7;
1109 stack[8] = canonical->arg8;
1110
1111 #elif defined(VGP_amd64_solaris)
1112 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1113 UWord *stack = (UWord *)gst->guest_RSP;
1114
1115 /* Fasttraps or anything else cannot go through this way. */
1116 vg_assert(VG_SOLARIS_SYSNO_CLASS(canonical->sysno)
1117 == VG_SOLARIS_SYSCALL_CLASS_CLASSIC);
1118 gst->guest_RAX = canonical->sysno;
1119 /* stack[0] is a return address. */
1120 gst->guest_RDI = canonical->arg1;
1121 gst->guest_RSI = canonical->arg2;
1122 gst->guest_RDX = canonical->arg3;
1123 gst->guest_R10 = canonical->arg4;
1124 gst->guest_R8 = canonical->arg5;
1125 gst->guest_R9 = canonical->arg6;
1126 stack[1] = canonical->arg7;
1127 stack[2] = canonical->arg8;
1128
1129 #else
1130 # error "putSyscallArgsIntoGuestState: unknown arch"
1131 #endif
1132 }
1133
1134 static
getSyscallStatusFromGuestState(SyscallStatus * canonical,VexGuestArchState * gst_vanilla)1135 void getSyscallStatusFromGuestState ( /*OUT*/SyscallStatus* canonical,
1136 /*IN*/ VexGuestArchState* gst_vanilla )
1137 {
1138 # if defined(VGP_x86_linux)
1139 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1140 canonical->sres = VG_(mk_SysRes_x86_linux)( gst->guest_EAX );
1141 canonical->what = SsComplete;
1142
1143 # elif defined(VGP_amd64_linux)
1144 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1145 canonical->sres = VG_(mk_SysRes_amd64_linux)( gst->guest_RAX );
1146 canonical->what = SsComplete;
1147
1148 # elif defined(VGP_ppc32_linux)
1149 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
1150 UInt cr = LibVEX_GuestPPC32_get_CR( gst );
1151 UInt cr0so = (cr >> 28) & 1;
1152 canonical->sres = VG_(mk_SysRes_ppc32_linux)( gst->guest_GPR3, cr0so );
1153 canonical->what = SsComplete;
1154
1155 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1156 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
1157 UInt cr = LibVEX_GuestPPC64_get_CR( gst );
1158 UInt cr0so = (cr >> 28) & 1;
1159 canonical->sres = VG_(mk_SysRes_ppc64_linux)( gst->guest_GPR3, cr0so );
1160 canonical->what = SsComplete;
1161
1162 # elif defined(VGP_x86_dragonfly)
1163 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1164 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1165 UInt flags = LibVEX_GuestX86_get_eflags(gst);
1166
1167 canonical->sres = VG_(mk_SysRes_x86_dragonfly)(gst->guest_EAX, gst->guest_EDX,
1168 (flags & 1) != 0 ? True : False);
1169 canonical->what = SsComplete;
1170
1171 # elif defined(VGP_arm_linux)
1172 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
1173 canonical->sres = VG_(mk_SysRes_arm_linux)( gst->guest_R0 );
1174 canonical->what = SsComplete;
1175
1176 # elif defined(VGP_arm64_linux)
1177 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1178 canonical->sres = VG_(mk_SysRes_arm64_linux)( gst->guest_X0 );
1179 canonical->what = SsComplete;
1180
1181 # elif defined(VGP_mips32_linux)
1182 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1183 UInt v0 = gst->guest_r2; // v0
1184 UInt v1 = gst->guest_r3; // v1
1185 UInt a3 = gst->guest_r7; // a3
1186 canonical->sres = VG_(mk_SysRes_mips32_linux)( v0, v1, a3 );
1187 canonical->what = SsComplete;
1188
1189 # elif defined(VGP_mips64_linux)
1190 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
1191 ULong v0 = gst->guest_r2; // v0
1192 ULong v1 = gst->guest_r3; // v1
1193 ULong a3 = gst->guest_r7; // a3
1194 canonical->sres = VG_(mk_SysRes_mips64_linux)(v0, v1, a3);
1195 canonical->what = SsComplete;
1196
1197 # elif defined(VGP_amd64_dragonfly)
1198 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1199 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1200 ULong flags = LibVEX_GuestAMD64_get_rflags(gst);
1201 canonical->sres = VG_(mk_SysRes_amd64_dragonfly)(gst->guest_RAX, gst->guest_RDX,
1202 (flags & 1) != 0 ? True : False);
1203 canonical->what = SsComplete;
1204
1205 # elif defined(VGP_x86_darwin)
1206 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1207 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1208 UInt carry = 1 & LibVEX_GuestX86_get_eflags(gst);
1209 UInt err = 0;
1210 UInt wLO = 0;
1211 UInt wHI = 0;
1212 switch (gst->guest_SC_CLASS) {
1213 case VG_DARWIN_SYSCALL_CLASS_UNIX:
1214 // int $0x80 = Unix, 64-bit result
1215 err = carry;
1216 wLO = gst->guest_EAX;
1217 wHI = gst->guest_EDX;
1218 break;
1219 case VG_DARWIN_SYSCALL_CLASS_MACH:
1220 // int $0x81 = Mach, 32-bit result
1221 wLO = gst->guest_EAX;
1222 break;
1223 case VG_DARWIN_SYSCALL_CLASS_MDEP:
1224 // int $0x82 = mdep, 32-bit result
1225 wLO = gst->guest_EAX;
1226 break;
1227 default:
1228 vg_assert(0);
1229 break;
1230 }
1231 canonical->sres = VG_(mk_SysRes_x86_darwin)(
1232 gst->guest_SC_CLASS, err ? True : False,
1233 wHI, wLO
1234 );
1235 canonical->what = SsComplete;
1236
1237 # elif defined(VGP_amd64_darwin)
1238 /* duplicates logic in m_signals.VG_UCONTEXT_SYSCALL_SYSRES */
1239 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1240 ULong carry = 1 & LibVEX_GuestAMD64_get_rflags(gst);
1241 ULong err = 0;
1242 ULong wLO = 0;
1243 ULong wHI = 0;
1244 switch (gst->guest_SC_CLASS) {
1245 case VG_DARWIN_SYSCALL_CLASS_UNIX:
1246 // syscall = Unix, 128-bit result
1247 err = carry;
1248 wLO = gst->guest_RAX;
1249 wHI = gst->guest_RDX;
1250 break;
1251 case VG_DARWIN_SYSCALL_CLASS_MACH:
1252 // syscall = Mach, 64-bit result
1253 wLO = gst->guest_RAX;
1254 break;
1255 case VG_DARWIN_SYSCALL_CLASS_MDEP:
1256 // syscall = mdep, 64-bit result
1257 wLO = gst->guest_RAX;
1258 break;
1259 default:
1260 vg_assert(0);
1261 break;
1262 }
1263 canonical->sres = VG_(mk_SysRes_amd64_darwin)(
1264 gst->guest_SC_CLASS, err ? True : False,
1265 wHI, wLO
1266 );
1267 canonical->what = SsComplete;
1268
1269 # elif defined(VGP_s390x_linux)
1270 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
1271 canonical->sres = VG_(mk_SysRes_s390x_linux)( gst->guest_r2 );
1272 canonical->what = SsComplete;
1273
1274 # elif defined(VGP_x86_solaris)
1275 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1276 UInt carry = 1 & LibVEX_GuestX86_get_eflags(gst);
1277
1278 canonical->sres = VG_(mk_SysRes_x86_solaris)(carry ? True : False,
1279 gst->guest_EAX,
1280 carry ? 0 : gst->guest_EDX);
1281 canonical->what = SsComplete;
1282
1283 # elif defined(VGP_amd64_solaris)
1284 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1285 UInt carry = 1 & LibVEX_GuestAMD64_get_rflags(gst);
1286
1287 canonical->sres = VG_(mk_SysRes_amd64_solaris)(carry ? True : False,
1288 gst->guest_RAX,
1289 carry ? 0 : gst->guest_RDX);
1290 canonical->what = SsComplete;
1291
1292 # else
1293 # error "getSyscallStatusFromGuestState: unknown arch"
1294 # endif
1295 }
1296
1297 static
putSyscallStatusIntoGuestState(ThreadId tid,SyscallStatus * canonical,VexGuestArchState * gst_vanilla)1298 void putSyscallStatusIntoGuestState ( /*IN*/ ThreadId tid,
1299 /*IN*/ SyscallStatus* canonical,
1300 /*OUT*/VexGuestArchState* gst_vanilla )
1301 {
1302 # if defined(VGP_x86_linux)
1303 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1304 vg_assert(canonical->what == SsComplete);
1305 if (sr_isError(canonical->sres)) {
1306 /* This isn't exactly right, in that really a Failure with res
1307 not in the range 1 .. 4095 is unrepresentable in the
1308 Linux-x86 scheme. Oh well. */
1309 gst->guest_EAX = - (Int)sr_Err(canonical->sres);
1310 } else {
1311 gst->guest_EAX = sr_Res(canonical->sres);
1312 }
1313 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1314 OFFSET_x86_EAX, sizeof(UWord) );
1315
1316 # elif defined(VGP_amd64_linux)
1317 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1318 vg_assert(canonical->what == SsComplete);
1319 if (sr_isError(canonical->sres)) {
1320 /* This isn't exactly right, in that really a Failure with res
1321 not in the range 1 .. 4095 is unrepresentable in the
1322 Linux-amd64 scheme. Oh well. */
1323 gst->guest_RAX = - (Long)sr_Err(canonical->sres);
1324 } else {
1325 gst->guest_RAX = sr_Res(canonical->sres);
1326 }
1327 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1328 OFFSET_amd64_RAX, sizeof(UWord) );
1329
1330 # elif defined(VGP_ppc32_linux)
1331 VexGuestPPC32State* gst = (VexGuestPPC32State*)gst_vanilla;
1332 UInt old_cr = LibVEX_GuestPPC32_get_CR(gst);
1333 vg_assert(canonical->what == SsComplete);
1334 if (sr_isError(canonical->sres)) {
1335 /* set CR0.SO */
1336 LibVEX_GuestPPC32_put_CR( old_cr | (1<<28), gst );
1337 gst->guest_GPR3 = sr_Err(canonical->sres);
1338 } else {
1339 /* clear CR0.SO */
1340 LibVEX_GuestPPC32_put_CR( old_cr & ~(1<<28), gst );
1341 gst->guest_GPR3 = sr_Res(canonical->sres);
1342 }
1343 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1344 OFFSET_ppc32_GPR3, sizeof(UWord) );
1345 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1346 OFFSET_ppc32_CR0_0, sizeof(UChar) );
1347
1348 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1349 VexGuestPPC64State* gst = (VexGuestPPC64State*)gst_vanilla;
1350 UInt old_cr = LibVEX_GuestPPC64_get_CR(gst);
1351 vg_assert(canonical->what == SsComplete);
1352 if (sr_isError(canonical->sres)) {
1353 /* set CR0.SO */
1354 LibVEX_GuestPPC64_put_CR( old_cr | (1<<28), gst );
1355 gst->guest_GPR3 = sr_Err(canonical->sres);
1356 } else {
1357 /* clear CR0.SO */
1358 LibVEX_GuestPPC64_put_CR( old_cr & ~(1<<28), gst );
1359 gst->guest_GPR3 = sr_Res(canonical->sres);
1360 }
1361 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1362 OFFSET_ppc64_GPR3, sizeof(UWord) );
1363 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1364 OFFSET_ppc64_CR0_0, sizeof(UChar) );
1365
1366 # elif defined(VGP_arm_linux)
1367 VexGuestARMState* gst = (VexGuestARMState*)gst_vanilla;
1368 vg_assert(canonical->what == SsComplete);
1369 if (sr_isError(canonical->sres)) {
1370 /* This isn't exactly right, in that really a Failure with res
1371 not in the range 1 .. 4095 is unrepresentable in the
1372 Linux-arm scheme. Oh well. */
1373 gst->guest_R0 = - (Int)sr_Err(canonical->sres);
1374 } else {
1375 gst->guest_R0 = sr_Res(canonical->sres);
1376 }
1377 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1378 OFFSET_arm_R0, sizeof(UWord) );
1379
1380 # elif defined(VGP_arm64_linux)
1381 VexGuestARM64State* gst = (VexGuestARM64State*)gst_vanilla;
1382 vg_assert(canonical->what == SsComplete);
1383 if (sr_isError(canonical->sres)) {
1384 /* This isn't exactly right, in that really a Failure with res
1385 not in the range 1 .. 4095 is unrepresentable in the
1386 Linux-arm64 scheme. Oh well. */
1387 gst->guest_X0 = - (Long)sr_Err(canonical->sres);
1388 } else {
1389 gst->guest_X0 = sr_Res(canonical->sres);
1390 }
1391 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1392 OFFSET_arm64_X0, sizeof(UWord) );
1393
1394 #elif defined(VGP_x86_dragonfly)
1395 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1396 vg_assert(canonical->what == SsComplete);
1397 if (sr_isError(canonical->sres)) {
1398 gst->guest_EAX = sr_Err(canonical->sres);
1399 LibVEX_GuestX86_put_eflag_c(1, gst);
1400 } else {
1401 gst->guest_EAX = sr_Res(canonical->sres);
1402 gst->guest_EDX = sr_ResHI(canonical->sres);
1403 LibVEX_GuestX86_put_eflag_c(0, gst);
1404 }
1405 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1406 OFFSET_x86_EAX, sizeof(UInt) );
1407 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1408 OFFSET_x86_EDX, sizeof(UInt) );
1409 // GrP fixme sets defined for entire eflags, not just bit c
1410 // DDD: this breaks exp-ptrcheck.
1411 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1412 offsetof(VexGuestX86State, guest_CC_DEP1), sizeof(UInt) );
1413
1414 #elif defined(VGP_amd64_dragonfly)
1415 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1416 vg_assert(canonical->what == SsComplete);
1417 if (sr_isError(canonical->sres)) {
1418 gst->guest_RAX = sr_Err(canonical->sres);
1419 LibVEX_GuestAMD64_put_rflag_c(1, gst);
1420 } else {
1421 gst->guest_RAX = sr_Res(canonical->sres);
1422 gst->guest_RDX = sr_ResHI(canonical->sres);
1423 LibVEX_GuestAMD64_put_rflag_c(0, gst);
1424 }
1425 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1426 OFFSET_amd64_RAX, sizeof(ULong) );
1427 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1428 OFFSET_amd64_RDX, sizeof(ULong) );
1429 // GrP fixme sets defined for entire eflags, not just bit c
1430 // DDD: this breaks exp-ptrcheck.
1431 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1432 offsetof(VexGuestAMD64State, guest_CC_DEP1), sizeof(ULong) );
1433 #elif defined(VGP_x86_darwin)
1434 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1435 SysRes sres = canonical->sres;
1436 vg_assert(canonical->what == SsComplete);
1437 /* Unfortunately here we have to break abstraction and look
1438 directly inside 'res', in order to decide what to do. */
1439 switch (sres._mode) {
1440 case SysRes_MACH: // int $0x81 = Mach, 32-bit result
1441 case SysRes_MDEP: // int $0x82 = mdep, 32-bit result
1442 gst->guest_EAX = sres._wLO;
1443 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1444 OFFSET_x86_EAX, sizeof(UInt) );
1445 break;
1446 case SysRes_UNIX_OK: // int $0x80 = Unix, 64-bit result
1447 case SysRes_UNIX_ERR: // int $0x80 = Unix, 64-bit error
1448 gst->guest_EAX = sres._wLO;
1449 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1450 OFFSET_x86_EAX, sizeof(UInt) );
1451 gst->guest_EDX = sres._wHI;
1452 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1453 OFFSET_x86_EDX, sizeof(UInt) );
1454 LibVEX_GuestX86_put_eflag_c( sres._mode==SysRes_UNIX_ERR ? 1 : 0,
1455 gst );
1456 // GrP fixme sets defined for entire eflags, not just bit c
1457 // DDD: this breaks exp-ptrcheck.
1458 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1459 offsetof(VexGuestX86State, guest_CC_DEP1), sizeof(UInt) );
1460 break;
1461 default:
1462 vg_assert(0);
1463 break;
1464 }
1465
1466 #elif defined(VGP_amd64_darwin)
1467 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1468 SysRes sres = canonical->sres;
1469 vg_assert(canonical->what == SsComplete);
1470 /* Unfortunately here we have to break abstraction and look
1471 directly inside 'res', in order to decide what to do. */
1472 switch (sres._mode) {
1473 case SysRes_MACH: // syscall = Mach, 64-bit result
1474 case SysRes_MDEP: // syscall = mdep, 64-bit result
1475 gst->guest_RAX = sres._wLO;
1476 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1477 OFFSET_amd64_RAX, sizeof(ULong) );
1478 break;
1479 case SysRes_UNIX_OK: // syscall = Unix, 128-bit result
1480 case SysRes_UNIX_ERR: // syscall = Unix, 128-bit error
1481 gst->guest_RAX = sres._wLO;
1482 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1483 OFFSET_amd64_RAX, sizeof(ULong) );
1484 gst->guest_RDX = sres._wHI;
1485 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1486 OFFSET_amd64_RDX, sizeof(ULong) );
1487 LibVEX_GuestAMD64_put_rflag_c( sres._mode==SysRes_UNIX_ERR ? 1 : 0,
1488 gst );
1489 // GrP fixme sets defined for entire rflags, not just bit c
1490 // DDD: this breaks exp-ptrcheck.
1491 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1492 offsetof(VexGuestAMD64State, guest_CC_DEP1), sizeof(ULong) );
1493 break;
1494 default:
1495 vg_assert(0);
1496 break;
1497 }
1498
1499 # elif defined(VGP_s390x_linux)
1500 VexGuestS390XState* gst = (VexGuestS390XState*)gst_vanilla;
1501 vg_assert(canonical->what == SsComplete);
1502 if (sr_isError(canonical->sres)) {
1503 gst->guest_r2 = - (Long)sr_Err(canonical->sres);
1504 } else {
1505 gst->guest_r2 = sr_Res(canonical->sres);
1506 }
1507
1508 # elif defined(VGP_mips32_linux)
1509 VexGuestMIPS32State* gst = (VexGuestMIPS32State*)gst_vanilla;
1510 vg_assert(canonical->what == SsComplete);
1511 if (sr_isError(canonical->sres)) {
1512 gst->guest_r2 = (Int)sr_Err(canonical->sres);
1513 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1514 } else {
1515 gst->guest_r2 = sr_Res(canonical->sres);
1516 gst->guest_r3 = sr_ResEx(canonical->sres);
1517 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1518 }
1519 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1520 OFFSET_mips32_r2, sizeof(UWord) );
1521 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1522 OFFSET_mips32_r3, sizeof(UWord) );
1523 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1524 OFFSET_mips32_r7, sizeof(UWord) );
1525
1526 # elif defined(VGP_mips64_linux)
1527 VexGuestMIPS64State* gst = (VexGuestMIPS64State*)gst_vanilla;
1528 vg_assert(canonical->what == SsComplete);
1529 if (sr_isError(canonical->sres)) {
1530 gst->guest_r2 = (Int)sr_Err(canonical->sres);
1531 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1532 } else {
1533 gst->guest_r2 = sr_Res(canonical->sres);
1534 gst->guest_r3 = sr_ResEx(canonical->sres);
1535 gst->guest_r7 = (Int)sr_Err(canonical->sres);
1536 }
1537 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1538 OFFSET_mips64_r2, sizeof(UWord) );
1539 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1540 OFFSET_mips64_r3, sizeof(UWord) );
1541 VG_TRACK( post_reg_write, Vg_CoreSysCall, tid,
1542 OFFSET_mips64_r7, sizeof(UWord) );
1543
1544 # elif defined(VGP_x86_solaris)
1545 VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla;
1546 SysRes sres = canonical->sres;
1547 vg_assert(canonical->what == SsComplete);
1548
1549 if (sr_isError(sres)) {
1550 gst->guest_EAX = sr_Err(sres);
1551 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EAX,
1552 sizeof(UInt));
1553 LibVEX_GuestX86_put_eflag_c(1, gst);
1554 }
1555 else {
1556 gst->guest_EAX = sr_Res(sres);
1557 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EAX,
1558 sizeof(UInt));
1559 gst->guest_EDX = sr_ResHI(sres);
1560 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_x86_EDX,
1561 sizeof(UInt));
1562 LibVEX_GuestX86_put_eflag_c(0, gst);
1563 }
1564 /* Make CC_DEP1 and CC_DEP2 defined. This is inaccurate because it makes
1565 other eflags defined too (see README.solaris). */
1566 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestX86State,
1567 guest_CC_DEP1), sizeof(UInt));
1568 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestX86State,
1569 guest_CC_DEP2), sizeof(UInt));
1570
1571 # elif defined(VGP_amd64_solaris)
1572 VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla;
1573 SysRes sres = canonical->sres;
1574 vg_assert(canonical->what == SsComplete);
1575
1576 if (sr_isError(sres)) {
1577 gst->guest_RAX = sr_Err(sres);
1578 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RAX,
1579 sizeof(ULong));
1580 LibVEX_GuestAMD64_put_rflag_c(1, gst);
1581 }
1582 else {
1583 gst->guest_RAX = sr_Res(sres);
1584 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RAX,
1585 sizeof(ULong));
1586 gst->guest_RDX = sr_ResHI(sres);
1587 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, OFFSET_amd64_RDX,
1588 sizeof(ULong));
1589 LibVEX_GuestAMD64_put_rflag_c(0, gst);
1590 }
1591 /* Make CC_DEP1 and CC_DEP2 defined. This is inaccurate because it makes
1592 other eflags defined too (see README.solaris). */
1593 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestAMD64State,
1594 guest_CC_DEP1), sizeof(ULong));
1595 VG_TRACK(post_reg_write, Vg_CoreSysCall, tid, offsetof(VexGuestAMD64State,
1596 guest_CC_DEP2), sizeof(ULong));
1597
1598 # else
1599 # error "putSyscallStatusIntoGuestState: unknown arch"
1600 # endif
1601 }
1602
1603
1604 /* Tell me the offsets in the guest state of the syscall params, so
1605 that the scalar argument checkers don't have to have this info
1606 hardwired. */
1607
1608 static
getSyscallArgLayout(SyscallArgLayout * layout)1609 void getSyscallArgLayout ( /*OUT*/SyscallArgLayout* layout )
1610 {
1611 VG_(bzero_inline)(layout, sizeof(*layout));
1612
1613 #if defined(VGP_x86_linux)
1614 layout->o_sysno = OFFSET_x86_EAX;
1615 layout->o_arg1 = OFFSET_x86_EBX;
1616 layout->o_arg2 = OFFSET_x86_ECX;
1617 layout->o_arg3 = OFFSET_x86_EDX;
1618 layout->o_arg4 = OFFSET_x86_ESI;
1619 layout->o_arg5 = OFFSET_x86_EDI;
1620 layout->o_arg6 = OFFSET_x86_EBP;
1621 layout->uu_arg7 = -1; /* impossible value */
1622 layout->uu_arg8 = -1; /* impossible value */
1623
1624 #elif defined(VGP_amd64_linux)
1625 layout->o_sysno = OFFSET_amd64_RAX;
1626 layout->o_arg1 = OFFSET_amd64_RDI;
1627 layout->o_arg2 = OFFSET_amd64_RSI;
1628 layout->o_arg3 = OFFSET_amd64_RDX;
1629 layout->o_arg4 = OFFSET_amd64_R10;
1630 layout->o_arg5 = OFFSET_amd64_R8;
1631 layout->o_arg6 = OFFSET_amd64_R9;
1632 layout->uu_arg7 = -1; /* impossible value */
1633 layout->uu_arg8 = -1; /* impossible value */
1634
1635 #elif defined(VGP_ppc32_linux)
1636 layout->o_sysno = OFFSET_ppc32_GPR0;
1637 layout->o_arg1 = OFFSET_ppc32_GPR3;
1638 layout->o_arg2 = OFFSET_ppc32_GPR4;
1639 layout->o_arg3 = OFFSET_ppc32_GPR5;
1640 layout->o_arg4 = OFFSET_ppc32_GPR6;
1641 layout->o_arg5 = OFFSET_ppc32_GPR7;
1642 layout->o_arg6 = OFFSET_ppc32_GPR8;
1643 layout->uu_arg7 = -1; /* impossible value */
1644 layout->uu_arg8 = -1; /* impossible value */
1645
1646 #elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1647 layout->o_sysno = OFFSET_ppc64_GPR0;
1648 layout->o_arg1 = OFFSET_ppc64_GPR3;
1649 layout->o_arg2 = OFFSET_ppc64_GPR4;
1650 layout->o_arg3 = OFFSET_ppc64_GPR5;
1651 layout->o_arg4 = OFFSET_ppc64_GPR6;
1652 layout->o_arg5 = OFFSET_ppc64_GPR7;
1653 layout->o_arg6 = OFFSET_ppc64_GPR8;
1654 layout->uu_arg7 = -1; /* impossible value */
1655 layout->uu_arg8 = -1; /* impossible value */
1656
1657 #elif defined(VGP_x86_dragonfly)
1658 layout->o_sysno = OFFSET_x86_EAX;
1659 // syscall parameters are on stack in C convention
1660 layout->s_arg1 = sizeof(UWord) * 1;
1661 layout->s_arg2 = sizeof(UWord) * 2;
1662 layout->s_arg3 = sizeof(UWord) * 3;
1663 layout->s_arg4 = sizeof(UWord) * 4;
1664 layout->s_arg5 = sizeof(UWord) * 5;
1665 layout->s_arg6 = sizeof(UWord) * 6;
1666 layout->s_arg7 = sizeof(UWord) * 7;
1667 layout->s_arg8 = sizeof(UWord) * 8;
1668
1669 #elif defined(VGP_amd64_dragonfly)
1670 layout->o_sysno = OFFSET_amd64_RAX;
1671 layout->o_arg1 = OFFSET_amd64_RDI;
1672 layout->o_arg2 = OFFSET_amd64_RSI;
1673 layout->o_arg3 = OFFSET_amd64_RDX;
1674 layout->o_arg4 = OFFSET_amd64_R10;
1675 layout->o_arg5 = OFFSET_amd64_R8;
1676 layout->o_arg6 = OFFSET_amd64_R9;
1677 layout->s_arg7 = sizeof(UWord) * 1;
1678 layout->s_arg8 = sizeof(UWord) * 2;
1679
1680 #elif defined(VGP_arm_linux)
1681 layout->o_sysno = OFFSET_arm_R7;
1682 layout->o_arg1 = OFFSET_arm_R0;
1683 layout->o_arg2 = OFFSET_arm_R1;
1684 layout->o_arg3 = OFFSET_arm_R2;
1685 layout->o_arg4 = OFFSET_arm_R3;
1686 layout->o_arg5 = OFFSET_arm_R4;
1687 layout->o_arg6 = OFFSET_arm_R5;
1688 layout->uu_arg7 = -1; /* impossible value */
1689 layout->uu_arg8 = -1; /* impossible value */
1690
1691 #elif defined(VGP_arm64_linux)
1692 layout->o_sysno = OFFSET_arm64_X8;
1693 layout->o_arg1 = OFFSET_arm64_X0;
1694 layout->o_arg2 = OFFSET_arm64_X1;
1695 layout->o_arg3 = OFFSET_arm64_X2;
1696 layout->o_arg4 = OFFSET_arm64_X3;
1697 layout->o_arg5 = OFFSET_arm64_X4;
1698 layout->o_arg6 = OFFSET_arm64_X5;
1699 layout->uu_arg7 = -1; /* impossible value */
1700 layout->uu_arg8 = -1; /* impossible value */
1701
1702 #elif defined(VGP_mips32_linux)
1703 layout->o_sysno = OFFSET_mips32_r2;
1704 layout->o_arg1 = OFFSET_mips32_r4;
1705 layout->o_arg2 = OFFSET_mips32_r5;
1706 layout->o_arg3 = OFFSET_mips32_r6;
1707 layout->o_arg4 = OFFSET_mips32_r7;
1708 layout->s_arg5 = sizeof(UWord) * 4;
1709 layout->s_arg6 = sizeof(UWord) * 5;
1710 layout->s_arg7 = sizeof(UWord) * 6;
1711 layout->uu_arg8 = -1; /* impossible value */
1712
1713 #elif defined(VGP_mips64_linux)
1714 layout->o_sysno = OFFSET_mips64_r2;
1715 layout->o_arg1 = OFFSET_mips64_r4;
1716 layout->o_arg2 = OFFSET_mips64_r5;
1717 layout->o_arg3 = OFFSET_mips64_r6;
1718 layout->o_arg4 = OFFSET_mips64_r7;
1719 layout->o_arg5 = OFFSET_mips64_r8;
1720 layout->o_arg6 = OFFSET_mips64_r9;
1721 layout->uu_arg7 = -1; /* impossible value */
1722 layout->uu_arg8 = -1; /* impossible value */
1723
1724 #elif defined(VGP_x86_darwin)
1725 layout->o_sysno = OFFSET_x86_EAX;
1726 // syscall parameters are on stack in C convention
1727 layout->s_arg1 = sizeof(UWord) * 1;
1728 layout->s_arg2 = sizeof(UWord) * 2;
1729 layout->s_arg3 = sizeof(UWord) * 3;
1730 layout->s_arg4 = sizeof(UWord) * 4;
1731 layout->s_arg5 = sizeof(UWord) * 5;
1732 layout->s_arg6 = sizeof(UWord) * 6;
1733 layout->s_arg7 = sizeof(UWord) * 7;
1734 layout->s_arg8 = sizeof(UWord) * 8;
1735
1736 #elif defined(VGP_amd64_darwin)
1737 layout->o_sysno = OFFSET_amd64_RAX;
1738 layout->o_arg1 = OFFSET_amd64_RDI;
1739 layout->o_arg2 = OFFSET_amd64_RSI;
1740 layout->o_arg3 = OFFSET_amd64_RDX;
1741 layout->o_arg4 = OFFSET_amd64_RCX;
1742 layout->o_arg5 = OFFSET_amd64_R8;
1743 layout->o_arg6 = OFFSET_amd64_R9;
1744 layout->s_arg7 = sizeof(UWord) * 1;
1745 layout->s_arg8 = sizeof(UWord) * 2;
1746
1747 #elif defined(VGP_s390x_linux)
1748 layout->o_sysno = OFFSET_s390x_SYSNO;
1749 layout->o_arg1 = OFFSET_s390x_r2;
1750 layout->o_arg2 = OFFSET_s390x_r3;
1751 layout->o_arg3 = OFFSET_s390x_r4;
1752 layout->o_arg4 = OFFSET_s390x_r5;
1753 layout->o_arg5 = OFFSET_s390x_r6;
1754 layout->o_arg6 = OFFSET_s390x_r7;
1755 layout->uu_arg7 = -1; /* impossible value */
1756 layout->uu_arg8 = -1; /* impossible value */
1757
1758 #elif defined(VGP_x86_solaris)
1759 layout->o_sysno = OFFSET_x86_EAX;
1760 /* Syscall parameters are on the stack. */
1761 layout->s_arg1 = sizeof(UWord) * 1;
1762 layout->s_arg2 = sizeof(UWord) * 2;
1763 layout->s_arg3 = sizeof(UWord) * 3;
1764 layout->s_arg4 = sizeof(UWord) * 4;
1765 layout->s_arg5 = sizeof(UWord) * 5;
1766 layout->s_arg6 = sizeof(UWord) * 6;
1767 layout->s_arg7 = sizeof(UWord) * 7;
1768 layout->s_arg8 = sizeof(UWord) * 8;
1769
1770 #elif defined(VGP_amd64_solaris)
1771 layout->o_sysno = OFFSET_amd64_RAX;
1772 layout->o_arg1 = OFFSET_amd64_RDI;
1773 layout->o_arg2 = OFFSET_amd64_RSI;
1774 layout->o_arg3 = OFFSET_amd64_RDX;
1775 layout->o_arg4 = OFFSET_amd64_R10;
1776 layout->o_arg5 = OFFSET_amd64_R8;
1777 layout->o_arg6 = OFFSET_amd64_R9;
1778 layout->s_arg7 = sizeof(UWord) * 1;
1779 layout->s_arg8 = sizeof(UWord) * 2;
1780
1781 #else
1782 # error "getSyscallLayout: unknown arch"
1783 #endif
1784 }
1785
1786
1787 /* ---------------------------------------------------------------------
1788 The main driver logic
1789 ------------------------------------------------------------------ */
1790
1791 /* Finding the handlers for a given syscall, or faking up one
1792 when no handler is found. */
1793
1794 static
bad_before(ThreadId tid,SyscallArgLayout * layout,SyscallArgs * args,SyscallStatus * status,UWord * flags)1795 void bad_before ( ThreadId tid,
1796 SyscallArgLayout* layout,
1797 /*MOD*/SyscallArgs* args,
1798 /*OUT*/SyscallStatus* status,
1799 /*OUT*/UWord* flags )
1800 {
1801 VG_(dmsg)("WARNING: unhandled %s syscall: %s\n",
1802 VG_PLATFORM, VG_SYSNUM_STRING(args->sysno));
1803 if (VG_(clo_verbosity) > 1) {
1804 VG_(get_and_pp_StackTrace)(tid, VG_(clo_backtrace_size));
1805 }
1806 VG_(dmsg)("You may be able to write your own handler.\n");
1807 VG_(dmsg)("Read the file README_MISSING_SYSCALL_OR_IOCTL.\n");
1808 VG_(dmsg)("Nevertheless we consider this a bug. Please report\n");
1809 VG_(dmsg)("it at http://valgrind.org/support/bug_reports.html.\n");
1810
1811 SET_STATUS_Failure(VKI_ENOSYS);
1812
1813 # if defined(VGO_solaris)
1814 VG_(exit)(1);
1815 # endif
1816 }
1817
1818 static SyscallTableEntry bad_sys =
1819 { bad_before, NULL };
1820
get_syscall_entry(Int syscallno)1821 static const SyscallTableEntry* get_syscall_entry ( Int syscallno )
1822 {
1823 const SyscallTableEntry* sys = NULL;
1824
1825 # if defined(VGO_linux)
1826 sys = ML_(get_linux_syscall_entry)( syscallno );
1827
1828 # elif defined(VGO_dragonfly)
1829 if (syscallno >= 0 && syscallno < ML_(syscall_table_size) &&
1830 ML_(syscall_table)[syscallno].before != NULL)
1831 sys = &ML_(syscall_table)[syscallno];
1832
1833 # elif defined(VGO_darwin)
1834 Int idx = VG_DARWIN_SYSNO_INDEX(syscallno);
1835
1836 switch (VG_DARWIN_SYSNO_CLASS(syscallno)) {
1837 case VG_DARWIN_SYSCALL_CLASS_UNIX:
1838 if (idx >= 0 && idx < ML_(syscall_table_size) &&
1839 ML_(syscall_table)[idx].before != NULL)
1840 sys = &ML_(syscall_table)[idx];
1841 break;
1842 case VG_DARWIN_SYSCALL_CLASS_MACH:
1843 if (idx >= 0 && idx < ML_(mach_trap_table_size) &&
1844 ML_(mach_trap_table)[idx].before != NULL)
1845 sys = &ML_(mach_trap_table)[idx];
1846 break;
1847 case VG_DARWIN_SYSCALL_CLASS_MDEP:
1848 if (idx >= 0 && idx < ML_(mdep_trap_table_size) &&
1849 ML_(mdep_trap_table)[idx].before != NULL)
1850 sys = &ML_(mdep_trap_table)[idx];
1851 break;
1852 default:
1853 vg_assert(0);
1854 break;
1855 }
1856
1857 # elif defined(VGO_solaris)
1858 sys = ML_(get_solaris_syscall_entry)(syscallno);
1859
1860 # else
1861 # error Unknown OS
1862 # endif
1863
1864 return sys == NULL ? &bad_sys : sys;
1865 }
1866
1867
1868 /* Add and remove signals from mask so that we end up telling the
1869 kernel the state we actually want rather than what the client
1870 wants. */
VG_(sanitize_client_sigmask)1871 void VG_(sanitize_client_sigmask)(vki_sigset_t *mask)
1872 {
1873 VG_(sigdelset)(mask, VKI_SIGKILL);
1874 VG_(sigdelset)(mask, VKI_SIGSTOP);
1875 VG_(sigdelset)(mask, VG_SIGVGKILL); /* never block */
1876 }
1877
1878 typedef
1879 struct {
1880 SyscallArgs orig_args;
1881 SyscallArgs args;
1882 SyscallStatus status;
1883 UWord flags;
1884 }
1885 SyscallInfo;
1886
1887 SyscallInfo *syscallInfo;
1888
1889 /* The scheduler needs to be able to zero out these records after a
1890 fork, hence this is exported from m_syswrap. */
VG_(clear_syscallInfo)1891 void VG_(clear_syscallInfo) ( ThreadId tid )
1892 {
1893 vg_assert(syscallInfo);
1894 vg_assert(tid >= 0 && tid < VG_N_THREADS);
1895 VG_(memset)( & syscallInfo[tid], 0, sizeof( syscallInfo[tid] ));
1896 syscallInfo[tid].status.what = SsIdle;
1897 }
1898
VG_(is_in_syscall)1899 Bool VG_(is_in_syscall) ( ThreadId tid )
1900 {
1901 vg_assert(tid >= 0 && tid < VG_N_THREADS);
1902 return (syscallInfo[tid].status.what != SsIdle);
1903 }
1904
VG_(is_in_syscall_no)1905 Word VG_(is_in_syscall_no) (ThreadId tid )
1906 {
1907 vg_assert(tid >= 0 && tid < VG_N_THREADS);
1908 return syscallInfo[tid].orig_args.sysno;
1909 }
1910
ensure_initialised(void)1911 static void ensure_initialised ( void )
1912 {
1913 Int i;
1914 static Bool init_done = False;
1915 if (init_done)
1916 return;
1917 init_done = True;
1918
1919 syscallInfo = VG_(malloc)("scinfo", VG_N_THREADS * sizeof syscallInfo[0]);
1920
1921 for (i = 0; i < VG_N_THREADS; i++) {
1922 VG_(clear_syscallInfo)( i );
1923 }
1924 }
1925
1926 /* --- This is the main function of this file. --- */
1927
VG_(client_syscall)1928 void VG_(client_syscall) ( ThreadId tid, UInt trc )
1929 {
1930 Word sysno;
1931 ThreadState* tst;
1932 const SyscallTableEntry* ent;
1933 SyscallArgLayout layout;
1934 SyscallInfo* sci;
1935
1936 ensure_initialised();
1937
1938 vg_assert(VG_(is_valid_tid)(tid));
1939 vg_assert(tid >= 1 && tid < VG_N_THREADS);
1940 vg_assert(VG_(is_running_thread)(tid));
1941
1942 # if !defined(VGO_darwin)
1943 // Resync filtering is meaningless on non-Darwin targets.
1944 vg_assert(VG_(clo_resync_filter) == 0);
1945 # endif
1946
1947 tst = VG_(get_ThreadState)(tid);
1948
1949 /* BEGIN ensure root thread's stack is suitably mapped */
1950 /* In some rare circumstances, we may do the syscall without the
1951 bottom page of the stack being mapped, because the stack pointer
1952 was moved down just a few instructions before the syscall
1953 instruction, and there have been no memory references since
1954 then, that would cause a call to VG_(extend_stack) to have
1955 happened.
1956
1957 In native execution that's OK: the kernel automagically extends
1958 the stack's mapped area down to cover the stack pointer (or sp -
1959 redzone, really). In simulated normal execution that's OK too,
1960 since any signals we get from accessing below the mapped area of
1961 the (guest's) stack lead us to VG_(extend_stack), where we
1962 simulate the kernel's stack extension logic. But that leaves
1963 the problem of entering a syscall with the SP unmapped. Because
1964 the kernel doesn't know that the segment immediately above SP is
1965 supposed to be a grow-down segment, it causes the syscall to
1966 fail, and thereby causes a divergence between native behaviour
1967 (syscall succeeds) and simulated behaviour (syscall fails).
1968
1969 This is quite a rare failure mode. It has only been seen
1970 affecting calls to sys_readlink on amd64-linux, and even then it
1971 requires a certain code sequence around the syscall to trigger
1972 it. Here is one:
1973
1974 extern int my_readlink ( const char* path );
1975 asm(
1976 ".text\n"
1977 ".globl my_readlink\n"
1978 "my_readlink:\n"
1979 "\tsubq $0x1008,%rsp\n"
1980 "\tmovq %rdi,%rdi\n" // path is in rdi
1981 "\tmovq %rsp,%rsi\n" // &buf[0] -> rsi
1982 "\tmovl $0x1000,%edx\n" // sizeof(buf) in rdx
1983 "\tmovl $"__NR_READLINK",%eax\n" // syscall number
1984 "\tsyscall\n"
1985 "\taddq $0x1008,%rsp\n"
1986 "\tret\n"
1987 ".previous\n"
1988 );
1989
1990 For more details, see bug #156404
1991 (https://bugs.kde.org/show_bug.cgi?id=156404).
1992
1993 The fix is actually very simple. We simply need to call
1994 VG_(extend_stack) for this thread, handing it the lowest
1995 possible valid address for stack (sp - redzone), to ensure the
1996 pages all the way down to that address, are mapped. Because
1997 this is a potentially expensive and frequent operation, we
1998 do the following:
1999
2000 Only the main thread (tid=1) has a growdown stack. So
2001 ignore all others. It is conceivable, although highly unlikely,
2002 that the main thread exits, and later another thread is
2003 allocated tid=1, but that's harmless, I believe;
2004 VG_(extend_stack) will do nothing when applied to a non-root
2005 thread.
2006
2007 All this guff is of course Linux-specific. Hence the ifdef.
2008 */
2009 # if defined(VGO_linux)
2010 if (tid == 1/*ROOT THREAD*/) {
2011 Addr stackMin = VG_(get_SP)(tid) - VG_STACK_REDZONE_SZB;
2012
2013 /* The precise thing to do here would be to extend the stack only
2014 if the system call can be proven to access unmapped user stack
2015 memory. That is an enormous amount of work even if a proper
2016 spec of system calls was available.
2017
2018 In the case where the system call does not access user memory
2019 the stack pointer here can have any value. A legitimate testcase
2020 that exercises this is none/tests/s390x/stmg.c:
2021 The stack pointer happens to be in the reservation segment near
2022 the end of the addressable memory and there is no SkAnonC segment
2023 above.
2024
2025 So the approximation we're taking here is to extend the stack only
2026 if the client stack pointer does not look bogus. */
2027 if (VG_(am_addr_is_in_extensible_client_stack)(stackMin))
2028 VG_(extend_stack)( tid, stackMin );
2029 }
2030 # endif
2031 /* END ensure root thread's stack is suitably mapped */
2032
2033 /* First off, get the syscall args and number. This is a
2034 platform-dependent action. */
2035
2036 sci = & syscallInfo[tid];
2037 if (sci->status.what != SsIdle)
2038 VG_(memset)(sci, 0, sizeof *sci);
2039
2040 getSyscallArgsFromGuestState( &sci->orig_args, &tst->arch.vex, trc );
2041
2042 /* Copy .orig_args to .args. The pre-handler may modify .args, but
2043 we want to keep the originals too, just in case. */
2044 sci->args = sci->orig_args;
2045
2046 /* Save the syscall number in the thread state in case the syscall
2047 is interrupted by a signal. */
2048 sysno = sci->orig_args.sysno;
2049
2050 # if defined(VGO_dragonfly)
2051 tst->arch.vex.guest_SC_CLASS = sci->orig_args.klass;
2052 # endif
2053 /* It's sometimes useful, as a crude debugging hack, to get a
2054 stack trace at each (or selected) syscalls. */
2055 if (0 && sysno == __NR_ioctl) {
2056 VG_(umsg)("\nioctl:\n");
2057 VG_(get_and_pp_StackTrace)(tid, 10);
2058 VG_(umsg)("\n");
2059 }
2060
2061 # if defined(VGO_darwin)
2062 /* Record syscall class. But why? Because the syscall might be
2063 interrupted by a signal, and in the signal handler (which will
2064 be m_signals.async_signalhandler) we will need to build a SysRes
2065 reflecting the syscall return result. In order to do that we
2066 need to know the syscall class. Hence stash it in the guest
2067 state of this thread. This madness is not needed on Linux
2068 because it only has a single syscall return convention and so
2069 there is no ambiguity involved in converting the post-signal
2070 machine state into a SysRes. */
2071 tst->arch.vex.guest_SC_CLASS = VG_DARWIN_SYSNO_CLASS(sysno);
2072 # endif
2073
2074 /* The default what-to-do-next thing is hand the syscall to the
2075 kernel, so we pre-set that here. Set .sres to something
2076 harmless looking (is irrelevant because .what is not
2077 SsComplete.) */
2078 sci->status.what = SsHandToKernel;
2079 sci->status.sres = VG_(mk_SysRes_Error)(0);
2080 sci->flags = 0;
2081
2082 /* Fetch the syscall's handlers. If no handlers exist for this
2083 syscall, we are given dummy handlers which force an immediate
2084 return with ENOSYS. */
2085 ent = get_syscall_entry(sysno);
2086
2087 /* Fetch the layout information, which tells us where in the guest
2088 state the syscall args reside. This is a platform-dependent
2089 action. This info is needed so that the scalar syscall argument
2090 checks (PRE_REG_READ calls) know which bits of the guest state
2091 they need to inspect. */
2092 getSyscallArgLayout( &layout );
2093
2094 /* Make sure the tmp signal mask matches the real signal mask;
2095 sigsuspend may change this. */
2096 vg_assert(VG_(iseqsigset)(&tst->sig_mask, &tst->tmp_sig_mask));
2097
2098 /* Right, we're finally ready to Party. Call the pre-handler and
2099 see what we get back. At this point:
2100
2101 sci->status.what is Unset (we don't know yet).
2102 sci->orig_args contains the original args.
2103 sci->args is the same as sci->orig_args.
2104 sci->flags is zero.
2105 */
2106
2107 PRINT("SYSCALL[%d,%u](%s) ",
2108 VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno));
2109
2110 /* Do any pre-syscall actions */
2111 if (VG_(needs).syscall_wrapper) {
2112 UWord tmpv[8];
2113 tmpv[0] = sci->orig_args.arg1;
2114 tmpv[1] = sci->orig_args.arg2;
2115 tmpv[2] = sci->orig_args.arg3;
2116 tmpv[3] = sci->orig_args.arg4;
2117 tmpv[4] = sci->orig_args.arg5;
2118 tmpv[5] = sci->orig_args.arg6;
2119 tmpv[6] = sci->orig_args.arg7;
2120 tmpv[7] = sci->orig_args.arg8;
2121 VG_TDICT_CALL(tool_pre_syscall, tid, sysno,
2122 &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]));
2123 }
2124
2125 vg_assert(ent);
2126 vg_assert(ent->before);
2127 (ent->before)( tid,
2128 &layout,
2129 &sci->args, &sci->status, &sci->flags );
2130
2131 /* If needed, gdbserver will report syscall entry to GDB */
2132 VG_(gdbserver_report_syscall)(True, sysno, tid);
2133
2134 /* The pre-handler may have modified:
2135 sci->args
2136 sci->status
2137 sci->flags
2138 All else remains unchanged.
2139 Although the args may be modified, pre handlers are not allowed
2140 to change the syscall number.
2141 */
2142 /* Now we proceed according to what the pre-handler decided. */
2143 vg_assert(sci->status.what == SsHandToKernel
2144 || sci->status.what == SsComplete);
2145 vg_assert(sci->args.sysno == sci->orig_args.sysno);
2146
2147 if (sci->status.what == SsComplete && !sr_isError(sci->status.sres)) {
2148 /* The pre-handler completed the syscall itself, declaring
2149 success. */
2150 if (sci->flags & SfNoWriteResult) {
2151 PRINT(" --> [pre-success] NoWriteResult");
2152 } else {
2153 PRINT(" --> [pre-success] %s", VG_(sr_as_string)(sci->status.sres));
2154 }
2155 /* In this case the allowable flags are to ask for a signal-poll
2156 and/or a yield after the call. Changing the args isn't
2157 allowed. */
2158 vg_assert(0 == (sci->flags
2159 & ~(SfPollAfter | SfYieldAfter | SfNoWriteResult)));
2160 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
2161 }
2162
2163 else
2164 if (sci->status.what == SsComplete && sr_isError(sci->status.sres)) {
2165 /* The pre-handler decided to fail syscall itself. */
2166 PRINT(" --> [pre-fail] %s", VG_(sr_as_string)(sci->status.sres));
2167 /* In this case, the pre-handler is also allowed to ask for the
2168 post-handler to be run anyway. Changing the args is not
2169 allowed. */
2170 vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter)));
2171 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
2172 }
2173
2174 else
2175 if (sci->status.what != SsHandToKernel) {
2176 /* huh?! */
2177 vg_assert(0);
2178 }
2179
2180 else /* (sci->status.what == HandToKernel) */ {
2181 /* Ok, this is the usual case -- and the complicated one. There
2182 are two subcases: sync and async. async is the general case
2183 and is to be used when there is any possibility that the
2184 syscall might block [a fact that the pre-handler must tell us
2185 via the sci->flags field.] Because the tidying-away /
2186 context-switch overhead of the async case could be large, if
2187 we are sure that the syscall will not block, we fast-track it
2188 by doing it directly in this thread, which is a lot
2189 simpler. */
2190
2191 /* Check that the given flags are allowable: MayBlock, PollAfter
2192 and PostOnFail are ok. */
2193 vg_assert(0 == (sci->flags & ~(SfMayBlock | SfPostOnFail | SfPollAfter)));
2194
2195 if (sci->flags & SfMayBlock) {
2196
2197 /* Syscall may block, so run it asynchronously */
2198 vki_sigset_t mask;
2199
2200 PRINT(" --> [async] ... \n");
2201
2202 mask = tst->sig_mask;
2203 VG_(sanitize_client_sigmask)(&mask);
2204
2205 /* Gack. More impedance matching. Copy the possibly
2206 modified syscall args back into the guest state. */
2207 /* JRS 2009-Mar-16: if the syscall args are possibly modified,
2208 then this assertion is senseless:
2209 vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args));
2210 The case that exposed it was sys_posix_spawn on Darwin,
2211 which heavily modifies its arguments but then lets the call
2212 go through anyway, with SfToBlock set, hence we end up here. */
2213 putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex );
2214
2215 /* SfNoWriteResult flag is invalid for blocking signals because
2216 do_syscall_for_client() directly modifies the guest state. */
2217 vg_assert(!(sci->flags & SfNoWriteResult));
2218
2219 /* Drop the bigLock */
2220 VG_(release_BigLock)(tid, VgTs_WaitSys, "VG_(client_syscall)[async]");
2221 /* Urr. We're now in a race against other threads trying to
2222 acquire the bigLock. I guess that doesn't matter provided
2223 that do_syscall_for_client only touches thread-local
2224 state. */
2225
2226 /* Do the call, which operates directly on the guest state,
2227 not on our abstracted copies of the args/result. */
2228 do_syscall_for_client(sysno, tst, &mask);
2229
2230 /* do_syscall_for_client may not return if the syscall was
2231 interrupted by a signal. In that case, flow of control is
2232 first to m_signals.async_sighandler, which calls
2233 VG_(fixup_guest_state_after_syscall_interrupted), which
2234 fixes up the guest state, and possibly calls
2235 VG_(post_syscall). Once that's done, control drops back
2236 to the scheduler. */
2237
2238 /* Darwin: do_syscall_for_client may not return if the
2239 syscall was workq_ops(WQOPS_THREAD_RETURN) and the kernel
2240 responded by starting the thread at wqthread_hijack(reuse=1)
2241 (to run another workqueue item). In that case, wqthread_hijack
2242 calls ML_(wqthread_continue), which is similar to
2243 VG_(fixup_guest_state_after_syscall_interrupted). */
2244
2245 /* Reacquire the lock */
2246 VG_(acquire_BigLock)(tid, "VG_(client_syscall)[async]");
2247
2248 /* Even more impedance matching. Extract the syscall status
2249 from the guest state. */
2250 getSyscallStatusFromGuestState( &sci->status, &tst->arch.vex );
2251 vg_assert(sci->status.what == SsComplete);
2252
2253 /* Be decorative, if required. */
2254 if (VG_(clo_trace_syscalls)) {
2255 PRINT("SYSCALL[%d,%u](%s) ... [async] --> %s",
2256 VG_(getpid)(), tid, VG_SYSNUM_STRING(sysno),
2257 VG_(sr_as_string)(sci->status.sres));
2258 }
2259
2260 } else {
2261
2262 /* run the syscall directly */
2263 /* The pre-handler may have modified the syscall args, but
2264 since we're passing values in ->args directly to the
2265 kernel, there's no point in flushing them back to the
2266 guest state. Indeed doing so could be construed as
2267 incorrect. */
2268 SysRes sres
2269 = VG_(do_syscall)(sysno, sci->args.arg1, sci->args.arg2,
2270 sci->args.arg3, sci->args.arg4,
2271 sci->args.arg5, sci->args.arg6,
2272 sci->args.arg7, sci->args.arg8 );
2273 sci->status = convert_SysRes_to_SyscallStatus(sres);
2274
2275 /* Be decorative, if required. */
2276 if (VG_(clo_trace_syscalls)) {
2277 PRINT("[sync] --> %s", VG_(sr_as_string)(sci->status.sres));
2278 }
2279 }
2280 }
2281
2282 vg_assert(sci->status.what == SsComplete);
2283
2284 vg_assert(VG_(is_running_thread)(tid));
2285
2286 /* Dump the syscall result back in the guest state. This is
2287 a platform-specific action. */
2288 if (!(sci->flags & SfNoWriteResult))
2289 putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex );
2290
2291 /* If needed, gdbserver will report syscall return to GDB */
2292 VG_(gdbserver_report_syscall)(False, sysno, tid);
2293
2294 /* Situation now:
2295 - the guest state is now correctly modified following the syscall
2296 - modified args, original args and syscall status are still
2297 available in the syscallInfo[] entry for this syscall.
2298
2299 Now go on to do the post-syscall actions (read on down ..)
2300 */
2301 PRINT(" ");
2302 VG_(post_syscall)(tid);
2303 PRINT("\n");
2304 }
2305
2306
2307 /* Perform post syscall actions. The expected state on entry is
2308 precisely as at the end of VG_(client_syscall), that is:
2309
2310 - guest state up to date following the syscall
2311 - modified args, original args and syscall status are still
2312 available in the syscallInfo[] entry for this syscall.
2313 - syscall status matches what's in the guest state.
2314
2315 There are two ways to get here: the normal way -- being called by
2316 VG_(client_syscall), and the unusual way, from
2317 VG_(fixup_guest_state_after_syscall_interrupted).
2318 Darwin: there's a third way, ML_(wqthread_continue).
2319 */
VG_(post_syscall)2320 void VG_(post_syscall) (ThreadId tid)
2321 {
2322 SyscallInfo* sci;
2323 const SyscallTableEntry* ent;
2324 SyscallStatus test_status;
2325 ThreadState* tst;
2326 Word sysno;
2327
2328 /* Preliminaries */
2329 vg_assert(VG_(is_valid_tid)(tid));
2330 vg_assert(tid >= 1 && tid < VG_N_THREADS);
2331 vg_assert(VG_(is_running_thread)(tid));
2332
2333 tst = VG_(get_ThreadState)(tid);
2334 sci = & syscallInfo[tid];
2335
2336 /* m_signals.sigvgkill_handler might call here even when not in
2337 a syscall. */
2338 if (sci->status.what == SsIdle || sci->status.what == SsHandToKernel) {
2339 sci->status.what = SsIdle;
2340 return;
2341 }
2342
2343 /* Validate current syscallInfo entry. In particular we require
2344 that the current .status matches what's actually in the guest
2345 state. At least in the normal case where we have actually
2346 previously written the result into the guest state. */
2347 vg_assert(sci->status.what == SsComplete);
2348
2349 /* Get the system call number. Because the pre-handler isn't
2350 allowed to mess with it, it should be the same for both the
2351 original and potentially-modified args. */
2352 vg_assert(sci->args.sysno == sci->orig_args.sysno);
2353 sysno = sci->args.sysno;
2354
2355 getSyscallStatusFromGuestState( &test_status, &tst->arch.vex );
2356 if (!(sci->flags & SfNoWriteResult))
2357 vg_assert(eq_SyscallStatus( sysno, &sci->status, &test_status ));
2358 /* Failure of the above assertion on Darwin can indicate a problem
2359 in the syscall wrappers that pre-fail or pre-succeed the
2360 syscall, by calling SET_STATUS_Success or SET_STATUS_Failure,
2361 when they really should call SET_STATUS_from_SysRes. The former
2362 create a UNIX-class syscall result on Darwin, which may not be
2363 correct for the syscall; if that's the case then this assertion
2364 fires. See PRE(thread_fast_set_cthread_self) for an example. On
2365 non-Darwin platforms this assertion is should never fail, and this
2366 comment is completely irrelevant. */
2367 /* Ok, looks sane */
2368
2369 /* pre: status == Complete (asserted above) */
2370 /* Consider either success or failure. Now run the post handler if:
2371 - it exists, and
2372 - Success or (Failure and PostOnFail is set)
2373 */
2374 ent = get_syscall_entry(sysno);
2375 if (ent->after
2376 && ((!sr_isError(sci->status.sres))
2377 || (sr_isError(sci->status.sres)
2378 && (sci->flags & SfPostOnFail) ))) {
2379
2380 (ent->after)( tid, &sci->args, &sci->status );
2381 }
2382
2383 /* Because the post handler might have changed the status (eg, the
2384 post-handler for sys_open can change the result from success to
2385 failure if the kernel supplied a fd that it doesn't like), once
2386 again dump the syscall result back in the guest state.*/
2387 if (!(sci->flags & SfNoWriteResult))
2388 putSyscallStatusIntoGuestState( tid, &sci->status, &tst->arch.vex );
2389
2390 /* Do any post-syscall actions required by the tool. */
2391 if (VG_(needs).syscall_wrapper) {
2392 UWord tmpv[8];
2393 tmpv[0] = sci->orig_args.arg1;
2394 tmpv[1] = sci->orig_args.arg2;
2395 tmpv[2] = sci->orig_args.arg3;
2396 tmpv[3] = sci->orig_args.arg4;
2397 tmpv[4] = sci->orig_args.arg5;
2398 tmpv[5] = sci->orig_args.arg6;
2399 tmpv[6] = sci->orig_args.arg7;
2400 tmpv[7] = sci->orig_args.arg8;
2401 VG_TDICT_CALL(tool_post_syscall, tid,
2402 sysno,
2403 &tmpv[0], sizeof(tmpv)/sizeof(tmpv[0]),
2404 sci->status.sres);
2405 }
2406
2407 /* The syscall is done. */
2408 vg_assert(sci->status.what == SsComplete);
2409 sci->status.what = SsIdle;
2410
2411 /* The pre/post wrappers may have concluded that pending signals
2412 might have been created, and will have set SfPollAfter to
2413 request a poll for them once the syscall is done. */
2414 if (sci->flags & SfPollAfter)
2415 VG_(poll_signals)(tid);
2416
2417 /* Similarly, the wrappers might have asked for a yield
2418 afterwards. */
2419 if (sci->flags & SfYieldAfter)
2420 VG_(vg_yield)();
2421 }
2422
2423
2424 /* ---------------------------------------------------------------------
2425 Dealing with syscalls which get interrupted by a signal:
2426 VG_(fixup_guest_state_after_syscall_interrupted)
2427 ------------------------------------------------------------------ */
2428
2429 /* Syscalls done on behalf of the client are finally handed off to the
2430 kernel in VG_(client_syscall) above, either by calling
2431 do_syscall_for_client (the async case), or by calling
2432 VG_(do_syscall6) (the sync case).
2433
2434 If the syscall is not interrupted by a signal (it may block and
2435 later unblock, but that's irrelevant here) then those functions
2436 eventually return and so control is passed to VG_(post_syscall).
2437 NB: not sure if the sync case can actually get interrupted, as it
2438 operates with all signals masked.
2439
2440 However, the syscall may get interrupted by an async-signal. In
2441 that case do_syscall_for_client/VG_(do_syscall6) do not
2442 return. Instead we wind up in m_signals.async_sighandler. We need
2443 to fix up the guest state to make it look like the syscall was
2444 interrupted for guest. So async_sighandler calls here, and this
2445 does the fixup. Note that from here we wind up calling
2446 VG_(post_syscall) too.
2447 */
2448
2449
2450 /* These are addresses within ML_(do_syscall_for_client_WRK). See
2451 syscall-$PLAT.S for details.
2452 */
2453 #if defined(VGO_linux) || defined(VGO_dragonfly)
2454 extern const Addr ML_(blksys_setup);
2455 extern const Addr ML_(blksys_restart);
2456 extern const Addr ML_(blksys_complete);
2457 extern const Addr ML_(blksys_committed);
2458 extern const Addr ML_(blksys_finished);
2459 #elif defined(VGO_darwin)
2460 /* Darwin requires extra uglyness */
2461 extern const Addr ML_(blksys_setup_MACH);
2462 extern const Addr ML_(blksys_restart_MACH);
2463 extern const Addr ML_(blksys_complete_MACH);
2464 extern const Addr ML_(blksys_committed_MACH);
2465 extern const Addr ML_(blksys_finished_MACH);
2466 extern const Addr ML_(blksys_setup_MDEP);
2467 extern const Addr ML_(blksys_restart_MDEP);
2468 extern const Addr ML_(blksys_complete_MDEP);
2469 extern const Addr ML_(blksys_committed_MDEP);
2470 extern const Addr ML_(blksys_finished_MDEP);
2471 extern const Addr ML_(blksys_setup_UNIX);
2472 extern const Addr ML_(blksys_restart_UNIX);
2473 extern const Addr ML_(blksys_complete_UNIX);
2474 extern const Addr ML_(blksys_committed_UNIX);
2475 extern const Addr ML_(blksys_finished_UNIX);
2476 #elif defined(VGO_solaris)
2477 extern const Addr ML_(blksys_setup);
2478 extern const Addr ML_(blksys_complete);
2479 extern const Addr ML_(blksys_committed);
2480 extern const Addr ML_(blksys_finished);
2481 extern const Addr ML_(blksys_setup_DRET);
2482 extern const Addr ML_(blksys_complete_DRET);
2483 extern const Addr ML_(blksys_committed_DRET);
2484 extern const Addr ML_(blksys_finished_DRET);
2485 #else
2486 # error "Unknown OS"
2487 #endif
2488
2489
2490 /* Back up guest state to restart a system call. */
2491
ML_(fixup_guest_state_to_restart_syscall)2492 void ML_(fixup_guest_state_to_restart_syscall) ( ThreadArchState* arch )
2493 {
2494 #if defined(VGP_x86_linux)
2495 arch->vex.guest_EIP -= 2; // sizeof(int $0x80)
2496
2497 /* Make sure our caller is actually sane, and we're really backing
2498 back over a syscall.
2499
2500 int $0x80 == CD 80
2501 */
2502 {
2503 UChar *p = (UChar *)arch->vex.guest_EIP;
2504
2505 if (p[0] != 0xcd || p[1] != 0x80)
2506 VG_(message)(Vg_DebugMsg,
2507 "?! restarting over syscall at %#x %02x %02x\n",
2508 arch->vex.guest_EIP, p[0], p[1]);
2509
2510 vg_assert(p[0] == 0xcd && p[1] == 0x80);
2511 }
2512
2513 #elif defined(VGP_amd64_linux)
2514 arch->vex.guest_RIP -= 2; // sizeof(syscall)
2515
2516 /* Make sure our caller is actually sane, and we're really backing
2517 back over a syscall.
2518
2519 syscall == 0F 05
2520 */
2521 {
2522 UChar *p = (UChar *)arch->vex.guest_RIP;
2523
2524 if (p[0] != 0x0F || p[1] != 0x05)
2525 VG_(message)(Vg_DebugMsg,
2526 "?! restarting over syscall at %#llx %02x %02x\n",
2527 arch->vex.guest_RIP, p[0], p[1]);
2528
2529 vg_assert(p[0] == 0x0F && p[1] == 0x05);
2530 }
2531
2532 #elif defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux)
2533 arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr)
2534
2535 /* Make sure our caller is actually sane, and we're really backing
2536 back over a syscall.
2537
2538 sc == 44 00 00 02
2539 */
2540 {
2541 UChar *p = (UChar *)arch->vex.guest_CIA;
2542
2543 if (p[0] != 0x44 || p[1] != 0x0 || p[2] != 0x0 || p[3] != 0x02)
2544 VG_(message)(Vg_DebugMsg,
2545 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2546 (ULong)arch->vex.guest_CIA, p[0], p[1], p[2], p[3]);
2547
2548 vg_assert(p[0] == 0x44 && p[1] == 0x0 && p[2] == 0x0 && p[3] == 0x2);
2549 }
2550
2551 #elif defined(VGP_ppc64le_linux)
2552 arch->vex.guest_CIA -= 4; // sizeof(ppc32 instr)
2553
2554 /* Make sure our caller is actually sane, and we're really backing
2555 back over a syscall.
2556
2557 sc == 44 00 00 02
2558 */
2559 {
2560 UChar *p = (UChar *)arch->vex.guest_CIA;
2561
2562 if (p[3] != 0x44 || p[2] != 0x0 || p[1] != 0x0 || p[0] != 0x02)
2563 VG_(message)(Vg_DebugMsg,
2564 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2565 arch->vex.guest_CIA, p[3], p[2], p[1], p[0]);
2566
2567 vg_assert(p[3] == 0x44 && p[2] == 0x0 && p[1] == 0x0 && p[0] == 0x2);
2568 }
2569
2570 #elif defined(VGP_arm_linux)
2571 if (arch->vex.guest_R15T & 1) {
2572 // Thumb mode. SVC is a encoded as
2573 // 1101 1111 imm8
2574 // where imm8 is the SVC number, and we only accept 0.
2575 arch->vex.guest_R15T -= 2; // sizeof(thumb 16 bit insn)
2576 UChar* p = (UChar*)(arch->vex.guest_R15T - 1);
2577 Bool valid = p[0] == 0 && p[1] == 0xDF;
2578 if (!valid) {
2579 VG_(message)(Vg_DebugMsg,
2580 "?! restarting over (Thumb) syscall that is not syscall "
2581 "at %#x %02x %02x\n",
2582 arch->vex.guest_R15T - 1, p[0], p[1]);
2583 }
2584 vg_assert(valid);
2585 // FIXME: NOTE, this really isn't right. We need to back up
2586 // ITSTATE to what it was before the SVC instruction, but we
2587 // don't know what it was. At least assert that it is now
2588 // zero, because if it is nonzero then it must also have
2589 // been nonzero for the SVC itself, which means it was
2590 // conditional. Urk.
2591 vg_assert(arch->vex.guest_ITSTATE == 0);
2592 } else {
2593 // ARM mode. SVC is encoded as
2594 // cond 1111 imm24
2595 // where imm24 is the SVC number, and we only accept 0.
2596 arch->vex.guest_R15T -= 4; // sizeof(arm instr)
2597 UChar* p = (UChar*)arch->vex.guest_R15T;
2598 Bool valid = p[0] == 0 && p[1] == 0 && p[2] == 0
2599 && (p[3] & 0xF) == 0xF;
2600 if (!valid) {
2601 VG_(message)(Vg_DebugMsg,
2602 "?! restarting over (ARM) syscall that is not syscall "
2603 "at %#x %02x %02x %02x %02x\n",
2604 arch->vex.guest_R15T, p[0], p[1], p[2], p[3]);
2605 }
2606 vg_assert(valid);
2607 }
2608
2609 #elif defined(VGP_arm64_linux)
2610 arch->vex.guest_PC -= 4; // sizeof(arm64 instr)
2611
2612 /* Make sure our caller is actually sane, and we're really backing
2613 back over a syscall.
2614
2615 svc #0 == d4 00 00 01
2616 */
2617 {
2618 UChar *p = (UChar *)arch->vex.guest_PC;
2619
2620 if (p[0] != 0x01 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0xD4)
2621 VG_(message)(
2622 Vg_DebugMsg,
2623 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2624 arch->vex.guest_PC, p[0], p[1], p[2], p[3]
2625 );
2626
2627 vg_assert(p[0] == 0x01 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0xD4);
2628 }
2629
2630 #elif defined(VGP_x86_dragonfly)
2631 /* XXX: we support different syscall methods. */
2632 arch->vex.guest_EIP -= 2; // sizeof(int $0x80)
2633
2634 /* Make sure our caller is actually sane, and we're really backing
2635 back over a syscall.
2636
2637 int $0x80 == CD 80
2638 */
2639 {
2640 UChar *p = (UChar *)arch->vex.guest_EIP;
2641
2642 if (p[0] != 0xcd || p[1] != 0x80)
2643 VG_(message)(Vg_DebugMsg,
2644 "?! restarting over syscall at %#x %02x %02x\n",
2645 arch->vex.guest_EIP, p[0], p[1]);
2646
2647 vg_assert(p[0] == 0xcd && p[1] == 0x80);
2648 }
2649
2650 #elif defined(VGP_amd64_dragonfly)
2651 /* XXX: we support different syscall methods. */
2652 arch->vex.guest_RIP -= 2; // sizeof(syscall)
2653
2654 /* Make sure our caller is actually sane, and we're really backing
2655 back over a syscall.
2656
2657 syscall == 0F 05
2658 */
2659 {
2660 UChar *p = (UChar *)arch->vex.guest_RIP;
2661
2662 if (p[0] != 0x0F || p[1] != 0x05)
2663 VG_(message)(Vg_DebugMsg,
2664 "?! restarting over syscall at %#llx %02x %02x\n",
2665 arch->vex.guest_RIP, p[0], p[1]);
2666
2667 vg_assert(p[0] == 0x0F && p[1] == 0x05);
2668 }
2669
2670 #elif defined(VGP_x86_darwin)
2671 arch->vex.guest_EIP = arch->vex.guest_IP_AT_SYSCALL;
2672
2673 /* Make sure our caller is actually sane, and we're really backing
2674 back over a syscall.
2675
2676 int $0x80 == CD 80 // Used to communicate with BSD syscalls
2677 int $0x81 == CD 81 // Used to communicate with Mach traps
2678 int $0x82 == CD 82 // Used to communicate with "thread" ?
2679 sysenter == 0F 34 // Used to communicate with Unix syscalls
2680 */
2681 {
2682 UChar *p = (UChar *)arch->vex.guest_EIP;
2683 Bool ok = (p[0] == 0xCD && p[1] == 0x80)
2684 || (p[0] == 0xCD && p[1] == 0x81)
2685 || (p[0] == 0xCD && p[1] == 0x82)
2686 || (p[0] == 0x0F && p[1] == 0x34);
2687 if (!ok)
2688 VG_(message)(Vg_DebugMsg,
2689 "?! restarting over syscall at %#x %02x %02x\n",
2690 arch->vex.guest_EIP, p[0], p[1]);
2691 vg_assert(ok);
2692 }
2693
2694 #elif defined(VGP_amd64_darwin)
2695 arch->vex.guest_RIP = arch->vex.guest_IP_AT_SYSCALL;
2696
2697 /* Make sure our caller is actually sane, and we're really backing
2698 back over a syscall.
2699
2700 syscall == 0F 05
2701 */
2702 {
2703 UChar *p = (UChar *)arch->vex.guest_RIP;
2704
2705 Bool ok = (p[0] == 0x0F && p[1] == 0x05);
2706 if (!ok)
2707 VG_(message)(Vg_DebugMsg,
2708 "?! restarting over syscall at %#llx %02x %02x\n",
2709 arch->vex.guest_RIP, p[0], p[1]);
2710 vg_assert(ok);
2711 }
2712
2713 #elif defined(VGP_s390x_linux)
2714 arch->vex.guest_IA -= 2; // sizeof(syscall)
2715
2716 /* Make sure our caller is actually sane, and we're really backing
2717 back over a syscall.
2718
2719 syscall == 0A <num>
2720 */
2721 {
2722 UChar *p = (UChar *)arch->vex.guest_IA;
2723 if (p[0] != 0x0A)
2724 VG_(message)(Vg_DebugMsg,
2725 "?! restarting over syscall at %#llx %02x %02x\n",
2726 arch->vex.guest_IA, p[0], p[1]);
2727
2728 vg_assert(p[0] == 0x0A);
2729 }
2730
2731 #elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
2732
2733 arch->vex.guest_PC -= 4; // sizeof(mips instr)
2734
2735 /* Make sure our caller is actually sane, and we're really backing
2736 back over a syscall.
2737
2738 syscall == 00 00 00 0C
2739 big endian
2740 syscall == 0C 00 00 00
2741 */
2742 {
2743 UChar *p = (UChar *)(Addr)(arch->vex.guest_PC);
2744 # if defined (VG_LITTLEENDIAN)
2745 if (p[0] != 0x0c || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x00)
2746 VG_(message)(Vg_DebugMsg,
2747 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2748 (ULong)arch->vex.guest_PC, p[0], p[1], p[2], p[3]);
2749
2750 vg_assert(p[0] == 0x0c && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x00);
2751 # elif defined (VG_BIGENDIAN)
2752 if (p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x00 || p[3] != 0x0c)
2753 VG_(message)(Vg_DebugMsg,
2754 "?! restarting over syscall at %#llx %02x %02x %02x %02x\n",
2755 (ULong)arch->vex.guest_PC, p[0], p[1], p[2], p[3]);
2756
2757 vg_assert(p[0] == 0x00 && p[1] == 0x00 && p[2] == 0x00 && p[3] == 0x0c);
2758 # else
2759 # error "Unknown endianness"
2760 # endif
2761 }
2762
2763 #elif defined(VGP_x86_solaris)
2764 arch->vex.guest_EIP -= 2; // sizeof(int $0x91) or sizeof(syscall)
2765
2766 /* Make sure our caller is actually sane, and we're really backing
2767 back over a syscall.
2768
2769 int $0x91 == CD 91
2770 syscall == 0F 05
2771 sysenter == 0F 34
2772
2773 Handle also other syscall instructions because we also handle them in
2774 the scheduler.
2775 int $0x80 == CD 80
2776 int $0x81 == CD 81
2777 int $0x82 == CD 82
2778 */
2779 {
2780 UChar *p = (UChar *)arch->vex.guest_EIP;
2781
2782 Bool ok = (p[0] == 0xCD && p[1] == 0x91)
2783 || (p[0] == 0x0F && p[1] == 0x05)
2784 || (p[0] == 0x0F && p[1] == 0x34)
2785 || (p[0] == 0xCD && p[1] == 0x80)
2786 || (p[0] == 0xCD && p[1] == 0x81)
2787 || (p[0] == 0xCD && p[1] == 0x82);
2788 if (!ok)
2789 VG_(message)(Vg_DebugMsg,
2790 "?! restarting over syscall at %#x %02x %02x\n",
2791 arch->vex.guest_EIP, p[0], p[1]);
2792 vg_assert(ok);
2793 }
2794
2795 #elif defined(VGP_amd64_solaris)
2796 arch->vex.guest_RIP -= 2; // sizeof(syscall)
2797
2798 /* Make sure our caller is actually sane, and we're really backing
2799 back over a syscall.
2800
2801 syscall == 0F 05
2802 */
2803 {
2804 UChar *p = (UChar *)arch->vex.guest_RIP;
2805
2806 Bool ok = (p[0] == 0x0F && p[1] == 0x05);
2807 if (!ok)
2808 VG_(message)(Vg_DebugMsg,
2809 "?! restarting over syscall at %#llx %02x %02x\n",
2810 arch->vex.guest_RIP, p[0], p[1]);
2811 vg_assert(ok);
2812 }
2813
2814 #else
2815 # error "ML_(fixup_guest_state_to_restart_syscall): unknown plat"
2816 #endif
2817 }
2818
2819
2820 /*
2821 Fix up the guest state when a syscall is interrupted by a signal
2822 and so has been forced to return 'sysret'.
2823
2824 To do this, we determine the precise state of the syscall by
2825 looking at the (real) IP at the time the signal happened. The
2826 syscall sequence looks like:
2827
2828 1. unblock signals
2829 2. perform syscall
2830 3. save result to guest state (EAX, RAX, R3+CR0.SO, R0, V0)
2831 4. re-block signals
2832
2833 If a signal
2834 happens at Then Why?
2835 [1-2) restart nothing has happened (restart syscall)
2836 [2] restart syscall hasn't started, or kernel wants to restart
2837 [2-3) save syscall complete, but results not saved
2838 [3-4) syscall complete, results saved
2839
2840 Sometimes we never want to restart an interrupted syscall (because
2841 sigaction says not to), so we only restart if "restart" is True.
2842
2843 This will also call VG_(post_syscall) if the syscall has actually
2844 completed (either because it was interrupted, or because it
2845 actually finished). It will not call VG_(post_syscall) if the
2846 syscall is set up for restart, which means that the pre-wrapper may
2847 get called multiple times.
2848 */
2849
2850 void
VG_(fixup_guest_state_after_syscall_interrupted)2851 VG_(fixup_guest_state_after_syscall_interrupted)( ThreadId tid,
2852 Addr ip,
2853 SysRes sres,
2854 Bool restart,
2855 struct vki_ucontext *uc)
2856 {
2857 /* Note that we don't know the syscall number here, since (1) in
2858 general there's no reliable way to get hold of it short of
2859 stashing it in the guest state before the syscall, and (2) in
2860 any case we don't need to know it for the actions done by this
2861 routine.
2862
2863 Furthermore, 'sres' is only used in the case where the syscall
2864 is complete, but the result has not been committed to the guest
2865 state yet. In any other situation it will be meaningless and
2866 therefore ignored. */
2867
2868 ThreadState* tst;
2869 SyscallStatus canonical;
2870 ThreadArchState* th_regs;
2871 SyscallInfo* sci;
2872
2873 /* Compute some Booleans indicating which range we're in. */
2874 Bool outside_range,
2875 in_setup_to_restart, // [1,2) in the .S files
2876 at_restart, // [2] in the .S files
2877 in_complete_to_committed, // [3,4) in the .S files
2878 in_committed_to_finished; // [4,5) in the .S files
2879
2880 if (VG_(clo_trace_signals))
2881 VG_(message)( Vg_DebugMsg,
2882 "interrupted_syscall: tid=%u, ip=%#lx, "
2883 "restart=%s, sres.isErr=%s, sres.val=%" FMT_REGWORD "u\n",
2884 tid,
2885 ip,
2886 restart ? "True" : "False",
2887 sr_isError(sres) ? "True" : "False",
2888 sr_isError(sres) ? (RegWord)sr_Err(sres) :
2889 (RegWord)sr_Res(sres));
2890
2891 vg_assert(VG_(is_valid_tid)(tid));
2892 vg_assert(tid >= 1 && tid < VG_N_THREADS);
2893 vg_assert(VG_(is_running_thread)(tid));
2894
2895 tst = VG_(get_ThreadState)(tid);
2896 th_regs = &tst->arch;
2897 sci = & syscallInfo[tid];
2898
2899 # if defined(VGO_linux) || defined(VGO_dragonfly)
2900 outside_range
2901 = ip < ML_(blksys_setup) || ip >= ML_(blksys_finished);
2902 in_setup_to_restart
2903 = ip >= ML_(blksys_setup) && ip < ML_(blksys_restart);
2904 at_restart
2905 = ip == ML_(blksys_restart);
2906 in_complete_to_committed
2907 = ip >= ML_(blksys_complete) && ip < ML_(blksys_committed);
2908 in_committed_to_finished
2909 = ip >= ML_(blksys_committed) && ip < ML_(blksys_finished);
2910 # elif defined(VGO_darwin)
2911 outside_range
2912 = (ip < ML_(blksys_setup_MACH) || ip >= ML_(blksys_finished_MACH))
2913 && (ip < ML_(blksys_setup_MDEP) || ip >= ML_(blksys_finished_MDEP))
2914 && (ip < ML_(blksys_setup_UNIX) || ip >= ML_(blksys_finished_UNIX));
2915 in_setup_to_restart
2916 = (ip >= ML_(blksys_setup_MACH) && ip < ML_(blksys_restart_MACH))
2917 || (ip >= ML_(blksys_setup_MDEP) && ip < ML_(blksys_restart_MDEP))
2918 || (ip >= ML_(blksys_setup_UNIX) && ip < ML_(blksys_restart_UNIX));
2919 at_restart
2920 = (ip == ML_(blksys_restart_MACH))
2921 || (ip == ML_(blksys_restart_MDEP))
2922 || (ip == ML_(blksys_restart_UNIX));
2923 in_complete_to_committed
2924 = (ip >= ML_(blksys_complete_MACH) && ip < ML_(blksys_committed_MACH))
2925 || (ip >= ML_(blksys_complete_MDEP) && ip < ML_(blksys_committed_MDEP))
2926 || (ip >= ML_(blksys_complete_UNIX) && ip < ML_(blksys_committed_UNIX));
2927 in_committed_to_finished
2928 = (ip >= ML_(blksys_committed_MACH) && ip < ML_(blksys_finished_MACH))
2929 || (ip >= ML_(blksys_committed_MDEP) && ip < ML_(blksys_finished_MDEP))
2930 || (ip >= ML_(blksys_committed_UNIX) && ip < ML_(blksys_finished_UNIX));
2931 /* Wasn't that just So Much Fun? Does your head hurt yet? Mine does. */
2932 # elif defined(VGO_solaris)
2933 /* The solaris port is never outside the range. */
2934 outside_range = False;
2935 /* The Solaris kernel never restarts syscalls directly! */
2936 at_restart = False;
2937 if (tst->os_state.in_door_return) {
2938 vg_assert(ip >= ML_(blksys_setup_DRET)
2939 && ip < ML_(blksys_finished_DRET));
2940
2941 in_setup_to_restart
2942 = ip >= ML_(blksys_setup_DRET) && ip < ML_(blksys_complete_DRET);
2943 in_complete_to_committed
2944 = ip >= ML_(blksys_complete_DRET) && ip < ML_(blksys_committed_DRET);
2945 in_committed_to_finished
2946 = ip >= ML_(blksys_committed_DRET) && ip < ML_(blksys_finished_DRET);
2947 }
2948 else {
2949 vg_assert(ip >= ML_(blksys_setup) && ip < ML_(blksys_finished));
2950
2951 in_setup_to_restart
2952 = ip >= ML_(blksys_setup) && ip < ML_(blksys_complete);
2953 in_complete_to_committed
2954 = ip >= ML_(blksys_complete) && ip < ML_(blksys_committed);
2955 in_committed_to_finished
2956 = ip >= ML_(blksys_committed) && ip < ML_(blksys_finished);
2957 }
2958 # else
2959 # error "Unknown OS"
2960 # endif
2961
2962 /* Figure out what the state of the syscall was by examining the
2963 (real) IP at the time of the signal, and act accordingly. */
2964 if (outside_range) {
2965 if (VG_(clo_trace_signals))
2966 VG_(message)( Vg_DebugMsg,
2967 " not in syscall at all: hmm, very suspicious\n" );
2968 /* Looks like we weren't in a syscall at all. Hmm. */
2969 vg_assert(sci->status.what != SsIdle);
2970 return;
2971 }
2972
2973 /* We should not be here unless this thread had first started up
2974 the machinery for a syscall by calling VG_(client_syscall).
2975 Hence: */
2976 vg_assert(sci->status.what != SsIdle);
2977
2978 /* now, do one of four fixup actions, depending on where the IP has
2979 got to. */
2980
2981 if (in_setup_to_restart) {
2982 /* syscall hasn't even started; go around again */
2983 if (VG_(clo_trace_signals))
2984 VG_(message)( Vg_DebugMsg, " not started: restarting\n");
2985 vg_assert(sci->status.what == SsHandToKernel);
2986 ML_(fixup_guest_state_to_restart_syscall)(th_regs);
2987 }
2988
2989 else
2990 if (at_restart) {
2991 # if defined(VGO_solaris)
2992 /* We should never hit this branch on Solaris, see the comment above. */
2993 vg_assert(0);
2994 # endif
2995
2996 /* We're either about to run the syscall, or it was interrupted
2997 and the kernel restarted it. Restart if asked, otherwise
2998 EINTR it. */
2999 if (restart) {
3000 if (VG_(clo_trace_signals))
3001 VG_(message)( Vg_DebugMsg, " at syscall instr: restarting\n");
3002 ML_(fixup_guest_state_to_restart_syscall)(th_regs);
3003 } else {
3004 if (VG_(clo_trace_signals))
3005 VG_(message)( Vg_DebugMsg, " at syscall instr: returning EINTR\n");
3006 canonical = convert_SysRes_to_SyscallStatus(
3007 VG_(mk_SysRes_Error)( VKI_EINTR )
3008 );
3009 if (!(sci->flags & SfNoWriteResult))
3010 putSyscallStatusIntoGuestState( tid, &canonical, &th_regs->vex );
3011 sci->status = canonical;
3012 VG_(post_syscall)(tid);
3013 }
3014 }
3015
3016 else
3017 if (in_complete_to_committed) {
3018 /* Syscall complete, but result hasn't been written back yet.
3019 Write the SysRes we were supplied with back to the guest
3020 state. */
3021 if (VG_(clo_trace_signals))
3022 VG_(message)( Vg_DebugMsg,
3023 " completed, but uncommitted: committing\n");
3024 canonical = convert_SysRes_to_SyscallStatus( sres );
3025 vg_assert(!(sci->flags & SfNoWriteResult));
3026 putSyscallStatusIntoGuestState( tid, &canonical, &th_regs->vex );
3027 # if defined(VGO_solaris)
3028 if (tst->os_state.in_door_return) {
3029 # if defined(VGP_x86_solaris)
3030 /* Registers %esp and %ebp were also modified by the syscall. */
3031 tst->arch.vex.guest_ESP = uc->uc_mcontext.gregs[VKI_UESP];
3032 tst->arch.vex.guest_EBP = uc->uc_mcontext.gregs[VKI_EBP];
3033 # elif defined(VGP_amd64_solaris)
3034 tst->arch.vex.guest_RSP = uc->uc_mcontext.gregs[VKI_REG_RSP];
3035 tst->arch.vex.guest_RBP = uc->uc_mcontext.gregs[VKI_REG_RBP];
3036 # endif
3037 }
3038 # endif
3039 sci->status = canonical;
3040 VG_(post_syscall)(tid);
3041 }
3042
3043 else
3044 if (in_committed_to_finished) {
3045 /* Result committed, but the signal mask has not been restored;
3046 we expect our caller (the signal handler) will have fixed
3047 this up. */
3048 /* XXX: needed? */
3049 #if defined(VGP_x86_dragonfly)
3050 /* On Dragonfly, the success/fail status is returned to the caller
3051 and still has to be fixed up here. */
3052 if (!(sci->flags & SfNoWriteResult)) {
3053 if (sr_isError(sres))
3054 LibVEX_GuestX86_put_eflag_c(1, &th_regs->vex);
3055 else
3056 LibVEX_GuestX86_put_eflag_c(0, &th_regs->vex);
3057 }
3058 #elif defined(VGP_amd64_dragonfly)
3059 if (!(sci->flags & SfNoWriteResult)) {
3060 if (sr_isError(sres))
3061 LibVEX_GuestAMD64_put_rflag_c(1, &th_regs->vex);
3062 else
3063 LibVEX_GuestAMD64_put_rflag_c(0, &th_regs->vex);
3064 }
3065 #endif
3066 if (VG_(clo_trace_signals))
3067 VG_(message)( Vg_DebugMsg,
3068 " completed and committed: nothing to do\n");
3069 # if defined(VGP_x86_solaris)
3070 /* The %eax and %edx values are committed but the carry flag is still
3071 uncommitted. Save it now. */
3072 LibVEX_GuestX86_put_eflag_c(sr_isError(sres), &th_regs->vex);
3073 # elif defined(VGP_amd64_solaris)
3074 LibVEX_GuestAMD64_put_rflag_c(sr_isError(sres), &th_regs->vex);
3075 # endif
3076 getSyscallStatusFromGuestState( &sci->status, &th_regs->vex );
3077 vg_assert(sci->status.what == SsComplete);
3078 VG_(post_syscall)(tid);
3079 }
3080
3081 else
3082 VG_(core_panic)("?? strange syscall interrupt state?");
3083
3084 /* In all cases, the syscall is now finished (even if we called
3085 ML_(fixup_guest_state_to_restart_syscall), since that just
3086 re-positions the guest's IP for another go at it). So we need
3087 to record that fact. */
3088 sci->status.what = SsIdle;
3089 }
3090
3091
3092 #if defined(VGO_solaris)
3093 /* Returns True if ip is inside a fixable syscall code in syscall-*-*.S. This
3094 function can be called by a 'non-running' thread! */
VG_(is_ip_in_blocking_syscall)3095 Bool VG_(is_ip_in_blocking_syscall)(ThreadId tid, Addr ip)
3096 {
3097 ThreadState *tst = VG_(get_ThreadState)(tid);
3098
3099 if (tst->os_state.in_door_return)
3100 return ip >= ML_(blksys_setup_DRET) && ip < ML_(blksys_finished_DRET);
3101 else
3102 return ip >= ML_(blksys_setup) && ip < ML_(blksys_finished);
3103 }
3104 #endif
3105
3106
3107 #if defined(VGO_darwin)
3108 // Clean up after workq_ops(WQOPS_THREAD_RETURN) jumped to wqthread_hijack.
3109 // This is similar to VG_(fixup_guest_state_after_syscall_interrupted).
3110 // This longjmps back to the scheduler.
ML_(wqthread_continue_NORETURN)3111 void ML_(wqthread_continue_NORETURN)(ThreadId tid)
3112 {
3113 ThreadState* tst;
3114 SyscallInfo* sci;
3115
3116 VG_(acquire_BigLock)(tid, "wqthread_continue_NORETURN");
3117
3118 PRINT("SYSCALL[%d,%u](%s) workq_ops() starting new workqueue item\n",
3119 VG_(getpid)(), tid, VG_SYSNUM_STRING(__NR_workq_ops));
3120
3121 vg_assert(VG_(is_valid_tid)(tid));
3122 vg_assert(tid >= 1 && tid < VG_N_THREADS);
3123 vg_assert(VG_(is_running_thread)(tid));
3124
3125 tst = VG_(get_ThreadState)(tid);
3126 sci = & syscallInfo[tid];
3127 vg_assert(sci->status.what != SsIdle);
3128 vg_assert(tst->os_state.wq_jmpbuf_valid); // check this BEFORE post_syscall
3129
3130 // Pretend the syscall completed normally, but don't touch the thread state.
3131 sci->status = convert_SysRes_to_SyscallStatus( VG_(mk_SysRes_Success)(0) );
3132 sci->flags |= SfNoWriteResult;
3133 VG_(post_syscall)(tid);
3134
3135 ML_(sync_mappings)("in", "ML_(wqthread_continue_NORETURN)", 0);
3136
3137 sci->status.what = SsIdle;
3138
3139 vg_assert(tst->sched_jmpbuf_valid);
3140 VG_MINIMAL_LONGJMP(tst->sched_jmpbuf);
3141
3142 /* NOTREACHED */
3143 vg_assert(0);
3144 }
3145 #endif
3146
3147
3148 /* ---------------------------------------------------------------------
3149 A place to store the where-to-call-when-really-done pointer
3150 ------------------------------------------------------------------ */
3151
3152 // When the final thread is done, where shall I call to shutdown the
3153 // system cleanly? Is set once at startup (in m_main) and never
3154 // changes after that. Is basically a pointer to the exit
3155 // continuation. This is all just a nasty hack to avoid calling
3156 // directly from m_syswrap to m_main at exit, since that would cause
3157 // m_main to become part of a module cycle, which is silly.
3158 void (* VG_(address_of_m_main_shutdown_actions_NORETURN) )
3159 (ThreadId,VgSchedReturnCode)
3160 = NULL;
3161
3162 /*--------------------------------------------------------------------*/
3163 /*--- end ---*/
3164 /*--------------------------------------------------------------------*/
3165