test: rtl/ppc/context.c File Reference

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

# context.c File Reference

`#include <ntos.h>`
`#include <kxppc.h>`

Go to the source code of this file.

## Defines

#define | _KXPPC_C_HEADER_

## 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 Arguments, BOOLEAN PassContext, BOOLEAN AlreadySuspended)

## Define Documentation

#define _KXPPC_C_HEADER_

| Definition at line 27 of file rtl/ppc/context.c.

## 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 31 of file rtl/ppc/context.c.

References CONTEXT_FULL, RtlRaiseStatus(), and STK_MIN_FRAME.

Referenced by RtlCreateUserThread(), and TestTokenInitialize().

    00041                    :
    00042
    00043     This function initializes a context structure so that it can be used in
    00044     a subsequent call to NtCreateThread.
    00045
    00046 Arguments:
    00047
    00048     Context - Supplies a pointer to a context record that is to be initialized.
    00049
    00050     InitialPc - Supplies an initial program counter value.
    00051
    00052     InitialSp - Supplies an initial stack pointer value.
    00053
    00054 Return Value:
    00055
    00056     Raises STATUS_BAD_INITIAL_STACK if the value of InitialSp is not properly
    00057            aligned.
    00058
    00059     Raises STATUS_BAD_INITIAL_PC if the value of InitialPc is not properly
    00060            aligned.
    00061
    00062 --*/
    00063
    00064 {
    00065
    00066     //
    00067     // Check for proper initial stack and PC alignment.
    00068     //
    00069
    00070     if (((ULONG)InitialSp & 0x7) != 0) {
    00071         RtlRaiseStatus(STATUS_BAD_INITIAL_STACK);
    00072     }
    00073     if (((ULONG)InitialPc & 0x3) != 0) {
    00074         RtlRaiseStatus(STATUS_BAD_INITIAL_PC);
    00075     }
    00076
    00077     //
    00078     // Initialize the integer and floating registers to contain zeroes.
    00079     //
    00080
    00081     RtlZeroMemory(Context, sizeof(CONTEXT));
    00082
    00083     //
    00084     // Initialize the control registers.
    00085     //
    00086
    00087     if ( ARGUMENT_PRESENT(InitialPc) ) {
    00088         Context->Iar = (ULONG)InitialPc;
    00089     }
    00090     if ( ARGUMENT_PRESENT(InitialSp) ) {
    00091         Context->Gpr1 = (ULONG)InitialSp - STK_MIN_FRAME;
    00092     }
    00093
    00094     Context->Msr =
    00095         MASK_SPR(MSR_ILE,1)|
    00096         MASK_SPR(MSR_FP,1) |
    00097         MASK_SPR(MSR_FE0,1)|
    00098         MASK_SPR(MSR_FE1,1)|
    00099         MASK_SPR(MSR_ME,1) |
    00100         MASK_SPR(MSR_IR,1) |
    00101         MASK_SPR(MSR_DR,1) |
    00102         MASK_SPR(MSR_PR,1) |
    00103         MASK_SPR(MSR_LE,1);
    00104     Context->ContextFlags = CONTEXT_FULL;
    00105
    00106     //
    00107     // Set the initial context of the thread in a machine specific way.
    00108     //
    00109
    00110     Context->Gpr3 = (ULONG)Parameter;
    00111 }

NTSTATUS RtlRemoteCall | ( | HANDLE | Process,
|  | HANDLE | Thread,
|  | PVOID | CallSite,
|  | ULONG | ArgumentCount,
|  | PULONG | Arguments,
|  | BOOLEAN | PassContext,
|  | BOOLEAN | AlreadySuspended
| ) |

Definition at line 114 of file rtl/ppc/context.c.

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

Referenced by SrvActivateDebugger().

    00126                    :
    00127
    00128     This function calls a procedure in another thread/process,  by using
    00129     NtGetContext and NtSetContext. Parameters are passed to the target
    00130     procedure via the nonvolatile registers (s0 - s7).
    00131
    00132 Arguments:
    00133
    00134     Process - Supplies an open handle to the target process.
    00135
    00136     Thread - Supplies an open handle to the target thread within the target
    00137         process.
    00138
    00139     CallSize - Supplies the address of the procedure to call in the target
    00140         process.
    00141
    00142     ArgumentCount - Supplies the number of 32 bit parameters to pass to the
    00143         target procedure.
    00144
    00145     Arguments - Supplies a pointer to the array of 32 bit parameters to pass.
    00146
    00147     PassContext - Supplies a boolean value that determines whether a parameter
    00148         is to be passed that points to a context record. This parameter is
    00149         ignored on MIPS hosts.
    00150
    00151     AlreadySuspended - Supplies a boolean value that determines whether the
    00152         target thread is already in a suspended or waiting state.
    00153
    00154 Return Value:
    00155
    00156     Status - Status value
    00157
    00158 --*/
    00159
    00160 {
    00161
    00162     NTSTATUS Status;
    00163     CONTEXT Context;
    00164     ULONG NewSp;
    00165
    00166     if (ArgumentCount > 8) {
    00167         return(STATUS_INVALID_PARAMETER);
    00168     }
    00169
    00170     //
    00171     // If necessary, suspend the target thread before getting the thread's
    00172     // current state.
    00173     //
    00174
    00175     if (AlreadySuspended == FALSE) {
    00176         Status = NtSuspendThread(Thread, NULL);
    00177         if (NT_SUCCESS(Status) == FALSE) {
    00178             return(Status);
    00179         }
    00180     }
    00181
    00182     //
    00183     // Get the current state of the target thread.
    00184     //
    00185
    00186     Context.ContextFlags = CONTEXT_FULL;
    00187     Status = NtGetContextThread(Thread, &Context);
    00188     if (NT_SUCCESS(Status) == FALSE) {
    00189         if (AlreadySuspended == FALSE) {
    00190             NtResumeThread(Thread, NULL);
    00191         }
    00192         return(Status);
    00193     }
    00194
    00195     if (AlreadySuspended ) {
    00196
    00197         Context.Gpr3 = STATUS_ALERTED;
    00198     }
    00199
    00200     //
    00201     // Pass the parameters to the other thread via the non-volatile registers
    00202     // s0 - s7. The context record is passed on the stack of the target thread.
    00203     //
    00204
    00205     NewSp = Context.Gpr1 - sizeof(CONTEXT) - STK_MIN_FRAME;
    00206     Status = NtWriteVirtualMemory(Process, (PVOID)(NewSp + STK_MIN_FRAME), &Context,
    00207                                   sizeof(CONTEXT), NULL);
    00208     Status = NtWriteVirtualMemory(Process, (PVOID)NewSp, &Context.Gpr1,
    00209                                   sizeof(ULONG), NULL);
    00210     if (NT_SUCCESS(Status) == FALSE) {
    00211         if (AlreadySuspended == FALSE) {
    00212             NtResumeThread(Thread, NULL);
    00213         }
    00214         return(Status);
    00215     }
    00216
    00217     Context.Gpr1 = NewSp;
    00218
    00219     if (PassContext) {
    00220         Context.Gpr14 = NewSp + STK_MIN_FRAME;
    00221         RtlMoveMemory(&Context.Gpr15, Arguments, ArgumentCount * sizeof(ULONG));
    00222
    00223     } else {
    00224
    00225         RtlMoveMemory(&Context.Gpr14, Arguments, ArgumentCount * sizeof(ULONG));
    00226     }
    00227
    00228     //
    00229     // Set the address of the target code into FIR and set the thread context
    00230     // to cause the target procedure to be executed.
    00231     //
    00232
    00233     Context.Iar = (ULONG)CallSite;      // Set context will dereference the
    00234     Context.Gpr2 = 0;                   // FNDESC in the remote threads context
    00235     Status = NtSetContextThread(Thread, &Context);
    00236     if (AlreadySuspended == FALSE) {
    00237         NtResumeThread(Thread, NULL);
    00238     }
    00239     return(Status);
    00240 }
    }