bits-1151 released with these changes:
The "I FFI, UEFI, we all FFI for EFI" release.
BITS now supports making EFI calls via the Python ctypes module, rather than
manually using efi.call
. This provides simplified call syntax, type safety,
better (reference-counted) memory lifetime handling, bounds checking, and the
ability to have EFI call Python callbacks.
All EFI protocols, functions, and types have been converted to use ctypes.
This also provides automatic conversions to and from Python types as
appropriate. For instance, functions declared to accept a c_wchar_p
(a
Unicode string) accept Python string and unicode objects:
out = efi.system_table.ConOut.contents
out.OutputString(out, "Hello world!\r\n")
Add support for the 64-bit EFI calling convention in ctypes
Ship a separate copy of libffi with 64-bit EFI support added, and change Python's
_ctypes
module to support that calling convention.Add the
uintptr_t
andintptr_t
types to ourstdint.h
, since libffi needsuintptr_t
.Convert all EFI functions, structure, and protocols to ctypes
Now that ctypes can call EFI functions, convert all functions to use it, along with the corresponding types and protocols. This significantly improves type safety, memory lifetime handling, bounds checking, and similar.
In particular, code should now almost never use from_address or addressof, since those produce raw addresses that may outlive the objects they point to; code using from_address should now use from_buffer or similar, and code using addressof should use byref or similar.
Define a new type
EFIFUNCTYPE
, analogous toctypes.CFUNCTYPE
, for calls using the EFI calling convention. For convenience, provide a wrapperefi.FUNC
that assumes a return type ofEFI_STATUS
(overridable with a keyword parameterret
).To simplify the process of translating EFI functions and structures from specifications, define appropriate EFI type aliases for ctypes types. For instance, EFI extensively uses the type
UINTN
for "an integer the size of a pointer", so the efi module defines that type asc_ulong
.Using ctypes function types also enables many convenient conversions. For example, a function taking a parameter of type
c_wchar_p
can accept a Python string or unicode object. See the ctypes documentation for more details.When defining function parameter and return types, note that the ctypes types
c_char_p
andc_wchar_p
have additional magic behavior above and beyond a normal pointer, to transparently accept and return strings. This behavior can be convenient, but it means that an EFI function specified to accept or return a pointer toCHAR16
may want to use eitherPOINTER(CHAR16)
orEFI_STRING
(AKAc_wchar_p
) as its type, depending on the desired semantic behavior. UsePOINTER(CHAR16)
(andcreate_unicode_buffer
) for a pointer that EFI will fill in (since passing a temporary object converted from a Python unicode object would not produce useful results), or for a returned pointer that the caller must free via the EFIFreePool
or similar (since the automatic conversion of return types fromc_wchar_p
to a Python unicode object would discard the pointer that needs freeing).EFIException
now decodes known EFI error codes as symbolic names, in addition to showing the hex value of all error codes.Since efi now makes much more extensive use of ctypes types, switch from
import ctypes
tofrom ctypes import *
. Similarly,bits.present
doesfrom efi import *
to get the EFI types. In general, modules that just call efi functions shouldimport efi
, but modules defining new EFI protocols or structures shouldfrom efi import *
.efi.call
, and the associatedsplit64()
magic for 64-bit parameters on 32-bit EFI, are no more. They will not be mourned.Backport a grub change to fix a build failure on systems with new flex
With current versions of flex, grub failed to build with this error:
grub_script.yy.c:2367:13: error: 'yy_fatal_error' defined but not used [-Werror=unused-function] static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
Fix that by backporting the change from git commit 9cc836a27be4a95f6f7bfd5b6bc099801645c0ea to disable additional warnings for the flex-generated lexer.
Disable
-Wunused-value
for PythonCurrent Python on current GCC generates a
-Wunused-value
warning on uses of thePyObject_INIT
macro, because it expands to a comma expression where the rightmost value goes unused if nothing looks at the return value. This warning turns into an error because of-Werror
.