2 thunking native code to ebc, 3 thunking ebc to ebc – Intel Extensible Firmware Interface User Manual

Page 847

Advertising
background image

EFI Byte Code Virtual Machine

Version 1.10

12/01/02

19-73

19.12.10.2 Thunking Native Code to EBC

An EBC driver may install protocols for use by other EBC drivers or EFI drivers or applications.
These protocols provide the mechanism by which external native code can call EBC. Typical EFI
C code to install a generic protocol is shown below.

EFI_STATUS Foo(UINT32 Arg1, UINT32 Arg2);

MyProtInterface->Service1

= Foo;


Status = LibInstallProtocolInterfaces (&Handle, &MyProtGUID,
MyProtInterface, NULL);

To support thunking native code to EBC, the EBC compiler resolves all EBC function pointers
using one level of indirection. In this way, the address of an EBC function actually becomes the
address of a piece of native (thunk) code that invokes the interpreter to execute the actual EBC
function. As a result of this implementation, any time the address of an EBC function is taken, the
EBC C compiler must generate the following:
• A 64-bit function pointer data object that contains the actual address of the EBC function
• EBC initialization code that is executed before the image entry point that will execute EBC

BREAK

5 instructions to create thunks for each function pointer data object

• Associated relocations for the above
So for the above code sample, the compiler must generate EBC initialization code similar to the
following. This code is executed prior to execution of the actual EBC driver’s entry point.

MOVqq R7, Foo_pointer

; get address of Foo pointer

BREAK 5

; create a thunk for the function

The BREAK instruction causes the interpreter to create native thunk code elsewhere in memory,
and then modify the memory location pointed to by R7 to point to the newly created thunk code for
EBC function Foo. From within EBC, when the address of Foo is taken, the address of the thunk is
actually returned. So for the assignment of the protocol Service1 above, the EBC C compiler will
generate something like the following:

MOVqq R7, Foo_pointer

; get address of Foo function pointer

MOVqq R7, @R7

; one level of indirection

MOVn R6, _MyProtInterface->Service1 ; get address of variable
MOVqq @R6, R7

; address of thunk to ->Service1

19.12.10.3 Thunking EBC to EBC

EBC can call EBC via function pointers or protocols. These two mechanisms are treated identically
by the EBC C compiler, and are performed using EBC

CALLEX

instructions. For EBC to call

EBC, the EBC being called must have provided the address of the function. As described above,
the address is actually the address of native thunk code for the actual EBC function. Therefore,
when EBC calls EBC, the interpreter assumes native code is being called so prepares function
arguments accordingly, and then makes the call. The native thunk code assumes native code is
calling EBC, so will basically “undo” the preparation of function arguments, and then invoke the
interpreter to execute the actual EBC function of interest.

Advertising