[edk2-devel] [PATCH v4 1/7] OvmfPkg: Make the Xen ELF header generator more flexible

Boeuf, Sebastien sebastien.boeuf at intel.com
Fri Feb 25 10:45:27 UTC 2022


From: Sebastien Boeuf <sebastien.boeuf at intel.com>

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 at redhat.com>
Signed-off-by: Sebastien Boeuf <sebastien.boeuf at intel.com>
---
 OvmfPkg/OvmfXenElfHeaderGenerator.c | 141 +++++++++++++++++++++-------
 1 file changed, 109 insertions(+), 32 deletions(-)

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;
 }
-- 
2.32.0

---------------------------------------------------------------------
Intel Corporation SAS (French simplified joint stock company)
Registered headquarters: "Les Montalets"- 2, rue de Paris, 
92196 Meudon Cedex, France
Registration Number:  302 456 199 R.C.S. NANTERRE
Capital: 4,572,000 Euros

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#87009): https://edk2.groups.io/g/devel/message/87009
Mute This Topic: https://groups.io/mt/89385941/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list