1
2/*--------------------------------------------------------------------*/
3/*--- The thread state.                     pub_core_threadstate.h ---*/
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#ifndef __PUB_CORE_THREADSTATE_H
32#define __PUB_CORE_THREADSTATE_H
33
34//--------------------------------------------------------------------
35// PURPOSE: This module defines the ThreadState type and the
36// VG_(threads)[] data structure which holds all the important thread
37// state.  It also defines some simple operations on the data structure
38// that don't require any external help.  (m_scheduler does the complex
39// stuff).
40//--------------------------------------------------------------------
41
42#include "pub_tool_threadstate.h"
43#include "pub_core_libcsetjmp.h"   // VG_MINIMAL_JMP_BUF
44#include "pub_core_vki.h"          // vki_sigset_t
45#include "pub_core_guest.h"        // VexGuestArchState
46#include "libvex.h"                // LibVEX_N_SPILL_BYTES
47
48
49/*------------------------------------------------------------*/
50/*--- Types                                                ---*/
51/*------------------------------------------------------------*/
52
53/*
54   Thread state machine:
55
56   Empty -> Init -> Runnable <=> WaitSys/Yielding
57     ^                 |
58     \---- Zombie -----/
59 */
60typedef
61   enum ThreadStatus {
62      VgTs_Empty,      /* this slot is not in use */
63      VgTs_Init,       /* just allocated */
64      VgTs_Runnable,   /* ready to run */
65      VgTs_WaitSys,    /* waiting for a syscall to complete */
66      VgTs_Yielding,   /* temporarily yielding the CPU */
67      VgTs_Zombie,     /* transient state just before exiting */
68   }
69   ThreadStatus;
70
71/* Return codes from the scheduler. */
72typedef
73   enum {
74      VgSrc_None,	 /* not exiting yet */
75      VgSrc_ExitThread,  /* just this thread is exiting */
76      VgSrc_ExitProcess, /* this thread is exiting due to another thread
77                            calling exit() */
78      VgSrc_FatalSig	 /* Killed by the default action of a fatal
79			    signal */
80   }
81   VgSchedReturnCode;
82
83
84/* Forward declarations */
85struct SyscallStatus;
86struct SyscallArgs;
87
88/* Architecture-specific thread state */
89typedef
90   struct {
91      /* --- BEGIN vex-mandated guest state --- */
92
93      /* Note that for code generation reasons, we require that the
94         guest state area, its two shadows, and the spill area, are
95         aligned on LibVEX_GUEST_STATE_ALIGN and have sizes, such that
96         there are no holes in between. This is checked by do_pre_run_checks()
97         in scheduler.c. */
98
99      /* Saved machine context. */
100      VexGuestArchState vex __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
101
102      /* Saved shadow context (2 copies). */
103      VexGuestArchState vex_shadow1
104                        __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
105      VexGuestArchState vex_shadow2
106                        __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
107
108      /* Spill area. */
109      UChar vex_spill[LibVEX_N_SPILL_BYTES]
110            __attribute__((aligned(LibVEX_GUEST_STATE_ALIGN)));
111
112      /* --- END vex-mandated guest state --- */
113   }
114   ThreadArchState;
115
116
117#define NULL_STK_ID (~(UWord)0)
118
119/* OS-specific thread state.  IMPORTANT: if you add fields to this,
120   you _must_ add code to os_state_clear() to initialise those
121   fields. */
122typedef
123   struct {
124      /* who we are */
125      Int lwpid;        // PID of kernel task  (Darwin: Mach thread)
126      Int threadgroup;  // thread group id
127
128      ThreadId parent;  // parent tid (if any)
129
130      /* runtime details */
131      Addr valgrind_stack_base;    // Valgrind's stack (VgStack*)
132      Addr valgrind_stack_init_SP; // starting value for SP
133
134      /* Client stack is registered as stk_id (on linux/darwin, by
135         ML_(guess_and_register_stack)).
136         Stack id NULL_STK_ID means that the user stack is not (yet)
137         registered. */
138      UWord stk_id;
139
140      /* exit details */
141      Word exitcode; // in the case of exitgroup, set by someone else
142      Int  fatalsig; // fatal signal
143
144#     if defined(VGO_darwin)
145      // Mach trap POST handler as chosen by PRE
146      void (*post_mach_trap_fn)(ThreadId tid,
147                                struct SyscallArgs *, struct SyscallStatus *);
148
149      // This thread's pthread
150      Addr pthread;
151
152      // Argument passed when thread started
153      Addr func_arg;
154
155      // Synchronization between child thread and parent thread's POST wrapper
156      semaphore_t child_go;
157      semaphore_t child_done;
158
159      // Workqueue re-entry
160      // (setjmp in PRE(workq_ops), longjmp in wqthread_hijack)
161      // DDD: JRS fixme: this comment is no longer correct; wq_jmpbuf is
162      // never used, and there is no such setjmp or longjmp pair.
163      // I guess we could leave wq_jmpbuf_valid in place though, since
164      // it does allow for an assertion in ML_(wqthread_continue_NORETURN).
165      Bool wq_jmpbuf_valid;
166      //jmp_buf wq_jmpbuf;
167
168      // Values saved from transient Mach RPC messages
169      Addr remote_port;  // destination for original message
170      Int msgh_id;       // outgoing message id
171      union {
172         struct {
173            Addr port;
174         } mach_port;
175         struct {
176            Int right;
177         } mach_port_allocate;
178         struct {
179            Addr port;
180            Int right;
181            Int delta;
182         } mach_port_mod_refs;
183         struct {
184            Addr task;
185            Addr name;
186            Int disposition;
187         } mach_port_insert_right;
188         struct {
189            Addr size;
190            int flags;
191         } vm_allocate;
192         struct {
193            Addr address;
194            Addr size;
195         } vm_deallocate;
196         struct {
197            Addr src;
198            Addr dst;
199            Addr size;
200         } vm_copy;
201         struct {
202            Addr address;
203            Addr size;
204            int set_maximum;
205            UWord new_protection;
206         } vm_protect;
207         struct {
208            Addr addr;
209            SizeT size;
210         } vm_read;
211         struct {
212            ULong addr;
213            ULong size;
214         } mach_vm_read;
215         struct {
216            Addr addr;
217            SizeT size;
218            Addr data;
219         } vm_read_overwrite;
220         struct {
221            Addr size;
222            int copy;
223            UWord protection;
224         } vm_map;
225         struct {
226            Addr size;
227         } vm_remap;
228         struct {
229            ULong size;
230            int flags;
231         } mach_vm_allocate;
232         struct {
233            ULong address;
234            ULong size;
235         } mach_vm_deallocate;
236         struct {
237            ULong address;
238            ULong size;
239            int set_maximum;
240            unsigned int new_protection;
241         } mach_vm_protect;
242         struct {
243            ULong size;
244            int copy;
245            UWord protection;
246         } mach_vm_map;
247         struct {
248            ULong size;
249            int copy;
250         } mach_vm_remap;
251         struct {
252            Addr thread;
253            UWord flavor;
254         } thread_get_state;
255         struct {
256            Addr address;
257         } io_connect_unmap_memory;
258         struct {
259            int which_port;
260         } task_get_special_port;
261         struct {
262            int which;
263         } host_get_special_port;
264         struct {
265            char *service_name;
266         } bootstrap_look_up;
267         struct {
268            vki_size_t size;
269         } WindowServer_29828;
270         struct {
271            Int access_rights;
272         } WindowServer_29831;
273         struct {
274            char *path;
275         } io_registry_entry_from_path;
276      } mach_args;
277
278#     elif defined(VGO_solaris)
279#     if defined(VGP_x86_solaris)
280      /* A pointer to thread related data. The pointer is used to set up
281         a segment descriptor (GDT[VKI_GDT_LWPGS]) when the thread is about to
282         be run. A client program sets this value explicitly by calling the
283         lwp_private syscall or it can be passed as a part of ucontext_t when
284         a new thread is created (the lwp_create syscall). */
285      Addr thrptr;
286#     elif defined(VGP_amd64_solaris)
287      /* GDT is not fully simulated by AMD64/Solaris. The %fs segment
288         register is assumed to be always zero and vex->guest_FS_CONST holds
289         the 64-bit offset associated with a %fs value of zero. */
290#     endif
291
292      /* Simulation of the kernel's lwp->lwp_ustack. Set in the PRE wrapper
293         of the getsetcontext syscall, for SETUSTACK. Used in
294         VG_(save_context)(), VG_(restore_context)() and
295         VG_(sigframe_create)(). */
296      vki_stack_t *ustack;
297
298      /* Flag saying if the current call is in the door_return() variant of
299         the door() syscall. */
300      Bool in_door_return;
301
302      /* Address of the door server procedure corresponding to the current
303         thread. Used to keep track which door call the current thread
304         services. Valid only between subsequent door_return() invocations. */
305      Addr door_return_procedure;
306
307      /* Simulation of the kernel's lwp->lwp_oldcontext. Set in
308         VG_(restore_context)() and VG_(sigframe_create)(). Used in
309         VG_(save_context)(). */
310      vki_ucontext_t *oldcontext;
311
312      /* Address of sc_shared_t struct shared between kernel and libc.
313         Set in POST(sys_schedctl). Every thread gets its own address
314         but typically many are squeezed on a singled mapped page.
315         Cleaned in the child atfork handler. */
316      Addr schedctl_data;
317
318      /* True if this is daemon thread. */
319      Bool daemon_thread;
320#     endif
321
322   }
323   ThreadOSstate;
324
325
326/* Overall thread state */
327typedef struct {
328   /* ThreadId == 0 (and hence vg_threads[0]) is NEVER USED.
329      The thread identity is simply the index in vg_threads[].
330      ThreadId == 1 is the root thread and has the special property
331      that we don't try and allocate or deallocate its stack.  For
332      convenience of generating error message, we also put the
333      ThreadId in this tid field, but be aware that it should
334      ALWAYS == the index in vg_threads[]. */
335   ThreadId tid;
336
337   /* Current scheduling status. */
338   ThreadStatus status;
339
340   /* This is set if the thread is in the process of exiting for any
341      reason.  The precise details of the exit are in the OS-specific
342      state. */
343   VgSchedReturnCode exitreason;
344
345   /* Architecture-specific thread state. */
346   ThreadArchState arch;
347
348   /* This thread's blocked-signals mask.  Semantics is that for a
349      signal to be delivered to this thread, the signal must not be
350      blocked by this signal mask.  If more than one thread accepts a
351      signal, then it will be delivered to one at random.  If all
352      threads block the signal, it will remain pending until either a
353      thread unblocks it or someone uses sigwaitsig/sigtimedwait. */
354   vki_sigset_t sig_mask;
355
356   /* tmp_sig_mask is usually the same as sig_mask, and is kept in
357      sync whenever sig_mask is changed.  The only time they have
358      different values is during the execution of a sigsuspend, where
359      tmp_sig_mask is the temporary mask which sigsuspend installs.
360      It is only consulted to compute the signal mask applied to a
361      signal handler.
362      PW Nov 2016 : it is not clear if and where this tmp_sig_mask
363      is set when an handler runs "inside" a sigsuspend. */
364   vki_sigset_t tmp_sig_mask;
365
366   /* A little signal queue for signals we can't get the kernel to
367      queue for us.  This is only allocated as needed, since it should
368      be rare. */
369   struct SigQueue *sig_queue;
370
371   /* Client stacks.  When a thread slot is freed, we don't deallocate its
372      stack; we just leave it lying around for the next use of the
373      slot.  If the next use of the slot requires a larger stack,
374      only then is the old one deallocated and a new one
375      allocated.
376
377      For the main thread (threadid == 1), this mechanism doesn't
378      apply.  We don't know the size of the stack since we didn't
379      allocate it, and furthermore we never reallocate it. */
380
381   /* The allocated size of this thread's stack */
382   SizeT client_stack_szB;
383
384   /* Address of the highest legitimate byte in this stack.  This is
385      used for error messages only -- not critical for execution
386      correctness.  Is is set for all stacks, specifically including
387      ThreadId == 1 (the main thread). */
388   Addr client_stack_highest_byte;
389
390   /* Alternate signal stack */
391   vki_stack_t altstack;
392
393   /* OS-specific thread state */
394   ThreadOSstate os_state;
395
396   /* Error disablement level.  A counter which allows selectively
397      disabling error reporting in threads.  When zero, reporting is
398      enabled.  When nonzero, it is disabled.  This is controlled by
399      the client request 'VG_USERREQ__CHANGE_ERR_DISABLEMENT'.  New
400      threads are always created with this as zero (errors
401      enabled). */
402   UInt err_disablement_level;
403
404   /* Per-thread jmp_buf to resume scheduler after a signal */
405   Bool               sched_jmpbuf_valid;
406   VG_MINIMAL_JMP_BUF(sched_jmpbuf);
407
408   /* This thread's name. NULL, if no name. */
409   HChar *thread_name;
410   UInt ptrace;
411}
412ThreadState;
413
414
415/*------------------------------------------------------------*/
416/*--- The thread table.                                    ---*/
417/*------------------------------------------------------------*/
418
419/* An array of threads, dynamically allocated by VG_(init_Threads).
420   NOTE: [0] is never used, to simplify the simulation of initialisers
421   for LinuxThreads. */
422extern ThreadState *VG_(threads);
423
424/* In an outer valgrind, VG_(inner_threads) stores the address of
425   the inner VG_(threads) array, as reported by the inner using
426   the client request INNER_THREADS. */
427extern ThreadState *VG_(inner_threads);
428
429// The running thread.  m_scheduler should be the only other module
430// to write to this.
431extern ThreadId VG_(running_tid);
432
433
434/*------------------------------------------------------------*/
435/*--- Basic operations on the thread table.                ---*/
436/*------------------------------------------------------------*/
437
438/* Initialize the m_threadstate module. */
439void VG_(init_Threads)(void);
440
441// Convert a ThreadStatus to a string.
442const HChar* VG_(name_of_ThreadStatus) ( ThreadStatus status );
443
444// Convert a VgSchedReturnCode to a string.
445const HChar* VG_(name_of_VgSchedReturnCode) ( VgSchedReturnCode retcode );
446
447/* Get the ThreadState for a particular thread */
448extern ThreadState *VG_(get_ThreadState) ( ThreadId tid );
449
450/* Check that tid is in range and denotes a non-Empty thread. */
451extern Bool VG_(is_valid_tid) ( ThreadId tid );
452
453/* Returns true if a thread is currently running (ie, has the CPU lock) */
454extern Bool VG_(is_running_thread)(ThreadId tid);
455
456/* Returns true if the thread is in the process of exiting */
457extern Bool VG_(is_exiting)(ThreadId tid);
458
459/* Return the number of non-dead Threads */
460extern Int VG_(count_living_threads)(void);
461
462/* Return the number of threads in VgTs_Runnable state */
463extern Int VG_(count_runnable_threads)(void);
464
465/* Given an LWP id (ie, real kernel thread id), find the corresponding
466   ThreadId */
467extern ThreadId VG_(lwpid_to_vgtid)(Int lwpid);
468
469#endif   // __PUB_CORE_THREADSTATE_H
470
471/*--------------------------------------------------------------------*/
472/*--- end                                                          ---*/
473/*--------------------------------------------------------------------*/
474