|  | @@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 28 | 28 |  
 | 
		
	
		
			
			| 29 | 29 |  #include <string.h>
 | 
		
	
		
			
			| 30 | 30 |  #include <stdio.h>
 | 
		
	
		
			
			|  | 31 | +#include <errno.h>
 | 
		
	
		
			
			| 31 | 32 |  #include <ipxe/efi/efi.h>
 | 
		
	
		
			
			| 32 | 33 |  #include <ipxe/efi/Protocol/LoadedImage.h>
 | 
		
	
		
			
			| 33 | 34 |  #include <ipxe/efi/efi_wrap.h>
 | 
		
	
	
		
			
			|  | @@ -135,6 +136,28 @@ efi_locate_handle_wrapper ( EFI_LOCATE_SEARCH_TYPE search_type,
 | 
		
	
		
			
			| 135 | 136 |  	return efirc;
 | 
		
	
		
			
			| 136 | 137 |  }
 | 
		
	
		
			
			| 137 | 138 |  
 | 
		
	
		
			
			|  | 139 | +/**
 | 
		
	
		
			
			|  | 140 | + * Wrap LocateDevicePath()
 | 
		
	
		
			
			|  | 141 | + *
 | 
		
	
		
			
			|  | 142 | + */
 | 
		
	
		
			
			|  | 143 | +static EFI_STATUS EFIAPI
 | 
		
	
		
			
			|  | 144 | +efi_locate_device_path_wrapper ( EFI_GUID *protocol,
 | 
		
	
		
			
			|  | 145 | +				 EFI_DEVICE_PATH_PROTOCOL **device_path,
 | 
		
	
		
			
			|  | 146 | +				 EFI_HANDLE *device ) {
 | 
		
	
		
			
			|  | 147 | +	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
 | 
		
	
		
			
			|  | 148 | +	void *retaddr = __builtin_return_address ( 0 );
 | 
		
	
		
			
			|  | 149 | +	EFI_STATUS efirc;
 | 
		
	
		
			
			|  | 150 | +
 | 
		
	
		
			
			|  | 151 | +	DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
 | 
		
	
		
			
			|  | 152 | +	       efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
 | 
		
	
		
			
			|  | 153 | +	efirc = bs->LocateDevicePath ( protocol, device_path, device );
 | 
		
	
		
			
			|  | 154 | +	DBGC ( colour, "= %s ( %p, ",
 | 
		
	
		
			
			|  | 155 | +	       efi_status ( efirc ), efi_devpath_text ( *device_path ) );
 | 
		
	
		
			
			|  | 156 | +	DBGC ( colour, "%p %s ) -> %p\n",
 | 
		
	
		
			
			|  | 157 | +	       *device, efi_handle_name ( *device ), retaddr );
 | 
		
	
		
			
			|  | 158 | +	return efirc;
 | 
		
	
		
			
			|  | 159 | +}
 | 
		
	
		
			
			|  | 160 | +
 | 
		
	
		
			
			| 138 | 161 |  /**
 | 
		
	
		
			
			| 139 | 162 |   * Wrap LoadImage()
 | 
		
	
		
			
			| 140 | 163 |   *
 | 
		
	
	
		
			
			|  | @@ -161,28 +184,29 @@ efi_load_image_wrapper ( BOOLEAN boot_policy, EFI_HANDLE parent_image_handle,
 | 
		
	
		
			
			| 161 | 184 |  		       efi_handle_name ( *image_handle ) );
 | 
		
	
		
			
			| 162 | 185 |  	}
 | 
		
	
		
			
			| 163 | 186 |  	DBGC ( colour, ") -> %p\n", retaddr );
 | 
		
	
		
			
			|  | 187 | +
 | 
		
	
		
			
			|  | 188 | +	/* Wrap the new image */
 | 
		
	
		
			
			|  | 189 | +	if ( efirc == 0 )
 | 
		
	
		
			
			|  | 190 | +		efi_wrap ( *image_handle );
 | 
		
	
		
			
			|  | 191 | +
 | 
		
	
		
			
			| 164 | 192 |  	return efirc;
 | 
		
	
		
			
			| 165 | 193 |  }
 | 
		
	
		
			
			| 166 | 194 |  
 | 
		
	
		
			
			| 167 | 195 |  /**
 | 
		
	
		
			
			| 168 |  | - * Wrap LocateDevicePath()
 | 
		
	
		
			
			|  | 196 | + * Wrap ExitBootServices()
 | 
		
	
		
			
			| 169 | 197 |   *
 | 
		
	
		
			
			| 170 | 198 |   */
 | 
		
	
		
			
			| 171 | 199 |  static EFI_STATUS EFIAPI
 | 
		
	
		
			
			| 172 |  | -efi_locate_device_path_wrapper ( EFI_GUID *protocol,
 | 
		
	
		
			
			| 173 |  | -				 EFI_DEVICE_PATH_PROTOCOL **device_path,
 | 
		
	
		
			
			| 174 |  | -				 EFI_HANDLE *device ) {
 | 
		
	
		
			
			|  | 200 | +efi_exit_boot_services_wrapper ( EFI_HANDLE image_handle, UINTN map_key ) {
 | 
		
	
		
			
			| 175 | 201 |  	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
 | 
		
	
		
			
			| 176 | 202 |  	void *retaddr = __builtin_return_address ( 0 );
 | 
		
	
		
			
			| 177 | 203 |  	EFI_STATUS efirc;
 | 
		
	
		
			
			| 178 | 204 |  
 | 
		
	
		
			
			| 179 |  | -	DBGC ( colour, "LocateDevicePath ( %s, %s, ... ) ",
 | 
		
	
		
			
			| 180 |  | -	       efi_guid_ntoa ( protocol ), efi_devpath_text ( *device_path ) );
 | 
		
	
		
			
			| 181 |  | -	efirc = bs->LocateDevicePath ( protocol, device_path, device );
 | 
		
	
		
			
			| 182 |  | -	DBGC ( colour, "= %s ( %p, ",
 | 
		
	
		
			
			| 183 |  | -	       efi_status ( efirc ), efi_devpath_text ( *device_path ) );
 | 
		
	
		
			
			| 184 |  | -	DBGC ( colour, "%p %s ) -> %p\n",
 | 
		
	
		
			
			| 185 |  | -	       *device, efi_handle_name ( *device ), retaddr );
 | 
		
	
		
			
			|  | 205 | +	DBGC ( colour, "ExitBootServices ( %p %s, %#llx ) ",
 | 
		
	
		
			
			|  | 206 | +	       image_handle, efi_handle_name ( image_handle ),
 | 
		
	
		
			
			|  | 207 | +	       ( ( unsigned long long ) map_key ) );
 | 
		
	
		
			
			|  | 208 | +	efirc = bs->ExitBootServices ( image_handle, map_key );
 | 
		
	
		
			
			|  | 209 | +	DBGC ( colour, "= %s -> %p\n", efi_status ( efirc ), retaddr );
 | 
		
	
		
			
			| 186 | 210 |  	return efirc;
 | 
		
	
		
			
			| 187 | 211 |  }
 | 
		
	
		
			
			| 188 | 212 |  
 | 
		
	
	
		
			
			|  | @@ -234,10 +258,15 @@ efi_locate_protocol_wrapper ( EFI_GUID *protocol, VOID *registration,
 | 
		
	
		
			
			| 234 | 258 |   * Wrap the calls made by a loaded image
 | 
		
	
		
			
			| 235 | 259 |   *
 | 
		
	
		
			
			| 236 | 260 |   * @v handle		Image handle
 | 
		
	
		
			
			| 237 |  | - * @v loaded		Loaded image protocol
 | 
		
	
		
			
			| 238 | 261 |   */
 | 
		
	
		
			
			| 239 |  | -void efi_wrap ( EFI_HANDLE handle, EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
 | 
		
	
		
			
			|  | 262 | + void efi_wrap ( EFI_HANDLE handle ) {
 | 
		
	
		
			
			| 240 | 263 |  	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
 | 
		
	
		
			
			|  | 264 | +	union {
 | 
		
	
		
			
			|  | 265 | +		EFI_LOADED_IMAGE_PROTOCOL *image;
 | 
		
	
		
			
			|  | 266 | +		void *intf;
 | 
		
	
		
			
			|  | 267 | +	} loaded;
 | 
		
	
		
			
			|  | 268 | +	EFI_STATUS efirc;
 | 
		
	
		
			
			|  | 269 | +	int rc;
 | 
		
	
		
			
			| 241 | 270 |  
 | 
		
	
		
			
			| 242 | 271 |  	/* Do nothing unless debugging is enabled */
 | 
		
	
		
			
			| 243 | 272 |  	if ( ! DBG_LOG )
 | 
		
	
	
		
			
			|  | @@ -252,18 +281,35 @@ void efi_wrap ( EFI_HANDLE handle, EFI_LOADED_IMAGE_PROTOCOL *loaded ) {
 | 
		
	
		
			
			| 252 | 281 |  	efi_bs_wrapper.LocateHandle	= efi_locate_handle_wrapper;
 | 
		
	
		
			
			| 253 | 282 |  	efi_bs_wrapper.LocateDevicePath	= efi_locate_device_path_wrapper;
 | 
		
	
		
			
			| 254 | 283 |  	efi_bs_wrapper.LoadImage	= efi_load_image_wrapper;
 | 
		
	
		
			
			|  | 284 | +	efi_bs_wrapper.ExitBootServices	= efi_exit_boot_services_wrapper;
 | 
		
	
		
			
			| 255 | 285 |  	efi_bs_wrapper.OpenProtocol	= efi_open_protocol_wrapper;
 | 
		
	
		
			
			| 256 | 286 |  	efi_bs_wrapper.LocateProtocol	= efi_locate_protocol_wrapper;
 | 
		
	
		
			
			| 257 | 287 |  
 | 
		
	
		
			
			|  | 288 | +	/* Open loaded image protocol */
 | 
		
	
		
			
			|  | 289 | +	if ( ( efirc = bs->OpenProtocol ( handle,
 | 
		
	
		
			
			|  | 290 | +					  &efi_loaded_image_protocol_guid,
 | 
		
	
		
			
			|  | 291 | +					  &loaded.intf, efi_image_handle, NULL,
 | 
		
	
		
			
			|  | 292 | +					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
 | 
		
	
		
			
			|  | 293 | +		rc = -EEFI ( efirc );
 | 
		
	
		
			
			|  | 294 | +		DBGC ( colour, "Could not get loaded image protocol for %p %s: "
 | 
		
	
		
			
			|  | 295 | +		       "%s\n", handle, efi_handle_name ( handle ),
 | 
		
	
		
			
			|  | 296 | +		       strerror ( rc ) );
 | 
		
	
		
			
			|  | 297 | +		return;
 | 
		
	
		
			
			|  | 298 | +	}
 | 
		
	
		
			
			|  | 299 | +
 | 
		
	
		
			
			| 258 | 300 |  	/* Provide system table wrapper to image */
 | 
		
	
		
			
			| 259 |  | -	loaded->SystemTable = &efi_systab_wrapper;
 | 
		
	
		
			
			|  | 301 | +	loaded.image->SystemTable = &efi_systab_wrapper;
 | 
		
	
		
			
			| 260 | 302 |  	DBGC ( colour, "Wrapped image %p %s at base %p has protocols:\n",
 | 
		
	
		
			
			| 261 |  | -	       handle, efi_handle_name ( handle ), loaded->ImageBase );
 | 
		
	
		
			
			|  | 303 | +	       handle, efi_handle_name ( handle ), loaded.image->ImageBase );
 | 
		
	
		
			
			| 262 | 304 |  	DBGC_EFI_PROTOCOLS ( colour, handle );
 | 
		
	
		
			
			| 263 |  | -	DBGC ( colour, "Parent image %p %s\n", loaded->ParentHandle,
 | 
		
	
		
			
			| 264 |  | -	       efi_handle_name ( loaded->ParentHandle ) );
 | 
		
	
		
			
			| 265 |  | -	DBGC ( colour, "Device %p %s ", loaded->DeviceHandle,
 | 
		
	
		
			
			| 266 |  | -	       efi_handle_name ( loaded->DeviceHandle ) );
 | 
		
	
		
			
			| 267 |  | -	DBGC ( colour, "file %p %s\n", loaded->FilePath,
 | 
		
	
		
			
			| 268 |  | -	       efi_devpath_text ( loaded->FilePath ) );
 | 
		
	
		
			
			|  | 305 | +	DBGC ( colour, "Parent image %p %s\n", loaded.image->ParentHandle,
 | 
		
	
		
			
			|  | 306 | +	       efi_handle_name ( loaded.image->ParentHandle ) );
 | 
		
	
		
			
			|  | 307 | +	DBGC ( colour, "Device %p %s ", loaded.image->DeviceHandle,
 | 
		
	
		
			
			|  | 308 | +	       efi_handle_name ( loaded.image->DeviceHandle ) );
 | 
		
	
		
			
			|  | 309 | +	DBGC ( colour, "file %p %s\n", loaded.image->FilePath,
 | 
		
	
		
			
			|  | 310 | +	       efi_devpath_text ( loaded.image->FilePath ) );
 | 
		
	
		
			
			|  | 311 | +
 | 
		
	
		
			
			|  | 312 | +	/* Close loaded image protocol */
 | 
		
	
		
			
			|  | 313 | +	bs->CloseProtocol ( handle, &efi_loaded_image_protocol_guid,
 | 
		
	
		
			
			|  | 314 | +			    efi_image_handle, NULL );
 | 
		
	
		
			
			| 269 | 315 |  }
 |