From 62ba2e4ade20ad48dec105e9f7db4a99d46da43b Mon Sep 17 00:00:00 2001 From: mdkinney Date: Tue, 27 Oct 2009 22:58:55 +0000 Subject: [PATCH] Update transition from EBC function to native IPF function to guarantee that at least 0x40 bytes of stack frame are reserved to prevent stack corruption. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9377 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Universal/EbcDxe/Ipf/EbcLowLevel.s | 72 ++++++++++++++----- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s index 4c0f80fb02..26b3c48616 100644 --- a/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s +++ b/MdeModulePkg/Universal/EbcDxe/Ipf/EbcLowLevel.s @@ -121,30 +121,66 @@ PROCEDURE_ENTRY(EbcAsmLLCALLEX) PROCEDURE_EXIT(EbcAsmLLCALLEX) +//----------------------------------------------------------------------------- +//++ +// EbcLLCALLEXNative +// +// This function is called to execute an EBC CALLEX instruction. +// This instruction requires that we thunk out to external native +// code. On return, we restore the stack pointer to its original location. +// Destroys no working registers. For IPF, at least 8 register slots +// must be allocated on the stack frame to support any number of +// arguments beiung passed to the external native function. The +// size of the stack frame is FramePtr - EbcSp. If this size is less +// than 64-bytes, the amount of stack frame allocated is rounded up +// to 64-bytes +// +// Arguments On Entry : +// in0 = CallAddr The function address. +// in1 = EbcSp The new EBC stack pointer. +// in2 = FramePtr The frame pointer. +// +// Return Value: +// None +// +// C Function Prototype: +// VOID +// EFIAPI +// EbcLLCALLEXNative ( +// IN UINTN CallAddr, +// IN UINTN EbcSp, +// IN VOID *FramePtr +// ); +//-- +//--------------------------------------------------------------------------- + PROCEDURE_ENTRY(EbcLLCALLEXNative) NESTED_SETUP (3,6,3,0) - mov loc2 = in2;; - mov loc3 = in1;; - sub loc2 = loc2, loc3 - mov loc4 = r12;; - or loc5 = r1, r0 + mov loc2 = in2;; // loc2 = in2 = FramePtr + mov loc3 = in1;; // loc3 = in1 = EbcSp + sub loc2 = loc2, loc3;; // loc2 = loc2 - loc3 = FramePtr - EbcSp + mov out2 = loc2;; // out2 = loc2 = FramePtr - EbcSp + mov loc4 = 0x40;; // loc4 = 0x40 + cmp.leu p6 = out2, loc4;; // IF out2 < loc4 THEN P6=1 ELSE P6=0; IF (FramePtr - EbcSp) < 0x40 THEN P6 = 1 ELSE P6=0 + (p6) mov loc2 = loc4;; // IF P6==1 THEN loc2 = loc4 = 0x40 + mov loc4 = r12;; // save sp + or loc5 = r1, r0 // save gp - sub r12 = r12, loc2 - mov out2 = loc2;; + sub r12 = r12, loc2;; // sp = sp - loc2 = sp - MAX (0x40, FramePtr - EbcSp) - and r12 = -0x10, r12 - mov out1 = in1;; - mov out0 = r12;; - adds r12 = -0x8, r12 - (p0) br.call.dptk.many b0 = CopyMem;; - adds r12 = 0x8, r12 + and r12 = -0x10, r12 // Round sp down to the nearest 16-byte boundary + mov out1 = in1;; // out1 = EbcSp + mov out0 = r12;; // out0 = sp + adds r12 = -0x8, r12 + (p0) br.call.dptk.many b0 = CopyMem;; // CopyMem (sp, EbcSp, (FramePtr - EbcSp)) + adds r12 = 0x8, r12 - mov out0 = in0;; - mov out1 = r12;; - (p0) br.call.dptk.many b0 = EbcAsmLLCALLEX;; - mov r12 = loc4;; - or r1 = loc5, r0 + mov out0 = in0;; // out0 = CallAddr + mov out1 = r12;; // out1 = sp + (p0) br.call.dptk.many b0 = EbcAsmLLCALLEX;; // EbcAsmLLCALLEX (CallAddr, sp) + mov r12 = loc4;; // restore sp + or r1 = loc5, r0 // restore gp NESTED_RETURN PROCEDURE_EXIT(EbcLLCALLEXNative)