aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorHeinrich Schuchardt2018-09-23 10:21:51 -0500
committerAlexander Graf2018-09-23 14:55:31 -0500
commitc982874e930d5d673501cd94df07bcbd215d5883 (patch)
tree83538d2ee2c50b61a6dca207d3c5f5c60fd2ebeb /lib
parenta47c1b5b87fcbd2bdb2e297d3c41d41c0c663967 (diff)
downloadu-boot-c982874e930d5d673501cd94df07bcbd215d5883.tar.gz
u-boot-c982874e930d5d673501cd94df07bcbd215d5883.tar.xz
u-boot-c982874e930d5d673501cd94df07bcbd215d5883.zip
efi_loader: refactor efi_setup_loaded_image()
Create the handle of loaded images and the EFI_LOADED_IMAGE_PROTOCOL inside efi_setup_loaded_image(). Do not use local variables. Currently we expect the loaded image handle to point to the loaded image protocol. Additionally we have appended private fields to the protocol. With the patch the handle points to a loaded image object and the private fields are added here. This matches how we handle the net and the gop object. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_boottime.c92
-rw-r--r--lib/efi_loader/efi_image_loader.c23
2 files changed, 57 insertions, 58 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 8e0e2f7f87..97eb19cd14 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1470,17 +1470,31 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid,
1470 * 1470 *
1471 * Return: status code 1471 * Return: status code
1472 */ 1472 */
1473efi_status_t efi_setup_loaded_image( 1473efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
1474 struct efi_loaded_image *info, struct efi_object *obj, 1474 struct efi_device_path *file_path,
1475 struct efi_device_path *device_path, 1475 struct efi_loaded_image_obj **handle_ptr,
1476 struct efi_device_path *file_path) 1476 struct efi_loaded_image **info_ptr)
1477{ 1477{
1478 efi_status_t ret; 1478 efi_status_t ret;
1479 struct efi_loaded_image *info;
1480 struct efi_loaded_image_obj *obj;
1481
1482 info = calloc(1, sizeof(*info));
1483 if (!info)
1484 return EFI_OUT_OF_RESOURCES;
1485 obj = calloc(1, sizeof(*obj));
1486 if (!obj) {
1487 free(info);
1488 return EFI_OUT_OF_RESOURCES;
1489 }
1479 1490
1480 /* Add internal object to object list */ 1491 /* Add internal object to object list */
1481 efi_add_handle(obj); 1492 efi_add_handle(&obj->parent);
1482 /* efi_exit() assumes that the handle points to the info */ 1493
1483 obj->handle = info; 1494 if (info_ptr)
1495 *info_ptr = info;
1496 if (handle_ptr)
1497 *handle_ptr = obj;
1484 1498
1485 info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION; 1499 info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
1486 info->file_path = file_path; 1500 info->file_path = file_path;
@@ -1492,8 +1506,8 @@ efi_status_t efi_setup_loaded_image(
1492 * When asking for the device path interface, return 1506 * When asking for the device path interface, return
1493 * bootefi_device_path 1507 * bootefi_device_path
1494 */ 1508 */
1495 ret = efi_add_protocol(obj->handle, &efi_guid_device_path, 1509 ret = efi_add_protocol(obj->parent.handle,
1496 device_path); 1510 &efi_guid_device_path, device_path);
1497 if (ret != EFI_SUCCESS) 1511 if (ret != EFI_SUCCESS)
1498 goto failure; 1512 goto failure;
1499 } 1513 }
@@ -1502,7 +1516,8 @@ efi_status_t efi_setup_loaded_image(
1502 * When asking for the loaded_image interface, just 1516 * When asking for the loaded_image interface, just
1503 * return handle which points to loaded_image_info 1517 * return handle which points to loaded_image_info
1504 */ 1518 */
1505 ret = efi_add_protocol(obj->handle, &efi_guid_loaded_image, info); 1519 ret = efi_add_protocol(obj->parent.handle,
1520 &efi_guid_loaded_image, info);
1506 if (ret != EFI_SUCCESS) 1521 if (ret != EFI_SUCCESS)
1507 goto failure; 1522 goto failure;
1508 1523
@@ -1585,7 +1600,8 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
1585 efi_handle_t *image_handle) 1600 efi_handle_t *image_handle)
1586{ 1601{
1587 struct efi_loaded_image *info; 1602 struct efi_loaded_image *info;
1588 struct efi_object *obj; 1603 struct efi_loaded_image_obj **image_obj =
1604 (struct efi_loaded_image_obj **)image_handle;
1589 efi_status_t ret; 1605 efi_status_t ret;
1590 1606
1591 EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image, 1607 EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image,
@@ -1601,18 +1617,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
1601 goto error; 1617 goto error;
1602 } 1618 }
1603 1619
1604 info = calloc(1, sizeof(*info));
1605 if (!info) {
1606 ret = EFI_OUT_OF_RESOURCES;
1607 goto error;
1608 }
1609 obj = calloc(1, sizeof(*obj));
1610 if (!obj) {
1611 free(info);
1612 ret = EFI_OUT_OF_RESOURCES;
1613 goto error;
1614 }
1615
1616 if (!source_buffer) { 1620 if (!source_buffer) {
1617 struct efi_device_path *dp, *fp; 1621 struct efi_device_path *dp, *fp;
1618 1622
@@ -1624,29 +1628,29 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
1624 * file parts: 1628 * file parts:
1625 */ 1629 */
1626 efi_dp_split_file_path(file_path, &dp, &fp); 1630 efi_dp_split_file_path(file_path, &dp, &fp);
1627 ret = efi_setup_loaded_image(info, obj, dp, fp); 1631 ret = efi_setup_loaded_image(dp, fp, image_obj, &info);
1628 if (ret != EFI_SUCCESS) 1632 if (ret != EFI_SUCCESS)
1629 goto failure; 1633 goto failure;
1630 } else { 1634 } else {
1631 /* In this case, file_path is the "device" path, i.e. 1635 /* In this case, file_path is the "device" path, i.e.
1632 * something like a HARDWARE_DEVICE:MEMORY_MAPPED 1636 * something like a HARDWARE_DEVICE:MEMORY_MAPPED
1633 */ 1637 */
1634 ret = efi_setup_loaded_image(info, obj, file_path, NULL); 1638 ret = efi_setup_loaded_image(file_path, NULL, image_obj, &info);
1635 if (ret != EFI_SUCCESS) 1639 if (ret != EFI_SUCCESS)
1636 goto failure; 1640 goto error;
1637 } 1641 }
1638 info->reserved = efi_load_pe(source_buffer, info); 1642 (*image_obj)->entry = efi_load_pe(*image_obj, source_buffer, info);
1639 if (!info->reserved) { 1643 if (!(*image_obj)->entry) {
1640 ret = EFI_UNSUPPORTED; 1644 ret = EFI_UNSUPPORTED;
1641 goto failure; 1645 goto failure;
1642 } 1646 }
1643 info->system_table = &systab; 1647 info->system_table = &systab;
1644 info->parent_handle = parent_image; 1648 info->parent_handle = parent_image;
1645 *image_handle = obj->handle;
1646 return EFI_EXIT(EFI_SUCCESS); 1649 return EFI_EXIT(EFI_SUCCESS);
1647failure: 1650failure:
1651 efi_delete_handle(*image_handle);
1652 *image_handle = NULL;
1648 free(info); 1653 free(info);
1649 efi_delete_handle(obj);
1650error: 1654error:
1651 return EFI_EXIT(ret); 1655 return EFI_EXIT(ret);
1652} 1656}
@@ -1668,16 +1672,14 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
1668 unsigned long *exit_data_size, 1672 unsigned long *exit_data_size,
1669 s16 **exit_data) 1673 s16 **exit_data)
1670{ 1674{
1671 EFIAPI efi_status_t (*entry)(efi_handle_t image_handle, 1675 struct efi_loaded_image_obj *image_obj =
1672 struct efi_system_table *st); 1676 (struct efi_loaded_image_obj *)image_handle;
1673 struct efi_loaded_image *info = image_handle;
1674 efi_status_t ret; 1677 efi_status_t ret;
1675 1678
1676 EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data); 1679 EFI_ENTRY("%p, %p, %p", image_handle, exit_data_size, exit_data);
1677 entry = info->reserved;
1678 1680
1679 /* call the image! */ 1681 /* call the image! */
1680 if (setjmp(&info->exit_jmp)) { 1682 if (setjmp(&image_obj->exit_jmp)) {
1681 /* 1683 /*
1682 * We called the entry point of the child image with EFI_CALL 1684 * We called the entry point of the child image with EFI_CALL
1683 * in the lines below. The child image called the Exit() boot 1685 * in the lines below. The child image called the Exit() boot
@@ -1700,12 +1702,12 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
1700 assert(__efi_entry_check()); 1702 assert(__efi_entry_check());
1701 debug("%sEFI: %lu returned by started image\n", 1703 debug("%sEFI: %lu returned by started image\n",
1702 __efi_nesting_dec(), 1704 __efi_nesting_dec(),
1703 (unsigned long)((uintptr_t)info->exit_status & 1705 (unsigned long)((uintptr_t)image_obj->exit_status &
1704 ~EFI_ERROR_MASK)); 1706 ~EFI_ERROR_MASK));
1705 return EFI_EXIT(info->exit_status); 1707 return EFI_EXIT(image_obj->exit_status);
1706 } 1708 }
1707 1709
1708 ret = EFI_CALL(entry(image_handle, &systab)); 1710 ret = EFI_CALL(image_obj->entry(image_handle, &systab));
1709 1711
1710 /* 1712 /*
1711 * Usually UEFI applications call Exit() instead of returning. 1713 * Usually UEFI applications call Exit() instead of returning.
@@ -1736,17 +1738,11 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
1736 int16_t *exit_data) 1738 int16_t *exit_data)
1737{ 1739{
1738 /* 1740 /*
1739 * We require that the handle points to the original loaded
1740 * image protocol interface.
1741 *
1742 * For getting the longjmp address this is safer than locating
1743 * the protocol because the protocol may have been reinstalled
1744 * pointing to another memory location.
1745 *
1746 * TODO: We should call the unload procedure of the loaded 1741 * TODO: We should call the unload procedure of the loaded
1747 * image protocol. 1742 * image protocol.
1748 */ 1743 */
1749 struct efi_loaded_image *loaded_image_info = (void *)image_handle; 1744 struct efi_loaded_image_obj *image_obj =
1745 (struct efi_loaded_image_obj *)image_handle;
1750 1746
1751 EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status, 1747 EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status,
1752 exit_data_size, exit_data); 1748 exit_data_size, exit_data);
@@ -1760,8 +1756,8 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
1760 */ 1756 */
1761 efi_restore_gd(); 1757 efi_restore_gd();
1762 1758
1763 loaded_image_info->exit_status = exit_status; 1759 image_obj->exit_status = exit_status;
1764 longjmp(&loaded_image_info->exit_jmp, 1); 1760 longjmp(&image_obj->exit_jmp, 1);
1765 1761
1766 panic("EFI application exited"); 1762 panic("EFI application exited");
1767} 1763}
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index fdf40a62c8..a18ce0a570 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -48,20 +48,21 @@ static int machines[] = {
48 * If the program counter is located within the image the offset to the base 48 * If the program counter is located within the image the offset to the base
49 * address is shown. 49 * address is shown.
50 * 50 *
51 * @obj: EFI object
51 * @image: loaded image 52 * @image: loaded image
52 * @pc: program counter (use NULL to suppress offset output) 53 * @pc: program counter (use NULL to suppress offset output)
53 * @return: status code 54 * @return: status code
54 */ 55 */
55efi_status_t efi_print_image_info(struct efi_loaded_image *image, void *pc) 56static efi_status_t efi_print_image_info(struct efi_loaded_image_obj *obj,
57 struct efi_loaded_image *image,
58 void *pc)
56{ 59{
57 if (!image)
58 return EFI_INVALID_PARAMETER;
59 printf("UEFI image"); 60 printf("UEFI image");
60 printf(" [0x%p:0x%p]", 61 printf(" [0x%p:0x%p]",
61 image->reloc_base, image->reloc_base + image->reloc_size - 1); 62 obj->reloc_base, obj->reloc_base + obj->reloc_size - 1);
62 if (pc && pc >= image->reloc_base && 63 if (pc && pc >= obj->reloc_base &&
63 pc < image->reloc_base + image->reloc_size) 64 pc < obj->reloc_base + obj->reloc_size)
64 printf(" pc=0x%zx", pc - image->reloc_base); 65 printf(" pc=0x%zx", pc - obj->reloc_base);
65 if (image->file_path) 66 if (image->file_path)
66 printf(" '%pD'", image->file_path); 67 printf(" '%pD'", image->file_path);
67 printf("\n"); 68 printf("\n");
@@ -82,6 +83,7 @@ void efi_print_image_infos(void *pc)
82 list_for_each_entry(handler, &efiobj->protocols, link) { 83 list_for_each_entry(handler, &efiobj->protocols, link) {
83 if (!guidcmp(handler->guid, &efi_guid_loaded_image)) { 84 if (!guidcmp(handler->guid, &efi_guid_loaded_image)) {
84 efi_print_image_info( 85 efi_print_image_info(
86 (struct efi_loaded_image_obj *)efiobj,
85 handler->protocol_interface, pc); 87 handler->protocol_interface, pc);
86 } 88 }
87 } 89 }
@@ -196,7 +198,8 @@ static void efi_set_code_and_data_type(
196 * piece of memory. On successful load it then returns the entry point for 198 * piece of memory. On successful load it then returns the entry point for
197 * the binary. Otherwise NULL. 199 * the binary. Otherwise NULL.
198 */ 200 */
199void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) 201void *efi_load_pe(struct efi_loaded_image_obj *handle, void *efi,
202 struct efi_loaded_image *loaded_image_info)
200{ 203{
201 IMAGE_NT_HEADERS32 *nt; 204 IMAGE_NT_HEADERS32 *nt;
202 IMAGE_DOS_HEADER *dos; 205 IMAGE_DOS_HEADER *dos;
@@ -314,8 +317,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
314 /* Populate the loaded image interface bits */ 317 /* Populate the loaded image interface bits */
315 loaded_image_info->image_base = efi; 318 loaded_image_info->image_base = efi;
316 loaded_image_info->image_size = image_size; 319 loaded_image_info->image_size = image_size;
317 loaded_image_info->reloc_base = efi_reloc; 320 handle->reloc_base = efi_reloc;
318 loaded_image_info->reloc_size = virt_size; 321 handle->reloc_size = virt_size;
319 322
320 return entry; 323 return entry;
321} 324}