summaryrefslogtreecommitdiff
path: root/OvmfPkg/OvmfXenElfHeaderGenerator.c
diff options
context:
space:
mode:
authorSebastien Boeuf <sebastien.boeuf@intel.com>2022-03-02 21:31:30 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2022-03-04 02:41:57 +0000
commitb909b4ad097080f865cbb7caae4cca101c0fe96c (patch)
tree429290a9850284df3324c3949dd0c9b202e96c4c /OvmfPkg/OvmfXenElfHeaderGenerator.c
parent589d51df260465e2561979b8a988e77b0f32a6e8 (diff)
downloadedk2-b909b4ad097080f865cbb7caae4cca101c0fe96c.zip
edk2-b909b4ad097080f865cbb7caae4cca101c0fe96c.tar.gz
edk2-b909b4ad097080f865cbb7caae4cca101c0fe96c.tar.bz2
OvmfPkg: Make the Xen ELF header generator more flexible
Adding some flexibility to the program through optional parameters and global define, so that other targets can use the generator. * A global define is added so that we can choose at build time if we want to use 32-bit or 64-bit base structures. * A first optional parameter is added so the user can provide the expected blob size of the generated binary. * A second optional parameter is added so the user can specify an output file to which the generated output will be printed. The default behavior isn't modified. Acked-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Diffstat (limited to 'OvmfPkg/OvmfXenElfHeaderGenerator.c')
-rw-r--r--OvmfPkg/OvmfXenElfHeaderGenerator.c141
1 files changed, 109 insertions, 32 deletions
diff --git a/OvmfPkg/OvmfXenElfHeaderGenerator.c b/OvmfPkg/OvmfXenElfHeaderGenerator.c
index 489060c..672129b 100644
--- a/OvmfPkg/OvmfXenElfHeaderGenerator.c
+++ b/OvmfPkg/OvmfXenElfHeaderGenerator.c
@@ -10,19 +10,31 @@
**/
#include "elf.h"
-#include "stdio.h"
+#include "fcntl.h"
+#include "stdbool.h"
#include "stddef.h"
+#include "stdio.h"
+#include "stdlib.h"
void
print_hdr (
+ FILE *file,
void *s,
- size_t size
+ size_t size,
+ bool end_delimiter
)
{
char *c = s;
- while (size--) {
- printf ("0x%02hhx, ", *(c++));
+ fprintf (file, " ");
+ while (size-- > 1) {
+ fprintf (file, "0x%02hhx, ", *(c++));
+ }
+
+ if (end_delimiter) {
+ fprintf (file, "0x%02hhx,", *c);
+ } else {
+ fprintf (file, "0x%02hhx", *c);
}
}
@@ -36,34 +48,79 @@ typedef struct {
uint32_t desc;
} xen_elfnote_phys32_entry;
+#define LICENSE_HDR "\
+## @file\r\n\
+# FDF include file that defines a PVH ELF header.\r\n\
+#\r\n\
+# Copyright (c) 2022, Intel Corporation. All rights reserved.\r\n\
+#\r\n\
+# SPDX-License-Identifier: BSD-2-Clause-Patent\r\n\
+#\r\n\
+##\r\n\
+\r\n\
+"
+
int
main (
- void
+ int argc,
+ char *argv[]
)
{
/* FW_SIZE */
size_t ovmf_blob_size = 0x00200000;
/* Load OVMF at 1MB when running as PVH guest */
uint32_t ovmf_base_address = 0x00100000;
+ uint32_t ovmfxen_pvh_entry_point;
+ size_t offset_into_file = 0;
+ char *endptr, *str;
+ long param;
+ FILE *file = stdout;
+
+ /* Parse the size parameter */
+ if (argc > 1) {
+ str = argv[1];
+ param = strtol (str, &endptr, 10);
+ if (endptr != str) {
+ ovmf_blob_size = (size_t)param;
+ }
+ }
+
+ /* Parse the filepath parameter */
+ if (argc > 2) {
+ file = fopen (argv[2], "w");
+ fprintf (file, LICENSE_HDR);
+ }
+
/* Xen PVH entry point */
- uint32_t ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
- size_t offset_into_file = 0;
+ ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
/* ELF file header */
+ #ifdef PVH64
+ Elf64_Ehdr hdr = {
+ #else
Elf32_Ehdr hdr = {
- .e_ident = ELFMAG,
- .e_type = ET_EXEC,
- .e_machine = EM_386,
- .e_version = EV_CURRENT,
- .e_entry = ovmfxen_pvh_entry_point,
- .e_flags = R_386_NONE,
- .e_ehsize = sizeof (hdr),
+ #endif
+ .e_ident = ELFMAG,
+ .e_type = ET_EXEC,
+ .e_machine = EM_386,
+ .e_version = EV_CURRENT,
+ .e_entry = ovmfxen_pvh_entry_point,
+ .e_flags = R_386_NONE,
+ .e_ehsize = sizeof (hdr),
+ #ifdef PVH64
+ .e_phentsize = sizeof (Elf64_Phdr),
+ #else
.e_phentsize = sizeof (Elf32_Phdr),
+ #endif
};
offset_into_file += sizeof (hdr);
- hdr.e_ident[EI_CLASS] = ELFCLASS32;
+ #ifdef PVH64
+ hdr.e_ident[EI_CLASS] = ELFCLASS64;
+ #else
+ hdr.e_ident[EI_CLASS] = ELFCLASS32;
+ #endif
hdr.e_ident[EI_DATA] = ELFDATA2LSB;
hdr.e_ident[EI_VERSION] = EV_CURRENT;
hdr.e_ident[EI_OSABI] = ELFOSABI_LINUX;
@@ -71,14 +128,22 @@ main (
hdr.e_phoff = sizeof (hdr);
/* program header */
+ #ifdef PVH64
+ Elf64_Phdr phdr_load = {
+ #else
Elf32_Phdr phdr_load = {
+ #endif
.p_type = PT_LOAD,
.p_offset = 0, /* load everything */
.p_paddr = ovmf_base_address,
.p_filesz = ovmf_blob_size,
.p_memsz = ovmf_blob_size,
.p_flags = PF_X | PF_W | PF_R,
+ #ifdef PVH64
+ .p_align = 4,
+ #else
.p_align = 0,
+ #endif
};
phdr_load.p_vaddr = phdr_load.p_paddr;
@@ -98,12 +163,20 @@ main (
sizeof (xen_elfnote_phys32_entry) -
offsetof (xen_elfnote_phys32_entry, desc),
};
- Elf32_Phdr phdr_note = {
+ #ifdef PVH64
+ Elf64_Phdr phdr_note = {
+ #else
+ Elf32_Phdr phdr_note = {
+ #endif
.p_type = PT_NOTE,
.p_filesz = sizeof (xen_elf_note),
.p_memsz = sizeof (xen_elf_note),
.p_flags = PF_R,
+ #ifdef PVH64
+ .p_align = 4,
+ #else
.p_align = 0,
+ #endif
};
hdr.e_phnum += 1;
@@ -120,31 +193,35 @@ main (
size_t hdr_size = sizeof (hdr);
size_t entry_off = offsetof (typeof(hdr), e_entry);
- printf ("# ELF file header\n");
- print_hdr (&hdr, entry_off);
- printf ("\n");
- print_hdr (&hdr.e_entry, sizeof (hdr.e_entry));
- printf (" # hdr.e_entry\n");
- print_hdr (&hdr.e_entry + 1, hdr_size - entry_off - sizeof (hdr.e_entry));
+ fprintf (file, "DATA = {\r\n");
- printf ("\n\n# ELF Program segment headers\n");
- printf ("# - Load segment\n");
+ fprintf (file, " # ELF file header\r\n");
+ print_hdr (file, &hdr, entry_off, true);
+ fprintf (file, "\r\n");
+ print_hdr (file, &hdr.e_entry, sizeof (hdr.e_entry), true);
+ fprintf (file, " # hdr.e_entry\r\n");
+ print_hdr (file, &hdr.e_entry + 1, hdr_size - entry_off - sizeof (hdr.e_entry), true);
+
+ fprintf (file, "\r\n\r\n # ELF Program segment headers\r\n");
+ fprintf (file, " # - Load segment\r\n");
for (i = 0; i < sizeof (phdr_load); i += 4) {
- print_hdr (((char *)&phdr_load) + i, 4);
- printf ("\n");
+ print_hdr (file, ((char *)&phdr_load) + i, 4, true);
+ fprintf (file, "\r\n");
}
- printf ("# - ELFNOTE segment\n");
+ fprintf (file, " # - ELFNOTE segment\r\n");
for (i = 0; i < sizeof (phdr_note); i += 4) {
- print_hdr (((char *)&phdr_note) + i, 4);
- printf ("\n");
+ print_hdr (file, ((char *)&phdr_note) + i, 4, true);
+ fprintf (file, "\r\n");
}
- printf ("\n# XEN_ELFNOTE_PHYS32_ENTRY\n");
+ fprintf (file, "\r\n # XEN_ELFNOTE_PHYS32_ENTRY\r\n");
for (i = 0; i < sizeof (xen_elf_note); i += 4) {
- print_hdr (((char *)&xen_elf_note) + i, 4);
- printf ("\n");
+ print_hdr (file, ((char *)&xen_elf_note) + i, 4, (sizeof (xen_elf_note) - i) > 4);
+ fprintf (file, "\r\n");
}
+ fprintf (file, "}\r\n");
+
return 0;
}