mirror of https://github.com/acidanthera/audk.git
Re-org the EBC thunk code for better code maintenance.
signed-off-by: jyao1 reviewed-by: lgao4 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12769 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
6cf9230ff2
commit
21d13c6156
|
@ -1,6 +1,6 @@
|
|||
/** @file
|
||||
This module contains EBC support routines that are customized based on
|
||||
the target processor.
|
||||
the target ia32 processor.
|
||||
|
||||
Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
|
@ -23,10 +23,47 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
// platform-specific configurations.
|
||||
//
|
||||
#define VM_STACK_SIZE (1024 * 4)
|
||||
#define EBC_THUNK_SIZE 32
|
||||
|
||||
#define STACK_REMAIN_SIZE (1024 * 4)
|
||||
|
||||
//
|
||||
// This is instruction buffer used to create EBC thunk
|
||||
//
|
||||
#define EBC_ENTRYPOINT_SIGNATURE 0xAFAFAFAF
|
||||
#define EBC_LL_EBC_ENTRYPOINT_SIGNATURE 0xFAFAFAFA
|
||||
UINT8 mInstructionBufferTemplate[] = {
|
||||
//
|
||||
// Add a magic code here to help the VM recognize the thunk..
|
||||
// mov eax, 0xca112ebc => B8 BC 2E 11 CA
|
||||
//
|
||||
0xB8, 0xBC, 0x2E, 0x11, 0xCA,
|
||||
//
|
||||
// Add code bytes to load up a processor register with the EBC entry point.
|
||||
// mov eax, EbcEntryPoint => B8 XX XX XX XX (To be fixed at runtime)
|
||||
// These 4 bytes of the thunk entry is the address of the EBC
|
||||
// entry point.
|
||||
//
|
||||
0xB8,
|
||||
(UINT8)(EBC_ENTRYPOINT_SIGNATURE & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
|
||||
//
|
||||
// Stick in a load of ecx with the address of appropriate VM function.
|
||||
// mov ecx, EbcLLEbcInterpret => B9 XX XX XX XX (To be fixed at runtime)
|
||||
//
|
||||
0xB9,
|
||||
(UINT8)(EBC_LL_EBC_ENTRYPOINT_SIGNATURE & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
|
||||
//
|
||||
// Stick in jump opcode bytes
|
||||
// jmp ecx => FF E1
|
||||
//
|
||||
0xFF, 0xE1,
|
||||
};
|
||||
|
||||
/**
|
||||
Begin executing an EBC image.
|
||||
This is used for Ebc Thunk call.
|
||||
|
@ -79,54 +116,37 @@ EbcLLCALLEX (
|
|||
{
|
||||
UINTN IsThunk;
|
||||
UINTN TargetEbcAddr;
|
||||
UINT8 InstructionBuffer[sizeof(mInstructionBufferTemplate)];
|
||||
UINTN Index;
|
||||
UINTN IndexOfEbcEntrypoint;
|
||||
|
||||
IsThunk = 1;
|
||||
TargetEbcAddr = 0;
|
||||
IndexOfEbcEntrypoint = 0;
|
||||
|
||||
//
|
||||
// Processor specific code to check whether the callee is a thunk to EBC.
|
||||
//
|
||||
if (*((UINT8 *)FuncAddr) != 0xB8) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
CopyMem (InstructionBuffer, (VOID *)FuncAddr, sizeof(InstructionBuffer));
|
||||
//
|
||||
// Fill the signature according to mInstructionBufferTemplate
|
||||
//
|
||||
for (Index = 0; Index < sizeof(mInstructionBufferTemplate) - sizeof(UINTN); Index++) {
|
||||
if (*(UINTN *)&mInstructionBufferTemplate[Index] == EBC_ENTRYPOINT_SIGNATURE) {
|
||||
*(UINTN *)&InstructionBuffer[Index] = EBC_ENTRYPOINT_SIGNATURE;
|
||||
IndexOfEbcEntrypoint = Index;
|
||||
}
|
||||
if (*(UINTN *)&mInstructionBufferTemplate[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
|
||||
*(UINTN *)&InstructionBuffer[Index] = EBC_LL_EBC_ENTRYPOINT_SIGNATURE;
|
||||
}
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 1) != 0xBC) {
|
||||
//
|
||||
// Check if we need thunk to native
|
||||
//
|
||||
if (CompareMem (InstructionBuffer, mInstructionBufferTemplate, sizeof(mInstructionBufferTemplate)) != 0) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 2) != 0x2E) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 3) != 0x11) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 4) != 0xCA) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 5) != 0xB8) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 10) != 0xB9) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 15) != 0xFF) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 16) != 0xE1) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
|
||||
TargetEbcAddr = ((UINTN)(*((UINT8 *)FuncAddr + 9)) << 24) + ((UINTN)(*((UINT8 *)FuncAddr + 8)) << 16) +
|
||||
((UINTN)(*((UINT8 *)FuncAddr + 7)) << 8) + ((UINTN)(*((UINT8 *)FuncAddr + 6)));
|
||||
|
||||
Action:
|
||||
if (IsThunk == 1){
|
||||
//
|
||||
// The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and
|
||||
|
@ -139,11 +159,12 @@ Action:
|
|||
VmPtr->Gpr[0] -= 8;
|
||||
VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], (UINT64) (UINTN) (VmPtr->Ip + Size));
|
||||
|
||||
CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + IndexOfEbcEntrypoint, sizeof(UINTN));
|
||||
VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;
|
||||
} else {
|
||||
//
|
||||
// The callee is not a thunk to EBC, call native code,
|
||||
// and get return value
|
||||
// and get return value.
|
||||
//
|
||||
VmPtr->Gpr[7] = EbcLLCALLEXNative (FuncAddr, NewStackPointer, FramePtr);
|
||||
|
||||
|
@ -449,8 +470,6 @@ EbcCreateThunks (
|
|||
UINT8 *Ptr;
|
||||
UINT8 *ThunkBase;
|
||||
UINT32 Index;
|
||||
UINT32 Addr;
|
||||
INT32 Size;
|
||||
INT32 ThunkSize;
|
||||
|
||||
//
|
||||
|
@ -460,10 +479,9 @@ EbcCreateThunks (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Size = EBC_THUNK_SIZE;
|
||||
ThunkSize = Size;
|
||||
ThunkSize = sizeof(mInstructionBufferTemplate);
|
||||
|
||||
Ptr = AllocatePool (Size);
|
||||
Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
|
||||
|
||||
if (Ptr == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
@ -481,74 +499,26 @@ EbcCreateThunks (
|
|||
*Thunk = (VOID *) Ptr;
|
||||
|
||||
//
|
||||
// Add a magic code here to help the VM recognize the thunk..
|
||||
// mov eax, 0xca112ebc => B8 BC 2E 11 CA
|
||||
// Copy whole thunk instruction buffer template
|
||||
//
|
||||
*Ptr = 0xB8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
Addr = (UINT32) 0xCA112EBC;
|
||||
for (Index = 0; Index < sizeof (Addr); Index++) {
|
||||
*Ptr = (UINT8) (UINTN) Addr;
|
||||
Addr >>= 8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
}
|
||||
CopyMem (Ptr, mInstructionBufferTemplate, sizeof(mInstructionBufferTemplate));
|
||||
|
||||
//
|
||||
// Add code bytes to load up a processor register with the EBC entry point.
|
||||
// mov eax, 0xaa55aa55 => B8 55 AA 55 AA
|
||||
// The first 8 bytes of the thunk entry is the address of the EBC
|
||||
// entry point.
|
||||
// Patch EbcEntryPoint and EbcLLEbcInterpret
|
||||
//
|
||||
*Ptr = 0xB8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
Addr = (UINT32) EbcEntryPoint;
|
||||
for (Index = 0; Index < sizeof (Addr); Index++) {
|
||||
*Ptr = (UINT8) (UINTN) Addr;
|
||||
Addr >>= 8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
}
|
||||
//
|
||||
// Stick in a load of ecx with the address of appropriate VM function.
|
||||
// mov ecx 12345678h => 0xB9 0x78 0x56 0x34 0x12
|
||||
//
|
||||
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
||||
Addr = (UINT32) (UINTN) EbcLLExecuteEbcImageEntryPoint;
|
||||
} else {
|
||||
Addr = (UINT32) (UINTN) EbcLLEbcInterpret;
|
||||
for (Index = 0; Index < sizeof(mInstructionBufferTemplate) - sizeof(UINTN); Index++) {
|
||||
if (*(UINTN *)&Ptr[Index] == EBC_ENTRYPOINT_SIGNATURE) {
|
||||
*(UINTN *)&Ptr[Index] = (UINTN)EbcEntryPoint;
|
||||
}
|
||||
if (*(UINTN *)&Ptr[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
|
||||
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
||||
*(UINTN *)&Ptr[Index] = (UINTN)EbcLLExecuteEbcImageEntryPoint;
|
||||
} else {
|
||||
*(UINTN *)&Ptr[Index] = (UINTN)EbcLLEbcInterpret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// MOV ecx
|
||||
//
|
||||
*Ptr = 0xB9;
|
||||
Ptr++;
|
||||
Size--;
|
||||
for (Index = 0; Index < sizeof (Addr); Index++) {
|
||||
*Ptr = (UINT8) Addr;
|
||||
Addr >>= 8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
}
|
||||
//
|
||||
// Stick in jump opcode bytes for jmp ecx => 0xFF 0xE1
|
||||
//
|
||||
*Ptr = 0xFF;
|
||||
Ptr++;
|
||||
Size--;
|
||||
*Ptr = 0xE1;
|
||||
Size--;
|
||||
|
||||
//
|
||||
// Double check that our defined size is ok (application error)
|
||||
//
|
||||
if (Size < 0) {
|
||||
ASSERT (FALSE);
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
//
|
||||
// Add the thunk to the list for this image. Do this last since the add
|
||||
// function flushes the cache for us.
|
||||
|
|
|
@ -23,10 +23,55 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
// platform-specific configurations.
|
||||
//
|
||||
#define VM_STACK_SIZE (1024 * 8)
|
||||
#define EBC_THUNK_SIZE 64
|
||||
|
||||
#define STACK_REMAIN_SIZE (1024 * 4)
|
||||
|
||||
//
|
||||
// This is instruction buffer used to create EBC thunk
|
||||
//
|
||||
#define EBC_ENTRYPOINT_SIGNATURE 0xAFAFAFAFAFAFAFAFull
|
||||
#define EBC_LL_EBC_ENTRYPOINT_SIGNATURE 0xFAFAFAFAFAFAFAFAull
|
||||
UINT8 mInstructionBufferTemplate[] = {
|
||||
//
|
||||
// Add a magic code here to help the VM recognize the thunk..
|
||||
// mov rax, 0xca112ebcca112ebc => 48 B8 BC 2E 11 CA BC 2E 11 CA
|
||||
//
|
||||
0x48, 0xB8, 0xBC, 0x2E, 0x11, 0xCA, 0xBC, 0x2E, 0x11, 0xCA,
|
||||
//
|
||||
// Add code bytes to load up a processor register with the EBC entry point.
|
||||
// mov r10, EbcEntryPoint => 49 BA XX XX XX XX XX XX XX XX (To be fixed at runtime)
|
||||
// These 8 bytes of the thunk entry is the address of the EBC
|
||||
// entry point.
|
||||
//
|
||||
0x49, 0xBA,
|
||||
(UINT8)(EBC_ENTRYPOINT_SIGNATURE & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 32) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 40) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 48) & 0xFF),
|
||||
(UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 56) & 0xFF),
|
||||
//
|
||||
// Stick in a load of r11 with the address of appropriate VM function.
|
||||
// mov r11, EbcLLEbcInterpret => 49 BB XX XX XX XX XX XX XX XX (To be fixed at runtime)
|
||||
//
|
||||
0x49, 0xBB,
|
||||
(UINT8)(EBC_LL_EBC_ENTRYPOINT_SIGNATURE & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 32) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 40) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 48) & 0xFF),
|
||||
(UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 56) & 0xFF),
|
||||
//
|
||||
// Stick in jump opcode bytes
|
||||
// jmp r11 => 41 FF E3
|
||||
//
|
||||
0x41, 0xFF, 0xE3,
|
||||
};
|
||||
|
||||
/**
|
||||
Begin executing an EBC image.
|
||||
This is used for Ebc Thunk call.
|
||||
|
@ -382,8 +427,6 @@ EbcCreateThunks (
|
|||
UINT8 *Ptr;
|
||||
UINT8 *ThunkBase;
|
||||
UINT32 Index;
|
||||
UINT64 Addr;
|
||||
INT32 Size;
|
||||
INT32 ThunkSize;
|
||||
|
||||
//
|
||||
|
@ -393,10 +436,9 @@ EbcCreateThunks (
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Size = EBC_THUNK_SIZE;
|
||||
ThunkSize = Size;
|
||||
ThunkSize = sizeof(mInstructionBufferTemplate);
|
||||
|
||||
Ptr = AllocatePool (Size);
|
||||
Ptr = AllocatePool (sizeof(mInstructionBufferTemplate));
|
||||
|
||||
if (Ptr == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
@ -414,89 +456,26 @@ EbcCreateThunks (
|
|||
*Thunk = (VOID *) Ptr;
|
||||
|
||||
//
|
||||
// Add a magic code here to help the VM recognize the thunk..
|
||||
// mov rax, ca112ebccall2ebch => 48 B8 BC 2E 11 CA BC 2E 11 CA
|
||||
// Copy whole thunk instruction buffer template
|
||||
//
|
||||
*Ptr = 0x48;
|
||||
Ptr++;
|
||||
Size--;
|
||||
*Ptr = 0xB8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
Addr = (UINT64) 0xCA112EBCCA112EBCULL;
|
||||
for (Index = 0; Index < sizeof (Addr); Index++) {
|
||||
*Ptr = (UINT8) (UINTN) Addr;
|
||||
Addr >>= 8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
}
|
||||
CopyMem (Ptr, mInstructionBufferTemplate, sizeof(mInstructionBufferTemplate));
|
||||
|
||||
//
|
||||
// Add code bytes to load up a processor register with the EBC entry point.
|
||||
// mov r10, 123456789abcdef0h => 49 BA F0 DE BC 9A 78 56 34 12
|
||||
// The first 8 bytes of the thunk entry is the address of the EBC
|
||||
// entry point.
|
||||
// Patch EbcEntryPoint and EbcLLEbcInterpret
|
||||
//
|
||||
*Ptr = 0x49;
|
||||
Ptr++;
|
||||
Size--;
|
||||
*Ptr = 0xBA;
|
||||
Ptr++;
|
||||
Size--;
|
||||
Addr = (UINT64) EbcEntryPoint;
|
||||
for (Index = 0; Index < sizeof (Addr); Index++) {
|
||||
*Ptr = (UINT8) (UINTN) Addr;
|
||||
Addr >>= 8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
for (Index = 0; Index < sizeof(mInstructionBufferTemplate) - sizeof(UINTN); Index++) {
|
||||
if (*(UINTN *)&Ptr[Index] == EBC_ENTRYPOINT_SIGNATURE) {
|
||||
*(UINTN *)&Ptr[Index] = (UINTN)EbcEntryPoint;
|
||||
}
|
||||
if (*(UINTN *)&Ptr[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
|
||||
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
||||
*(UINTN *)&Ptr[Index] = (UINTN)EbcLLExecuteEbcImageEntryPoint;
|
||||
} else {
|
||||
*(UINTN *)&Ptr[Index] = (UINTN)EbcLLEbcInterpret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Stick in a load of ecx with the address of appropriate VM function.
|
||||
// Using r11 because it's a volatile register and won't be used in this
|
||||
// point.
|
||||
// mov r11 123456789abcdef0h => 49 BB F0 DE BC 9A 78 56 34 12
|
||||
//
|
||||
if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
|
||||
Addr = (UINTN) EbcLLExecuteEbcImageEntryPoint;
|
||||
} else {
|
||||
Addr = (UINTN) EbcLLEbcInterpret;
|
||||
}
|
||||
|
||||
//
|
||||
// mov r11 Addr => 0x49 0xBB
|
||||
//
|
||||
*Ptr = 0x49;
|
||||
Ptr++;
|
||||
Size--;
|
||||
*Ptr = 0xBB;
|
||||
Ptr++;
|
||||
Size--;
|
||||
for (Index = 0; Index < sizeof (Addr); Index++) {
|
||||
*Ptr = (UINT8) Addr;
|
||||
Addr >>= 8;
|
||||
Ptr++;
|
||||
Size--;
|
||||
}
|
||||
//
|
||||
// Stick in jump opcode bytes for jmp r11 => 0x41 0xFF 0xE3
|
||||
//
|
||||
*Ptr = 0x41;
|
||||
Ptr++;
|
||||
Size--;
|
||||
*Ptr = 0xFF;
|
||||
Ptr++;
|
||||
Size--;
|
||||
*Ptr = 0xE3;
|
||||
Size--;
|
||||
|
||||
//
|
||||
// Double check that our defined size is ok (application error)
|
||||
//
|
||||
if (Size < 0) {
|
||||
ASSERT (FALSE);
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
}
|
||||
//
|
||||
// Add the thunk to the list for this image. Do this last since the add
|
||||
// function flushes the cache for us.
|
||||
|
@ -533,65 +512,37 @@ EbcLLCALLEX (
|
|||
{
|
||||
UINTN IsThunk;
|
||||
UINTN TargetEbcAddr;
|
||||
UINT8 InstructionBuffer[sizeof(mInstructionBufferTemplate)];
|
||||
UINTN Index;
|
||||
UINTN IndexOfEbcEntrypoint;
|
||||
|
||||
IsThunk = 1;
|
||||
TargetEbcAddr = 0;
|
||||
IndexOfEbcEntrypoint = 0;
|
||||
|
||||
//
|
||||
// Processor specific code to check whether the callee is a thunk to EBC.
|
||||
//
|
||||
if (*((UINT8 *)FuncAddr) != 0x48) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
CopyMem (InstructionBuffer, (VOID *)FuncAddr, sizeof(InstructionBuffer));
|
||||
//
|
||||
// Fill the signature according to mInstructionBufferTemplate
|
||||
//
|
||||
for (Index = 0; Index < sizeof(mInstructionBufferTemplate) - sizeof(UINTN); Index++) {
|
||||
if (*(UINTN *)&mInstructionBufferTemplate[Index] == EBC_ENTRYPOINT_SIGNATURE) {
|
||||
*(UINTN *)&InstructionBuffer[Index] = EBC_ENTRYPOINT_SIGNATURE;
|
||||
IndexOfEbcEntrypoint = Index;
|
||||
}
|
||||
if (*(UINTN *)&mInstructionBufferTemplate[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
|
||||
*(UINTN *)&InstructionBuffer[Index] = EBC_LL_EBC_ENTRYPOINT_SIGNATURE;
|
||||
}
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 1) != 0xB8) {
|
||||
//
|
||||
// Check if we need thunk to native
|
||||
//
|
||||
if (CompareMem (InstructionBuffer, mInstructionBufferTemplate, sizeof(mInstructionBufferTemplate)) != 0) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 2) != 0xBC) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 3) != 0x2E) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 4) != 0x11) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 5) != 0xCA) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 6) != 0xBC) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 7) != 0x2E) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 8) != 0x11) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 9) != 0xCA) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 10) != 0x49) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
if (*((UINT8 *)FuncAddr + 11) != 0xBA) {
|
||||
IsThunk = 0;
|
||||
goto Action;
|
||||
}
|
||||
|
||||
CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + 12, 8);
|
||||
|
||||
Action:
|
||||
if (IsThunk == 1){
|
||||
//
|
||||
// The callee is a thunk to EBC, adjust the stack pointer down 16 bytes and
|
||||
|
@ -602,8 +553,9 @@ Action:
|
|||
VmWriteMemN (VmPtr, (UINTN) VmPtr->Gpr[0], (UINTN) FramePtr);
|
||||
VmPtr->FramePtr = (VOID *) (UINTN) VmPtr->Gpr[0];
|
||||
VmPtr->Gpr[0] -= 8;
|
||||
VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], (UINT64) (VmPtr->Ip + Size));
|
||||
VmWriteMem64 (VmPtr, (UINTN) VmPtr->Gpr[0], (UINT64) (UINTN) (VmPtr->Ip + Size));
|
||||
|
||||
CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + IndexOfEbcEntrypoint, sizeof(UINTN));
|
||||
VmPtr->Ip = (VMIP) (UINTN) TargetEbcAddr;
|
||||
} else {
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue