TianoCore EDK2 master
Loading...
Searching...
No Matches
OvmfXenElfHeaderGenerator.c
Go to the documentation of this file.
1
12#include "elf.h"
13#include "fcntl.h"
14#include "stdbool.h"
15#include "stddef.h"
16#include "stdio.h"
17#include "stdlib.h"
18
19void
20print_hdr (
21 FILE *file,
22 void *s,
23 size_t size,
24 bool end_delimiter
25 )
26{
27 char *c = s;
28
29 fprintf (file, " ");
30 while (size-- > 1) {
31 fprintf (file, "0x%02hhx, ", *(c++));
32 }
33
34 if (end_delimiter) {
35 fprintf (file, "0x%02hhx,", *c);
36 } else {
37 fprintf (file, "0x%02hhx", *c);
38 }
39}
40
41/* Format for the XEN_ELFNOTE_PHYS32_ENTRY program segment */
42#define XEN_ELFNOTE_PHYS32_ENTRY 18
43typedef struct {
44 uint32_t name_size;
45 uint32_t desc_size;
46 uint32_t type;
47 char name[4];
48 uint32_t desc;
50
51#define LICENSE_HDR "\
52## @file\r\n\
53# FDF include file that defines a PVH ELF header.\r\n\
54#\r\n\
55# Copyright (c) 2022, Intel Corporation. All rights reserved.\r\n\
56#\r\n\
57# SPDX-License-Identifier: BSD-2-Clause-Patent\r\n\
58#\r\n\
59##\r\n\
60\r\n\
61"
62
63int
64main (
65 int argc,
66 char *argv[]
67 )
68{
69 /* FW_SIZE */
70 size_t ovmf_blob_size = 0x00200000;
71 /* Load OVMF at 1MB when running as PVH guest */
72 uint32_t ovmf_base_address = 0x00100000;
73 uint32_t ovmfxen_pvh_entry_point;
74 size_t offset_into_file = 0;
75 char *endptr, *str;
76 long param;
77 FILE *file = stdout;
78
79 /* Parse the size parameter */
80 if (argc > 1) {
81 str = argv[1];
82 param = strtol (str, &endptr, 10);
83 if (endptr != str) {
84 ovmf_blob_size = (size_t)param;
85 }
86 }
87
88 /* Parse the filepath parameter */
89 if (argc > 2) {
90 file = fopen (argv[2], "w");
91 fprintf (file, LICENSE_HDR);
92 }
93
94 /* Xen PVH entry point */
95 ovmfxen_pvh_entry_point = ovmf_base_address + ovmf_blob_size - 0x30;
96
97 /* ELF file header */
98 #ifdef PVH64
99 Elf64_Ehdr hdr = {
100 #else
101 Elf32_Ehdr hdr = {
102 #endif
103 .e_ident = ELFMAG,
104 .e_type = ET_EXEC,
105 .e_machine = EM_386,
106 .e_version = EV_CURRENT,
107 .e_entry = ovmfxen_pvh_entry_point,
108 .e_flags = R_386_NONE,
109 .e_ehsize = sizeof (hdr),
110 #ifdef PVH64
111 .e_phentsize = sizeof (Elf64_Phdr),
112 #else
113 .e_phentsize = sizeof (Elf32_Phdr),
114 #endif
115 };
116
117 offset_into_file += sizeof (hdr);
118
119 #ifdef PVH64
120 hdr.e_ident[EI_CLASS] = ELFCLASS64;
121 #else
122 hdr.e_ident[EI_CLASS] = ELFCLASS32;
123 #endif
124 hdr.e_ident[EI_DATA] = ELFDATA2LSB;
125 hdr.e_ident[EI_VERSION] = EV_CURRENT;
126 hdr.e_ident[EI_OSABI] = ELFOSABI_LINUX;
127 /* Placing program headers just after hdr */
128 hdr.e_phoff = sizeof (hdr);
129
130 /* program header */
131 #ifdef PVH64
132 Elf64_Phdr phdr_load = {
133 #else
134 Elf32_Phdr phdr_load = {
135 #endif
136 .p_type = PT_LOAD,
137 .p_offset = 0, /* load everything */
138 .p_paddr = ovmf_base_address,
139 .p_filesz = ovmf_blob_size,
140 .p_memsz = ovmf_blob_size,
141 .p_flags = PF_X | PF_W | PF_R,
142 #ifdef PVH64
143 .p_align = 4,
144 #else
145 .p_align = 0,
146 #endif
147 };
148
149 phdr_load.p_vaddr = phdr_load.p_paddr;
150 hdr.e_phnum += 1;
151 offset_into_file += sizeof (phdr_load);
152
153 /* Xen ELF Note. */
154
155 xen_elfnote_phys32_entry xen_elf_note = {
156 .type = XEN_ELFNOTE_PHYS32_ENTRY,
157 .name = "Xen",
158 .desc = ovmfxen_pvh_entry_point,
159 .name_size =
160 offsetof (xen_elfnote_phys32_entry, desc) -
161 offsetof (xen_elfnote_phys32_entry, name),
162 .desc_size =
163 sizeof (xen_elfnote_phys32_entry) -
164 offsetof (xen_elfnote_phys32_entry, desc),
165 };
166 #ifdef PVH64
167 Elf64_Phdr phdr_note = {
168 #else
169 Elf32_Phdr phdr_note = {
170 #endif
171 .p_type = PT_NOTE,
172 .p_filesz = sizeof (xen_elf_note),
173 .p_memsz = sizeof (xen_elf_note),
174 .p_flags = PF_R,
175 #ifdef PVH64
176 .p_align = 4,
177 #else
178 .p_align = 0,
179 #endif
180 };
181
182 hdr.e_phnum += 1;
183 offset_into_file += sizeof (phdr_note);
184 phdr_note.p_offset = offset_into_file;
185 phdr_note.p_paddr = ovmf_base_address + phdr_note.p_offset;
186 phdr_note.p_vaddr = phdr_note.p_paddr;
187
188 /*
189 * print elf header
190 */
191
192 size_t i;
193 size_t hdr_size = sizeof (hdr);
194 size_t entry_off = offsetof (typeof(hdr), e_entry);
195
196 fprintf (file, "DATA = {\r\n");
197
198 fprintf (file, " # ELF file header\r\n");
199 print_hdr (file, &hdr, entry_off, true);
200 fprintf (file, "\r\n");
201 print_hdr (file, &hdr.e_entry, sizeof (hdr.e_entry), true);
202 fprintf (file, " # hdr.e_entry\r\n");
203 print_hdr (file, &hdr.e_entry + 1, hdr_size - entry_off - sizeof (hdr.e_entry), true);
204
205 fprintf (file, "\r\n\r\n # ELF Program segment headers\r\n");
206 fprintf (file, " # - Load segment\r\n");
207 for (i = 0; i < sizeof (phdr_load); i += 4) {
208 print_hdr (file, ((char *)&phdr_load) + i, 4, true);
209 fprintf (file, "\r\n");
210 }
211
212 fprintf (file, " # - ELFNOTE segment\r\n");
213 for (i = 0; i < sizeof (phdr_note); i += 4) {
214 print_hdr (file, ((char *)&phdr_note) + i, 4, true);
215 fprintf (file, "\r\n");
216 }
217
218 fprintf (file, "\r\n # XEN_ELFNOTE_PHYS32_ENTRY\r\n");
219 for (i = 0; i < sizeof (xen_elf_note); i += 4) {
220 print_hdr (file, ((char *)&xen_elf_note) + i, 4, (sizeof (xen_elf_note) - i) > 4);
221 fprintf (file, "\r\n");
222 }
223
224 fprintf (file, "}\r\n");
225
226 return 0;
227}
int main()
=== TEST ENGINE ================================================================================