[U-Boot] [PATCH v2 2/4] efi_loader: set entry point in efi_load_pe()

Heinrich Schuchardt xypron.glpk at gmx.de
Fri Feb 8 18:46:48 UTC 2019


Up to now efi_load_pe() returns the entry point or NULL in case of an
error. This does not allow to return correct error codes from LoadImage().

Let efi_load_pe() return a status code and fill in the entry point in the
corresponding field of the image object.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
v2
	correct a comment
---
 cmd/bootefi.c                     | 13 ++++-------
 include/efi_loader.h              |  4 ++--
 lib/efi_loader/efi_boottime.c     |  6 ++---
 lib/efi_loader/efi_image_loader.c | 37 ++++++++++++++++++-------------
 4 files changed, 29 insertions(+), 31 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index ee685d8644..7f9913c0ee 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -266,9 +266,6 @@ static efi_status_t do_bootefi_exec(void *efi,
 	struct efi_loaded_image_obj *image_obj = NULL;
 	struct efi_loaded_image *loaded_image_info = NULL;
 
-	EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
-				     struct efi_system_table *st);
-
 	/*
 	 * Special case for efi payload not loaded from disk, such as
 	 * 'bootefi hello' or for example payload loaded directly into
@@ -300,11 +297,9 @@ static efi_status_t do_bootefi_exec(void *efi,
 		goto err_prepare;
 
 	/* Load the EFI payload */
-	entry = efi_load_pe(image_obj, efi, loaded_image_info);
-	if (!entry) {
-		ret = EFI_LOAD_ERROR;
+	ret = efi_load_pe(image_obj, efi, loaded_image_info);
+	if (ret != EFI_SUCCESS)
 		goto err_prepare;
-	}
 
 	if (memdp) {
 		struct efi_device_path_memory *mdp = (void *)memdp;
@@ -319,14 +314,14 @@ static efi_status_t do_bootefi_exec(void *efi,
 		"{ro,boot}(blob)0000000000000000");
 
 	/* Call our payload! */
-	debug("%s: Jumping to 0x%p\n", __func__, entry);
+	debug("%s: Jumping to 0x%p\n", __func__, image_obj->entry);
 
 	if (setjmp(&image_obj->exit_jmp)) {
 		ret = image_obj->exit_status;
 		goto err_prepare;
 	}
 
-	ret = efi_do_enter(&image_obj->header, &systab, entry);
+	ret = efi_do_enter(&image_obj->header, &systab, image_obj->entry);
 
 err_prepare:
 	/* image has returned, loaded-image obj goes *poof*: */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 6a98981ebb..3ce43f7a6f 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -301,8 +301,8 @@ efi_status_t efi_set_watchdog(unsigned long timeout);
 /* Called from places to check whether a timer expired */
 void efi_timer_check(void);
 /* PE loader implementation */
-void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
-		  struct efi_loaded_image *loaded_image_info);
+efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
+			 struct efi_loaded_image *loaded_image_info);
 /* Called once to store the pristine gd pointer */
 void efi_save_gd(void);
 /* Special case handler for error/abort that just tries to dtrt to get
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 7abdcf6da6..7a61a905f4 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1736,11 +1736,9 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
 	ret = efi_setup_loaded_image(dp, fp, image_obj, &info);
 	if (ret != EFI_SUCCESS)
 		goto error_invalid_image;
-	(*image_obj)->entry = efi_load_pe(*image_obj, source_buffer, info);
-	if (!(*image_obj)->entry) {
-		ret = EFI_UNSUPPORTED;
+	ret = efi_load_pe(*image_obj, source_buffer, info);
+	if (ret != EFI_SUCCESS)
 		goto error_invalid_image;
-	}
 	/* Update the type of the allocated memory */
 	efi_add_memory_map((uintptr_t)source_buffer,
 			   efi_size_in_pages(source_size),
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index a18ce0a570..b55c2840e8 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -193,13 +193,19 @@ static void efi_set_code_and_data_type(
 	}
 }
 
-/*
+/**
+ * efi_load_pe() - relocate EFI binary
+ *
  * This function loads all sections from a PE binary into a newly reserved
- * piece of memory. On successful load it then returns the entry point for
- * the binary. Otherwise NULL.
+ * piece of memory. On success the entry point is returned as handle->entry.
+ *
+ * @handle:		loaded image handle
+ * @efi:		pointer to the EFI binary
+ * @loaded_image_info:	loaded image protocol
+ * Return:		status code
  */
-void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
-		  struct efi_loaded_image *loaded_image_info)
+efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
+			 struct efi_loaded_image *loaded_image_info)
 {
 	IMAGE_NT_HEADERS32 *nt;
 	IMAGE_DOS_HEADER *dos;
@@ -210,7 +216,6 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 	const IMAGE_BASE_RELOCATION *rel;
 	unsigned long rel_size;
 	int rel_idx = IMAGE_DIRECTORY_ENTRY_BASERELOC;
-	void *entry;
 	uint64_t image_base;
 	uint64_t image_size;
 	unsigned long virt_size = 0;
@@ -219,13 +224,13 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 	dos = efi;
 	if (dos->e_magic != IMAGE_DOS_SIGNATURE) {
 		printf("%s: Invalid DOS Signature\n", __func__);
-		return NULL;
+		return EFI_LOAD_ERROR;
 	}
 
 	nt = (void *) ((char *)efi + dos->e_lfanew);
 	if (nt->Signature != IMAGE_NT_SIGNATURE) {
 		printf("%s: Invalid NT Signature\n", __func__);
-		return NULL;
+		return EFI_LOAD_ERROR;
 	}
 
 	for (i = 0; machines[i]; i++)
@@ -237,7 +242,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 	if (!supported) {
 		printf("%s: Machine type 0x%04x is not supported\n",
 		       __func__, nt->FileHeader.Machine);
-		return NULL;
+		return EFI_LOAD_ERROR;
 	}
 
 	/* Calculate upper virtual address boundary */
@@ -263,9 +268,9 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 		if (!efi_reloc) {
 			printf("%s: Could not allocate %lu bytes\n",
 			       __func__, virt_size);
-			return NULL;
+			return EFI_OUT_OF_RESOURCES;
 		}
-		entry = efi_reloc + opt->AddressOfEntryPoint;
+		handle->entry = efi_reloc + opt->AddressOfEntryPoint;
 		rel_size = opt->DataDirectory[rel_idx].Size;
 		rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
 		virt_size = ALIGN(virt_size, opt->SectionAlignment);
@@ -279,16 +284,16 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 		if (!efi_reloc) {
 			printf("%s: Could not allocate %lu bytes\n",
 			       __func__, virt_size);
-			return NULL;
+			return EFI_OUT_OF_RESOURCES;
 		}
-		entry = efi_reloc + opt->AddressOfEntryPoint;
+		handle->entry = efi_reloc + opt->AddressOfEntryPoint;
 		rel_size = opt->DataDirectory[rel_idx].Size;
 		rel = efi_reloc + opt->DataDirectory[rel_idx].VirtualAddress;
 		virt_size = ALIGN(virt_size, opt->SectionAlignment);
 	} else {
 		printf("%s: Invalid optional header magic %x\n", __func__,
 		       nt->OptionalHeader.Magic);
-		return NULL;
+		return EFI_LOAD_ERROR;
 	}
 
 	/* Load sections into RAM */
@@ -306,7 +311,7 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 				(unsigned long)image_base) != EFI_SUCCESS) {
 		efi_free_pages((uintptr_t) efi_reloc,
 			       (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
-		return NULL;
+		return EFI_LOAD_ERROR;
 	}
 
 	/* Flush cache */
@@ -320,5 +325,5 @@ void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
 	handle->reloc_base = efi_reloc;
 	handle->reloc_size = virt_size;
 
-	return entry;
+	return EFI_SUCCESS;
 }
-- 
2.20.1



More information about the U-Boot mailing list