Browse Source

[efi] Wrap any images loaded by our wrapped image

Propagate our modified EFI system table to any images loaded by the
image that we wrap, thereby allowing us to observe boot services calls
made by all subsequent EFI images.

Also show details of intercepted ExitBootServices() calls.  When
wrapping is used, exiting boot services will almost certainly fail,
but this at least allows us to see when it happens.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
0cc2f42f46
4 changed files with 70 additions and 24 deletions
  1. 1
    1
      src/image/efi_image.c
  2. 1
    2
      src/include/ipxe/efi/efi_wrap.h
  3. 1
    0
      src/include/ipxe/errfile.h
  4. 67
    21
      src/interface/efi/efi_wrap.c

+ 1
- 1
src/image/efi_image.c View File

@@ -227,7 +227,7 @@ static int efi_image_exec ( struct image *image ) {
227 227
 	efi_snp_release();
228 228
 
229 229
 	/* Wrap calls made by the loaded image (for debugging) */
230
-	efi_wrap ( handle, loaded.image );
230
+	efi_wrap ( handle );
231 231
 
232 232
 	/* Start the image */
233 233
 	if ( ( efirc = bs->StartImage ( handle, NULL, NULL ) ) != 0 ) {

+ 1
- 2
src/include/ipxe/efi/efi_wrap.h View File

@@ -9,8 +9,7 @@
9 9
 FILE_LICENCE ( GPL2_OR_LATER );
10 10
 
11 11
 #include <ipxe/efi/efi.h>
12
-#include <ipxe/efi/Protocol/LoadedImage.h>
13 12
 
14
-extern void efi_wrap ( EFI_HANDLE handle, EFI_LOADED_IMAGE_PROTOCOL *loaded );
13
+extern void efi_wrap ( EFI_HANDLE handle );
15 14
 
16 15
 #endif /* _IPXE_EFI_WRAP_H */

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -306,6 +306,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
306 306
 #define ERRFILE_xenbus		      ( ERRFILE_OTHER | 0x00430000 )
307 307
 #define ERRFILE_xengrant	      ( ERRFILE_OTHER | 0x00440000 )
308 308
 #define ERRFILE_efi_utils	      ( ERRFILE_OTHER | 0x00450000 )
309
+#define ERRFILE_efi_wrap	      ( ERRFILE_OTHER | 0x00460000 )
309 310
 
310 311
 /** @} */
311 312
 

+ 67
- 21
src/interface/efi/efi_wrap.c View File

@@ -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
 }

Loading…
Cancel
Save