All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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: link
Be 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.