Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

context.c File Reference

#include <nt.h>
#include <ntrtl.h>
#include <alphaops.h>

Go to the source code of this file.

Functions

VOID RtlInitializeContext (IN HANDLE Process, OUT PCONTEXT Context, IN PVOID Parameter OPTIONAL, IN PVOID InitialPc OPTIONAL, IN PVOID InitialSp OPTIONAL)
NTSTATUS RtlRemoteCall (HANDLE Process, HANDLE Thread, PVOID CallSite, ULONG ArgumentCount, PULONG_PTR Arguments, BOOLEAN PassContext, BOOLEAN AlreadySuspended)


Function Documentation

VOID RtlInitializeContext IN HANDLE  Process,
OUT PCONTEXT  Context,
IN PVOID Parameter  OPTIONAL,
IN PVOID InitialPc  OPTIONAL,
IN PVOID InitialSp  OPTIONAL
 

Definition at line 34 of file rtl/alpha/context.c.

References CONTEXT_FULL, and RtlRaiseStatus().

00044 : 00045 00046 This function initializes a context structure so that it can be used in 00047 a subsequent call to NtCreateThread. 00048 00049 Arguments: 00050 00051 Process - Supplies an open handle to the target process. This argument 00052 is ignored by this function. 00053 00054 Context - Supplies a pointer to a context record that is to be initialized. 00055 00056 Parameter - Supplies an initial value for register A0. 00057 00058 InitialPc - Supplies an initial program counter value. 00059 00060 InitialSp - Supplies an initial stack pointer value. 00061 00062 Return Value: 00063 00064 Raises STATUS_BAD_INITIAL_STACK if the value of InitialSp is not properly 00065 aligned. 00066 00067 Raises STATUS_BAD_INITIAL_PC if the value of InitialPc is not properly 00068 aligned. 00069 00070 --*/ 00071 00072 { 00073 00074 // 00075 // Check for proper initial stack and PC alignment. 00076 // 00077 00078 if (((ULONG_PTR)InitialSp & 0xF) != 0) { 00079 RtlRaiseStatus(STATUS_BAD_INITIAL_STACK); 00080 } 00081 if (((ULONG_PTR)InitialPc & 0x3) != 0) { 00082 RtlRaiseStatus(STATUS_BAD_INITIAL_PC); 00083 } 00084 00085 // 00086 // Initialize the integer registers to contain their register number 00087 // (they must be initialized and using register numbers instead of 0 00088 // can be useful for debugging). Integer registers a0, ra, gp, and sp 00089 // are set later. 00090 // 00091 00092 Context->IntV0 = 0; 00093 Context->IntT0 = 1; 00094 Context->IntT1 = 2; 00095 Context->IntT2 = 3; 00096 Context->IntT3 = 4; 00097 Context->IntT4 = 5; 00098 Context->IntT5 = 6; 00099 Context->IntT6 = 7; 00100 Context->IntT7 = 8; 00101 Context->IntS0 = 9; 00102 Context->IntS1 = 10; 00103 Context->IntS2 = 11; 00104 Context->IntS3 = 12; 00105 Context->IntS4 = 13; 00106 Context->IntS5 = 14; 00107 Context->IntFp = 15; 00108 Context->IntA1 = 17; 00109 Context->IntA2 = 18; 00110 Context->IntA3 = 19; 00111 Context->IntA4 = 20; 00112 Context->IntA5 = 21; 00113 Context->IntT8 = 22; 00114 Context->IntT9 = 23; 00115 Context->IntT10 = 24; 00116 Context->IntT11 = 25; 00117 Context->IntT12 = 27; 00118 Context->IntAt = 28; 00119 00120 // 00121 // Initialize the floating point registers to contain the integer value 00122 // of their register number (they must be initialized and using register 00123 // numbers instead of 0 can be useful for debugging). 00124 // 00125 00126 Context->FltF0 = 0; 00127 Context->FltF1 = 1; 00128 Context->FltF2 = 2; 00129 Context->FltF3 = 3; 00130 Context->FltF4 = 4; 00131 Context->FltF5 = 5; 00132 Context->FltF6 = 6; 00133 Context->FltF7 = 7; 00134 Context->FltF8 = 8; 00135 Context->FltF9 = 9; 00136 Context->FltF10 = 10; 00137 Context->FltF11 = 11; 00138 Context->FltF12 = 12; 00139 Context->FltF13 = 13; 00140 Context->FltF14 = 14; 00141 Context->FltF15 = 15; 00142 Context->FltF16 = 16; 00143 Context->FltF17 = 17; 00144 Context->FltF18 = 18; 00145 Context->FltF19 = 19; 00146 Context->FltF20 = 20; 00147 Context->FltF21 = 21; 00148 Context->FltF22 = 22; 00149 Context->FltF23 = 23; 00150 Context->FltF24 = 24; 00151 Context->FltF25 = 25; 00152 Context->FltF26 = 26; 00153 Context->FltF27 = 27; 00154 Context->FltF28 = 28; 00155 Context->FltF29 = 29; 00156 Context->FltF30 = 30; 00157 Context->FltF31 = 0; 00158 00159 // 00160 // Initialize the control registers. 00161 // 00162 // Gp: will be set in LdrpInitialize at thread startup. 00163 // Ra: some debuggers compare for 1 as a top-of-stack indication. 00164 // 00165 // N.B. On 32-bit systems, ULONG becomes canonical longword with the 00166 // (ULONGLONG)(LONG) cast. 00167 // 00168 00169 Context->IntGp = 0; 00170 Context->IntSp = (ULONGLONG)(LONG_PTR)InitialSp; 00171 Context->IntRa = 1; 00172 Context->Fir = (ULONGLONG)(LONG_PTR)InitialPc; 00173 00174 // 00175 // Set default Alpha floating point control register values. 00176 // 00177 00178 Context->Fpcr = (ULONGLONG)0; 00179 ((PFPCR)(&Context->Fpcr))->DynamicRoundingMode = ROUND_TO_NEAREST; 00180 Context->SoftFpcr = (ULONGLONG)0; 00181 00182 Context->Psr = 0; 00183 Context->ContextFlags = CONTEXT_FULL; 00184 00185 // 00186 // Set the initial context of the thread in a machine specific way. 00187 // 00188 00189 Context->IntA0 = (ULONGLONG)(LONG_PTR)Parameter; 00190 }

NTSTATUS RtlRemoteCall HANDLE  Process,
HANDLE  Thread,
PVOID  CallSite,
ULONG  ArgumentCount,
PULONG_PTR  Arguments,
BOOLEAN  PassContext,
BOOLEAN  AlreadySuspended
 

Definition at line 193 of file rtl/alpha/context.c.

References CONTEXT_FULL, FALSE, Index, NT_SUCCESS, NtGetContextThread(), NtResumeThread(), NtSetContextThread(), NTSTATUS(), NtSuspendThread(), NtWriteVirtualMemory(), NULL, and Status.

00205 : 00206 00207 This function calls a procedure in another thread/process by using 00208 NtGetContext and NtSetContext. Parameters are passed to the target 00209 procedure via the nonvolatile registers (s0 - s5). 00210 00211 Arguments: 00212 00213 Process - Supplies an open handle to the target process. 00214 00215 Thread - Supplies an open handle to the target thread within the target 00216 process. 00217 00218 CallSite - Supplies the address of the procedure to call in the target 00219 process. 00220 00221 ArgumentCount - Supplies the number of parameters to pass to the 00222 target procedure. 00223 00224 Arguments - Supplies a pointer to the array of parameters to pass. 00225 00226 PassContext - Supplies a boolean value that determines whether a parameter 00227 is to be passed that points to a context record. This parameter is 00228 ignored on MIPS and Alpha hosts. 00229 00230 AlreadySuspended - Supplies a boolean value that determines whether the 00231 target thread is already in a suspended or waiting state. 00232 00233 Return Value: 00234 00235 Status - Status value. 00236 00237 --*/ 00238 00239 { 00240 00241 NTSTATUS Status; 00242 CONTEXT Context; 00243 ULONG Index; 00244 ULONGLONG NewSp; 00245 00246 if ((ArgumentCount > 6) || 00247 (PassContext && (ArgumentCount > 5))) { 00248 return(STATUS_INVALID_PARAMETER); 00249 } 00250 00251 // 00252 // If necessary, suspend the target thread before getting the thread's 00253 // current state. 00254 // 00255 00256 if (AlreadySuspended == FALSE) { 00257 Status = NtSuspendThread(Thread, NULL); 00258 if (NT_SUCCESS(Status) == FALSE) { 00259 return(Status); 00260 } 00261 } 00262 00263 // 00264 // Get the current state of the target thread. 00265 // 00266 00267 Context.ContextFlags = CONTEXT_FULL; 00268 Status = NtGetContextThread(Thread, &Context); 00269 if (NT_SUCCESS(Status) == FALSE) { 00270 if (AlreadySuspended == FALSE) { 00271 NtResumeThread(Thread, NULL); 00272 } 00273 return(Status); 00274 } 00275 00276 if (AlreadySuspended) { 00277 Context.IntV0 = STATUS_ALERTED; 00278 } 00279 00280 // 00281 // Pass the parameters to the other thread via the non-volatile registers 00282 // s0 - s5. The context record is passed on the stack of the target thread. 00283 // 00284 00285 NewSp = Context.IntSp - sizeof(CONTEXT); 00286 Status = NtWriteVirtualMemory(Process, (PVOID)NewSp, &Context, 00287 sizeof(CONTEXT), NULL); 00288 if (NT_SUCCESS(Status) == FALSE) { 00289 if (AlreadySuspended == FALSE) { 00290 NtResumeThread(Thread, NULL); 00291 } 00292 return(Status); 00293 } 00294 00295 // 00296 // N.B. On 32-bit system each ULONG argument is converted to canonical 00297 // form with the (ULONGLONG)(LONG) cast as required by the calling 00298 // standard. 00299 // 00300 00301 Context.IntSp = NewSp; 00302 00303 if (PassContext) { 00304 Context.IntS0 = NewSp; 00305 for (Index = 0; Index < ArgumentCount; Index += 1) { 00306 (&Context.IntS1)[Index] = (ULONGLONG)(LONG_PTR)Arguments[Index]; 00307 } 00308 00309 } else { 00310 for (Index = 0; Index < ArgumentCount; Index += 1) { 00311 (&Context.IntS0)[Index] = (ULONGLONG)(LONG_PTR)Arguments[Index]; 00312 } 00313 } 00314 00315 // 00316 // Set the address of the target code into FIR and set the thread context 00317 // to cause the target procedure to be executed. 00318 // 00319 // N.B. The PVOID CallSite is stored as a canonical longword in order 00320 // for Fir to be a valid 64-bit address. 00321 // 00322 00323 Context.Fir = (ULONGLONG)(LONG_PTR)CallSite; 00324 Status = NtSetContextThread(Thread, &Context); 00325 if (AlreadySuspended == FALSE) { 00326 NtResumeThread(Thread, NULL); 00327 } 00328 return(Status); 00329 } }


Generated on Sat May 15 19:43:16 2004 for test by doxygen 1.3.7