From b909b4ad097080f865cbb7caae4cca101c0fe96c Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 2 Mar 2022 21:31:30 +0800 Subject: 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 Signed-off-by: Sebastien Boeuf Reviewed-by: Jiewen Yao --- OvmfPkg/OvmfXenElfHeaderGenerator.c | 141 ++++++++++++++++++++++++++++-------- 1 file changed, 109 insertions(+), 32 deletions(-) (limited to 'OvmfPkg/OvmfXenElfHeaderGenerator.c') diff --git a/OvmfPkg/OvmfXenElfHeaderGenerator.c b/OvmfPkg/OvmfXenElfHeaderGenerator.c index 489060cdad..672129b85d 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; } -- cgit v1.2.3