123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- /** @file
- This program generates a hex array to be manually coppied into
- OvmfXen.fdf.
- The purpose is for the flash device image to be recognize as an ELF.
- Copyright (c) 2019, Citrix Systems, Inc.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "elf.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,
- bool end_delimiter
- )
- {
- char *c = s;
- fprintf (file, " ");
- while (size-- > 1) {
- fprintf (file, "0x%02hhx, ", *(c++));
- }
- if (end_delimiter) {
- fprintf (file, "0x%02hhx,", *c);
- } else {
- fprintf (file, "0x%02hhx", *c);
- }
- }
- /* Format for the XEN_ELFNOTE_PHYS32_ENTRY program segment */
- #define XEN_ELFNOTE_PHYS32_ENTRY 18
- typedef struct {
- uint32_t name_size;
- uint32_t desc_size;
- uint32_t type;
- char name[4];
- 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 (
- 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 */
- ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
- /* ELF file header */
- #ifdef PVH64
- Elf64_Ehdr hdr = {
- #else
- Elf32_Ehdr 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);
- #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;
- /* Placing program headers just after hdr */
- 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;
- hdr.e_phnum += 1;
- offset_into_file += sizeof (phdr_load);
- /* Xen ELF Note. */
- xen_elfnote_phys32_entry xen_elf_note = {
- .type = XEN_ELFNOTE_PHYS32_ENTRY,
- .name = "Xen",
- .desc = ovmfxen_pvh_entry_point,
- .name_size =
- offsetof (xen_elfnote_phys32_entry, desc) -
- offsetof (xen_elfnote_phys32_entry, name),
- .desc_size =
- sizeof (xen_elfnote_phys32_entry) -
- offsetof (xen_elfnote_phys32_entry, desc),
- };
- #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;
- offset_into_file += sizeof (phdr_note);
- phdr_note.p_offset = offset_into_file;
- phdr_note.p_paddr = ovmf_base_address + phdr_note.p_offset;
- phdr_note.p_vaddr = phdr_note.p_paddr;
- /*
- * print elf header
- */
- size_t i;
- size_t hdr_size = sizeof (hdr);
- size_t entry_off = offsetof (typeof(hdr), e_entry);
- fprintf (file, "DATA = {\r\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 (file, ((char *)&phdr_load) + i, 4, true);
- fprintf (file, "\r\n");
- }
- fprintf (file, " # - ELFNOTE segment\r\n");
- for (i = 0; i < sizeof (phdr_note); i += 4) {
- print_hdr (file, ((char *)&phdr_note) + i, 4, true);
- fprintf (file, "\r\n");
- }
- fprintf (file, "\r\n # XEN_ELFNOTE_PHYS32_ENTRY\r\n");
- for (i = 0; i < sizeof (xen_elf_note); i += 4) {
- 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;
- }
|