mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
264 lines
6.6 KiB
264 lines
6.6 KiB
// TITLE("Win32 Thunks")
|
|
//++
|
|
//
|
|
// Copyright (c) 1990 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// thunk.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements Win32 functions that must be written in assembler.
|
|
//
|
|
// Author:
|
|
//
|
|
// Mark Lucovsky (markl) 5-Oct-1990
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Thomas Van Baak (tvb) 21-Jul-1992
|
|
//
|
|
// Adapted for Alpha AXP.
|
|
//
|
|
//--
|
|
|
|
#include "ksalpha.h"
|
|
|
|
//
|
|
// Division by 10000 is accomplished using reciprocal multiplication.
|
|
// Define the magic muliplier and right shift values for this.
|
|
//
|
|
|
|
#define MAGIC_10000_MULTIPLY 0xd1b71758e219652c
|
|
#define MAGIC_10000_SHIFT 13
|
|
|
|
|
|
SBTTL("Switch Stack Then Terminate")
|
|
//++
|
|
//
|
|
// VOID
|
|
// BaseSwitchStackThenTerminate (
|
|
// IN PVOID StackLimit,
|
|
// IN PVOID NewStack,
|
|
// IN DWORD ExitCode
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This API is called during thread termination to delete a thread's
|
|
// stack, switch to a stack in the thread's TEB, and then terminate.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// StackLimit (a0) - Supplies the address of the stack to be freed.
|
|
//
|
|
// NewStack (a1) - Supplies an address within the terminating thread's TE
|
|
// that is to be used as its temporary stack while exiting.
|
|
//
|
|
// ExitCode (a2) - Supplies the termination status that the thread
|
|
// is to exit with.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(BaseSwitchStackThenTerminate)
|
|
|
|
//
|
|
// Switch stacks and then jump to BaseFreeStackAndTerminate.
|
|
//
|
|
|
|
mov a1, sp // set new stack pointer
|
|
mov a2, a1 // set exit code argument
|
|
br zero, BaseFreeStackAndTerminate // jump
|
|
|
|
.end BaseSwitchStackThenTerminate
|
|
|
|
SBTTL("Base Attach Complete")
|
|
//++
|
|
//
|
|
// The following code is never executed. Its purpose is to support unwinding
|
|
// through the call to the exception dispatcher.
|
|
//
|
|
//--
|
|
|
|
NESTED_ENTRY(BaseAttachCompThunk, ContextFrameLength, zero);
|
|
|
|
.set noreorder
|
|
.set noat
|
|
|
|
lda sp, -ContextFrameLength(sp) // allocate stack frame
|
|
stq sp, CxIntSp(sp) // save stack pointer
|
|
stq ra, CxIntRa(sp) // save return address
|
|
stq ra, CxFir(sp) // mark continuation address location
|
|
stq fp, CxIntFp(sp) // save integer register fp/s6
|
|
stq gp, CxIntGp(sp) // save integer register gp
|
|
|
|
stq s0, CxIntS0(sp) // save integer registers s0 - s5
|
|
stq s1, CxIntS1(sp) //
|
|
stq s2, CxIntS2(sp) //
|
|
stq s3, CxIntS3(sp) //
|
|
stq s4, CxIntS4(sp) //
|
|
stq s5, CxIntS5(sp) //
|
|
|
|
stt f2, CxFltF2(sp) // store floating registers f2 - f9
|
|
stt f3, CxFltF3(sp) //
|
|
stt f4, CxFltF4(sp) //
|
|
stt f5, CxFltF5(sp) //
|
|
stt f6, CxFltF6(sp) //
|
|
stt f7, CxFltF7(sp) //
|
|
stt f8, CxFltF8(sp) //
|
|
stt f9, CxFltF9(sp) //
|
|
|
|
.set at
|
|
.set reorder
|
|
|
|
PROLOGUE_END
|
|
//++
|
|
//
|
|
// VOID
|
|
// BaseAttachCompleteThunk (
|
|
// VOID
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function is called after a successful debug attach. Its
|
|
// purpose is to call portable code that does a breakpoint, followed
|
|
// by an NtContinue.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
ALTERNATE_ENTRY(BaseAttachCompleteThunk)
|
|
|
|
mov s0, a0 // set context frame address argument
|
|
br zero, BaseAttachComplete // jump
|
|
|
|
.end BaseAttachCompThunk
|
|
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// WINAPI
|
|
// SwitchToFiber (
|
|
// LPVOID lpFiber
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function saves the state of the current fiber and switches
|
|
// to the new fiber.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// CurrentFiber - Supplies the address of the current fiber.
|
|
//
|
|
// NewFiber - Supplies the address of the new fiber.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
LEAF_ENTRY(SwitchToFiber)
|
|
|
|
GET_THREAD_ENVIRONMENT_BLOCK // get TEB in v0
|
|
|
|
//
|
|
// Get current fiber
|
|
//
|
|
ldl a1, TeFiberData(v0)
|
|
|
|
//
|
|
// Set new deallocation stack and fiberdata in TEB
|
|
//
|
|
ldl t0, FbDeallocationStack(a0)
|
|
stl t0, TeDeallocationStack(v0)
|
|
stl a0, TeFiberData(v0)
|
|
|
|
//
|
|
// Save stack limit.
|
|
//
|
|
ldl t1, TeStackLimit(v0)
|
|
stl t1, FbStackLimit(a1) // save StackLimit
|
|
|
|
//
|
|
// Save nonvolatile integer state
|
|
//
|
|
stq s0, CxIntS0+FbFiberContext(a1)
|
|
stq s1, CxIntS1+FbFiberContext(a1)
|
|
stq s2, CxIntS2+FbFiberContext(a1)
|
|
stq s3, CxIntS3+FbFiberContext(a1)
|
|
stq s4, CxIntS4+FbFiberContext(a1)
|
|
stq s5, CxIntS5+FbFiberContext(a1)
|
|
stq fp, CxIntFp+FbFiberContext(a1)
|
|
|
|
//
|
|
// Save nonvolatile float state
|
|
//
|
|
stt f2, CxFltF2+FbFiberContext(a1)
|
|
stt f3, CxFltF3+FbFiberContext(a1)
|
|
stt f4, CxFltF4+FbFiberContext(a1)
|
|
stt f5, CxFltF5+FbFiberContext(a1)
|
|
stt f6, CxFltF6+FbFiberContext(a1)
|
|
stt f7, CxFltF7+FbFiberContext(a1)
|
|
stt f8, CxFltF8+FbFiberContext(a1)
|
|
stt f9, CxFltF9+FbFiberContext(a1)
|
|
|
|
//
|
|
// Save RA and SP
|
|
//
|
|
stq ra, CxFir+FbFiberContext(a1)
|
|
stq sp, CxIntSp+FbFiberContext(a1)
|
|
|
|
//
|
|
// Restore new fiber's stack base and stack limit
|
|
//
|
|
ldl t0, FbStackBase(a0) // restore StackBase
|
|
stl t0, TeStackBase(v0)
|
|
ldl t1, FbStackLimit(a0) // restore StackLimit
|
|
stl t1, TeStackLimit(v0)
|
|
|
|
//
|
|
// Restore nonvolatile integer state
|
|
//
|
|
ldq s0, CxIntS0+FbFiberContext(a0)
|
|
ldq s1, CxIntS1+FbFiberContext(a0)
|
|
ldq s2, CxIntS2+FbFiberContext(a0)
|
|
ldq s3, CxIntS3+FbFiberContext(a0)
|
|
ldq s4, CxIntS4+FbFiberContext(a0)
|
|
ldq s5, CxIntS5+FbFiberContext(a0)
|
|
ldq fp, CxIntFp+FbFiberContext(a0)
|
|
|
|
//
|
|
// Restore nonvolatile float state
|
|
//
|
|
ldt f2, CxFltF2+FbFiberContext(a0)
|
|
ldt f3, CxFltF3+FbFiberContext(a0)
|
|
ldt f4, CxFltF4+FbFiberContext(a0)
|
|
ldt f5, CxFltF5+FbFiberContext(a0)
|
|
ldt f6, CxFltF6+FbFiberContext(a0)
|
|
ldt f7, CxFltF7+FbFiberContext(a0)
|
|
ldt f8, CxFltF8+FbFiberContext(a0)
|
|
ldt f9, CxFltF9+FbFiberContext(a0)
|
|
|
|
//
|
|
// Restore RA and SP
|
|
//
|
|
ldq ra, CxFir+FbFiberContext(a0)
|
|
ldq sp, CxIntSp+FbFiberContext(a0)
|
|
|
|
ret zero, (ra)
|
|
|
|
.end BasepSwitchToFiber
|