192 lines
5 KiB
NASM
192 lines
5 KiB
NASM
|
title "Stubless Support"
|
||
|
;++
|
||
|
;
|
||
|
; Copyright (C) 2000 Microsoft Corporation
|
||
|
;
|
||
|
; Module Name:
|
||
|
;
|
||
|
; stubless.asm
|
||
|
;
|
||
|
; Abstract:
|
||
|
;
|
||
|
; This module contains interpreter support routines for the AMD64 platform.
|
||
|
;
|
||
|
; Author:
|
||
|
;
|
||
|
; David N. Cutler 30-Dec-2000
|
||
|
;
|
||
|
; Environment:
|
||
|
;
|
||
|
; User mode.
|
||
|
;
|
||
|
;--
|
||
|
|
||
|
include ksamd64.inc
|
||
|
|
||
|
extern ObjectStublessClient:proc
|
||
|
extern __chkstk:proc
|
||
|
|
||
|
;
|
||
|
; Define object stubless client macro.
|
||
|
;
|
||
|
|
||
|
STUBLESS_CLIENT macro Method
|
||
|
|
||
|
LEAF_ENTRY ObjectStublessClient&Method, _TEXT$00
|
||
|
|
||
|
mov r10d, Method ; set method number
|
||
|
jmp ObjectStubless ; finish in common code
|
||
|
|
||
|
LEAF_END ObjectStublessClient&Method, _TEXT$00
|
||
|
|
||
|
endm
|
||
|
|
||
|
;
|
||
|
; Generate stubless client thunks.
|
||
|
;
|
||
|
|
||
|
index = 3
|
||
|
|
||
|
rept (1023 - 3 + 1)
|
||
|
|
||
|
STUBLESS_CLIENT %index
|
||
|
|
||
|
index = index + 1
|
||
|
|
||
|
endm
|
||
|
|
||
|
subttl "Common Object Stubless Client Code"
|
||
|
;++
|
||
|
;
|
||
|
; long
|
||
|
; ObjectStubless (
|
||
|
; ...
|
||
|
; )
|
||
|
;
|
||
|
; Routine description:
|
||
|
;
|
||
|
; This function is jumped to from the corresponding linkage stub and calls
|
||
|
; the object stubless client routine to invoke the ultimate function.
|
||
|
;
|
||
|
; N.B. Only three of the possible floating argument registers are saved.
|
||
|
; The first argument is the "this" pointer, and therefore, cannot be
|
||
|
; a floating value.
|
||
|
;
|
||
|
; Arguments:
|
||
|
;
|
||
|
; ...
|
||
|
;
|
||
|
; Implicit Arguments:
|
||
|
;
|
||
|
; Method (r10d) - Supplies the method number from the thunk code.
|
||
|
;
|
||
|
; Return Value:
|
||
|
;
|
||
|
; The value as returned by the target function.
|
||
|
;
|
||
|
;--
|
||
|
|
||
|
OsFrame struct
|
||
|
SavedXmm1 dq ? ; saved nonvolatile registers
|
||
|
SavedXmm2 dq ? ;
|
||
|
SavedXmm3 dq ? ;
|
||
|
OsFrame ends
|
||
|
|
||
|
NESTED_ENTRY ObjectStubless, _TEXT$00
|
||
|
|
||
|
alloc_stack sizeof OsFrame ; allocate stack frame
|
||
|
save_xmm xmm1, OsFrame.SavedXmm1 ; save nonvolatile registers
|
||
|
save_xmm xmm2, OsFrame.SavedXmm2 ;
|
||
|
save_xmm xmm3, OsFrame.SavedXmm3 ;
|
||
|
|
||
|
END_PROLOGUE
|
||
|
|
||
|
mov sizeof OsFrame + 8[rsp], rcx ; save register arguments in
|
||
|
mov sizeof OsFrame + 16[rsp], rdx ; home addresses
|
||
|
mov sizeof OsFrame + 24[rsp], r8 ;
|
||
|
mov sizeof OsFrame + 32[rsp], r9 ;
|
||
|
lea rcx, sizeof OsFrame + 8[rsp] ; set address of argument list
|
||
|
mov rdx, rsp ; set address of floating registers
|
||
|
mov r8d, r10d ; set method number
|
||
|
call ObjectStublessClient ;
|
||
|
add rsp, sizeof OsFrame ; deallocate stack frame
|
||
|
ret ; return
|
||
|
|
||
|
NESTED_END ObjectStubless, _TEXT$00
|
||
|
|
||
|
subttl "Invoke Function with Parameter List"
|
||
|
;++
|
||
|
;
|
||
|
; REGISTER_TYPE
|
||
|
; Invoke (
|
||
|
; MANAGER_FUNCTION Function,
|
||
|
; REGISTER_TYPE *ArgumentList,
|
||
|
; ULONG Arguments
|
||
|
; )
|
||
|
;
|
||
|
; Routine description:
|
||
|
;
|
||
|
; This function builds an appropriate argument list and calls the specified
|
||
|
; function.
|
||
|
;
|
||
|
; Arguments:
|
||
|
;
|
||
|
; Function (rcx) - Supplies a pointer to the target function.
|
||
|
;
|
||
|
; ArgumentList (rdx) - Supplies a pointer to the argument list.
|
||
|
;
|
||
|
; Arguments (r8d) - Supplies the number of arguments.
|
||
|
;
|
||
|
; Return Value:
|
||
|
;
|
||
|
; The value as returned by the target function.
|
||
|
;
|
||
|
;--
|
||
|
|
||
|
NESTED_ENTRY Invoke, _TEXT$00
|
||
|
|
||
|
push_reg rdi ; save nonvolatile registers
|
||
|
push_reg rsi ;
|
||
|
push_reg rbp ;
|
||
|
set_frame rbp, 0 ; set frame pointer
|
||
|
|
||
|
END_PROLOGUE
|
||
|
|
||
|
mov eax, r8d ; round to even argument count
|
||
|
inc eax ;
|
||
|
and al, 0feh ;
|
||
|
shl eax, 3 ; compute number of bytes
|
||
|
call __chkstk ; check stack allocation
|
||
|
sub rsp, rax ; allocate argument list
|
||
|
mov r10, rcx ; save address of function
|
||
|
mov rsi, rdx ; set source argument list address
|
||
|
mov rdi, rsp ; set destination argument list address
|
||
|
mov ecx, r8d ; set number of arguments
|
||
|
rep movsq ; copy arguments to the stack
|
||
|
|
||
|
;
|
||
|
; N.B. All four argument registers are loaded regardless of the actual number
|
||
|
; of arguments.
|
||
|
;
|
||
|
; N.B. The first argument cannot be in a floating point register and therefore
|
||
|
; xmm0 is not loaded.
|
||
|
;
|
||
|
|
||
|
mov rcx, 0[rsp] ; load first four argument registers
|
||
|
mov rdx, 8[rsp] ;
|
||
|
movq xmm1, 8[rsp] ;
|
||
|
mov r8, 16[rsp] ;
|
||
|
movq xmm2, 16[rsp] ;
|
||
|
mov r9, 24[rsp] ;
|
||
|
movq xmm3, 24[rsp] ;
|
||
|
call r10 ; call target function
|
||
|
mov rsp, rbp ; deallocate argument list
|
||
|
pop rbp ; restore nonvolatile register
|
||
|
pop rsi ;
|
||
|
pop rdi ;
|
||
|
ret ;
|
||
|
|
||
|
NESTED_END Invoke, _TEXT$00
|
||
|
|
||
|
end
|