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>
This commit is contained in:
parent
589d51df26
commit
b909b4ad09
|
@ -10,19 +10,31 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "stdio.h"
|
#include "fcntl.h"
|
||||||
|
#include "stdbool.h"
|
||||||
#include "stddef.h"
|
#include "stddef.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
#include "stdlib.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
print_hdr (
|
print_hdr (
|
||||||
|
FILE *file,
|
||||||
void *s,
|
void *s,
|
||||||
size_t size
|
size_t size,
|
||||||
|
bool end_delimiter
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char *c = s;
|
char *c = s;
|
||||||
|
|
||||||
while (size--) {
|
fprintf (file, " ");
|
||||||
printf ("0x%02hhx, ", *(c++));
|
while (size-- > 1) {
|
||||||
|
fprintf (file, "0x%02hhx, ", *(c++));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end_delimiter) {
|
||||||
|
fprintf (file, "0x%02hhx,", *c);
|
||||||
|
} else {
|
||||||
|
fprintf (file, "0x%02hhx", *c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,21 +48,58 @@ typedef struct {
|
||||||
uint32_t desc;
|
uint32_t desc;
|
||||||
} xen_elfnote_phys32_entry;
|
} 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
|
int
|
||||||
main (
|
main (
|
||||||
void
|
int argc,
|
||||||
|
char *argv[]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
/* FW_SIZE */
|
/* FW_SIZE */
|
||||||
size_t ovmf_blob_size = 0x00200000;
|
size_t ovmf_blob_size = 0x00200000;
|
||||||
/* Load OVMF at 1MB when running as PVH guest */
|
/* Load OVMF at 1MB when running as PVH guest */
|
||||||
uint32_t ovmf_base_address = 0x00100000;
|
uint32_t ovmf_base_address = 0x00100000;
|
||||||
/* Xen PVH entry point */
|
uint32_t ovmfxen_pvh_entry_point;
|
||||||
uint32_t ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
|
|
||||||
size_t offset_into_file = 0;
|
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 */
|
/* ELF file header */
|
||||||
|
#ifdef PVH64
|
||||||
|
Elf64_Ehdr hdr = {
|
||||||
|
#else
|
||||||
Elf32_Ehdr hdr = {
|
Elf32_Ehdr hdr = {
|
||||||
|
#endif
|
||||||
.e_ident = ELFMAG,
|
.e_ident = ELFMAG,
|
||||||
.e_type = ET_EXEC,
|
.e_type = ET_EXEC,
|
||||||
.e_machine = EM_386,
|
.e_machine = EM_386,
|
||||||
|
@ -58,12 +107,20 @@ main (
|
||||||
.e_entry = ovmfxen_pvh_entry_point,
|
.e_entry = ovmfxen_pvh_entry_point,
|
||||||
.e_flags = R_386_NONE,
|
.e_flags = R_386_NONE,
|
||||||
.e_ehsize = sizeof (hdr),
|
.e_ehsize = sizeof (hdr),
|
||||||
|
#ifdef PVH64
|
||||||
|
.e_phentsize = sizeof (Elf64_Phdr),
|
||||||
|
#else
|
||||||
.e_phentsize = sizeof (Elf32_Phdr),
|
.e_phentsize = sizeof (Elf32_Phdr),
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
offset_into_file += sizeof (hdr);
|
offset_into_file += sizeof (hdr);
|
||||||
|
|
||||||
|
#ifdef PVH64
|
||||||
|
hdr.e_ident[EI_CLASS] = ELFCLASS64;
|
||||||
|
#else
|
||||||
hdr.e_ident[EI_CLASS] = ELFCLASS32;
|
hdr.e_ident[EI_CLASS] = ELFCLASS32;
|
||||||
|
#endif
|
||||||
hdr.e_ident[EI_DATA] = ELFDATA2LSB;
|
hdr.e_ident[EI_DATA] = ELFDATA2LSB;
|
||||||
hdr.e_ident[EI_VERSION] = EV_CURRENT;
|
hdr.e_ident[EI_VERSION] = EV_CURRENT;
|
||||||
hdr.e_ident[EI_OSABI] = ELFOSABI_LINUX;
|
hdr.e_ident[EI_OSABI] = ELFOSABI_LINUX;
|
||||||
|
@ -71,14 +128,22 @@ main (
|
||||||
hdr.e_phoff = sizeof (hdr);
|
hdr.e_phoff = sizeof (hdr);
|
||||||
|
|
||||||
/* program header */
|
/* program header */
|
||||||
|
#ifdef PVH64
|
||||||
|
Elf64_Phdr phdr_load = {
|
||||||
|
#else
|
||||||
Elf32_Phdr phdr_load = {
|
Elf32_Phdr phdr_load = {
|
||||||
|
#endif
|
||||||
.p_type = PT_LOAD,
|
.p_type = PT_LOAD,
|
||||||
.p_offset = 0, /* load everything */
|
.p_offset = 0, /* load everything */
|
||||||
.p_paddr = ovmf_base_address,
|
.p_paddr = ovmf_base_address,
|
||||||
.p_filesz = ovmf_blob_size,
|
.p_filesz = ovmf_blob_size,
|
||||||
.p_memsz = ovmf_blob_size,
|
.p_memsz = ovmf_blob_size,
|
||||||
.p_flags = PF_X | PF_W | PF_R,
|
.p_flags = PF_X | PF_W | PF_R,
|
||||||
|
#ifdef PVH64
|
||||||
|
.p_align = 4,
|
||||||
|
#else
|
||||||
.p_align = 0,
|
.p_align = 0,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
phdr_load.p_vaddr = phdr_load.p_paddr;
|
phdr_load.p_vaddr = phdr_load.p_paddr;
|
||||||
|
@ -98,12 +163,20 @@ main (
|
||||||
sizeof (xen_elfnote_phys32_entry) -
|
sizeof (xen_elfnote_phys32_entry) -
|
||||||
offsetof (xen_elfnote_phys32_entry, desc),
|
offsetof (xen_elfnote_phys32_entry, desc),
|
||||||
};
|
};
|
||||||
|
#ifdef PVH64
|
||||||
|
Elf64_Phdr phdr_note = {
|
||||||
|
#else
|
||||||
Elf32_Phdr phdr_note = {
|
Elf32_Phdr phdr_note = {
|
||||||
|
#endif
|
||||||
.p_type = PT_NOTE,
|
.p_type = PT_NOTE,
|
||||||
.p_filesz = sizeof (xen_elf_note),
|
.p_filesz = sizeof (xen_elf_note),
|
||||||
.p_memsz = sizeof (xen_elf_note),
|
.p_memsz = sizeof (xen_elf_note),
|
||||||
.p_flags = PF_R,
|
.p_flags = PF_R,
|
||||||
|
#ifdef PVH64
|
||||||
|
.p_align = 4,
|
||||||
|
#else
|
||||||
.p_align = 0,
|
.p_align = 0,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
hdr.e_phnum += 1;
|
hdr.e_phnum += 1;
|
||||||
|
@ -120,31 +193,35 @@ main (
|
||||||
size_t hdr_size = sizeof (hdr);
|
size_t hdr_size = sizeof (hdr);
|
||||||
size_t entry_off = offsetof (typeof(hdr), e_entry);
|
size_t entry_off = offsetof (typeof(hdr), e_entry);
|
||||||
|
|
||||||
printf ("# ELF file header\n");
|
fprintf (file, "DATA = {\r\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));
|
|
||||||
|
|
||||||
printf ("\n\n# ELF Program segment headers\n");
|
fprintf (file, " # ELF file header\r\n");
|
||||||
printf ("# - Load segment\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) {
|
for (i = 0; i < sizeof (phdr_load); i += 4) {
|
||||||
print_hdr (((char *)&phdr_load) + i, 4);
|
print_hdr (file, ((char *)&phdr_load) + i, 4, true);
|
||||||
printf ("\n");
|
fprintf (file, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("# - ELFNOTE segment\n");
|
fprintf (file, " # - ELFNOTE segment\r\n");
|
||||||
for (i = 0; i < sizeof (phdr_note); i += 4) {
|
for (i = 0; i < sizeof (phdr_note); i += 4) {
|
||||||
print_hdr (((char *)&phdr_note) + i, 4);
|
print_hdr (file, ((char *)&phdr_note) + i, 4, true);
|
||||||
printf ("\n");
|
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) {
|
for (i = 0; i < sizeof (xen_elf_note); i += 4) {
|
||||||
print_hdr (((char *)&xen_elf_note) + i, 4);
|
print_hdr (file, ((char *)&xen_elf_note) + i, 4, (sizeof (xen_elf_note) - i) > 4);
|
||||||
printf ("\n");
|
fprintf (file, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf (file, "}\r\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue