4.3.6 Returning Pointers in a Function Parameter
The following example shows a bad example for casting pointers. The function
MyFunction()
returns a 64-bit value in an OUT
parameter that is assigned from a 32-bit input parameter. There is nothing wrong with MyFunction()
. The problem is when MyFunction()
is called. Here, the address of B
, a 32-bit container, is cast to a pointer to a 64-bit container and passed to MyFunction()
. MyFunction()
writes to 64 bits starting at B
. This location happens to overwrite the value of B
and the value of A
in the calling function.The first
Print()
correctly shows the values of A
and B
. The second Print()
shows that B
was given A
's original value, but the contents of A
were destroyed and overwritten with a 0.The cast from
&B
to a (UINT64 *)
is the problem here. This code compiles without errors or warnings on both 32-bit and 64-bit processors. It executes on 32-bit and 64-bit processors with these unexpected side effects. It might also generate an alignment fault on IPF if &B
is not 64-bit aligned. One possible fix for this issue is to change B from a UINT32
to a UINT64
.EFI_STATUS
EFIAPI
MyFunction (
IN UINT32 ValueU32,
OUT UINT64 *ValueU64
)
{
*ValueU64 = (UINT64)ValueU32;
return EFI_SUCCESS;
}
UINT32 A;
UINT32 B;
A = 0x11112222;
B = 0x33334444;
//
// Prints "A = 11112222 B = 33334444"
//
Print (L"A = %08x B = %08x\n", A, B);
MyFunction (A, (UINT64 *)(&B));
//
// Prints "A = 00000000 B = 11112222"
//
Print (L"A = %08x B = %08x\n", A, B);
Last modified 2yr ago