LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - nacl_app_thread.h (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 3 3 100.0 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Server Runtime user thread state.
       9                 :  */
      10                 : 
      11                 : #ifndef NATIVE_CLIENT_SERVICE_RUNTIME_NACL_APP_THREAD_H__
      12                 : #define NATIVE_CLIENT_SERVICE_RUNTIME_NACL_APP_THREAD_H__ 1
      13                 : 
      14                 : #include <stddef.h>
      15                 : 
      16                 : #include "native_client/src/include/atomic_ops.h"
      17                 : #include "native_client/src/shared/platform/nacl_sync.h"
      18                 : #include "native_client/src/shared/platform/nacl_threads.h"
      19                 : #include "native_client/src/trusted/service_runtime/nacl_signal.h"
      20                 : #include "native_client/src/trusted/service_runtime/sel_rt.h"
      21                 : #include "native_client/src/trusted/service_runtime/sys_futex.h"
      22                 : 
      23                 : 
      24                 : EXTERN_C_BEGIN
      25                 : 
      26                 : struct NaClApp;
      27                 : struct NaClAppThreadSuspendedRegisters;
      28                 : 
      29                 : /*
      30                 :  * The thread hosting the NaClAppThread may change suspend_state
      31                 :  * between NACL_APP_THREAD_TRUSTED and NACL_APP_THREAD_UNTRUSTED using
      32                 :  * NaClAppThreadSetSuspendState().
      33                 :  *
      34                 :  * On Linux, a controlling thread may change this from:
      35                 :  *   NACL_APP_THREAD_UNTRUSTED
      36                 :  *   -> NACL_APP_THREAD_UNTRUSTED | NACL_APP_THREAD_SUSPENDING
      37                 :  * or
      38                 :  *   NACL_APP_THREAD_TRUSTED
      39                 :  *   -> NACL_APP_THREAD_TRUSTED | NACL_APP_THREAD_SUSPENDING
      40                 :  * and back again.
      41                 :  *
      42                 :  * Furthermore, the signal handler in the thread being suspended will
      43                 :  * change suspend_state from:
      44                 :  *   NACL_APP_THREAD_UNTRUSTED | NACL_APP_THREAD_SUSPENDING
      45                 :  *   -> (NACL_APP_THREAD_UNTRUSTED | NACL_APP_THREAD_SUSPENDING
      46                 :  *       | NACL_APP_THREAD_SUSPENDED)
      47                 :  * The controlling thread will later change suspend_thread back to:
      48                 :  *   NACL_APP_THREAD_UNTRUSTED
      49                 :  * This tells the signal handler to resume execution.
      50                 :  */
      51                 : enum NaClSuspendState {
      52                 :   NACL_APP_THREAD_UNTRUSTED = 1,
      53                 :   NACL_APP_THREAD_TRUSTED = 2
      54                 : #if NACL_LINUX
      55                 :   , NACL_APP_THREAD_SUSPENDING = 4,
      56                 :   NACL_APP_THREAD_SUSPENDED = 8
      57                 : #endif
      58                 : };
      59                 : 
      60                 : /*
      61                 :  * Generally, only the thread itself will need to manipulate this
      62                 :  * structure, but occasionally we may need to blow away a thread for
      63                 :  * some reason, and look inside.  While a thread is in the NaCl
      64                 :  * application running untrusted code, the lock must *not* be held.
      65                 :  */
      66                 : struct NaClAppThread {
      67                 :   /*
      68                 :    * NaClAppThread 'inherits' from NaClThreadContext; the 'user' field
      69                 :    * is first so that NaClAppThreadFromThreadContext() can convert by
      70                 :    * casting.
      71                 :    *
      72                 :    * 'user' contains all the architecture-specific state for this thread.
      73                 :    * TODO(mseaborn): Rename it to a more descriptive name.
      74                 :    */
      75                 :   struct NaClThreadContext  user;
      76                 : 
      77                 :   struct NaClMutex          mu;
      78                 : 
      79                 :   /*
      80                 :    * The NaCl app that contains this thread.  The app must exist as
      81                 :    * long as a thread is still alive.
      82                 :    */
      83                 :   struct NaClApp            *nap;
      84                 : 
      85                 :   int                       thread_num;  /* index into nap->threads */
      86                 : 
      87                 :   /*
      88                 :    * If host_thread_is_defined is true, host_thread is initialized and
      89                 :    * owned by the NaClAppThread such that it will be freed by
      90                 :    * NaClAppThreadDelete().
      91                 :    *
      92                 :    * host_thread_is_defined may be false when running untrusted code
      93                 :    * on a borrowed host thread that was not created by
      94                 :    * NaClAppThreadSpawn().
      95                 :    */
      96                 :   int                       host_thread_is_defined;
      97                 :   struct NaClThread         host_thread;  /* low level thread representation */
      98                 : 
      99                 :   struct NaClMutex          suspend_mu;
     100                 :   Atomic32                  suspend_state; /* enum NaClSuspendState */
     101                 :   /*
     102                 :    * suspended_registers contains the register state of the thread if
     103                 :    * it has been suspended with save_registers=1 and if suspend_state
     104                 :    * contains NACL_APP_THREAD_UNTRUSTED.  This is for use by the debug
     105                 :    * stub.
     106                 :    *
     107                 :    * To save space, suspended_registers is allocated on demand.  It
     108                 :    * may be left allocated after the thread is resumed.
     109                 :    *
     110                 :    * suspended_registers will usually contain untrusted-code register
     111                 :    * state.  However, it may contain trusted-code register state if
     112                 :    * the thread suspension kicked in during a trusted/untrusted
     113                 :    * context switch (e.g. while executing the trampoline or
     114                 :    * nacl_syscall_hook.c).
     115                 :    */
     116                 :   struct NaClAppThreadSuspendedRegisters *suspended_registers;
     117                 :   /*
     118                 :    * If fault_signal is non-zero, the thread has faulted and so has
     119                 :    * been suspended.  fault_signal indicates the type of fault (it is
     120                 :    * a signal number on Linux and an exception code on Windows).
     121                 :    */
     122                 :   int fault_signal;
     123                 : 
     124                 :   uintptr_t                 usr_syscall_args;
     125                 :   /*
     126                 :    * user's syscall argument address, relative to untrusted user
     127                 :    * address.  the syscall arglist is on the untrusted stack.
     128                 :    */
     129                 : 
     130                 :   /* Stack for signal handling, registered with sigaltstack(). */
     131                 :   void                      *signal_stack;
     132                 : 
     133                 :   /*
     134                 :    * exception_stack is the address of the top of the untrusted
     135                 :    * exception handler stack, or 0 if no such stack is registered for
     136                 :    * this thread.
     137                 :    */
     138                 :   uint32_t                  exception_stack;
     139                 :   /*
     140                 :    * exception_flag is a boolean.  When it is 1, untrusted exception
     141                 :    * handling is disabled for this thread.  It is set to 1 when the
     142                 :    * exception handler is called, in order to prevent the exception
     143                 :    * handler from being re-entered.
     144                 :    */
     145                 :   uint32_t                  exception_flag;
     146                 : 
     147                 :   /*
     148                 :    * The last generation this thread reported into the service runtime
     149                 :    * Protected by mu
     150                 :    */
     151                 :   int                       dynamic_delete_generation;
     152                 : 
     153                 :   /*
     154                 :    * If this thread is waiting on a futex, futex_wait_list_node is
     155                 :    * linked into the doubly linked list NaClApp::futex_wait_list_head.
     156                 :    */
     157                 :   struct NaClListNode       futex_wait_list_node;
     158                 :   /*
     159                 :    * If this thread is waiting on a futex, futex_wait_addr contains
     160                 :    * the untrusted address that the thread is waiting on.
     161                 :    */
     162                 :   uint32_t                  futex_wait_addr;
     163                 :   struct NaClCondVar        futex_condvar;
     164                 : };
     165                 : 
     166                 : void WINAPI NaClAppThreadLauncher(void *state);
     167                 : 
     168                 : void NaClAppThreadTeardown(struct NaClAppThread *natp);
     169                 : 
     170                 : /*
     171                 :  * NaClAppThreadMake() creates a NaClAppThread object without invoking
     172                 :  * untrusted code or creating a host thread.
     173                 :  *
     174                 :  * The usr_entry and usr_stack_ptr values are directly used to
     175                 :  * initialize the user register values.  The caller is responsible for
     176                 :  * error checking: usr_entry must be a valid entry point (0 mod N).
     177                 :  */
     178                 : struct NaClAppThread *NaClAppThreadMake(struct NaClApp *nap,
     179                 :                                         uintptr_t      usr_entry,
     180                 :                                         uintptr_t      usr_stack_ptr,
     181                 :                                         uint32_t       user_tls1,
     182                 :                                         uint32_t       user_tls2) NACL_WUR;
     183                 : 
     184                 : /*
     185                 :  * NaClAppThreadSpawn() creates a NaClAppThread and launches a host
     186                 :  * thread that invokes the given entry point in untrusted code.  This
     187                 :  * returns true on success, false on failure.
     188                 :  */
     189                 : int NaClAppThreadSpawn(struct NaClApp *nap,
     190                 :                        uintptr_t      usr_entry,
     191                 :                        uintptr_t      usr_stack_ptr,
     192                 :                        uint32_t       user_tls1,
     193                 :                        uint32_t       user_tls2) NACL_WUR;
     194                 : 
     195                 : void NaClAppThreadDelete(struct NaClAppThread *natp);
     196                 : 
     197                 : /*
     198                 :  * This function can be called from the thread hosting the
     199                 :  * NaClAppThread.  It can be used to switch between the states
     200                 :  * NACL_APP_THREAD_TRUSTED and NACL_APP_THREAD_UNTRUSTED.
     201                 :  */
     202                 : void NaClAppThreadSetSuspendState(struct NaClAppThread *natp,
     203                 :                                   enum NaClSuspendState old_state,
     204                 :                                   enum NaClSuspendState new_state);
     205                 : 
     206                 : static INLINE struct NaClAppThread *NaClAppThreadFromThreadContext(
     207         3568704 :     struct NaClThreadContext *ntcp) {
     208         7137406 :   NACL_COMPILE_TIME_ASSERT(offsetof(struct NaClAppThread, user) == 0);
     209         3568705 :   return (struct NaClAppThread *) ntcp;
     210                 : }
     211                 : 
     212                 : EXTERN_C_END
     213                 : 
     214                 : #endif  /* NATIVE_CLIENT_SERVICE_RUNTIME_NACL_APP_THREAD_H__ */

Generated by: LCOV version 1.7