Remove assumption on EAX and R10 usage for IA32 compiler and X64 compiler.
Signed-off-by: jyao1 Reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12760 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
db40504eae
commit
7102b19961
@ -14,6 +14,8 @@
|
|||||||
#**/
|
#**/
|
||||||
|
|
||||||
ASM_GLOBAL ASM_PFX(CopyMem)
|
ASM_GLOBAL ASM_PFX(CopyMem)
|
||||||
|
ASM_GLOBAL ASM_PFX(EbcInterpret)
|
||||||
|
ASM_GLOBAL ASM_PFX(ExecuteEbcImageEntryPoint)
|
||||||
|
|
||||||
ASM_GLOBAL ASM_PFX(EbcLLCALLEXNative)
|
ASM_GLOBAL ASM_PFX(EbcLLCALLEXNative)
|
||||||
ASM_PFX(EbcLLCALLEXNative):
|
ASM_PFX(EbcLLCALLEXNative):
|
||||||
@ -42,6 +44,40 @@ ASM_PFX(EbcLLCALLEXNative):
|
|||||||
pop %ebp
|
pop %ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
ASM_GLOBAL ASM_PFX(EbcLLGetEbcEntryPoint)
|
ASM_GLOBAL ASM_PFX(EbcLLEbcInterpret)
|
||||||
ASM_PFX(EbcLLGetEbcEntryPoint):
|
ASM_PFX(EbcLLEbcInterpret):
|
||||||
ret
|
# Construct new stack
|
||||||
|
push %ebp
|
||||||
|
mov %esp, %ebp
|
||||||
|
push %esi
|
||||||
|
push %edi
|
||||||
|
sub $0x40, %esp
|
||||||
|
push %eax
|
||||||
|
mov %ebp, %esi
|
||||||
|
add $0x8, %esi
|
||||||
|
mov %esp, %edi
|
||||||
|
add $0x4, %edi
|
||||||
|
mov $0x10, %ecx
|
||||||
|
rep movsd
|
||||||
|
|
||||||
|
# call C-code
|
||||||
|
call ASM_PFX(EbcInterpret)
|
||||||
|
add $0x44, %esp
|
||||||
|
pop %edi
|
||||||
|
pop %esi
|
||||||
|
pop %ebp
|
||||||
|
ret
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(EbcLLExecuteEbcImageEntryPoint)
|
||||||
|
ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
|
||||||
|
# Construct new stack
|
||||||
|
mov %eax, -0xC(%esp)
|
||||||
|
mov 0x4(%esp), %eax
|
||||||
|
mov %eax, -0x8(%esp)
|
||||||
|
mov 0x8(%esp), %eax
|
||||||
|
mov %eax, -0x4(%esp)
|
||||||
|
# call C-code
|
||||||
|
sub $0xC, %esp
|
||||||
|
call ASM_PFX(ExecuteEbcImageEntryPoint)
|
||||||
|
add $0xC, %esp
|
||||||
|
ret
|
||||||
|
@ -30,9 +30,11 @@
|
|||||||
;---------------------------------------------------------------------------
|
;---------------------------------------------------------------------------
|
||||||
|
|
||||||
.686p
|
.686p
|
||||||
.model flat
|
.model flat, C
|
||||||
.code
|
.code
|
||||||
CopyMem PROTO C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
|
CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
|
||||||
|
EbcInterpret PROTO
|
||||||
|
ExecuteEbcImageEntryPoint PROTO
|
||||||
|
|
||||||
;****************************************************************************
|
;****************************************************************************
|
||||||
; EbcLLCALLEXNative
|
; EbcLLCALLEXNative
|
||||||
@ -47,7 +49,7 @@ CopyMem PROTO C Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
|
|||||||
; Destroys no working registers.
|
; Destroys no working registers.
|
||||||
;****************************************************************************
|
;****************************************************************************
|
||||||
; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
|
; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)
|
||||||
_EbcLLCALLEXNative PROC PUBLIC
|
EbcLLCALLEXNative PROC PUBLIC
|
||||||
push ebp
|
push ebp
|
||||||
push ebx
|
push ebx
|
||||||
mov ebp, esp ; standard function prolog
|
mov ebp, esp ; standard function prolog
|
||||||
@ -85,25 +87,121 @@ _EbcLLCALLEXNative PROC PUBLIC
|
|||||||
pop ebx
|
pop ebx
|
||||||
pop ebp
|
pop ebp
|
||||||
ret
|
ret
|
||||||
_EbcLLCALLEXNative ENDP
|
EbcLLCALLEXNative ENDP
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
; EbcLLEbcInterpret
|
||||||
|
;
|
||||||
|
; Begin executing an EBC image.
|
||||||
|
;****************************************************************************
|
||||||
|
; UINT64 EbcLLEbcInterpret(VOID)
|
||||||
|
EbcLLEbcInterpret PROC PUBLIC
|
||||||
|
;
|
||||||
|
;; mov eax, 0xca112ebc
|
||||||
|
;; mov eax, EbcEntryPoint
|
||||||
|
;; mov ecx, EbcLLEbcInterpret
|
||||||
|
;; jmp ecx
|
||||||
|
;
|
||||||
|
; Caller uses above instruction to jump here
|
||||||
|
; The stack is below:
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr |
|
||||||
|
; +-----------+
|
||||||
|
; |EntryPoint | (EAX)
|
||||||
|
; +-----------+
|
||||||
|
; | Arg1 | <- EDI
|
||||||
|
; +-----------+
|
||||||
|
; | Arg2 |
|
||||||
|
; +-----------+
|
||||||
|
; | ... |
|
||||||
|
; +-----------+
|
||||||
|
; | Arg16 |
|
||||||
|
; +-----------+
|
||||||
|
; | EDI |
|
||||||
|
; +-----------+
|
||||||
|
; | ESI |
|
||||||
|
; +-----------+
|
||||||
|
; | EBP | <- EBP
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr | <- ESP is here
|
||||||
|
; +-----------+
|
||||||
|
; | Arg1 | <- ESI
|
||||||
|
; +-----------+
|
||||||
|
; | Arg2 |
|
||||||
|
; +-----------+
|
||||||
|
; | ... |
|
||||||
|
; +-----------+
|
||||||
|
; | Arg16 |
|
||||||
|
; +-----------+
|
||||||
|
;
|
||||||
|
|
||||||
; UINTN EbcLLGetEbcEntryPoint(VOID);
|
; Construct new stack
|
||||||
; Routine Description:
|
push ebp
|
||||||
; The VM thunk code stuffs an EBC entry point into a processor
|
mov ebp, esp
|
||||||
; register. Since we can't use inline assembly to get it from
|
push esi
|
||||||
; the interpreter C code, stuff it into the return value
|
push edi
|
||||||
; register and return.
|
sub esp, 40h
|
||||||
;
|
push eax
|
||||||
; Arguments:
|
mov esi, ebp
|
||||||
; None.
|
add esi, 8
|
||||||
;
|
mov edi, esp
|
||||||
; Returns:
|
add edi, 4
|
||||||
; The contents of the register in which the entry point is passed.
|
mov ecx, 16
|
||||||
;
|
rep movsd
|
||||||
_EbcLLGetEbcEntryPoint PROC PUBLIC
|
|
||||||
; The EbcEntryPoint is saved to EAX, so just return here.
|
; call C-code
|
||||||
|
call EbcInterpret
|
||||||
|
add esp, 44h
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebp
|
||||||
ret
|
ret
|
||||||
_EbcLLGetEbcEntryPoint ENDP
|
EbcLLEbcInterpret ENDP
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
; EbcLLExecuteEbcImageEntryPoint
|
||||||
|
;
|
||||||
|
; Begin executing an EBC image.
|
||||||
|
;****************************************************************************
|
||||||
|
; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
|
||||||
|
EbcLLExecuteEbcImageEntryPoint PROC PUBLIC
|
||||||
|
;
|
||||||
|
;; mov eax, 0xca112ebc
|
||||||
|
;; mov eax, EbcEntryPoint
|
||||||
|
;; mov ecx, EbcLLExecuteEbcImageEntryPoint
|
||||||
|
;; jmp ecx
|
||||||
|
;
|
||||||
|
; Caller uses above instruction to jump here
|
||||||
|
; The stack is below:
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr |
|
||||||
|
; +-----------+
|
||||||
|
; |EntryPoint | (EAX)
|
||||||
|
; +-----------+
|
||||||
|
; |ImageHandle|
|
||||||
|
; +-----------+
|
||||||
|
; |SystemTable|
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr | <- ESP is here
|
||||||
|
; +-----------+
|
||||||
|
; |ImageHandle|
|
||||||
|
; +-----------+
|
||||||
|
; |SystemTable|
|
||||||
|
; +-----------+
|
||||||
|
;
|
||||||
|
|
||||||
|
; Construct new stack
|
||||||
|
mov [esp - 0Ch], eax
|
||||||
|
mov eax, [esp + 04h]
|
||||||
|
mov [esp - 08h], eax
|
||||||
|
mov eax, [esp + 08h]
|
||||||
|
mov [esp - 04h], eax
|
||||||
|
|
||||||
|
; call C-code
|
||||||
|
sub esp, 0Ch
|
||||||
|
call ExecuteEbcImageEntryPoint
|
||||||
|
add esp, 0Ch
|
||||||
|
ret
|
||||||
|
EbcLLExecuteEbcImageEntryPoint ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
@ -27,6 +27,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#define STACK_REMAIN_SIZE (1024 * 4)
|
#define STACK_REMAIN_SIZE (1024 * 4)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Begin executing an EBC image.
|
||||||
|
This is used for Ebc Thunk call.
|
||||||
|
|
||||||
|
@return The value returned by the EBC application we're going to run.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
EFIAPI
|
||||||
|
EbcLLEbcInterpret (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Begin executing an EBC image.
|
||||||
|
This is used for Ebc image entrypoint.
|
||||||
|
|
||||||
|
@return The value returned by the EBC application we're going to run.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
EFIAPI
|
||||||
|
EbcLLExecuteEbcImageEntryPoint (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function is called to execute an EBC CALLEX instruction.
|
This function is called to execute an EBC CALLEX instruction.
|
||||||
@ -131,14 +156,13 @@ Action:
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begin executing an EBC image. The address of the entry point is passed
|
Begin executing an EBC image.
|
||||||
in via a processor register, so we'll need to make a call to get the
|
|
||||||
value.
|
|
||||||
|
|
||||||
This is a thunk function. Microsoft x64 compiler only provide fast_call
|
This is a thunk function. Microsoft x64 compiler only provide fast_call
|
||||||
calling convention, so the first four arguments are passed by rcx, rdx,
|
calling convention, so the first four arguments are passed by rcx, rdx,
|
||||||
r8, and r9, while other arguments are passed in stack.
|
r8, and r9, while other arguments are passed in stack.
|
||||||
|
|
||||||
|
@param EntryPoint The entrypoint of EBC code.
|
||||||
@param Arg1 The 1st argument.
|
@param Arg1 The 1st argument.
|
||||||
@param Arg2 The 2nd argument.
|
@param Arg2 The 2nd argument.
|
||||||
@param Arg3 The 3rd argument.
|
@param Arg3 The 3rd argument.
|
||||||
@ -162,22 +186,23 @@ Action:
|
|||||||
UINT64
|
UINT64
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EbcInterpret (
|
EbcInterpret (
|
||||||
IN OUT UINTN Arg1,
|
IN UINTN EntryPoint,
|
||||||
IN OUT UINTN Arg2,
|
IN UINTN Arg1,
|
||||||
IN OUT UINTN Arg3,
|
IN UINTN Arg2,
|
||||||
IN OUT UINTN Arg4,
|
IN UINTN Arg3,
|
||||||
IN OUT UINTN Arg5,
|
IN UINTN Arg4,
|
||||||
IN OUT UINTN Arg6,
|
IN UINTN Arg5,
|
||||||
IN OUT UINTN Arg7,
|
IN UINTN Arg6,
|
||||||
IN OUT UINTN Arg8,
|
IN UINTN Arg7,
|
||||||
IN OUT UINTN Arg9,
|
IN UINTN Arg8,
|
||||||
IN OUT UINTN Arg10,
|
IN UINTN Arg9,
|
||||||
IN OUT UINTN Arg11,
|
IN UINTN Arg10,
|
||||||
IN OUT UINTN Arg12,
|
IN UINTN Arg11,
|
||||||
IN OUT UINTN Arg13,
|
IN UINTN Arg12,
|
||||||
IN OUT UINTN Arg14,
|
IN UINTN Arg13,
|
||||||
IN OUT UINTN Arg15,
|
IN UINTN Arg14,
|
||||||
IN OUT UINTN Arg16
|
IN UINTN Arg15,
|
||||||
|
IN UINTN Arg16
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -189,9 +214,9 @@ EbcInterpret (
|
|||||||
UINTN StackIndex;
|
UINTN StackIndex;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the EBC entry point from the processor register.
|
// Get the EBC entry point
|
||||||
//
|
//
|
||||||
Addr = EbcLLGetEbcEntryPoint ();
|
Addr = EntryPoint;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now clear out our context
|
// Now clear out our context
|
||||||
@ -297,10 +322,9 @@ EbcInterpret (
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begin executing an EBC image. The address of the entry point is passed
|
Begin executing an EBC image.
|
||||||
in via a processor register, so we'll need to make a call to get the
|
|
||||||
value.
|
|
||||||
|
|
||||||
|
@param EntryPoint The entrypoint of EBC code.
|
||||||
@param ImageHandle image handle for the EBC application we're executing
|
@param ImageHandle image handle for the EBC application we're executing
|
||||||
@param SystemTable standard system table passed into an driver's entry
|
@param SystemTable standard system table passed into an driver's entry
|
||||||
point
|
point
|
||||||
@ -311,6 +335,7 @@ EbcInterpret (
|
|||||||
UINT64
|
UINT64
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ExecuteEbcImageEntryPoint (
|
ExecuteEbcImageEntryPoint (
|
||||||
|
IN UINTN EntryPoint,
|
||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
@ -324,15 +349,10 @@ ExecuteEbcImageEntryPoint (
|
|||||||
UINTN StackIndex;
|
UINTN StackIndex;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the EBC entry point from the processor register. Make sure you don't
|
// Get the EBC entry point
|
||||||
// call any functions before this or you could mess up the register the
|
|
||||||
// entry point is passed in.
|
|
||||||
//
|
//
|
||||||
Addr = EbcLLGetEbcEntryPoint ();
|
Addr = EntryPoint;
|
||||||
|
|
||||||
//
|
|
||||||
// Print(L"*** Thunked into EBC entry point - ImageHandle = 0x%X\n", (UINTN)ImageHandle);
|
|
||||||
// Print(L"EBC entry point is 0x%X\n", (UINT32)(UINTN)Addr);
|
|
||||||
//
|
//
|
||||||
// Now clear out our context
|
// Now clear out our context
|
||||||
//
|
//
|
||||||
@ -496,9 +516,9 @@ EbcCreateThunks (
|
|||||||
// mov ecx 12345678h => 0xB9 0x78 0x56 0x34 0x12
|
// mov ecx 12345678h => 0xB9 0x78 0x56 0x34 0x12
|
||||||
//
|
//
|
||||||
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
||||||
Addr = (UINT32) (UINTN) ExecuteEbcImageEntryPoint;
|
Addr = (UINT32) (UINTN) EbcLLExecuteEbcImageEntryPoint;
|
||||||
} else {
|
} else {
|
||||||
Addr = (UINT32) (UINTN) EbcInterpret;
|
Addr = (UINT32) (UINTN) EbcLLEbcInterpret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
ASM_GLOBAL ASM_PFX(CopyMem);
|
ASM_GLOBAL ASM_PFX(CopyMem);
|
||||||
|
ASM_GLOBAL ASM_PFX(EbcInterpret);
|
||||||
|
ASM_GLOBAL ASM_PFX(ExecuteEbcImageEntryPoint);
|
||||||
|
|
||||||
#****************************************************************************
|
#****************************************************************************
|
||||||
# EbcLLCALLEX
|
# EbcLLCALLEX
|
||||||
@ -66,21 +68,53 @@ ASM_PFX(EbcLLCALLEXNative):
|
|||||||
pop %rbp
|
pop %rbp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(EbcLLEbcInterpret);
|
||||||
|
ASM_PFX(EbcLLEbcInterpret):
|
||||||
|
# save old parameter to stack
|
||||||
|
mov %rcx, 0x8(%rsp)
|
||||||
|
mov %rdx, 0x10(%rsp)
|
||||||
|
mov %r8, 0x18(%rsp)
|
||||||
|
mov %r9, 0x20(%rsp)
|
||||||
|
|
||||||
# UINTN EbcLLGetEbcEntryPoint(VOID);
|
# Construct new stack
|
||||||
# Routine Description:
|
push %rbp
|
||||||
# The VM thunk code stuffs an EBC entry point into a processor
|
mov %rsp, %rbp
|
||||||
# register. Since we can't use inline assembly to get it from
|
push %rsi
|
||||||
# the interpreter C code, stuff it into the return value
|
push %rdi
|
||||||
# register and return.
|
push %rbx
|
||||||
#
|
sub $0x80, %rsp
|
||||||
# Arguments:
|
push %r10
|
||||||
# None.
|
mov %rbp, %rsi
|
||||||
#
|
add $0x10, %rsi
|
||||||
# Returns:
|
mov %rsp, %rdi
|
||||||
# The contents of the register in which the entry point is passed.
|
add $0x8, %rdi
|
||||||
#
|
mov $0x10, %rcx
|
||||||
ASM_GLOBAL ASM_PFX(EbcLLGetEbcEntryPoint);
|
rep movsq
|
||||||
ASM_PFX(EbcLLGetEbcEntryPoint):
|
|
||||||
mov %r10, %rax
|
# build new paramater calling convention
|
||||||
|
mov 0x18(%rsp), %r9
|
||||||
|
mov 0x10(%rsp), %r8
|
||||||
|
mov 0x8(%rsp), %rdx
|
||||||
|
mov %r10, %rcx
|
||||||
|
|
||||||
|
# call C-code
|
||||||
|
call ASM_PFX(EbcInterpret)
|
||||||
|
add $0x88, %esp
|
||||||
|
pop %rbx
|
||||||
|
pop %rdi
|
||||||
|
pop %rsi
|
||||||
|
pop %rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
ASM_GLOBAL ASM_PFX(EbcLLExecuteEbcImageEntryPoint);
|
||||||
|
ASM_PFX(EbcLLExecuteEbcImageEntryPoint):
|
||||||
|
# build new paramater calling convention
|
||||||
|
mov %rdx, %r8
|
||||||
|
mov %rcx, %rdx
|
||||||
|
mov %r10, %rcx
|
||||||
|
|
||||||
|
# call C-code
|
||||||
|
sub $0x28, %rsp
|
||||||
|
call ASM_PFX(ExecuteEbcImageEntryPoint)
|
||||||
|
add $0x28, %rsp
|
||||||
ret
|
ret
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
.CODE
|
.CODE
|
||||||
|
|
||||||
CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
|
CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD
|
||||||
|
EbcInterpret PROTO
|
||||||
|
ExecuteEbcImageEntryPoint PROTO
|
||||||
|
|
||||||
;****************************************************************************
|
;****************************************************************************
|
||||||
; EbcLLCALLEX
|
; EbcLLCALLEX
|
||||||
@ -71,25 +73,146 @@ EbcLLCALLEXNative PROC PUBLIC
|
|||||||
ret
|
ret
|
||||||
EbcLLCALLEXNative ENDP
|
EbcLLCALLEXNative ENDP
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
; EbcLLEbcInterpret
|
||||||
|
;
|
||||||
|
; Begin executing an EBC image.
|
||||||
|
;****************************************************************************
|
||||||
|
; UINT64 EbcLLEbcInterpret(VOID)
|
||||||
|
EbcLLEbcInterpret PROC PUBLIC
|
||||||
|
;
|
||||||
|
;; mov rax, ca112ebccall2ebch
|
||||||
|
;; mov r10, EbcEntryPoint
|
||||||
|
;; mov r11, EbcLLEbcInterpret
|
||||||
|
;; jmp r11
|
||||||
|
;
|
||||||
|
; Caller uses above instruction to jump here
|
||||||
|
; The stack is below:
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr |
|
||||||
|
; +-----------+
|
||||||
|
; |EntryPoint | (R10)
|
||||||
|
; +-----------+
|
||||||
|
; | Arg1 | <- RDI
|
||||||
|
; +-----------+
|
||||||
|
; | Arg2 |
|
||||||
|
; +-----------+
|
||||||
|
; | ... |
|
||||||
|
; +-----------+
|
||||||
|
; | Arg16 |
|
||||||
|
; +-----------+
|
||||||
|
; | Dummy |
|
||||||
|
; +-----------+
|
||||||
|
; | RDI |
|
||||||
|
; +-----------+
|
||||||
|
; | RSI |
|
||||||
|
; +-----------+
|
||||||
|
; | RBP | <- RBP
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr | <- RSP is here
|
||||||
|
; +-----------+
|
||||||
|
; | Scratch1 | (RCX) <- RSI
|
||||||
|
; +-----------+
|
||||||
|
; | Scratch2 | (RDX)
|
||||||
|
; +-----------+
|
||||||
|
; | Scratch3 | (R8)
|
||||||
|
; +-----------+
|
||||||
|
; | Scratch4 | (R9)
|
||||||
|
; +-----------+
|
||||||
|
; | Arg5 |
|
||||||
|
; +-----------+
|
||||||
|
; | Arg6 |
|
||||||
|
; +-----------+
|
||||||
|
; | ... |
|
||||||
|
; +-----------+
|
||||||
|
; | Arg16 |
|
||||||
|
; +-----------+
|
||||||
|
;
|
||||||
|
|
||||||
; UINTN EbcLLGetEbcEntryPoint(VOID);
|
; save old parameter to stack
|
||||||
; Routine Description:
|
mov [rsp + 08h], rcx
|
||||||
; The VM thunk code stuffs an EBC entry point into a processor
|
mov [rsp + 10h], rdx
|
||||||
; register. Since we can't use inline assembly to get it from
|
mov [rsp + 18h], r8
|
||||||
; the interpreter C code, stuff it into the return value
|
mov [rsp + 20h], r9
|
||||||
; register and return.
|
|
||||||
;
|
; Construct new stack
|
||||||
; Arguments:
|
push rbp
|
||||||
; None.
|
mov rbp, rsp
|
||||||
;
|
push rsi
|
||||||
; Returns:
|
push rdi
|
||||||
; The contents of the register in which the entry point is passed.
|
push rbx
|
||||||
;
|
sub rsp, 80h
|
||||||
EbcLLGetEbcEntryPoint PROC PUBLIC
|
push r10
|
||||||
; The EbcEntryPoint is saved to R10.
|
mov rsi, rbp
|
||||||
mov rax, r10
|
add rsi, 10h
|
||||||
|
mov rdi, rsp
|
||||||
|
add rdi, 8
|
||||||
|
mov rcx, 16
|
||||||
|
rep movsq
|
||||||
|
|
||||||
|
; build new paramater calling convention
|
||||||
|
mov r9, [rsp + 18h]
|
||||||
|
mov r8, [rsp + 10h]
|
||||||
|
mov rdx, [rsp + 08h]
|
||||||
|
mov rcx, r10
|
||||||
|
|
||||||
|
; call C-code
|
||||||
|
call EbcInterpret
|
||||||
|
add rsp, 88h
|
||||||
|
pop rbx
|
||||||
|
pop rdi
|
||||||
|
pop rsi
|
||||||
|
pop rbp
|
||||||
ret
|
ret
|
||||||
EbcLLGetEbcEntryPoint ENDP
|
EbcLLEbcInterpret ENDP
|
||||||
|
|
||||||
|
;****************************************************************************
|
||||||
|
; EbcLLExecuteEbcImageEntryPoint
|
||||||
|
;
|
||||||
|
; Begin executing an EBC image.
|
||||||
|
;****************************************************************************
|
||||||
|
; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)
|
||||||
|
EbcLLExecuteEbcImageEntryPoint PROC PUBLIC
|
||||||
|
;
|
||||||
|
;; mov rax, ca112ebccall2ebch
|
||||||
|
;; mov r10, EbcEntryPoint
|
||||||
|
;; mov r11, EbcLLExecuteEbcImageEntryPoint
|
||||||
|
;; jmp r11
|
||||||
|
;
|
||||||
|
; Caller uses above instruction to jump here
|
||||||
|
; The stack is below:
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr |
|
||||||
|
; +-----------+
|
||||||
|
; |EntryPoint | (R10)
|
||||||
|
; +-----------+
|
||||||
|
; |ImageHandle|
|
||||||
|
; +-----------+
|
||||||
|
; |SystemTable|
|
||||||
|
; +-----------+
|
||||||
|
; | Dummy |
|
||||||
|
; +-----------+
|
||||||
|
; | Dummy |
|
||||||
|
; +-----------+
|
||||||
|
; | RetAddr | <- RSP is here
|
||||||
|
; +-----------+
|
||||||
|
; |ImageHandle| (RCX)
|
||||||
|
; +-----------+
|
||||||
|
; |SystemTable| (RDX)
|
||||||
|
; +-----------+
|
||||||
|
;
|
||||||
|
|
||||||
|
; build new paramater calling convention
|
||||||
|
mov r8, rdx
|
||||||
|
mov rdx, rcx
|
||||||
|
mov rcx, r10
|
||||||
|
|
||||||
|
; call C-code
|
||||||
|
sub rsp, 28h
|
||||||
|
call ExecuteEbcImageEntryPoint
|
||||||
|
add rsp, 28h
|
||||||
|
ret
|
||||||
|
EbcLLExecuteEbcImageEntryPoint ENDP
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
||||||
|
@ -27,6 +27,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||||||
|
|
||||||
#define STACK_REMAIN_SIZE (1024 * 4)
|
#define STACK_REMAIN_SIZE (1024 * 4)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Begin executing an EBC image.
|
||||||
|
This is used for Ebc Thunk call.
|
||||||
|
|
||||||
|
@return The value returned by the EBC application we're going to run.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
EFIAPI
|
||||||
|
EbcLLEbcInterpret (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Begin executing an EBC image.
|
||||||
|
This is used for Ebc image entrypoint.
|
||||||
|
|
||||||
|
@return The value returned by the EBC application we're going to run.
|
||||||
|
|
||||||
|
**/
|
||||||
|
UINT64
|
||||||
|
EFIAPI
|
||||||
|
EbcLLExecuteEbcImageEntryPoint (
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Pushes a 64 bit unsigned value to the VM stack.
|
Pushes a 64 bit unsigned value to the VM stack.
|
||||||
@ -52,14 +77,13 @@ PushU64 (
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begin executing an EBC image. The address of the entry point is passed
|
Begin executing an EBC image.
|
||||||
in via a processor register, so we'll need to make a call to get the
|
|
||||||
value.
|
|
||||||
|
|
||||||
This is a thunk function. Microsoft x64 compiler only provide fast_call
|
This is a thunk function. Microsoft x64 compiler only provide fast_call
|
||||||
calling convention, so the first four arguments are passed by rcx, rdx,
|
calling convention, so the first four arguments are passed by rcx, rdx,
|
||||||
r8, and r9, while other arguments are passed in stack.
|
r8, and r9, while other arguments are passed in stack.
|
||||||
|
|
||||||
|
@param EntryPoint The entrypoint of EBC code.
|
||||||
@param Arg1 The 1st argument.
|
@param Arg1 The 1st argument.
|
||||||
@param Arg2 The 2nd argument.
|
@param Arg2 The 2nd argument.
|
||||||
@param Arg3 The 3rd argument.
|
@param Arg3 The 3rd argument.
|
||||||
@ -83,22 +107,23 @@ PushU64 (
|
|||||||
UINT64
|
UINT64
|
||||||
EFIAPI
|
EFIAPI
|
||||||
EbcInterpret (
|
EbcInterpret (
|
||||||
IN OUT UINTN Arg1,
|
IN UINTN EntryPoint,
|
||||||
IN OUT UINTN Arg2,
|
IN UINTN Arg1,
|
||||||
IN OUT UINTN Arg3,
|
IN UINTN Arg2,
|
||||||
IN OUT UINTN Arg4,
|
IN UINTN Arg3,
|
||||||
IN OUT UINTN Arg5,
|
IN UINTN Arg4,
|
||||||
IN OUT UINTN Arg6,
|
IN UINTN Arg5,
|
||||||
IN OUT UINTN Arg7,
|
IN UINTN Arg6,
|
||||||
IN OUT UINTN Arg8,
|
IN UINTN Arg7,
|
||||||
IN OUT UINTN Arg9,
|
IN UINTN Arg8,
|
||||||
IN OUT UINTN Arg10,
|
IN UINTN Arg9,
|
||||||
IN OUT UINTN Arg11,
|
IN UINTN Arg10,
|
||||||
IN OUT UINTN Arg12,
|
IN UINTN Arg11,
|
||||||
IN OUT UINTN Arg13,
|
IN UINTN Arg12,
|
||||||
IN OUT UINTN Arg14,
|
IN UINTN Arg13,
|
||||||
IN OUT UINTN Arg15,
|
IN UINTN Arg14,
|
||||||
IN OUT UINTN Arg16
|
IN UINTN Arg15,
|
||||||
|
IN UINTN Arg16
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@ -110,11 +135,9 @@ EbcInterpret (
|
|||||||
UINTN StackIndex;
|
UINTN StackIndex;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the EBC entry point from the processor register.
|
// Get the EBC entry point
|
||||||
// Don't call any function before getting the EBC entry
|
|
||||||
// point because this will collab the return register.
|
|
||||||
//
|
//
|
||||||
Addr = EbcLLGetEbcEntryPoint ();
|
Addr = EntryPoint;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now clear out our context
|
// Now clear out our context
|
||||||
@ -221,10 +244,9 @@ EbcInterpret (
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Begin executing an EBC image. The address of the entry point is passed
|
Begin executing an EBC image.
|
||||||
in via a processor register, so we'll need to make a call to get the
|
|
||||||
value.
|
|
||||||
|
|
||||||
|
@param EntryPoint The entrypoint of EBC code.
|
||||||
@param ImageHandle image handle for the EBC application we're executing
|
@param ImageHandle image handle for the EBC application we're executing
|
||||||
@param SystemTable standard system table passed into an driver's entry
|
@param SystemTable standard system table passed into an driver's entry
|
||||||
point
|
point
|
||||||
@ -235,6 +257,7 @@ EbcInterpret (
|
|||||||
UINT64
|
UINT64
|
||||||
EFIAPI
|
EFIAPI
|
||||||
ExecuteEbcImageEntryPoint (
|
ExecuteEbcImageEntryPoint (
|
||||||
|
IN UINTN EntryPoint,
|
||||||
IN EFI_HANDLE ImageHandle,
|
IN EFI_HANDLE ImageHandle,
|
||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
@ -248,11 +271,9 @@ ExecuteEbcImageEntryPoint (
|
|||||||
UINTN StackIndex;
|
UINTN StackIndex;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get the EBC entry point from the processor register. Make sure you don't
|
// Get the EBC entry point
|
||||||
// call any functions before this or you could mess up the register the
|
|
||||||
// entry point is passed in.
|
|
||||||
//
|
//
|
||||||
Addr = EbcLLGetEbcEntryPoint ();
|
Addr = EntryPoint;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Now clear out our context
|
// Now clear out our context
|
||||||
@ -437,9 +458,9 @@ EbcCreateThunks (
|
|||||||
// mov r11 123456789abcdef0h => 49 BB F0 DE BC 9A 78 56 34 12
|
// mov r11 123456789abcdef0h => 49 BB F0 DE BC 9A 78 56 34 12
|
||||||
//
|
//
|
||||||
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
||||||
Addr = (UINTN) ExecuteEbcImageEntryPoint;
|
Addr = (UINTN) EbcLLExecuteEbcImageEntryPoint;
|
||||||
} else {
|
} else {
|
||||||
Addr = (UINTN) EbcInterpret;
|
Addr = (UINTN) EbcLLEbcInterpret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user