From 6f0a3cd23e4a2322c58c7dbf0ef8e66a4a01c42c Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Wed, 16 Nov 2016 21:24:08 +0800 Subject: [PATCH 1/1] MdeModulePkg/EbcDxe: prepare support for EBC Debugger * This patch introduces EbcDebuggerHook.c/h and inserts the required EBCDebugger references into the existing EBC source files. * With all the hooks defined to their empty version in EbcDebuggerHook.c the existing EBC VM behaviour is left unaffected. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Pete Batard Reviewed-by: Jiewen Yao --- .../Universal/EbcDxe/AArch64/EbcSupport.c | 3 + .../Universal/EbcDxe/EbcDebuggerHook.c | 158 ++++++++++++++++++ .../Universal/EbcDxe/EbcDebuggerHook.h | 113 +++++++++++++ MdeModulePkg/Universal/EbcDxe/EbcDxe.inf | 4 +- MdeModulePkg/Universal/EbcDxe/EbcExecute.c | 39 +++++ MdeModulePkg/Universal/EbcDxe/EbcInt.c | 6 + .../Universal/EbcDxe/Ia32/EbcSupport.c | 7 +- .../Universal/EbcDxe/Ipf/EbcSupport.c | 9 +- .../Universal/EbcDxe/X64/EbcSupport.c | 7 +- 9 files changed, 339 insertions(+), 7 deletions(-) create mode 100644 MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.c create mode 100644 MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.h diff --git a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c index c5cc76d7bd..ade47c4d06 100644 --- a/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/AArch64/EbcSupport.c @@ -18,6 +18,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "EbcInt.h" #include "EbcExecute.h" +#include "EbcDebuggerHook.h" // // Amount of space that is not used in the stack @@ -225,6 +226,7 @@ EbcInterpret ( // // Begin executing the EBC code // + EbcDebuggerHookEbcInterpret (&VmContext); EbcExecute (&VmContext); // @@ -336,6 +338,7 @@ ExecuteEbcImageEntryPoint ( // // Begin executing the EBC code // + EbcDebuggerHookExecuteEbcImageEntryPoint (&VmContext); EbcExecute (&VmContext); // diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.c b/MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.c new file mode 100644 index 0000000000..88a43f2364 --- /dev/null +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.c @@ -0,0 +1,158 @@ +/** @file + Contains the empty version of the EBC Debugger hooks, to be used when + compiling the regular EBC VM module. + As debugging is not needed for the standard EBC VM, all calls are left empty. + + The EBC Debugger defines its own version for these calls in EbdHooks.c. + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +VOID +EbcDebuggerHookInit ( + IN EFI_HANDLE Handle, + IN EFI_DEBUG_SUPPORT_PROTOCOL *EbcDebugProtocol + ) +{ + return; +} + +VOID +EbcDebuggerHookUnload ( + VOID + ) +{ + return; +} + +VOID +EbcDebuggerHookEbcUnloadImage ( + IN EFI_HANDLE Handle + ) +{ + return; +} + +VOID +EbcDebuggerHookExecuteEbcImageEntryPoint ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookEbcInterpret ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookExecuteStart ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookExecuteEnd ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookCALLStart ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookCALLEnd ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookCALLEXStart ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookCALLEXEnd ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookRETStart ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookRETEnd ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookJMPStart ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookJMPEnd ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookJMP8Start ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} + +VOID +EbcDebuggerHookJMP8End ( + IN VM_CONTEXT *VmPtr + ) +{ + return; +} diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.h b/MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.h new file mode 100644 index 0000000000..f4dd5cf813 --- /dev/null +++ b/MdeModulePkg/Universal/EbcDxe/EbcDebuggerHook.h @@ -0,0 +1,113 @@ +/** @file + Prototypes for the EBC Debugger hooks. + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _EFI_EBC_DEBUGGER_HOOK_H_ +#define _EFI_EBC_DEBUGGER_HOOK_H_ + +// +// Hooks in EbcInt.c +// +VOID +EbcDebuggerHookInit ( + IN EFI_HANDLE Handle, + IN EFI_DEBUG_SUPPORT_PROTOCOL *EbcDebugProtocol + ); + +VOID +EbcDebuggerHookUnload ( + VOID + ); + +VOID +EbcDebuggerHookEbcUnloadImage ( + IN EFI_HANDLE Handle + ); + +// +// Hooks in EbcSupport.c +// +VOID +EbcDebuggerHookExecuteEbcImageEntryPoint ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookEbcInterpret ( + IN VM_CONTEXT *VmPtr + ); + +// +// Hooks in EbcExecute.c +// +VOID +EbcDebuggerHookExecuteStart ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookExecuteEnd ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookCALLStart ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookCALLEnd ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookCALLEXStart ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookCALLEXEnd ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookRETStart ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookRETEnd ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookJMPStart ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookJMPEnd ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookJMP8Start ( + IN VM_CONTEXT *VmPtr + ); + +VOID +EbcDebuggerHookJMP8End ( + IN VM_CONTEXT *VmPtr + ); + +#endif diff --git a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf index e9a0b28c40..d11888e25f 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf +++ b/MdeModulePkg/Universal/EbcDxe/EbcDxe.inf @@ -33,6 +33,8 @@ # [Sources] + EbcDebuggerHook.h + EbcDebuggerHook.c EbcExecute.h EbcExecute.c EbcInt.h @@ -88,4 +90,4 @@ # EVENT_TYPE_PERIODIC_TIMER ## CONSUMES [UserExtensions.TianoCore."ExtraFiles"] - EbcDxeExtra.uni \ No newline at end of file + EbcDxeExtra.uni diff --git a/MdeModulePkg/Universal/EbcDxe/EbcExecute.c b/MdeModulePkg/Universal/EbcDxe/EbcExecute.c index d9c17f48a0..a4c51e9b0f 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcExecute.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcExecute.c @@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "EbcInt.h" #include "EbcExecute.h" +#include "EbcDebuggerHook.h" // @@ -1488,6 +1489,9 @@ EbcExecute ( Status = EFI_UNSUPPORTED; goto Done; } + + EbcDebuggerHookExecuteStart (VmPtr); + // // The EBC VM is a strongly ordered processor, so perform a fence operation before // and after each instruction is executed. @@ -1498,6 +1502,8 @@ EbcExecute ( MemoryFence (); + EbcDebuggerHookExecuteEnd (VmPtr); + // // If the step flag is set, signal an exception and continue. We don't // clear it here. Assuming the debugger is responsible for clearing it. @@ -1976,7 +1982,9 @@ ExecuteJMP ( ConditionFlag = (UINT8) VMFLAG_ISSET (VmPtr, VMFLAGS_CC); if ((Operand & CONDITION_M_CONDITIONAL) != 0) { if (CompareSet != ConditionFlag) { + EbcDebuggerHookJMPStart (VmPtr); VmPtr->Ip += Size; + EbcDebuggerHookJMPEnd (VmPtr); return EFI_SUCCESS; } } @@ -2015,11 +2023,13 @@ ExecuteJMP ( // // Take jump -- relative or absolute // + EbcDebuggerHookJMPStart (VmPtr); if ((Operand & JMP_M_RELATIVE) != 0) { VmPtr->Ip += (UINTN) Data64 + Size; } else { VmPtr->Ip = (VMIP) (UINTN) Data64; } + EbcDebuggerHookJMPEnd (VmPtr); return EFI_SUCCESS; } @@ -2065,11 +2075,14 @@ ExecuteJMP ( return EFI_UNSUPPORTED; } + EbcDebuggerHookJMPStart (VmPtr); if ((Operand & JMP_M_RELATIVE) != 0) { VmPtr->Ip += (UINTN) Addr + Size; } else { VmPtr->Ip = (VMIP) Addr; } + EbcDebuggerHookJMPEnd (VmPtr); + } else { // // Form: JMP32 Rx {Immed32} @@ -2085,11 +2098,14 @@ ExecuteJMP ( return EFI_UNSUPPORTED; } + EbcDebuggerHookJMPStart (VmPtr); if ((Operand & JMP_M_RELATIVE) != 0) { VmPtr->Ip += (UINTN) Addr + Size; } else { VmPtr->Ip = (VMIP) Addr; } + EbcDebuggerHookJMPEnd (VmPtr); + } return EFI_SUCCESS; @@ -2129,7 +2145,9 @@ ExecuteJMP8 ( // if ((Opcode & CONDITION_M_CONDITIONAL) != 0) { if (CompareSet != ConditionFlag) { + EbcDebuggerHookJMP8Start (VmPtr); VmPtr->Ip += 2; + EbcDebuggerHookJMP8End (VmPtr); return EFI_SUCCESS; } } @@ -2141,7 +2159,9 @@ ExecuteJMP8 ( // // Want to check for offset == -2 and then raise an exception? // + EbcDebuggerHookJMP8Start (VmPtr); VmPtr->Ip += (Offset * 2) + 2; + EbcDebuggerHookJMP8End (VmPtr); return EFI_SUCCESS; } @@ -2966,6 +2986,13 @@ ExecuteCALL ( // Opcode = GETOPCODE (VmPtr); Operands = GETOPERANDS (VmPtr); + + if (Operands & OPERAND_M_NATIVE_CALL) { + EbcDebuggerHookCALLEXStart (VmPtr); + } else { + EbcDebuggerHookCALLStart (VmPtr); + } + // // Assign these as well to avoid compiler warnings // @@ -3067,6 +3094,12 @@ ExecuteCALL ( } } + if (Operands & OPERAND_M_NATIVE_CALL) { + EbcDebuggerHookCALLEXEnd (VmPtr); + } else { + EbcDebuggerHookCALLEnd (VmPtr); + } + return EFI_SUCCESS; } @@ -3087,6 +3120,9 @@ ExecuteRET ( IN VM_CONTEXT *VmPtr ) { + + EbcDebuggerHookRETStart (VmPtr); + // // If we're at the top of the stack, then simply set the done // flag and return @@ -3114,6 +3150,9 @@ ExecuteRET ( VmPtr->Gpr[0] += 8; } + + EbcDebuggerHookRETEnd (VmPtr); + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/EbcDxe/EbcInt.c b/MdeModulePkg/Universal/EbcDxe/EbcInt.c index 549e0dd8dc..6fd2aaf5af 100644 --- a/MdeModulePkg/Universal/EbcDxe/EbcInt.c +++ b/MdeModulePkg/Universal/EbcDxe/EbcInt.c @@ -16,6 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "EbcInt.h" #include "EbcExecute.h" +#include "EbcDebuggerHook.h" // // We'll keep track of all thunks we create in a linked list. Each @@ -497,6 +498,8 @@ InitializeEbcDriver ( InitEbcVmTestProtocol (&ImageHandle); DEBUG_CODE_END (); + EbcDebuggerHookInit (ImageHandle, EbcDebugProtocol); + return EFI_SUCCESS; ErrorExit: @@ -1094,6 +1097,9 @@ EbcUnloadImage ( // Now free up the image list element // FreePool (ImageList); + + EbcDebuggerHookEbcUnloadImage (ImageHandle); + return EFI_SUCCESS; } diff --git a/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c index bddfbf630d..8e660b93ad 100644 --- a/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/Ia32/EbcSupport.c @@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "EbcInt.h" #include "EbcExecute.h" +#include "EbcDebuggerHook.h" // // NOTE: This is the stack size allocated for the interpreter @@ -332,10 +333,11 @@ EbcInterpret ( // // Begin executing the EBC code // + EbcDebuggerHookEbcInterpret (&VmContext); EbcExecute (&VmContext); // - // Return the value in R[7] unless there was an error + // Return the value in Gpr[7] unless there was an error // ReturnEBCStack(StackIndex); return (UINT64) VmContext.Gpr[7]; @@ -432,10 +434,11 @@ ExecuteEbcImageEntryPoint ( // // Begin executing the EBC code // + EbcDebuggerHookExecuteEbcImageEntryPoint (&VmContext); EbcExecute (&VmContext); // - // Return the value in R[7] unless there was an error + // Return the value in Gpr[7] unless there was an error // ReturnEBCStack(StackIndex); return (UINT64) VmContext.Gpr[7]; diff --git a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c index 23b6c1bd84..95837cb678 100644 --- a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcSupport.c @@ -16,6 +16,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "EbcInt.h" #include "EbcExecute.h" #include "EbcSupport.h" +#include "EbcDebuggerHook.h" /** Given raw bytes of Itanium based code, format them into a bundle and @@ -214,12 +215,15 @@ EbcInterpret ( PushU64 (&VmContext, 0); PushU64 (&VmContext, 0xDEADBEEFDEADBEEF); VmContext.StackRetAddr = (UINT64) VmContext.Gpr[0]; + // // Begin executing the EBC code // + EbcDebuggerHookEbcInterpret (&VmContext); EbcExecute (&VmContext); + // - // Return the value in R[7] unless there was an error + // Return the value in Gpr[7] unless there was an error // ReturnEBCStack(StackIndex); return (UINT64) VmContext.Gpr[7]; @@ -334,10 +338,11 @@ ExecuteEbcImageEntryPoint ( // // Begin executing the EBC code // + EbcDebuggerHookExecuteEbcImageEntryPoint (&VmContext); EbcExecute (&VmContext); // - // Return the value in R[7] unless there was an error + // Return the value in Gpr[7] unless there was an error // ReturnEBCStack(StackIndex); return (UINT64) VmContext.Gpr[7]; diff --git a/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c b/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c index bdde5e41fa..4325e2e527 100644 --- a/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c +++ b/MdeModulePkg/Universal/EbcDxe/X64/EbcSupport.c @@ -15,6 +15,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include "EbcInt.h" #include "EbcExecute.h" +#include "EbcDebuggerHook.h" // // NOTE: This is the stack size allocated for the interpreter @@ -278,10 +279,11 @@ EbcInterpret ( // // Begin executing the EBC code // + EbcDebuggerHookEbcInterpret (&VmContext); EbcExecute (&VmContext); // - // Return the value in R[7] unless there was an error + // Return the value in Gpr[7] unless there was an error // ReturnEBCStack(StackIndex); return (UINT64) VmContext.Gpr[7]; @@ -389,10 +391,11 @@ ExecuteEbcImageEntryPoint ( // // Begin executing the EBC code // + EbcDebuggerHookExecuteEbcImageEntryPoint (&VmContext); EbcExecute (&VmContext); // - // Return the value in R[7] unless there was an error + // Return the value in Gpr[7] unless there was an error // ReturnEBCStack(StackIndex); return (UINT64) VmContext.Gpr[7]; -- 2.39.2