types: Split aligned and packed guids

On ia64 alignment requirements are strict. When we pass a pointer to
UUID it needs to be at least 4-byte aligned or EFI will crash.
On the other hand in device path there is no padding for UUID, so we
need 2 types in one formor another. Make 4-byte aligned and unaligned types

The code is structured in a way to accept unaligned inputs
in most cases and supply 4-byte aligned outputs.

Efiemu case is a bit ugly because there inputs and outputs are
reversed and so we need careful casts to account for this
inversion.

Signed-off-by: Vladimir Serbinenko <phcoder@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Vladimir Serbinenko 2023-08-13 09:18:23 +02:00
parent 5fc985bfdd
commit 7de6fe9635
9 changed files with 54 additions and 24 deletions

View File

@ -96,7 +96,7 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
grub_efi_handle_t handle = handles[i];
grub_efi_status_t status;
grub_efi_uintn_t num_protocols;
grub_guid_t **protocols;
grub_packed_guid_t **protocols;
grub_efi_device_path_t *dp;
grub_printf ("Handle %p\n", handle);

View File

@ -66,7 +66,7 @@ efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
grub_efi_status_t __grub_efi_api
efiemu_get_variable (grub_efi_char16_t *variable_name,
const grub_guid_t *vendor_guid,
const grub_packed_guid_t *vendor_guid,
grub_efi_uint32_t *attributes,
grub_efi_uintn_t *data_size,
void *data);
@ -74,11 +74,11 @@ efiemu_get_variable (grub_efi_char16_t *variable_name,
grub_efi_status_t __grub_efi_api
efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size,
grub_efi_char16_t *variable_name,
grub_guid_t *vendor_guid);
grub_packed_guid_t *vendor_guid);
grub_efi_status_t __grub_efi_api
efiemu_set_variable (grub_efi_char16_t *variable_name,
const grub_guid_t *vendor_guid,
const grub_packed_guid_t *vendor_guid,
grub_efi_uint32_t attributes,
grub_efi_uintn_t data_size,
void *data);
@ -416,7 +416,7 @@ EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
/* Find variable by name and GUID. */
static struct efi_variable *
find_variable (const grub_guid_t *vendor_guid,
find_variable (const grub_packed_guid_t *vendor_guid,
grub_efi_char16_t *variable_name)
{
grub_uint8_t *ptr;
@ -438,7 +438,7 @@ find_variable (const grub_guid_t *vendor_guid,
grub_efi_status_t __grub_efi_api
EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
const grub_guid_t *vendor_guid,
const grub_packed_guid_t *vendor_guid,
grub_efi_uint32_t *attributes,
grub_efi_uintn_t *data_size,
void *data)
@ -464,7 +464,7 @@ EFI_FUNC (efiemu_get_variable) (grub_efi_char16_t *variable_name,
grub_efi_status_t __grub_efi_api EFI_FUNC
(efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
grub_efi_char16_t *variable_name,
grub_guid_t *vendor_guid)
grub_packed_guid_t *vendor_guid)
{
struct efi_variable *efivar;
LOG ('l');
@ -503,7 +503,7 @@ grub_efi_status_t __grub_efi_api EFI_FUNC
grub_efi_status_t __grub_efi_api
EFI_FUNC (efiemu_set_variable) (grub_efi_char16_t *variable_name,
const grub_guid_t *vendor_guid,
const grub_packed_guid_t *vendor_guid,
grub_efi_uint32_t attributes,
grub_efi_uintn_t data_size,
void *data)
@ -597,9 +597,30 @@ struct grub_efi_runtime_services efiemu_runtime_services =
.set_virtual_address_map = efiemu_set_virtual_address_map,
.convert_pointer = efiemu_convert_pointer,
.get_variable = efiemu_get_variable,
.get_next_variable_name = efiemu_get_next_variable_name,
.set_variable = efiemu_set_variable,
/*
The code is structured in a way to accept unaligned inputs
in most cases and supply 4-byte aligned outputs.
Efiemu case is a bit ugly because there inputs and outputs are
reversed and so we need careful casts to account for this
inversion.
*/
.get_variable = (grub_efi_status_t
(__grub_efi_api *) (grub_efi_char16_t *variable_name,
const grub_guid_t *vendor_guid,
grub_efi_uint32_t *attributes,
grub_efi_uintn_t *data_size,
void *data)) efiemu_get_variable,
.get_next_variable_name = (grub_efi_status_t
(__grub_efi_api *) (grub_efi_uintn_t *variable_name_size,
grub_efi_char16_t *variable_name,
grub_guid_t *vendor_guid)) efiemu_get_next_variable_name,
.set_variable = (grub_efi_status_t
(__grub_efi_api *) (grub_efi_char16_t *variable_name,
const grub_guid_t *vendor_guid,
grub_efi_uint32_t attributes,
grub_efi_uintn_t data_size,
void *data)) efiemu_set_variable,
.get_next_high_monotonic_count = efiemu_get_next_high_monotonic_count,
.reset_system = efiemu_reset_system

View File

@ -1039,7 +1039,7 @@ grub_efi_find_configuration_table (const grub_guid_t *target_guid)
for (i = 0; i < grub_efi_system_table->num_table_entries; i++)
{
grub_guid_t *guid =
grub_packed_guid_t *guid =
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, target_guid, sizeof (grub_guid_t)))

View File

@ -1068,7 +1068,7 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
if (*(fmt) == 'G')
{
++fmt;
grub_guid_t *guid = (grub_guid_t *)(grub_addr_t) curarg;
grub_packed_guid_t *guid = (grub_packed_guid_t *)(grub_addr_t) curarg;
write_number (str, &count, max_len, 8, 0, '0', 'x', guid->data1);
write_char (str, &count, max_len, '-');
write_number (str, &count, max_len, 4, 0, '0', 'x', guid->data2);

View File

@ -694,7 +694,7 @@ grub_cpu_xnu_fill_devicetree (grub_uint64_t *fsbfreq_out)
{
void *ptr;
struct grub_xnu_devtree_key *curkey;
grub_guid_t guid;
grub_packed_guid_t guid;
char guidbuf[64];
/* Retrieve current key. */

View File

@ -730,7 +730,7 @@ typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_
struct grub_efi_vendor_device_path
{
grub_efi_device_path_t header;
grub_guid_t vendor_guid;
grub_packed_guid_t vendor_guid;
grub_efi_uint8_t vendor_defined_data[0];
} GRUB_PACKED;
typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t;
@ -974,7 +974,7 @@ typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t;
struct grub_efi_vendor_media_device_path
{
grub_efi_device_path_t header;
grub_guid_t vendor_guid;
grub_packed_guid_t vendor_guid;
grub_efi_uint8_t vendor_defined_data[0];
} GRUB_PACKED;
typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t;
@ -993,7 +993,7 @@ typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t;
struct grub_efi_protocol_device_path
{
grub_efi_device_path_t header;
grub_guid_t guid;
grub_packed_guid_t guid;
} GRUB_PACKED;
typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
@ -1002,7 +1002,7 @@ typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t;
struct grub_efi_piwg_device_path
{
grub_efi_device_path_t header;
grub_guid_t guid;
grub_packed_guid_t guid;
} GRUB_PACKED;
typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t;
@ -1287,7 +1287,7 @@ struct grub_efi_boot_services
grub_efi_status_t
(__grub_efi_api *protocols_per_handle) (grub_efi_handle_t handle,
grub_guid_t ***protocol_buffer,
grub_packed_guid_t ***protocol_buffer,
grub_efi_uintn_t *protocol_buffer_count);
grub_efi_status_t
@ -1386,7 +1386,7 @@ typedef struct grub_efi_runtime_services grub_efi_runtime_services_t;
struct grub_efi_configuration_table
{
grub_guid_t vendor_guid;
grub_packed_guid_t vendor_guid;
void *vendor_table;
} GRUB_PACKED;
typedef struct grub_efi_configuration_table grub_efi_configuration_table_t;

View File

@ -183,13 +183,13 @@ struct grub_efiemu_configuration_table
};
struct grub_efiemu_configuration_table32
{
grub_guid_t vendor_guid;
grub_packed_guid_t vendor_guid;
grub_efi_uint32_t vendor_table;
} GRUB_PACKED;
typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table32_t;
struct grub_efiemu_configuration_table64
{
grub_guid_t vendor_guid;
grub_packed_guid_t vendor_guid;
grub_efi_uint64_t vendor_table;
} GRUB_PACKED;
typedef struct grub_efiemu_configuration_table64 grub_efiemu_configuration_table64_t;

View File

@ -29,7 +29,7 @@ struct grub_efiemu_ptv_rel
struct efi_variable
{
grub_guid_t guid;
grub_packed_guid_t guid;
grub_uint32_t namelen;
grub_uint32_t size;
grub_efi_uint32_t attributes;

View File

@ -376,7 +376,16 @@ struct grub_guid
grub_uint16_t data2;
grub_uint16_t data3;
grub_uint8_t data4[8];
} GRUB_PACKED;
} __attribute__ ((aligned(4)));
typedef struct grub_guid grub_guid_t;
struct grub_packed_guid
{
grub_uint32_t data1;
grub_uint16_t data2;
grub_uint16_t data3;
grub_uint8_t data4[8];
} GRUB_PACKED;
typedef struct grub_packed_guid grub_packed_guid_t;
#endif /* ! GRUB_TYPES_HEADER */