// Edit the thread state to send to the real kernel.
// The real thread will run start_thread_NORETURN(tst)
// on a separate non-client stack.
-void hijack_thread_state(thread_state_t mach_generic,
+void hijack_thread_state(thread_state_t mach_generic,
thread_state_flavor_t flavor,
mach_msg_type_number_t count,
ThreadState *tst)
-void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg,
+void pthread_hijack(Addr self, Addr kport, Addr func, Addr func_arg,
Addr stacksize, Addr flags, Addr sp)
{
vki_sigset_t blockall;
" push $0\n" // alignment
" push $0\n" // alignment
" push %ebp\n" // original sp
+" push %esi\n" // kevent_count
" push %edi\n" // reuse
" push %edx\n" // workitem
" push %ecx\n" // stackaddr
To handle this in valgrind, we create and destroy a valgrind
thread for every work item.
*/
-void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem,
+void wqthread_hijack(Addr self, Addr kport, Addr stackaddr, Addr workitem,
UInt reuse, Int kevent_count, Addr sp)
{
ThreadState *tst;
if (0) VG_(printf)(
"wqthread_hijack: self %#lx, kport %#lx, "
- "stackaddr %#lx, workitem %#lx, reuse/flags %x, sp %#lx\n",
- self, kport, stackaddr, workitem, reuse, sp);
+ "stackaddr %#lx, workitem %#lx, reuse/flags %x, kevent_count %d, sp %#lx\n",
+ self, kport, stackaddr, workitem, reuse, kevent_count, sp);
/* Start the thread with all signals blocked. VG_(scheduler) will
set the mask correctly when we finally get there. */
|| DARWIN_VERS == DARWIN_10_10 \
|| DARWIN_VERS == DARWIN_10_11 \
|| DARWIN_VERS == DARWIN_10_12 \
- || DARWIN_VERS == DARWIN_10_13
+ || DARWIN_VERS == DARWIN_10_13 \
+ || DARWIN_VERS == DARWIN_10_14
UWord magic_delta = 0xB0;
# else
# error "magic_delta: to be computed on new OS version"
tid, tst, tst->os_state.pthread, self);
vex = &tst->arch.vex;
+ if (tst->os_state.pthread - magic_delta != self) {
+ VG_(printf)("wqthread_hijack reuse: tst->os_state.pthread %#lx vs self %#lx (diff: %#lx vs %#lx)\n",
+ tst->os_state.pthread, self, tst->os_state.pthread - self, magic_delta);
+ }
vg_assert(tst->os_state.pthread - magic_delta == self);
}
else {
vex->guest_ECX = stackaddr;
vex->guest_EDX = workitem;
vex->guest_EDI = reuse;
- vex->guest_ESI = 0;
+ vex->guest_ESI = kevent_count;
vex->guest_ESP = sp;
stacksize = 512*1024; // wq stacks are always DEFAULT_STACK_SIZE