20#define VM_STACK_SIZE (1024 * 8)
22#define STACK_REMAIN_SIZE (1024 * 4)
27#define EBC_ENTRYPOINT_SIGNATURE 0xAFAFAFAFAFAFAFAFull
28#define EBC_LL_EBC_ENTRYPOINT_SIGNATURE 0xFAFAFAFAFAFAFAFAull
29UINT8 mInstructionBufferTemplate[] = {
34 0x48, 0xB8, 0xBC, 0x2E, 0x11, 0xCA, 0xBC, 0x2E, 0x11, 0xCA,
42 (UINT8)(EBC_ENTRYPOINT_SIGNATURE & 0xFF),
43 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
44 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
45 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
46 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 32) & 0xFF),
47 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 40) & 0xFF),
48 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 48) & 0xFF),
49 (UINT8)((EBC_ENTRYPOINT_SIGNATURE >> 56) & 0xFF),
55 (UINT8)(EBC_LL_EBC_ENTRYPOINT_SIGNATURE & 0xFF),
56 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 8) & 0xFF),
57 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 16) & 0xFF),
58 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 24) & 0xFF),
59 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 32) & 0xFF),
60 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 40) & 0xFF),
61 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 48) & 0xFF),
62 (UINT8)((EBC_LL_EBC_ENTRYPOINT_SIGNATURE >> 56) & 0xFF),
113 VmPtr->Gpr[0] -=
sizeof (UINT64);
114 *(UINT64 *)VmPtr->Gpr[0] = Arg;
189 VmContext.
Ip = (
VMIP)Addr;
201 if (EFI_ERROR (Status)) {
205 VmContext.StackTop = (UINT8 *)VmContext.StackPool + (STACK_REMAIN_SIZE);
206 VmContext.
Gpr[0] = (UINT64)((UINT8 *)VmContext.StackPool + STACK_POOL_SIZE);
213 VmContext.
Gpr[0] &= ~(VM_REGISTER)(
sizeof (
UINTN) - 1);
230 PushU64 (&VmContext, (UINT64)Arg16);
231 PushU64 (&VmContext, (UINT64)Arg15);
232 PushU64 (&VmContext, (UINT64)Arg14);
233 PushU64 (&VmContext, (UINT64)Arg13);
234 PushU64 (&VmContext, (UINT64)Arg12);
235 PushU64 (&VmContext, (UINT64)Arg11);
236 PushU64 (&VmContext, (UINT64)Arg10);
237 PushU64 (&VmContext, (UINT64)Arg9);
238 PushU64 (&VmContext, (UINT64)Arg8);
239 PushU64 (&VmContext, (UINT64)Arg7);
240 PushU64 (&VmContext, (UINT64)Arg6);
241 PushU64 (&VmContext, (UINT64)Arg5);
242 PushU64 (&VmContext, (UINT64)Arg4);
243 PushU64 (&VmContext, (UINT64)Arg3);
244 PushU64 (&VmContext, (UINT64)Arg2);
245 PushU64 (&VmContext, (UINT64)Arg1);
251 PushU64 (&VmContext, (UINT64)0);
252 PushU64 (&VmContext, (UINT64)0x1234567887654321ULL);
283 return (UINT64)VmContext.
Gpr[7];
332 VmContext.
Ip = (
VMIP)Addr;
339 Status =
GetEBCStack (ImageHandle, &VmContext.StackPool, &StackIndex);
340 if (EFI_ERROR (Status)) {
344 VmContext.StackTop = (UINT8 *)VmContext.StackPool + (STACK_REMAIN_SIZE);
345 VmContext.
Gpr[0] = (UINT64)((UINT8 *)VmContext.StackPool + STACK_POOL_SIZE);
357 VmContext.
Gpr[0] &= ~(VM_REGISTER)(
sizeof (
UINTN) - 1);
365 PushU64 (&VmContext, (UINT64)SystemTable);
366 PushU64 (&VmContext, (UINT64)ImageHandle);
371 PushU64 (&VmContext, (UINT64)0);
372 PushU64 (&VmContext, (UINT64)0x1234567887654321ULL);
394 return (UINT64)VmContext.
Gpr[7];
417 IN VOID *EbcEntryPoint,
430 if ((UINT32)(
UINTN)EbcEntryPoint & 0x01) {
431 return EFI_INVALID_PARAMETER;
434 ThunkSize =
sizeof (mInstructionBufferTemplate);
439 return EFI_OUT_OF_RESOURCES;
452 *Thunk = (VOID *)Ptr;
457 CopyMem (Ptr, mInstructionBufferTemplate,
sizeof (mInstructionBufferTemplate));
462 for (Index = 0; Index <
sizeof (mInstructionBufferTemplate) -
sizeof (
UINTN); Index++) {
463 if (*(
UINTN *)&Ptr[Index] == EBC_ENTRYPOINT_SIGNATURE) {
467 if (*(
UINTN *)&Ptr[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
468 if ((Flags & FLAG_THUNK_ENTRY_POINT) != 0) {
511 UINT8 InstructionBuffer[
sizeof (mInstructionBufferTemplate)];
513 UINTN IndexOfEbcEntrypoint;
517 IndexOfEbcEntrypoint = 0;
522 CopyMem (InstructionBuffer, (VOID *)FuncAddr,
sizeof (InstructionBuffer));
526 for (Index = 0; Index <
sizeof (mInstructionBufferTemplate) -
sizeof (
UINTN); Index++) {
527 if (*(
UINTN *)&mInstructionBufferTemplate[Index] == EBC_ENTRYPOINT_SIGNATURE) {
528 *(
UINTN *)&InstructionBuffer[Index] = EBC_ENTRYPOINT_SIGNATURE;
529 IndexOfEbcEntrypoint = Index;
532 if (*(
UINTN *)&mInstructionBufferTemplate[Index] == EBC_LL_EBC_ENTRYPOINT_SIGNATURE) {
533 *(
UINTN *)&InstructionBuffer[Index] = EBC_LL_EBC_ENTRYPOINT_SIGNATURE;
540 if (
CompareMem (InstructionBuffer, mInstructionBufferTemplate,
sizeof (mInstructionBufferTemplate)) != 0) {
552 VmPtr->FramePtr = (VOID *)(
UINTN)VmPtr->Gpr[0];
556 CopyMem (&TargetEbcAddr, (UINT8 *)FuncAddr + IndexOfEbcEntrypoint,
sizeof (
UINTN));
UINT64 EFIAPI ExecuteEbcImageEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable, IN UINTN EntryPoint)
UINT64 EFIAPI EbcLLExecuteEbcImageEntryPoint(VOID)
VOID PushU64(IN VM_CONTEXT *VmPtr, IN UINT64 Arg)
VOID EbcLLCALLEX(IN VM_CONTEXT *VmPtr, IN UINTN FuncAddr, IN UINTN NewStackPointer, IN VOID *FramePtr, IN UINT8 Size)
UINT64 EFIAPI EbcInterpret(IN UINTN Arg1, IN UINTN Arg2, IN UINTN Arg3, IN UINTN Arg4, IN UINTN Arg5, IN UINTN Arg6, IN UINTN Arg7, IN UINTN Arg8, IN UINTN EntryPoint, IN CONST UINTN Args9_16[])
UINT64 EFIAPI EbcLLEbcInterpret(VOID)
EFI_STATUS EbcCreateThunks(IN EFI_HANDLE ImageHandle, IN VOID *EbcEntryPoint, OUT VOID **Thunk, IN UINT32 Flags)
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EbcExecute(IN VM_CONTEXT *VmPtr)
EFI_STATUS VmWriteMemN(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINTN Data)
EFI_STATUS VmWriteMem64(IN VM_CONTEXT *VmPtr, IN UINTN Addr, IN UINT64 Data)
EFI_STATUS EbcAddImageThunk(IN EFI_HANDLE ImageHandle, IN VOID *ThunkBuffer, IN UINT32 ThunkSize)
VOID *EFIAPI EbcAllocatePoolForThunk(IN UINTN AllocationSize)
EFI_STATUS ReturnEBCStack(IN UINTN Index)
EFI_STATUS GetEBCStack(IN EFI_HANDLE Handle, OUT VOID **StackBuffer, OUT UINTN *BufferIndex)
INT64 EFIAPI EbcLLCALLEXNative(IN UINTN CallAddr, IN UINTN EbcSp, IN VOID *FramePtr)
VOID EbcDebuggerHookEbcInterpret(IN VM_CONTEXT *VmPtr)
VOID EbcDebuggerHookExecuteEbcImageEntryPoint(IN VM_CONTEXT *VmPtr)
UINT64 StackRetAddr
location of final return address on stack
UINTN HighStackBottom
bottom of the upper stack
UINTN * StackMagicPtr
pointer to magic value on stack to detect corruption
UINTN LowStackTop
top of the lower stack
VMIP Ip
Instruction pointer.
EFI_HANDLE ImageHandle
for this EBC driver
EFI_SYSTEM_TABLE * SystemTable
for debugging only