efi_loader: new functions to print loaded image information

Introduce functions to print information about loaded images.

If we want to analyze an exception in an EFI image we need the offset
between the PC and the start of the loaded image.

With efi_print_image_info() we can print the necessary information for a
single image, e.g.

UEFI image [0xbffe6000:0xbffe631f] pc=0x138 '/\snp.efi'

efi_print_image_infos() provides output for all loaded images.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Heinrich Schuchardt 2018-04-05 11:56:21 +02:00 committed by Alexander Graf
parent 1348c17ab2
commit c9a63f44b5
2 changed files with 51 additions and 0 deletions

View File

@ -308,6 +308,10 @@ efi_status_t efi_setup_loaded_image(
struct efi_device_path *file_path);
efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,
void **buffer);
/* Print information about a loaded image */
efi_status_t efi_print_image_info(struct efi_loaded_image *image, void *pc);
/* Print information about all loaded images */
void efi_print_image_infos(void *pc);
#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
extern void *efi_bounce_buffer;
@ -425,6 +429,7 @@ static inline void efi_restore_gd(void) { }
static inline void efi_set_bootdev(const char *dev, const char *devnr,
const char *path) { }
static inline void efi_net_set_dhcp_ack(void *pkt, int len) { }
static inline void efi_print_image_infos(void *pc) { }
#endif /* CONFIG_EFI_LOADER && !CONFIG_SPL_BUILD */

View File

@ -22,6 +22,52 @@ const efi_guid_t efi_simple_file_system_protocol_guid =
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
/*
* Print information about a loaded image.
*
* If the program counter is located within the image the offset to the base
* address is shown.
*
* @image: loaded image
* @pc: program counter (use NULL to suppress offset output)
* @return: status code
*/
efi_status_t efi_print_image_info(struct efi_loaded_image *image, void *pc)
{
if (!image)
return EFI_INVALID_PARAMETER;
printf("UEFI image");
printf(" [0x%p:0x%p]",
image->reloc_base, image->reloc_base + image->reloc_size - 1);
if (pc && pc >= image->reloc_base &&
pc < image->reloc_base + image->reloc_size)
printf(" pc=0x%zx", pc - image->reloc_base);
if (image->file_path)
printf(" '%pD'", image->file_path);
printf("\n");
return EFI_SUCCESS;
}
/*
* Print information about all loaded images.
*
* @pc: program counter (use NULL to suppress offset output)
*/
void efi_print_image_infos(void *pc)
{
struct efi_object *efiobj;
struct efi_handler *handler;
list_for_each_entry(efiobj, &efi_obj_list, link) {
list_for_each_entry(handler, &efiobj->protocols, link) {
if (!guidcmp(handler->guid, &efi_guid_loaded_image)) {
efi_print_image_info(
handler->protocol_interface, pc);
}
}
}
}
static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
unsigned long rel_size, void *efi_reloc)
{