/** @file

Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
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 "Edb.h"

/**

  Check the Hook flag, and trigger exception if match.

  @param  VmPtr        - EbcDebuggerCheckHookFlag
  @param  Flag         - Feature flag

**/
VOID
EbcDebuggerCheckHookFlag (
  IN VM_CONTEXT *VmPtr,
  IN UINT32     Flag
  )
{
  if ((mDebuggerPrivate.FeatureFlags & Flag) == Flag) {
    mDebuggerPrivate.StatusFlags = Flag;
    EbcDebugSignalException (
      EXCEPT_EBC_BREAKPOINT,
      EXCEPTION_FLAG_NONE,
      VmPtr
      );
  }
  return ;
}

/**

  It will record soruce address for Callstack entry.

  @param  SourceEntry  - Source address
  @param  Type         - Branch type

**/
VOID
EbcDebuggerPushCallstackSource (
  IN UINT64                   SourceEntry,
  IN EFI_DEBUGGER_BRANCH_TYPE Type
  )
{
  if (mDebuggerPrivate.CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
    ASSERT (FALSE);
    mDebuggerPrivate.CallStackEntryCount = EFI_DEBUGGER_CALLSTACK_MAX;
  }
  //
  // Record the new callstack entry
  //
  mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].SourceAddress = SourceEntry;
  mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].Type = Type;

  //
  // Do not change CallStackEntryCount
  //

  return ;
}

/**

  It will record parameter for Callstack entry.

  @param  ParameterAddress - The address for the parameter
  @param  Type             - Branch type

**/
VOID
EbcDebuggerPushCallstackParameter (
  IN UINT64                   ParameterAddress,
  IN EFI_DEBUGGER_BRANCH_TYPE Type
  )
{
  if (mDebuggerPrivate.CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
    ASSERT (FALSE);
    mDebuggerPrivate.CallStackEntryCount = EFI_DEBUGGER_CALLSTACK_MAX;
  }
  //
  // Record the new callstack parameter
  //
  mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].ParameterAddr = (UINTN)ParameterAddress;
  CopyMem (
    mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].Parameter,
    (VOID *)(UINTN)ParameterAddress,
    sizeof(mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].Parameter)
    );

  //
  // Do not change CallStackEntryCount
  //

  return ;
}

/**

  It will record source address for callstack entry.

  @param  DestEntry    - Source address
  @param  Type         - Branch type

**/
VOID
EbcDebuggerPushCallstackDest (
  IN UINT64                   DestEntry,
  IN EFI_DEBUGGER_BRANCH_TYPE Type
  )
{
  UINTN Index;

  if (mDebuggerPrivate.CallStackEntryCount < EFI_DEBUGGER_CALLSTACK_MAX) {
    //
    // If there is empty entry for callstack, add it
    //
    ASSERT (mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].Type == Type);
    mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].DestAddress = DestEntry;
    mDebuggerPrivate.CallStackEntryCount ++;
  } else {
    //
    // If there is no empty entry for callstack, throw the oldest one
    //
    ASSERT (mDebuggerPrivate.CallStackEntry[EFI_DEBUGGER_TRACE_MAX].Type == Type);
    for (Index = 0; Index < EFI_DEBUGGER_CALLSTACK_MAX; Index++) {
      CopyMem (&mDebuggerPrivate.CallStackEntry[Index],
               &mDebuggerPrivate.CallStackEntry[Index + 1],
               sizeof (mDebuggerPrivate.CallStackEntry[Index])
               );
    }
    mDebuggerPrivate.CallStackEntry[EFI_DEBUGGER_CALLSTACK_MAX - 1].DestAddress = DestEntry;
    mDebuggerPrivate.CallStackEntryCount = EFI_DEBUGGER_CALLSTACK_MAX;
  }

  return ;
}

/**

  It will throw the newest Callstack entry.

**/
VOID
EbcDebuggerPopCallstack (
  VOID
  )
{
  if ((mDebuggerPrivate.CallStackEntryCount > 0) &&
      (mDebuggerPrivate.CallStackEntryCount <= EFI_DEBUGGER_CALLSTACK_MAX)) {
    //
    // Throw the newest one
    //
    mDebuggerPrivate.CallStackEntryCount --;
    mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].SourceAddress = 0;
    mDebuggerPrivate.CallStackEntry[mDebuggerPrivate.CallStackEntryCount].DestAddress = 0;
  } else if (mDebuggerPrivate.CallStackEntryCount == 0) {
    //
    // NOT assert here because it is reasonable, because when we start to build
    // callstack, we do not know how many function already called.
    //
  } else {
    ASSERT (FALSE);
  }

  return ;
}

/**

  It will record source address for trace entry.

  @param  SourceEntry  - Source address
  @param  Type         - Branch type

**/
VOID
EbcDebuggerPushTraceSourceEntry (
  IN UINT64                   SourceEntry,
  IN EFI_DEBUGGER_BRANCH_TYPE Type
  )
{
  if (mDebuggerPrivate.TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
    ASSERT (FALSE);
    mDebuggerPrivate.TraceEntryCount = EFI_DEBUGGER_TRACE_MAX;
  }
  //
  // Record the new trace entry
  //
  mDebuggerPrivate.TraceEntry[mDebuggerPrivate.TraceEntryCount].SourceAddress = SourceEntry;
  mDebuggerPrivate.TraceEntry[mDebuggerPrivate.TraceEntryCount].Type = Type;

  //
  // Do not change TraceEntryCount
  //

  return ;
}

/**

  It will record destination address for trace entry.

  @param  DestEntry    - Destination address
  @param  Type         - Branch type

**/
VOID
EbcDebuggerPushTraceDestEntry (
  IN UINT64                   DestEntry,
  IN EFI_DEBUGGER_BRANCH_TYPE Type
  )
{
  UINTN Index;

  if (mDebuggerPrivate.TraceEntryCount < EFI_DEBUGGER_TRACE_MAX) {
    //
    // If there is empty entry for trace, add it
    //
    ASSERT (mDebuggerPrivate.TraceEntry[mDebuggerPrivate.TraceEntryCount].Type == Type);
    mDebuggerPrivate.TraceEntry[mDebuggerPrivate.TraceEntryCount].DestAddress = DestEntry;
    mDebuggerPrivate.TraceEntryCount ++;
  } else {
    //
    // If there is no empty entry for trace, throw the oldest one
    //
    ASSERT (mDebuggerPrivate.TraceEntry[EFI_DEBUGGER_TRACE_MAX].Type == Type);
    for (Index = 0; Index < EFI_DEBUGGER_TRACE_MAX; Index++) {
      mDebuggerPrivate.TraceEntry[Index] = mDebuggerPrivate.TraceEntry[Index + 1];
    }
    mDebuggerPrivate.TraceEntry[EFI_DEBUGGER_CALLSTACK_MAX - 1].DestAddress = DestEntry;
    mDebuggerPrivate.TraceEntryCount = EFI_DEBUGGER_TRACE_MAX;
  }

  return ;
}

/**

  It will record address for StepEntry, if STEPOVER or STEPOUT is enabled.

  @param  Entry    - Break Address
  @param  FramePtr - Break Frame pointer
  @param  Flag     - for STEPOVER or STEPOUT

**/
VOID
EbcDebuggerPushStepEntry (
  IN UINT64                   Entry,
  IN UINT64                   FramePtr,
  IN UINT32                   Flag
  )
{
  //
  // Check StepOver
  //
  if ((Flag == EFI_DEBUG_FLAG_EBC_STEPOVER) &&
      ((mDebuggerPrivate.FeatureFlags & EFI_DEBUG_FLAG_EBC_STEPOVER) == EFI_DEBUG_FLAG_EBC_STEPOVER)) {
    mDebuggerPrivate.StepContext.BreakAddress = Entry;
    mDebuggerPrivate.StepContext.FramePointer = FramePtr;
    mDebuggerPrivate.FeatureFlags &= ~EFI_DEBUG_FLAG_EBC_B_STEPOVER;
  }
  //
  // Check StepOut
  //
  if ((Flag == EFI_DEBUG_FLAG_EBC_STEPOUT) &&
      ((mDebuggerPrivate.FeatureFlags & EFI_DEBUG_FLAG_EBC_STEPOUT) == EFI_DEBUG_FLAG_EBC_STEPOUT)) {
    mDebuggerPrivate.StepContext.BreakAddress = Entry;
    mDebuggerPrivate.StepContext.FramePointer = FramePtr;
    mDebuggerPrivate.FeatureFlags &= ~EFI_DEBUG_FLAG_EBC_B_STEPOUT;
  }
}


/**
  Notify the callback function when an event is triggered.

  @param  Event                    Indicates the event that invoke this function.
  @param  Context                  Indicates the calling context.

**/
VOID
EFIAPI
EbcDebuggerBreakEventFunc (
  IN EFI_EVENT                Event,
  IN VOID                     *Context
  )
{
  EFI_STATUS  Status;

  if ((mDebuggerPrivate.FeatureFlags & EFI_DEBUG_FLAG_EBC_BOK) != EFI_DEBUG_FLAG_EBC_BOK) {
    return ;
  }

  Status = gBS->CheckEvent (gST->ConIn->WaitForKey);
  if (Status == EFI_SUCCESS) {
    mDebuggerPrivate.StatusFlags = EFI_DEBUG_FLAG_EBC_BOK;
  }
}

/**

  The hook in InitializeEbcDriver.
  It will init the EbcDebuggerPrivate data structure.

  @param Handle           - The EbcDebugProtocol handle.
  @param EbcDebugProtocol - The EbcDebugProtocol interface.

**/
VOID
EbcDebuggerHookInit (
  IN EFI_HANDLE                  Handle,
  IN EFI_DEBUG_SUPPORT_PROTOCOL  *EbcDebugProtocol
  )
{
  EFI_STATUS                 Status;
  UINTN                      Index;
  EFI_DEBUGGER_SYMBOL_OBJECT *Object;
  EFI_DEBUGGER_SYMBOL_ENTRY  *Entry;


  //
  // Register all exception handler
  //
  for (Index = EXCEPT_EBC_UNDEFINED; Index <= EXCEPT_EBC_STEP; Index++) {
    EbcDebugProtocol->RegisterExceptionCallback (
      EbcDebugProtocol,
      0,
      NULL,
      Index
      );
    EbcDebugProtocol->RegisterExceptionCallback (
      EbcDebugProtocol,
      0,
      EdbExceptionHandler,
      Index
      );
  }

  //
  // Init Symbol
  //
  Object = AllocateZeroPool (sizeof(EFI_DEBUGGER_SYMBOL_OBJECT) * EFI_DEBUGGER_SYMBOL_OBJECT_MAX);
  ASSERT (Object != NULL);
  mDebuggerPrivate.DebuggerSymbolContext.Object = Object;
  mDebuggerPrivate.DebuggerSymbolContext.ObjectCount = 0;
  mDebuggerPrivate.DebuggerSymbolContext.MaxObjectCount = EFI_DEBUGGER_SYMBOL_OBJECT_MAX;
  for (Index = 0; Index < EFI_DEBUGGER_SYMBOL_OBJECT_MAX; Index++) {
    Entry = AllocateZeroPool (sizeof(EFI_DEBUGGER_SYMBOL_ENTRY) * EFI_DEBUGGER_SYMBOL_ENTRY_MAX);
    ASSERT (Entry != NULL);
    Object[Index].Entry = Entry;
    Object[Index].MaxEntryCount = EFI_DEBUGGER_SYMBOL_ENTRY_MAX;
    Object[Index].SourceBuffer = AllocateZeroPool (sizeof(VOID *) * (EFI_DEBUGGER_SYMBOL_ENTRY_MAX + 1));
    ASSERT (Object[Index].SourceBuffer != NULL);
  }

  //
  // locate PciRootBridgeIo
  //
  Status = gBS->LocateProtocol (
                  &gEfiPciRootBridgeIoProtocolGuid,
                  NULL,
                  (VOID**) &mDebuggerPrivate.PciRootBridgeIo
                  );

  //
  // locate DebugImageInfoTable
  //
  Status = EfiGetSystemConfigurationTable (
             &gEfiDebugImageInfoTableGuid,
             (VOID**) &mDebuggerPrivate.DebugImageInfoTableHeader
             );

  //
  // Register Debugger Configuration Protocol, for config in shell
  //
  Status = gBS->InstallProtocolInterface (
                  &Handle,
                  &gEfiDebuggerConfigurationProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &mDebuggerPrivate.DebuggerConfiguration
                  );

  //
  //
  // Create break event
  //
  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  EbcDebuggerBreakEventFunc,
                  NULL,
                  &mDebuggerPrivate.BreakEvent
                  );
  if (!EFI_ERROR (Status)) {
    Status = gBS->SetTimer (
                    mDebuggerPrivate.BreakEvent,
                    TimerPeriodic,
                    EFI_DEBUG_BREAK_TIMER_INTERVAL
                    );
  }

  return ;
}

/**

  The hook in UnloadImage for EBC Interpreter.
  It clean up the environment.

**/
VOID
EbcDebuggerHookUnload (
  VOID
  )
{
  UINTN                      Index;
  UINTN                      SubIndex;
  EFI_DEBUGGER_SYMBOL_OBJECT *Object;

  //
  // Close the break event
  //
  if (mDebuggerPrivate.BreakEvent != NULL) {
    gBS->CloseEvent (mDebuggerPrivate.BreakEvent);
  }

  //
  // Clean up the symbol
  //
  Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
  for (Index = 0; Index < EFI_DEBUGGER_SYMBOL_OBJECT_MAX; Index++) {
    //
    // Clean up Entry
    //
    gBS->FreePool (Object[Index].Entry);
    Object[Index].Entry = NULL;
    Object[Index].EntryCount = 0;
    //
    // Clean up source buffer
    //
    for (SubIndex = 0; Object[Index].SourceBuffer[SubIndex] != NULL; SubIndex++) {
      gBS->FreePool (Object[Index].SourceBuffer[SubIndex]);
      Object[Index].SourceBuffer[SubIndex] = NULL;
    }
    gBS->FreePool (Object[Index].SourceBuffer);
    Object[Index].SourceBuffer = NULL;
  }

  //
  // Clean up Object
  //
  gBS->FreePool (Object);
  mDebuggerPrivate.DebuggerSymbolContext.Object = NULL;
  mDebuggerPrivate.DebuggerSymbolContext.ObjectCount = 0;

  //
  // Done
  //
  return ;
}

/**

  The hook in EbcUnloadImage.
  Currently do nothing here.

  @param  Handle           - The EbcImage handle.

**/
VOID
EbcDebuggerHookEbcUnloadImage (
  IN EFI_HANDLE                  Handle
  )
{
  return ;
}

/**

  The hook in ExecuteEbcImageEntryPoint.
  It will record the call-stack entry. (-1 means EbcImageEntryPoint call)
  and trigger Exception if BOE enabled.


  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookExecuteEbcImageEntryPoint (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushCallstackSource ((UINT64)(UINTN)-1, EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushCallstackParameter ((UINT64)(UINTN)VmPtr->Gpr[0], EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushCallstackDest ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerCheckHookFlag (VmPtr, EFI_DEBUG_FLAG_EBC_BOE);
  return ;
}

/**

  The hook in ExecuteEbcImageEntryPoint.
  It will record the call-stack entry. (-2 means EbcInterpret call)
  and trigger Exception if BOT enabled.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookEbcInterpret (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushCallstackSource ((UINT64)(UINTN)-2, EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushCallstackParameter ((UINT64)(UINTN)VmPtr->Gpr[0], EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushCallstackDest ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerCheckHookFlag (VmPtr, EFI_DEBUG_FLAG_EBC_BOT);
  return ;
}

/**

  The hook in EbcExecute, before ExecuteFunction.
  It will trigger Exception if GoTil, StepOver, or StepOut hit.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookExecuteStart (
  IN VM_CONTEXT *VmPtr
  )
{
  EFI_TPL   CurrentTpl;

  //
  // Check Ip for GoTil
  //
  if (mDebuggerPrivate.GoTilContext.BreakAddress == (UINT64)(UINTN)VmPtr->Ip) {
    mDebuggerPrivate.StatusFlags = EFI_DEBUG_FLAG_EBC_GT;
    mDebuggerPrivate.GoTilContext.BreakAddress = 0;
    EbcDebugSignalException (
      EXCEPT_EBC_BREAKPOINT,
      EXCEPTION_FLAG_NONE,
      VmPtr
      );
    mDebuggerPrivate.StatusFlags &= ~EFI_DEBUG_FLAG_EBC_B_GT;
    return ;
  }
  //
  // Check ReturnAddress for StepOver
  //
  if ((mDebuggerPrivate.StepContext.BreakAddress == (UINT64)(UINTN)VmPtr->Ip) &&
      (mDebuggerPrivate.StepContext.FramePointer == (UINT64)(UINTN)VmPtr->FramePtr)) {
    mDebuggerPrivate.StatusFlags = EFI_DEBUG_FLAG_EBC_STEPOVER;
    mDebuggerPrivate.StepContext.BreakAddress = 0;
    mDebuggerPrivate.StepContext.FramePointer = 0;
    EbcDebugSignalException (
      EXCEPT_EBC_BREAKPOINT,
      EXCEPTION_FLAG_NONE,
      VmPtr
      );
    mDebuggerPrivate.StatusFlags &= ~EFI_DEBUG_FLAG_EBC_B_STEPOVER;
  }
  //
  // Check FramePtr for StepOut
  //
  if (mDebuggerPrivate.StepContext.BreakAddress == (UINT64)(UINTN)VmPtr->FramePtr) {
    mDebuggerPrivate.StatusFlags = EFI_DEBUG_FLAG_EBC_STEPOUT;
    mDebuggerPrivate.StepContext.BreakAddress = 0;
    mDebuggerPrivate.StepContext.FramePointer = 0;
    EbcDebugSignalException (
      EXCEPT_EBC_BREAKPOINT,
      EXCEPTION_FLAG_NONE,
      VmPtr
      );
    mDebuggerPrivate.StatusFlags &= ~EFI_DEBUG_FLAG_EBC_B_STEPOUT;
  }
  //
  // Check Flags for BreakOnKey
  //
  if (mDebuggerPrivate.StatusFlags == EFI_DEBUG_FLAG_EBC_BOK) {
    //
    // Only break when the current TPL <= TPL_APPLICATION
    //
    CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
    gBS->RestoreTPL (CurrentTpl);
    if (CurrentTpl <= TPL_APPLICATION) {
      EbcDebugSignalException (
        EXCEPT_EBC_BREAKPOINT,
        EXCEPTION_FLAG_NONE,
        VmPtr
        );
      mDebuggerPrivate.StatusFlags &= ~EFI_DEBUG_FLAG_EBC_B_BOK;
    }
  }
  return ;
}

/**

  The hook in EbcExecute, after ExecuteFunction.
  It will record StepOut Entry if need.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookExecuteEnd (
  IN VM_CONTEXT *VmPtr
  )
{
  UINTN  Address;

  //
  // Use FramePtr as checkpoint for StepOut
  //
  CopyMem (&Address, (VOID *)((UINTN)VmPtr->FramePtr), sizeof(Address));
  EbcDebuggerPushStepEntry (Address, (UINT64)(UINTN)VmPtr->FramePtr, EFI_DEBUG_FLAG_EBC_STEPOUT);

  return ;
}

/**

  The hook in ExecuteCALL, before move IP.
  It will trigger Exception if BOC enabled,
  and record Callstack, and trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookCALLStart (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerCheckHookFlag (VmPtr, EFI_DEBUG_FLAG_EBC_BOC);
  EbcDebuggerPushCallstackSource ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushCallstackParameter ((UINT64)(UINTN)VmPtr->Gpr[0], EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushTraceSourceEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCall);
  return ;
}

/**

  The hook in ExecuteCALL, after move IP.
  It will record Callstack, trace information
  and record StepOver/StepOut Entry if need.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookCALLEnd (
  IN VM_CONTEXT *VmPtr
  )
{
  UINT64  Address;
  UINTN   FramePtr;

  EbcDebuggerPushCallstackDest ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCall);
  EbcDebuggerPushTraceDestEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCall);

  //
  // Get Old FramePtr
  //
  CopyMem (&FramePtr, (VOID *)((UINTN)VmPtr->FramePtr), sizeof(FramePtr));

  //
  // Use ReturnAddress as checkpoint for StepOver
  //
  CopyMem (&Address, (VOID *)(UINTN)VmPtr->Gpr[0], sizeof(Address));
  EbcDebuggerPushStepEntry (Address, FramePtr, EFI_DEBUG_FLAG_EBC_STEPOVER);

  //
  // Use FramePtr as checkpoint for StepOut
  //
  Address = 0;
  CopyMem (&Address, (VOID *)(FramePtr), sizeof(UINTN));
  EbcDebuggerPushStepEntry (Address, FramePtr, EFI_DEBUG_FLAG_EBC_STEPOUT);

  return ;
}

/**

  The hook in ExecuteCALL, before call EbcLLCALLEX.
  It will trigger Exception if BOCX enabled,
  and record Callstack information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookCALLEXStart (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerCheckHookFlag (VmPtr, EFI_DEBUG_FLAG_EBC_BOCX);
//  EbcDebuggerPushCallstackSource ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCallEx);
//  EbcDebuggerPushCallstackParameter ((UINT64)(UINTN)VmPtr->R[0], EfiDebuggerBranchTypeEbcCallEx);
  EbcDebuggerPushTraceSourceEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCallEx);
  return ;
}

/**

  The hook in ExecuteCALL, after call EbcLLCALLEX.
  It will record trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookCALLEXEnd (
  IN VM_CONTEXT *VmPtr
  )
{
//  EbcDebuggerPushCallstackDest ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCallEx);
  EbcDebuggerPushTraceDestEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcCallEx);
  return ;
}

/**

  The hook in ExecuteRET, before move IP.
  It will trigger Exception if BOR enabled,
  and record Callstack, and trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookRETStart (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerCheckHookFlag (VmPtr, EFI_DEBUG_FLAG_EBC_BOR);
  EbcDebuggerPopCallstack ();
  EbcDebuggerPushTraceSourceEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcRet);
  return ;
}

/**

  The hook in ExecuteRET, after move IP.
  It will record trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookRETEnd (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushTraceDestEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcRet);
  return ;
}

/**

  The hook in ExecuteJMP, before move IP.
  It will record trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookJMPStart (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushTraceSourceEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcJmp);
  return ;
}

/**

  The hook in ExecuteJMP, after move IP.
  It will record trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookJMPEnd (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushTraceDestEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcJmp);
  return ;
}

/**

  The hook in ExecuteJMP8, before move IP.
  It will record trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookJMP8Start (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushTraceSourceEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcJmp8);
  return ;
}

/**

  The hook in ExecuteJMP8, after move IP.
  It will record trace information.

  @param  VmPtr - pointer to VM context.

**/
VOID
EbcDebuggerHookJMP8End (
  IN VM_CONTEXT *VmPtr
  )
{
  EbcDebuggerPushTraceDestEntry ((UINT64)(UINTN)VmPtr->Ip, EfiDebuggerBranchTypeEbcJmp8);
  return ;
}
