diff options
author | Heinrich Schuchardt | 2018-09-23 10:21:51 -0500 |
---|---|---|
committer | Alexander Graf | 2018-09-23 14:55:31 -0500 |
commit | c982874e930d5d673501cd94df07bcbd215d5883 (patch) | |
tree | 83538d2ee2c50b61a6dca207d3c5f5c60fd2ebeb /lib | |
parent | a47c1b5b87fcbd2bdb2e297d3c41d41c0c663967 (diff) | |
download | u-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.c | 92 | ||||
-rw-r--r-- | lib/efi_loader/efi_image_loader.c | 23 |
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 | */ |
1473 | efi_status_t efi_setup_loaded_image( | 1473 | efi_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); |
1647 | failure: | 1650 | failure: |
1651 | efi_delete_handle(*image_handle); | ||
1652 | *image_handle = NULL; | ||
1648 | free(info); | 1653 | free(info); |
1649 | efi_delete_handle(obj); | ||
1650 | error: | 1654 | error: |
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 | */ |
55 | efi_status_t efi_print_image_info(struct efi_loaded_image *image, void *pc) | 56 | static 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 | */ |
199 | void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info) | 201 | void *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 | } |