From: Varad Gautam <varad.gautam@suse.com> To: kvm@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: pbonzini@redhat.com, drjones@redhat.com, jroedel@suse.de, bp@suse.de, thomas.lendacky@amd.com, brijesh.singh@amd.com, varad.gautam@suse.com Subject: [kvm-unit-tests PATCH 4/6] x86: efi_main: Self-relocate ELF .dynamic addresses Date: Fri, 2 Jul 2021 13:48:18 +0200 [thread overview] Message-ID: <20210702114820.16712-5-varad.gautam@suse.com> (raw) In-Reply-To: <20210702114820.16712-1-varad.gautam@suse.com> EFI expects a relocatable PE, and the loader will patch in the relocations from the COFF. Since we are wrapping an ELF into a PE here, the EFI loader will not handle ELF relocations, and we need to patch the ELF .dynamic section manually on early boot. Signed-off-by: Varad Gautam <varad.gautam@suse.com> --- x86/efi_main.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/x86/efi_main.c b/x86/efi_main.c index 237d4e7..be3f9ab 100644 --- a/x86/efi_main.c +++ b/x86/efi_main.c @@ -1,9 +1,13 @@ #include <alloc_phys.h> #include <linux/uefi.h> +#include <elf.h> unsigned long __efiapi efi_main(efi_handle_t handle, efi_system_table_t *sys_tab); efi_system_table_t *efi_system_table = NULL; +extern char ImageBase; +extern char _DYNAMIC; + static void efi_free_pool(void *ptr) { efi_bs_call(free_pool, ptr); @@ -93,11 +97,70 @@ static efi_status_t exit_efi(void *handle) return EFI_SUCCESS; } +static efi_status_t elf_reloc(unsigned long image_base, unsigned long dynamic) +{ + long relsz = 0, relent = 0; + Elf64_Rel *rel = 0; + Elf64_Dyn *dyn = (Elf64_Dyn *) dynamic; + unsigned long *addr; + int i; + + for (i = 0; dyn[i].d_tag != DT_NULL; i++) { + switch (dyn[i].d_tag) { + case DT_RELA: + rel = (Elf64_Rel *) + ((unsigned long) dyn[i].d_un.d_ptr + image_base); + break; + case DT_RELASZ: + relsz = dyn[i].d_un.d_val; + break; + case DT_RELAENT: + relent = dyn[i].d_un.d_val; + break; + default: + break; + } + } + + if (!rel && relent == 0) + return EFI_SUCCESS; + + if (!rel || relent == 0) + return EFI_LOAD_ERROR; + + while (relsz > 0) { + /* apply the relocs */ + switch (ELF64_R_TYPE (rel->r_info)) { + case R_X86_64_NONE: + break; + case R_X86_64_RELATIVE: + addr = (unsigned long *) (image_base + rel->r_offset); + *addr += image_base; + break; + default: + break; + } + rel = (Elf64_Rel *) ((char *) rel + relent); + relsz -= relent; + } + return EFI_SUCCESS; +} + unsigned long __efiapi efi_main(efi_handle_t handle, efi_system_table_t *sys_tab) { + unsigned long image_base, dyn; efi_system_table = sys_tab; exit_efi(handle); + image_base = (unsigned long) &ImageBase; + dyn = image_base + (unsigned long) &_DYNAMIC; + + /* The EFI loader does not handle ELF relocations, so fixup + * .dynamic addresses before proceeding any further. */ + elf_reloc(image_base, dyn); + + start64(); + return 0; } -- 2.30.2
WARNING: multiple messages have this Message-ID (diff)
From: Varad Gautam via Virtualization <virtualization@lists.linux-foundation.org> To: kvm@vger.kernel.org, virtualization@lists.linux-foundation.org Cc: thomas.lendacky@amd.com, drjones@redhat.com, jroedel@suse.de, brijesh.singh@amd.com, pbonzini@redhat.com, bp@suse.de Subject: [kvm-unit-tests PATCH 4/6] x86: efi_main: Self-relocate ELF .dynamic addresses Date: Fri, 2 Jul 2021 13:48:18 +0200 [thread overview] Message-ID: <20210702114820.16712-5-varad.gautam@suse.com> (raw) In-Reply-To: <20210702114820.16712-1-varad.gautam@suse.com> EFI expects a relocatable PE, and the loader will patch in the relocations from the COFF. Since we are wrapping an ELF into a PE here, the EFI loader will not handle ELF relocations, and we need to patch the ELF .dynamic section manually on early boot. Signed-off-by: Varad Gautam <varad.gautam@suse.com> --- x86/efi_main.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/x86/efi_main.c b/x86/efi_main.c index 237d4e7..be3f9ab 100644 --- a/x86/efi_main.c +++ b/x86/efi_main.c @@ -1,9 +1,13 @@ #include <alloc_phys.h> #include <linux/uefi.h> +#include <elf.h> unsigned long __efiapi efi_main(efi_handle_t handle, efi_system_table_t *sys_tab); efi_system_table_t *efi_system_table = NULL; +extern char ImageBase; +extern char _DYNAMIC; + static void efi_free_pool(void *ptr) { efi_bs_call(free_pool, ptr); @@ -93,11 +97,70 @@ static efi_status_t exit_efi(void *handle) return EFI_SUCCESS; } +static efi_status_t elf_reloc(unsigned long image_base, unsigned long dynamic) +{ + long relsz = 0, relent = 0; + Elf64_Rel *rel = 0; + Elf64_Dyn *dyn = (Elf64_Dyn *) dynamic; + unsigned long *addr; + int i; + + for (i = 0; dyn[i].d_tag != DT_NULL; i++) { + switch (dyn[i].d_tag) { + case DT_RELA: + rel = (Elf64_Rel *) + ((unsigned long) dyn[i].d_un.d_ptr + image_base); + break; + case DT_RELASZ: + relsz = dyn[i].d_un.d_val; + break; + case DT_RELAENT: + relent = dyn[i].d_un.d_val; + break; + default: + break; + } + } + + if (!rel && relent == 0) + return EFI_SUCCESS; + + if (!rel || relent == 0) + return EFI_LOAD_ERROR; + + while (relsz > 0) { + /* apply the relocs */ + switch (ELF64_R_TYPE (rel->r_info)) { + case R_X86_64_NONE: + break; + case R_X86_64_RELATIVE: + addr = (unsigned long *) (image_base + rel->r_offset); + *addr += image_base; + break; + default: + break; + } + rel = (Elf64_Rel *) ((char *) rel + relent); + relsz -= relent; + } + return EFI_SUCCESS; +} + unsigned long __efiapi efi_main(efi_handle_t handle, efi_system_table_t *sys_tab) { + unsigned long image_base, dyn; efi_system_table = sys_tab; exit_efi(handle); + image_base = (unsigned long) &ImageBase; + dyn = image_base + (unsigned long) &_DYNAMIC; + + /* The EFI loader does not handle ELF relocations, so fixup + * .dynamic addresses before proceeding any further. */ + elf_reloc(image_base, dyn); + + start64(); + return 0; } -- 2.30.2 _______________________________________________ Virtualization mailing list Virtualization@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/virtualization
next prev parent reply other threads:[~2021-07-02 11:48 UTC|newest] Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-07-02 11:48 [kvm-unit-tests PATCH 0/6] Initial x86_64 UEFI support Varad Gautam 2021-07-02 11:48 ` Varad Gautam via Virtualization 2021-07-02 11:48 ` [kvm-unit-tests PATCH 1/6] x86: Build tests as PE objects for the EFI loader Varad Gautam 2021-07-02 11:48 ` Varad Gautam via Virtualization 2021-07-02 11:48 ` [kvm-unit-tests PATCH 2/6] x86: Call efi_main from _efi_pe_entry Varad Gautam 2021-07-02 11:48 ` Varad Gautam via Virtualization 2021-07-02 11:48 ` [kvm-unit-tests PATCH 3/6] x86: efi_main: Get EFI memory map and exit boot services Varad Gautam 2021-07-02 11:48 ` Varad Gautam via Virtualization 2021-07-02 11:48 ` Varad Gautam [this message] 2021-07-02 11:48 ` [kvm-unit-tests PATCH 4/6] x86: efi_main: Self-relocate ELF .dynamic addresses Varad Gautam via Virtualization 2021-07-02 11:48 ` [kvm-unit-tests PATCH 5/6] cstart64.S: x86_64 bootstrapping after exiting EFI Varad Gautam 2021-07-02 11:48 ` Varad Gautam via Virtualization 2021-07-02 11:48 ` [kvm-unit-tests PATCH 6/6] x86: Disable some breaking tests for EFI and modify vmexit test Varad Gautam 2021-07-02 11:48 ` Varad Gautam via Virtualization 2021-07-12 16:29 ` [kvm-unit-tests PATCH 0/6] Initial x86_64 UEFI support Andrew Jones 2021-07-12 16:29 ` Andrew Jones 2021-08-13 18:44 ` Marc Orr 2021-08-16 7:26 ` Andrew Jones 2021-08-16 7:26 ` Andrew Jones 2021-08-17 3:41 ` Marc Orr 2021-08-17 10:49 ` Joerg Roedel 2021-08-17 10:49 ` Joerg Roedel 2021-08-18 1:52 ` Marc Orr 2021-08-18 8:38 ` Varad Gautam 2021-08-18 8:38 ` Varad Gautam via Virtualization 2021-08-19 1:32 ` Marc Orr 2021-08-19 1:42 ` Nadav Amit 2021-08-19 1:42 ` Nadav Amit 2021-08-19 1:54 ` Zixuan Wang 2021-08-19 11:36 ` Varad Gautam 2021-08-19 11:36 ` Varad Gautam via Virtualization 2021-08-20 17:29 ` Marc Orr
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210702114820.16712-5-varad.gautam@suse.com \ --to=varad.gautam@suse.com \ --cc=bp@suse.de \ --cc=brijesh.singh@amd.com \ --cc=drjones@redhat.com \ --cc=jroedel@suse.de \ --cc=kvm@vger.kernel.org \ --cc=pbonzini@redhat.com \ --cc=thomas.lendacky@amd.com \ --cc=virtualization@lists.linux-foundation.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.