Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

497 lines
9.9 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
thunk.s
Abstract:
Implements the API thunk that gets executed for all
re-directed APIS.
Author:
Wesley Witt (wesw) 28-June-1995
Environment:
User Mode
--*/
#include <ksalpha.h>
.extern HandleDynamicDllLoadA
.extern HandleDynamicDllLoadW
.extern QueryPerformanceCounter
.extern GetApiInfo
.extern ApiCounter
.extern pGetLastError
.extern pSetLastError
.extern pTlsGetValue
.extern pTlsSetValue
.extern TlsReEnter
.extern TlsStack
#define move(r1,of1,r2,of2) ldq t9,of1(r1); stq t9,of2(r2)
#define DllEnabledOffset 52
#define ApiInfoCountOffset 12
#define ApiInfoAddressOffset 4
#define ApiInfoTimeOffset 16
#define RaFrm 0
#define A0Frm 8
#define A1Frm 16
#define A2Frm 24
#define A3Frm 32
#define A4Frm 40
#define A5Frm 48
#define DllInfoFrm 56
#define ApiInfoFrm 64
#define FlagFrm 72
#define S5Frm 80
#define TimeFrm 88
#define FrameSize 96
#define RaSave 0
#define A0Save 8
#define A1Save 16
#define A2Save 24
#define A3Save 32
#define A4Save 40
#define A5Save 48
#define DllInfoSave 56
#define ApiInfoSave 64
#define FlagSave 72
#define V0Save 80
#define LastErrorSave 88
#define FuncAddrSave 96
#define TimeSave 104
#define StackSize 112
/*++ >>>> ApiMonThunkComplete <<<<
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
.text;
.globl ApiMonThunkComplete;
.ent ApiMonThunkComplete, 0;
ApiMonThunkComplete:;
.set noreorder
//
// create some temporary stack
//
lda sp,-StackSize(sp)
//
// save the return value from the api
//
stq v0,V0Save(sp)
//
// save the last error value
//
ldl v0,pGetLastError
jsr ra,(v0),0
stq v0,LastErrorSave(sp)
//
// get the final timestamp value
//
addl sp,TimeSave,a0
jsr QueryPerformanceCounter
//
// compute the time used for this api
//
ldq t8,TimeFrm(s5)
ldq t9,TimeSave(sp)
subq t9,t8,t9
//
// add the result to the api's time counter
//
ldq t11,ApiInfoSave(s5)
ldq t10,ApiInfoTimeOffset(t11)
addq t9,t10,t9
stq t9,ApiInfoTimeOffset(t11)
//
// branch to the correct handler
//
ldl t12,FlagFrm(s5)
beq t12,ThunkNormal
xor t12,1,t9
beq t9,DoLoadLibraryA
xor t12,2,t9
beq t9,DoLoadLibraryW
xor t12,3,t9
beq t9,DoFreeLibrary
jmp ThunkNormal
DoLoadLibraryW:
ldl a0,V0Save(sp)
ldl a1,A0Frm(s5)
jsr HandleDynamicDllLoadW
jmp ThunkNormal
DoLoadLibraryA:
ldl a0,V0Save(sp)
ldl a1,A0Frm(s5)
jsr HandleDynamicDllLoadA
jmp ThunkNormal
DoFreeLibrary:
ldl a0,A0Frm(s5)
jsr HandleDynamicDllFree
//jmp ThunkNormal
ThunkNormal:
//
// do the api tracing?
//
ldl t9,ApiTraceEnabled
beq t9,NoTracing
ldl a0,ApiInfoFrm(s5)
addl s5,A0Frm,a1
ldl a2,V0Save(sp)
jsr ApiTrace
NoTracing:
//
// destroy this frame
//
bis s5,zero,a1
ldl a0,TlsStack
ldl v0,pTlsSetValue
jsr ra,(v0),0
//
// reset the last error value
//
ldl a0,LastErrorSave(sp)
ldl v0,pSetLastError
jsr ra,(v0),0
//
// restore the registers
//
ldq ra,RaFrm(s5)
ldq s5,S5Frm(s5)
ldq v0,V0Save(sp)
//
// reset the stack pointer
//
lda sp,StackSize(sp)
//
// jump back to the caller
//
ret zero,(ra),0
.set reorder
.end ApiMonThunkComplete
/*++ >>>> ApiMonThunk <<<<
Routine Description:
Each API is routed through a thunk which stores a description of the
call, then jumps to this entry point.
Arguments:
t10 - Supplies a pointer to a DLL_INFO structure
t11 - Supplies a pointer to an API_INFO structure
t12 - Supplies the special API flag:
0 - none
1 - LoadLibraryA,
2 - LoadLibraryW
Return Value:
None.
--*/
.text;
.globl ApiMonThunk;
.ent ApiMonThunk, 0;
ApiMonThunk:;
.set noreorder
//
// create some temporary stack
//
lda sp,-StackSize(sp)
//
// Save ApiMon args
//
stq t10,DllInfoSave(sp)
stq t11,ApiInfoSave(sp)
stq t12,FlagSave(sp)
//
// save the argument registers
//
stq a0,A0Save(sp)
stq a1,A1Save(sp)
stq a2,A2Save(sp)
stq a3,A3Save(sp)
stq a4,A4Save(sp)
stq a5,A5Save(sp)
stq ra,RaSave(sp)
//
// save the last error value
//
ldl v0,pGetLastError
jsr ra,(v0),0
stq v0,LastErrorSave(sp)
//
// get the reentry flag
//
ldl a0,TlsReEnter
ldl v0,pTlsGetValue
jsr ra,(v0),0
//
// don't enter if disallow flag is set
//
beq v0,ThunkOk
DontReEnter:
//
// reset the last error value
//
ldl a0,LastErrorSave(sp)
ldl v0,pSetLastError
jsr ra,(v0),0
//
// restore the registers
//
ldq a0,A0Save(sp)
ldq a1,A1Save(sp)
ldq a2,A2Save(sp)
ldq a3,A3Save(sp)
ldq a4,A4Save(sp)
ldq a5,A5Save(sp)
ldq ra,RaSave(sp)
ldq t11,ApiInfoSave(sp)
//
// reset the stack pointer
//
lda sp,StackSize(sp)
//
// jump to the real api
//
ldl v0,ApiInfoAddressOffset(t11)
jmp zero,(v0),0
ThunkOk:
//
// don't allow re-entry
//
ldl a0,TlsReEnter
bis zero,1,a1
ldl v0,pTlsSetValue
jsr ra,(v0),0
//
// get the parallel stack pointer
//
ldl a0,TlsStack
ldl v0,pTlsGetValue
jsr ra,(v0),0
//
// create a frame on the stack
//
stq s5,S5Frm(v0)
bis v0,zero,s5
addl v0,FrameSize,a1
ldl a0,TlsStack
ldl v0,pTlsSetValue
jsr ra,(v0),0
//
// move the data into the parallel stack frame
//
move ( sp, RaSave, s5, RaFrm )
move ( sp, A0Save, s5, A0Frm )
move ( sp, A1Save, s5, A1Frm )
move ( sp, A2Save, s5, A2Frm )
move ( sp, A3Save, s5, A3Frm )
move ( sp, A4Save, s5, A4Frm )
move ( sp, A5Save, s5, A5Frm )
move ( sp, DllInfoSave, s5, DllInfoFrm )
move ( sp, ApiInfoSave, s5, ApiInfoFrm )
move ( sp, FlagSave, s5, FlagFrm )
Thunk_Middle:
//
// check to see if api counting is enabled
// if not then bypass the counting code
//
ldl t10,DllInfoSave(sp)
ldl t10,DllEnabledOffset(t10)
beq t10,ThunkBypass
//
// get the initial timestamp value
//
addl s5,TimeFrm,a0
jsr QueryPerformanceCounter
//
// increment the api's counter
//
ldl t11,ApiInfoSave(sp)
ldl t9,ApiInfoCountOffset(t11)
addl t9,1,t9
stl t9,ApiInfoCountOffset(t11)
//
// increment the global api counter
//
lda t9,ApiCounter
ldl t9,0(t9)
ldl t8,0(t9)
addl t8,1,t8
stl t8,0(t9)
ThunkBypass:
//
// reset the last error value
//
ldl a0,LastErrorSave(sp)
ldl v0,pSetLastError
jsr ra,(v0),0
//
// allow re-entry
//
ldl a0,TlsReEnter
bis zero,0,a1
ldl v0,pTlsSetValue
jsr ra,(v0),0
//
// change the return address to the completion thunk
//
lda ra,ApiMonThunkComplete
//
// restore the registers
//
ldq a0,A0Save(sp)
ldq a1,A1Save(sp)
ldq a2,A2Save(sp)
ldq a3,A3Save(sp)
ldq a4,A4Save(sp)
ldq a5,A5Save(sp)
//
// get the func address
//
ldl t11,ApiInfoSave(sp)
ldl v0,ApiInfoAddressOffset(t11)
//
// reset the stack pointer
//
lda sp,StackSize(sp)
//
// jump to the real api
//
jmp zero,(v0),0
.set reorder
.end ApiMonThunk
/*++ >>>> __penter <<<<
Routine Description:
None.
Arguments:
None.
Return Value:
None.
--*/
.text;
.globl __penter;
.ent __penter, 0;
__penter:;
.set noreorder
ret zero,(ra),1
.set reorder
.end __penter