test: rtl/alpha/context.c File Reference

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 }
    }