/*
 * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/**
 * @file
 *
 * EFI debugging utilities
 *
 */

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ipxe/uuid.h>
#include <ipxe/base16.h>
#include <ipxe/vsprintf.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/Protocol/ComponentName.h>
#include <ipxe/efi/Protocol/ComponentName2.h>
#include <ipxe/efi/Protocol/DevicePathToText.h>
#include <ipxe/efi/IndustryStandard/PeImage.h>

/** Device path to text protocol */
static EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *efidpt;
EFI_REQUEST_PROTOCOL ( EFI_DEVICE_PATH_TO_TEXT_PROTOCOL, &efidpt );

/** HttpBootDxe module GUID */
static EFI_GUID efi_http_boot_dxe_guid = {
	0xecebcb00, 0xd9c8, 0x11e4,
	{ 0xaf, 0x3d, 0x8c, 0xdc, 0xd4, 0x26, 0xc9, 0x73 }
};

/** IScsiDxe module GUID */
static EFI_GUID efi_iscsi_dxe_guid = {
	0x86cddf93, 0x4872, 0x4597,
	{ 0x8a, 0xf9, 0xa3, 0x5a, 0xe4, 0xd3, 0x72, 0x5f }
};

/** Old IScsi4Dxe module GUID */
static EFI_GUID efi_iscsi4_dxe_guid = {
	0x4579b72d, 0x7ec4, 0x4dd4,
	{ 0x84, 0x86, 0x08, 0x3c, 0x86, 0xb1, 0x82, 0xa7 }
};

/** UefiPxeBcDxe module GUID */
static EFI_GUID efi_uefi_pxe_bc_dxe_guid = {
	0xb95e9fda, 0x26de, 0x48d2,
	{ 0x88, 0x07, 0x1f, 0x91, 0x07, 0xac, 0x5e, 0x3a }
};

/** VlanConfigDxe module GUID */
static EFI_GUID efi_vlan_config_dxe_guid = {
	0xe4f61863, 0xfe2c, 0x4b56,
	{ 0xa8, 0xf4, 0x08, 0x51, 0x9b, 0xc4, 0x39, 0xdf }
};

/** A well-known GUID */
struct efi_well_known_guid {
	/** GUID */
	EFI_GUID *guid;
	/** Name */
	const char *name;
};

/** Well-known GUIDs */
static struct efi_well_known_guid efi_well_known_guids[] = {
	{ &efi_absolute_pointer_protocol_guid,
	  "AbsolutePointer" },
	{ &efi_acpi_table_protocol_guid,
	  "AcpiTable" },
	{ &efi_apple_net_boot_protocol_guid,
	  "AppleNetBoot" },
	{ &efi_arp_protocol_guid,
	  "Arp" },
	{ &efi_arp_service_binding_protocol_guid,
	  "ArpSb" },
	{ &efi_block_io_protocol_guid,
	  "BlockIo" },
	{ &efi_block_io2_protocol_guid,
	  "BlockIo2" },
	{ &efi_bus_specific_driver_override_protocol_guid,
	  "BusSpecificDriverOverride" },
	{ &efi_component_name_protocol_guid,
	  "ComponentName" },
	{ &efi_component_name2_protocol_guid,
	  "ComponentName2" },
	{ &efi_console_control_protocol_guid,
	  "ConsoleControl" },
	{ &efi_device_path_protocol_guid,
	  "DevicePath" },
	{ &efi_driver_binding_protocol_guid,
	  "DriverBinding" },
	{ &efi_dhcp4_protocol_guid,
	  "Dhcp4" },
	{ &efi_dhcp4_service_binding_protocol_guid,
	  "Dhcp4Sb" },
	{ &efi_dhcp6_protocol_guid,
	  "Dhcp6" },
	{ &efi_dhcp6_service_binding_protocol_guid,
	  "Dhcp6Sb" },
	{ &efi_disk_io_protocol_guid,
	  "DiskIo" },
	{ &efi_dns4_protocol_guid,
	  "Dns4" },
	{ &efi_dns4_service_binding_protocol_guid,
	  "Dns4Sb" },
	{ &efi_dns6_protocol_guid,
	  "Dns6" },
	{ &efi_dns6_service_binding_protocol_guid,
	  "Dns6Sb" },
	{ &efi_graphics_output_protocol_guid,
	  "GraphicsOutput" },
	{ &efi_hii_config_access_protocol_guid,
	  "HiiConfigAccess" },
	{ &efi_hii_font_protocol_guid,
	  "HiiFont" },
	{ &efi_http_boot_dxe_guid,
	  "HttpBootDxe" },
	{ &efi_http_protocol_guid,
	  "Http" },
	{ &efi_http_service_binding_protocol_guid,
	  "HttpSb" },
	{ &efi_ip4_protocol_guid,
	  "Ip4" },
	{ &efi_ip4_config_protocol_guid,
	  "Ip4Config" },
	{ &efi_ip4_config2_protocol_guid,
	  "Ip4Config2" },
	{ &efi_ip4_service_binding_protocol_guid,
	  "Ip4Sb" },
	{ &efi_ip6_protocol_guid,
	  "Ip6" },
	{ &efi_ip6_config_protocol_guid,
	  "Ip6Config" },
	{ &efi_ip6_service_binding_protocol_guid,
	  "Ip6Sb" },
	{ &efi_iscsi_dxe_guid,
	  "IScsiDxe" },
	{ &efi_iscsi4_dxe_guid,
	  "IScsi4Dxe" },
	{ &efi_load_file_protocol_guid,
	  "LoadFile" },
	{ &efi_load_file2_protocol_guid,
	  "LoadFile2" },
	{ &efi_loaded_image_protocol_guid,
	  "LoadedImage" },
	{ &efi_loaded_image_device_path_protocol_guid,
	  "LoadedImageDevicePath"},
	{ &efi_managed_network_protocol_guid,
	  "ManagedNetwork" },
	{ &efi_managed_network_service_binding_protocol_guid,
	  "ManagedNetworkSb" },
	{ &efi_mtftp4_protocol_guid,
	  "Mtftp4" },
	{ &efi_mtftp4_service_binding_protocol_guid,
	  "Mtftp4Sb" },
	{ &efi_mtftp6_protocol_guid,
	  "Mtftp6" },
	{ &efi_mtftp6_service_binding_protocol_guid,
	  "Mtftp6Sb" },
	{ &efi_nii_protocol_guid,
	  "Nii" },
	{ &efi_nii31_protocol_guid,
	  "Nii31" },
	{ &efi_pci_io_protocol_guid,
	  "PciIo" },
	{ &efi_pci_root_bridge_io_protocol_guid,
	  "PciRootBridgeIo" },
	{ &efi_pxe_base_code_protocol_guid,
	  "PxeBaseCode" },
	{ &efi_serial_io_protocol_guid,
	  "SerialIo" },
	{ &efi_shim_lock_protocol_guid,
	  "ShimLock" },
	{ &efi_simple_file_system_protocol_guid,
	  "SimpleFileSystem" },
	{ &efi_simple_network_protocol_guid,
	  "SimpleNetwork" },
	{ &efi_simple_pointer_protocol_guid,
	  "SimplePointer" },
	{ &efi_simple_text_input_protocol_guid,
	  "SimpleTextInput" },
	{ &efi_simple_text_input_ex_protocol_guid,
	  "SimpleTextInputEx" },
	{ &efi_simple_text_output_protocol_guid,
	  "SimpleTextOutput" },
	{ &efi_tcg_protocol_guid,
	  "Tcg" },
	{ &efi_tcp4_protocol_guid,
	  "Tcp4" },
	{ &efi_tcp4_service_binding_protocol_guid,
	  "Tcp4Sb" },
	{ &efi_tcp6_protocol_guid,
	  "Tcp6" },
	{ &efi_tcp6_service_binding_protocol_guid,
	  "Tcp6Sb" },
	{ &efi_tree_protocol_guid,
	  "TrEE" },
	{ &efi_udp4_protocol_guid,
	  "Udp4" },
	{ &efi_udp4_service_binding_protocol_guid,
	  "Udp4Sb" },
	{ &efi_udp6_protocol_guid,
	  "Udp6" },
	{ &efi_udp6_service_binding_protocol_guid,
	  "Udp6Sb" },
	{ &efi_uefi_pxe_bc_dxe_guid,
	  "UefiPxeBcDxe" },
	{ &efi_uga_draw_protocol_guid,
	  "UgaDraw" },
	{ &efi_unicode_collation_protocol_guid,
	  "UnicodeCollation" },
	{ &efi_usb_hc_protocol_guid,
	  "UsbHc" },
	{ &efi_usb2_hc_protocol_guid,
	  "Usb2Hc" },
	{ &efi_usb_io_protocol_guid,
	  "UsbIo" },
	{ &efi_vlan_config_protocol_guid,
	  "VlanConfig" },
	{ &efi_vlan_config_dxe_guid,
	  "VlanConfigDxe" },
};

/**
 * Convert GUID to a printable string
 *
 * @v guid		GUID
 * @ret string		Printable string
 */
const __attribute__ (( pure )) char * efi_guid_ntoa ( CONST EFI_GUID *guid ) {
	union {
		union uuid uuid;
		EFI_GUID guid;
	} u;
	unsigned int i;

	/* Sanity check */
	if ( ! guid )
		return NULL;

	/* Check for a match against well-known GUIDs */
	for ( i = 0 ; i < ( sizeof ( efi_well_known_guids ) /
			    sizeof ( efi_well_known_guids[0] ) ) ; i++ ) {
		if ( memcmp ( guid, efi_well_known_guids[i].guid,
			      sizeof ( *guid ) ) == 0 ) {
			return efi_well_known_guids[i].name;
		}
	}

	/* Convert GUID to standard endianness */
	memcpy ( &u.guid, guid, sizeof ( u.guid ) );
	uuid_mangle ( &u.uuid );
	return uuid_ntoa ( &u.uuid );
}

/**
 * Name locate search type
 *
 * @v search_type	Locate search type
 * @ret name		Locate search type name
 */
const __attribute__ (( pure )) char *
efi_locate_search_type_name ( EFI_LOCATE_SEARCH_TYPE search_type ) {
	static char buf[16];

	switch ( search_type ) {
	case AllHandles :	return "AllHandles";
	case ByRegisterNotify:	return "ByRegisterNotify";
	case ByProtocol:	return "ByProtocol";
	default:
		snprintf ( buf, sizeof ( buf ), "UNKNOWN<%d>", search_type );
		return buf;
	}
}

/**
 * Name protocol open attributes
 *
 * @v attributes	Protocol open attributes
 * @ret name		Protocol open attributes name
 *
 * Returns a (static) string with characters for each set bit
 * corresponding to BY_(H)ANDLE_PROTOCOL, (G)ET_PROTOCOL,
 * (T)EST_PROTOCOL, BY_(C)HILD_CONTROLLER, BY_(D)RIVER, and
 * E(X)CLUSIVE.
 */
const __attribute__ (( pure )) char *
efi_open_attributes_name ( unsigned int attributes ) {
	static char attribute_chars[] = "HGTCDX";
	static char name[ sizeof ( attribute_chars ) ];
	char *tmp = name;
	unsigned int i;

	for ( i = 0 ; i < ( sizeof ( attribute_chars ) - 1 ) ; i++ ) {
		if ( attributes & ( 1 << i ) )
			*(tmp++) = attribute_chars[i];
	}
	*tmp = '\0';

	return name;
}

/**
 * Print opened protocol information
 *
 * @v handle		EFI handle
 * @V protocol		Protocol GUID
 * @v opener		Opened protocol information
 */
void dbg_efi_opener ( EFI_HANDLE handle, EFI_GUID *protocol,
		      EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *opener ) {

	printf ( "HANDLE %s %s opened %dx (%s)", efi_handle_name ( handle ),
		 efi_guid_ntoa ( protocol ), opener->OpenCount,
		 efi_open_attributes_name ( opener->Attributes ) );
	printf ( " by %s", efi_handle_name ( opener->AgentHandle ) );
	if ( opener->ControllerHandle == handle ) {
		printf ( "\n" );
	} else {
		printf ( " for %s\n",
			 efi_handle_name ( opener->ControllerHandle ) );
	}
}

/**
 * Print list of openers of a given protocol on a given handle
 *
 * @v handle		EFI handle
 * @v protocol		Protocol GUID
 */
void dbg_efi_openers ( EFI_HANDLE handle, EFI_GUID *protocol ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *openers;
	UINTN count;
	unsigned int i;
	EFI_STATUS efirc;
	int rc;

	/* Sanity check */
	if ( ( ! handle ) || ( ! protocol ) ) {
		printf ( "HANDLE %s could not retrieve openers for %s\n",
			 efi_handle_name ( handle ),
			 efi_guid_ntoa ( protocol ) );
		return;
	}

	/* Retrieve list of openers */
	if ( ( efirc = bs->OpenProtocolInformation ( handle, protocol, &openers,
						     &count ) ) != 0 ) {
		rc = -EEFI ( efirc );
		printf ( "HANDLE %s could not retrieve openers for %s: %s\n",
			 efi_handle_name ( handle ),
			 efi_guid_ntoa ( protocol ), strerror ( rc ) );
		return;
	}

	/* Dump list of openers */
	for ( i = 0 ; i < count ; i++ )
		dbg_efi_opener ( handle, protocol, &openers[i] );

	/* Free list */
	bs->FreePool ( openers );
}

/**
 * Print protocol information on a given handle
 *
 * @v handle		EFI handle
 * @v protocol		Protocol GUID
 */
void dbg_efi_protocol ( EFI_HANDLE handle, EFI_GUID *protocol ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	VOID *interface;
	EFI_STATUS efirc;
	int rc;

	/* Get protocol instance */
	if ( ( efirc = bs->HandleProtocol ( handle, protocol,
					    &interface ) ) != 0 ) {
		rc = -EEFI ( efirc );
		printf ( "HANDLE %s could not identify %s: %s\n",
			 efi_handle_name ( handle ),
			 efi_guid_ntoa ( protocol ), strerror ( rc ) );
		return;
	}
	printf ( "HANDLE %s %s at %p\n", efi_handle_name ( handle ),
		 efi_guid_ntoa ( protocol ), interface );

	/* Dump list of openers */
	dbg_efi_openers ( handle, protocol );
}

/**
 * Print list of protocol handlers attached to a handle
 *
 * @v handle		EFI handle
 */
void dbg_efi_protocols ( EFI_HANDLE handle ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	EFI_GUID **protocols;
	UINTN count;
	unsigned int i;
	EFI_STATUS efirc;
	int rc;

	/* Sanity check */
	if ( ! handle ) {
		printf ( "HANDLE %p could not retrieve protocols\n", handle );
		return;
	}

	/* Retrieve list of protocols */
	if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
						&count ) ) != 0 ) {
		rc = -EEFI ( efirc );
		printf ( "HANDLE %s could not retrieve protocols: %s\n",
			 efi_handle_name ( handle ), strerror ( rc ) );
		return;
	}

	/* Dump list of protocols */
	for ( i = 0 ; i < count ; i++ ) {
		dbg_efi_protocol ( handle, protocols[i] );
	}

	/* Free list */
	bs->FreePool ( protocols );
}

/**
 * Get textual representation of device path
 *
 * @v path		Device path
 * @ret text		Textual representation of device path, or NULL
 */
const __attribute__ (( pure )) char *
efi_devpath_text ( EFI_DEVICE_PATH_PROTOCOL *path ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	static char text[512];
	size_t len;
	CHAR16 *wtext;

	/* Sanity checks */
	if ( ! path ) {
		DBG ( "[NULL DevicePath]" );
		return NULL;
	}

	/* If we have no DevicePathToText protocol then use a raw hex string */
	if ( ! efidpt ) {
		DBG ( "[No DevicePathToText]" );
		len = efi_path_len ( path );
		base16_encode ( path, len, text, sizeof ( text ) );
		return text;
	}

	/* Convert path to a textual representation */
	wtext = efidpt->ConvertDevicePathToText ( path, TRUE, FALSE );
	if ( ! wtext )
		return NULL;

	/* Store path in buffer */
	snprintf ( text, sizeof ( text ), "%ls", wtext );

	/* Free path */
	bs->FreePool ( wtext );

	return text;
}

/**
 * Get driver name
 *
 * @v wtf		Component name protocol
 * @ret name		Driver name, or NULL
 */
static const char * efi_driver_name ( EFI_COMPONENT_NAME_PROTOCOL *wtf ) {
	static char name[64];
	CHAR16 *driver_name;
	EFI_STATUS efirc;

	/* Sanity check */
	if ( ! wtf ) {
		DBG ( "[NULL ComponentName]" );
		return NULL;
	}

	/* Try "eng" first; if that fails then try the first language */
	if ( ( ( efirc = wtf->GetDriverName ( wtf, "eng",
					      &driver_name ) ) != 0 ) &&
	     ( ( efirc = wtf->GetDriverName ( wtf, wtf->SupportedLanguages,
					      &driver_name ) ) != 0 ) ) {
		return NULL;
	}

	/* Convert name from CHAR16 to char */
	snprintf ( name, sizeof ( name ), "%ls", driver_name );
	return name;
}

/**
 * Get driver name
 *
 * @v wtf		Component name protocol
 * @ret name		Driver name, or NULL
 */
static const char * efi_driver_name2 ( EFI_COMPONENT_NAME2_PROTOCOL *wtf ) {
	static char name[64];
	CHAR16 *driver_name;
	EFI_STATUS efirc;

	/* Sanity check */
	if ( ! wtf ) {
		DBG ( "[NULL ComponentName2]" );
		return NULL;
	}

	/* Try "en" first; if that fails then try the first language */
	if ( ( ( efirc = wtf->GetDriverName ( wtf, "en",
					      &driver_name ) ) != 0 ) &&
	     ( ( efirc = wtf->GetDriverName ( wtf, wtf->SupportedLanguages,
					      &driver_name ) ) != 0 ) ) {
		return NULL;
	}

	/* Convert name from CHAR16 to char */
	snprintf ( name, sizeof ( name ), "%ls", driver_name );
	return name;
}

/**
 * Get PE/COFF debug filename
 *
 * @v loaded		Loaded image
 * @ret name		PE/COFF debug filename, or NULL
 */
static const char *
efi_pecoff_debug_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
	static char buf[32];
	EFI_IMAGE_DOS_HEADER *dos;
	EFI_IMAGE_OPTIONAL_HEADER_UNION *pe;
	EFI_IMAGE_OPTIONAL_HEADER32 *opt32;
	EFI_IMAGE_OPTIONAL_HEADER64 *opt64;
	EFI_IMAGE_DATA_DIRECTORY *datadir;
	EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *debug;
	EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *codeview_nb10;
	EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY *codeview_rsds;
	EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY *codeview_mtoc;
	uint16_t dos_magic;
	uint32_t pe_magic;
	uint16_t opt_magic;
	uint32_t codeview_magic;
	size_t max_len;
	char *name;
	char *tmp;

	/* Sanity check */
	if ( ! loaded ) {
		DBG ( "[NULL LoadedImage]" );
		return NULL;
	}

	/* Parse DOS header */
	dos = loaded->ImageBase;
	if ( ! dos ) {
		DBG ( "[Missing DOS header]" );
		return NULL;
	}
	dos_magic = dos->e_magic;
	if ( dos_magic != EFI_IMAGE_DOS_SIGNATURE ) {
		DBG ( "[Bad DOS signature %#04x]", dos_magic );
		return NULL;
	}
	pe = ( loaded->ImageBase + dos->e_lfanew );

	/* Parse PE header */
	pe_magic = pe->Pe32.Signature;
	if ( pe_magic != EFI_IMAGE_NT_SIGNATURE ) {
		DBG ( "[Bad PE signature %#08x]", pe_magic );
		return NULL;
	}
	opt32 = &pe->Pe32.OptionalHeader;
	opt64 = &pe->Pe32Plus.OptionalHeader;
	opt_magic = opt32->Magic;
	if ( opt_magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC ) {
		datadir = opt32->DataDirectory;
	} else if ( opt_magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC ) {
		datadir = opt64->DataDirectory;
	} else {
		DBG ( "[Bad optional header signature %#04x]", opt_magic );
		return NULL;
	}

	/* Parse data directory entry */
	if ( ! datadir[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress ) {
		DBG ( "[Empty debug directory entry]" );
		return NULL;
	}
	debug = ( loaded->ImageBase +
		  datadir[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress );

	/* Parse debug directory entry */
	if ( debug->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW ) {
		DBG ( "[Not a CodeView debug directory entry (type %d)]",
		      debug->Type );
		return NULL;
	}
	codeview_nb10 = ( loaded->ImageBase + debug->RVA );
	codeview_rsds = ( loaded->ImageBase + debug->RVA );
	codeview_mtoc = ( loaded->ImageBase + debug->RVA );
	codeview_magic = codeview_nb10->Signature;

	/* Parse CodeView entry */
	if ( codeview_magic == CODEVIEW_SIGNATURE_NB10 ) {
		name = ( ( void * ) ( codeview_nb10 + 1 ) );
	} else if ( codeview_magic == CODEVIEW_SIGNATURE_RSDS ) {
		name = ( ( void * ) ( codeview_rsds + 1 ) );
	} else if ( codeview_magic == CODEVIEW_SIGNATURE_MTOC ) {
		name = ( ( void * ) ( codeview_mtoc + 1 ) );
	} else {
		DBG ( "[Bad CodeView signature %#08x]", codeview_magic );
		return NULL;
	}

	/* Sanity check - avoid scanning endlessly through memory */
	max_len = EFI_PAGE_SIZE; /* Reasonably sane */
	if ( strnlen ( name, max_len ) == max_len ) {
		DBG ( "[Excessively long or invalid CodeView name]" );
		return NULL;
	}

	/* Skip any directory components.  We cannot modify this data
	 * or create a temporary buffer, so do not use basename().
	 */
	while ( ( ( tmp = strchr ( name, '/' ) ) != NULL ) ||
		( ( tmp = strchr ( name, '\\' ) ) != NULL ) ) {
		name = ( tmp + 1 );
	}

	/* Copy base name to buffer */
	snprintf ( buf, sizeof ( buf ), "%s", name );

	/* Strip file suffix, if present */
	if ( ( tmp = strrchr ( name, '.' ) ) != NULL )
		*tmp = '\0';

	return name;
}

/**
 * Get initial loaded image name
 *
 * @v loaded		Loaded image
 * @ret name		Initial loaded image name, or NULL
 */
static const char *
efi_first_loaded_image_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {

	/* Sanity check */
	if ( ! loaded ) {
		DBG ( "[NULL LoadedImage]" );
		return NULL;
	}

	return ( ( loaded->ParentHandle == NULL ) ? "DxeCore(?)" : NULL );
}

/**
 * Get loaded image name from file path
 *
 * @v loaded		Loaded image
 * @ret name		Loaded image name, or NULL
 */
static const char *
efi_loaded_image_filepath_name ( EFI_LOADED_IMAGE_PROTOCOL *loaded ) {

	/* Sanity check */
	if ( ! loaded ) {
		DBG ( "[NULL LoadedImage]" );
		return NULL;
	}

	return efi_devpath_text ( loaded->FilePath );
}

/**
 * Get console input handle name
 *
 * @v input		Simple text input protocol
 * @ret name		Console input handle name, or NULL
 */
static const char *
efi_conin_name ( EFI_SIMPLE_TEXT_INPUT_PROTOCOL *input ) {

	/* Check for match against ConIn */
	if ( input == efi_systab->ConIn )
		return "ConIn";

	return NULL;
}

/**
 * Get console output handle name
 *
 * @v output		Simple text output protocol
 * @ret name		Console output handle name, or NULL
 */
static const char *
efi_conout_name ( EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *output ) {

	/* Check for match against ConOut */
	if ( output == efi_systab->ConOut )
		return "ConOut";

	/* Check for match against StdErr (if different from ConOut) */
	if ( output == efi_systab->StdErr )
		return "StdErr";

	return NULL;
}

/** An EFI handle name type */
struct efi_handle_name_type {
	/** Protocol */
	EFI_GUID *protocol;
	/**
	 * Get name
	 *
	 * @v interface		Protocol interface
	 * @ret name		Name of handle, or NULL on failure
	 */
	const char * ( * name ) ( void *interface );
};

/**
 * Define an EFI handle name type
 *
 * @v protocol		Protocol interface
 * @v name		Method to get name
 * @ret type		EFI handle name type
 */
#define EFI_HANDLE_NAME_TYPE( protocol, name ) {	\
	(protocol),					\
	( const char * ( * ) ( void * ) ) (name),	\
	}

/** EFI handle name types */
static struct efi_handle_name_type efi_handle_name_types[] = {
	/* Device path */
	EFI_HANDLE_NAME_TYPE ( &efi_device_path_protocol_guid,
			       efi_devpath_text ),
	/* Driver name (for driver image handles) */
	EFI_HANDLE_NAME_TYPE ( &efi_component_name2_protocol_guid,
			       efi_driver_name2 ),
	/* Driver name (via obsolete original ComponentName protocol) */
	EFI_HANDLE_NAME_TYPE ( &efi_component_name_protocol_guid,
			       efi_driver_name ),
	/* PE/COFF debug filename (for image handles) */
	EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
			       efi_pecoff_debug_name ),
	/* Loaded image device path (for image handles) */
	EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_device_path_protocol_guid,
			       efi_devpath_text ),
	/* First loaded image name (for the DxeCore image) */
	EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
			       efi_first_loaded_image_name ),
	/* Handle's loaded image file path (for image handles) */
	EFI_HANDLE_NAME_TYPE ( &efi_loaded_image_protocol_guid,
			       efi_loaded_image_filepath_name ),
	/* Our standard input file handle */
	EFI_HANDLE_NAME_TYPE ( &efi_simple_text_input_protocol_guid,
			       efi_conin_name ),
	/* Our standard output and standard error file handles */
	EFI_HANDLE_NAME_TYPE ( &efi_simple_text_output_protocol_guid,
			       efi_conout_name ),
};

/**
 * Get name of an EFI handle
 *
 * @v handle		EFI handle
 * @ret text		Name of handle, or NULL
 */
const __attribute__ (( pure )) char * efi_handle_name ( EFI_HANDLE handle ) {
	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
	struct efi_handle_name_type *type;
	static char buf[256];
	size_t used = 0;
	EFI_GUID **protocols;
	UINTN count;
	unsigned int i;
	void *interface;
	const char *name;
	EFI_STATUS efirc;

	/* Fail immediately for NULL handles */
	if ( ! handle )
		return NULL;

	/* Try each name type in turn */
	for ( i = 0 ; i < ( sizeof ( efi_handle_name_types ) /
			    sizeof ( efi_handle_name_types[0] ) ) ; i++ ) {
		type = &efi_handle_name_types[i];
		DBG2 ( "<%d", i );

		/* Try to open the applicable protocol */
		efirc = bs->OpenProtocol ( handle, type->protocol, &interface,
					   efi_image_handle, handle,
					   EFI_OPEN_PROTOCOL_GET_PROTOCOL );
		if ( efirc != 0 ) {
			DBG2 ( ">" );
			continue;
		}

		/* Try to get name from this protocol */
		DBG2 ( "-" );
		name = type->name ( interface );
		DBG2 ( "%c", ( name ? ( name[0] ? 'Y' : 'E' ) : 'N' ) );

		/* Close protocol */
		bs->CloseProtocol ( handle, type->protocol,
				    efi_image_handle, handle );
		DBG2 ( ">" );

		/* Use this name, if possible */
		if ( name && name[0] )
			return name;
	}

	/* If no name is found, then use the raw handle value and a
	 * list of installed protocols.
	 */
	used = ssnprintf ( buf, sizeof ( buf ), "UNKNOWN<%p", handle );
	if ( ( efirc = bs->ProtocolsPerHandle ( handle, &protocols,
						&count ) ) == 0 ) {
		for ( i = 0 ; i < count ; i++ ) {
			used += ssnprintf ( ( buf + used ),
					    ( sizeof ( buf ) - used ), ",%s",
					    efi_guid_ntoa ( protocols[i] ) );
		}
		bs->FreePool ( protocols );
	}
	used += ssnprintf ( ( buf + used ), ( sizeof ( buf ) - used ), ">" );
	return buf;
}
