Implements the EBC CALL instruction. Instruction format: CALL64 Immed64 CALL32 {@}R1 {Immed32|Index32} CALLEX64 Immed64 CALLEX16 {@}R1 {Immed32} If Rx == R0, then it's a PC relative call to PC = PC + imm32. @param VmPtr A pointer to a VM context. @retval EFI_SUCCESS The instruction is executed successfully. **/
| 2964 | |
| 2965 | **/ |
| 2966 | EFI_STATUS |
| 2967 | ExecuteCALL ( |
| 2968 | IN VM_CONTEXT *VmPtr |
| 2969 | ) |
| 2970 | { |
| 2971 | UINT8 Opcode; |
| 2972 | UINT8 Operands; |
| 2973 | INT32 Immed32; |
| 2974 | UINT8 Size; |
| 2975 | INT64 Immed64; |
| 2976 | VOID *FramePtr; |
| 2977 | |
| 2978 | // |
| 2979 | // Get opcode and operands |
| 2980 | // |
| 2981 | Opcode = GETOPCODE (VmPtr); |
| 2982 | Operands = GETOPERANDS (VmPtr); |
| 2983 | |
| 2984 | if ((Operands & OPERAND_M_NATIVE_CALL) != 0) { |
| 2985 | EbcDebuggerHookCALLEXStart (VmPtr); |
| 2986 | } else { |
| 2987 | EbcDebuggerHookCALLStart (VmPtr); |
| 2988 | } |
| 2989 | |
| 2990 | // |
| 2991 | // Assign these as well to avoid compiler warnings |
| 2992 | // |
| 2993 | Immed64 = 0; |
| 2994 | Immed32 = 0; |
| 2995 | |
| 2996 | FramePtr = VmPtr->FramePtr; |
| 2997 | // |
| 2998 | // Determine the instruction size, and get immediate data if present |
| 2999 | // |
| 3000 | if ((Opcode & OPCODE_M_IMMDATA) != 0) { |
| 3001 | if ((Opcode & OPCODE_M_IMMDATA64) != 0) { |
| 3002 | Immed64 = VmReadImmed64 (VmPtr, 2); |
| 3003 | Size = 10; |
| 3004 | } else { |
| 3005 | // |
| 3006 | // If register operand is indirect, then the immediate data is an index |
| 3007 | // |
| 3008 | if (OPERAND1_INDIRECT (Operands)) { |
| 3009 | Immed32 = VmReadIndex32 (VmPtr, 2); |
| 3010 | } else { |
| 3011 | Immed32 = VmReadImmed32 (VmPtr, 2); |
| 3012 | } |
| 3013 | |
| 3014 | Size = 6; |
| 3015 | } |
| 3016 | } else { |
| 3017 | Size = 2; |
| 3018 | } |
| 3019 | // |
| 3020 | // If it's a call to EBC, adjust the stack pointer down 16 bytes and |
| 3021 | // put our return address and frame pointer on the VM stack. |
| 3022 | // |
| 3023 | if ((Operands & OPERAND_M_NATIVE_CALL) == 0) { |
nothing calls this directly
no test coverage detected