]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenFw/GenFw.c
There is a limitation on WINDOWS OS for the length of entire file path can’t be large...
[mirror_edk2.git] / BaseTools / Source / C / GenFw / GenFw.c
CommitLineData
30fdf114
LG
1/** @file\r
2\r
1be2ed90 3Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
40d841f6 4This program and the accompanying materials\r
30fdf114
LG
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 GenFw.c\r
15\r
16Abstract:\r
17\r
18 Converts a pe32+ image to an FW, Te image type, or other specific image.\r
19\r
20**/\r
21\r
22#include "WinNtInclude.h"\r
23\r
24#ifndef __GNUC__\r
25#include <windows.h>\r
fd171542 26#include <io.h>\r
636f2be6
LG
27#include <sys/types.h>\r
28#include <sys/stat.h>\r
30fdf114
LG
29#endif\r
30#include <stdio.h>\r
31#include <stdlib.h>\r
32#include <string.h>\r
33#include <time.h>\r
34#include <ctype.h>\r
35\r
36#include <Common/UefiBaseTypes.h>\r
37#include <IndustryStandard/PeImage.h>\r
b303ea72 38#include <Common/UefiInternalFormRepresentation.h>\r
30fdf114
LG
39\r
40//\r
41// Acpi Table definition\r
42//\r
43#include <IndustryStandard/Acpi.h>\r
44#include <IndustryStandard/Acpi1_0.h>\r
45#include <IndustryStandard/Acpi2_0.h>\r
46#include <IndustryStandard/Acpi3_0.h>\r
47#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>\r
48\r
49#include "CommonLib.h"\r
fd171542 50#include "PeCoffLib.h"\r
51#include "ParseInf.h"\r
30fdf114
LG
52#include "EfiUtilityMsgs.h"\r
53\r
40d841f6 54#include "GenFw.h"\r
30fdf114
LG
55\r
56//\r
57// Version of this utility\r
58//\r
59#define UTILITY_NAME "GenFw"\r
60#define UTILITY_MAJOR_VERSION 0\r
61#define UTILITY_MINOR_VERSION 2\r
62\r
b303ea72
LG
63#define HII_RESOURCE_SECTION_INDEX 1\r
64#define HII_RESOURCE_SECTION_NAME "HII"\r
30fdf114
LG
65\r
66#define DEFAULT_MC_PAD_BYTE_VALUE 0xFF\r
67#define DEFAULT_MC_ALIGNMENT 16\r
68\r
40d841f6 69#define STATUS_IGNORE 0xA\r
30fdf114
LG
70//\r
71// Structure definition for a microcode header\r
72//\r
73typedef struct {\r
74 UINT32 HeaderVersion;\r
75 UINT32 PatchId;\r
76 UINT32 Date;\r
77 UINT32 CpuId;\r
78 UINT32 Checksum;\r
79 UINT32 LoaderVersion;\r
80 UINT32 PlatformId;\r
81 UINT32 DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid\r
82 UINT32 TotalSize; // number of bytes\r
83 UINT32 Reserved[3];\r
84} MICROCODE_IMAGE_HEADER;\r
85\r
b303ea72
LG
86static EFI_GUID mZeroGuid = {0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};\r
87\r
88static const char *gHiiPackageRCFileHeader[] = {\r
89 "//",\r
90 "// DO NOT EDIT -- auto-generated file",\r
91 "//",\r
92 NULL\r
93};\r
94\r
52302d4d
LG
95//\r
96// Module image information\r
97//\r
40d841f6
LG
98CHAR8 *mInImageName;\r
99UINT32 mImageTimeStamp = 0;\r
100UINT32 mImageSize = 0;\r
da92f276 101UINT32 mOutImageType = FW_DUMMY_IMAGE;\r
40d841f6 102\r
52302d4d 103\r
30fdf114
LG
104STATIC\r
105EFI_STATUS\r
106ZeroDebugData (\r
107 IN OUT UINT8 *FileBuffer,\r
108 BOOLEAN ZeroDebug\r
109 );\r
110\r
111STATIC\r
112EFI_STATUS\r
113SetStamp (\r
114 IN OUT UINT8 *FileBuffer,\r
115 IN CHAR8 *TimeStamp\r
116 );\r
117\r
118STATIC\r
119STATUS\r
120MicrocodeReadData (\r
121 FILE *InFptr,\r
122 UINT32 *Data\r
123 );\r
124\r
125STATIC\r
126VOID\r
127Version (\r
128 VOID\r
129 )\r
130/*++\r
131\r
132Routine Description:\r
133\r
134 Print out version information for this utility.\r
135\r
136Arguments:\r
137\r
138 None\r
139\r
140Returns:\r
141\r
142 None\r
143\r
144--*/\r
145{\r
b36d134f 146 fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
30fdf114
LG
147}\r
148\r
149STATIC\r
150VOID\r
151Usage (\r
152 VOID\r
153 )\r
154/*++\r
155\r
156Routine Description:\r
157\r
158 Print Help message.\r
159\r
160Arguments:\r
161\r
162 VOID\r
163\r
164Returns:\r
165\r
166 None\r
167\r
168--*/\r
169{\r
170 //\r
171 // Summary usage\r
172 //\r
173 fprintf (stdout, "\nUsage: %s [options] <input_file>\n\n", UTILITY_NAME);\r
174\r
175 //\r
176 // Copyright declaration\r
177 //\r
1be2ed90 178 fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
30fdf114
LG
179\r
180 //\r
181 // Details Option\r
182 //\r
183 fprintf (stdout, "Options:\n");\r
184 fprintf (stdout, " -o FileName, --outputfile FileName\n\\r
185 File will be created to store the ouput content.\n");\r
186 fprintf (stdout, " -e EFI_FILETYPE, --efiImage EFI_FILETYPE\n\\r
a709adfa 187 Create Efi Image. EFI_FILETYPE is one of BASE,SMM_CORE,\n\\r
30fdf114 188 PEI_CORE, PEIM, DXE_CORE, DXE_DRIVER, UEFI_APPLICATION,\n\\r
a709adfa
LG
189 SEC, DXE_SAL_DRIVER, UEFI_DRIVER, DXE_RUNTIME_DRIVER,\n\\r
190 DXE_SMM_DRIVER, SECURITY_CORE, COMBINED_PEIM_DRIVER,\n\\r
30fdf114
LG
191 PIC_PEIM, RELOCATABLE_PEIM, BS_DRIVER, RT_DRIVER,\n\\r
192 APPLICATION, SAL_RT_DRIVER to support all module types\n\\r
193 It can only be used together with --keepexceptiontable,\n\\r
194 --keepzeropending, -r, -o option.It is a action option.\n\\r
195 If it is combined with other action options, the later\n\\r
196 input action option will override the previous one.\n");\r
197 fprintf (stdout, " -c, --acpi Create Acpi table.\n\\r
198 It can't be combined with other action options\n\\r
199 except for -o, -r option. It is a action option.\n\\r
200 If it is combined with other action options, the later\n\\r
201 input action option will override the previous one.\n");\r
202 fprintf (stdout, " -t, --terse Create Te Image.\n\\r
203 It can only be used together with --keepexceptiontable,\n\\r
204 --keepzeropending, -r, -o option.It is a action option.\n\\r
205 If it is combined with other action options, the later\n\\r
206 input action option will override the previous one.\n");\r
207 fprintf (stdout, " -u, --dump Dump TeImage Header.\n\\r
208 It can't be combined with other action options\n\\r
209 except for -o, -r option. It is a action option.\n\\r
210 If it is combined with other action options, the later\n\\r
211 input action option will override the previous one.\n");\r
212 fprintf (stdout, " -z, --zero Zero the Debug Data Fields in the PE input image file.\n\\r
213 It also zeros the time stamp fields.\n\\r
214 This option can be used to compare the binary efi image.\n\\r
215 It can't be combined with other action options\n\\r
216 except for -o, -r option. It is a action option.\n\\r
217 If it is combined with other action options, the later\n\\r
218 input action option will override the previous one.\n");\r
219 fprintf (stdout, " -b, --exe2bin Convert the input EXE to the output BIN file.\n\\r
220 It can't be combined with other action options\n\\r
221 except for -o, -r option. It is a action option.\n\\r
222 If it is combined with other action options, the later\n\\r
223 input action option will override the previous one.\n");;\r
a709adfa 224 fprintf (stdout, " -l, --stripped Strip off the relocation info from PE or TE image.\n\\r
30fdf114
LG
225 It can't be combined with other action options\n\\r
226 except for -o, -r option. It is a action option.\n\\r
227 If it is combined with other action options, the later\n\\r
228 input action option will override the previous one.\n");\r
229 fprintf (stdout, " -s timedate, --stamp timedate\n\\r
230 timedate format is \"yyyy-mm-dd 00:00:00\". if timedata \n\\r
231 is set to NOW, current system time is used. The support\n\\r
52302d4d
LG
232 date scope is 1970-01-01 00+timezone:00:00\n\\r
233 ~ 2038-01-19 03+timezone:14:07\n\\r
234 The scope is adjusted according to the different zones.\n\\r
30fdf114
LG
235 It can't be combined with other action options\n\\r
236 except for -o, -r option. It is a action option.\n\\r
237 If it is combined with other action options, the later\n\\r
238 input action option will override the previous one.\n");\r
239 fprintf (stdout, " -m, --mcifile Convert input microcode txt file to microcode bin file.\n\\r
240 It can't be combined with other action options\n\\r
241 except for -o option. It is a action option.\n\\r
242 If it is combined with other action options, the later\n\\r
243 input action option will override the previous one.\n");\r
244 fprintf (stdout, " -j, --join Combine multi microcode bin files to one file.\n\\r
245 It can be specified with -a, -p, -o option.\n\\r
246 No other options can be combined with it.\n\\r
247 If it is combined with other action options, the later\n\\r
248 input action option will override the previous one.\n");\r
249 fprintf (stdout, " -a NUM, --align NUM NUM is one HEX or DEC format alignment value.\n\\r
250 This option is only used together with -j option.\n"); \r
251 fprintf (stdout, " -p NUM, --pad NUM NUM is one HEX or DEC format padding value.\n\\r
252 This option is only used together with -j option.\n");\r
253 fprintf (stdout, " --keepexceptiontable Don't clear exception table.\n\\r
254 This option can be used together with -e or -t.\n\\r
255 It doesn't work for other options.\n");\r
256 fprintf (stdout, " --keepzeropending Don't strip zero pending of .reloc.\n\\r
257 This option can be used together with -e or -t.\n\\r
258 It doesn't work for other options.\n");\r
259 fprintf (stdout, " -r, --replace Overwrite the input file with the output content.\n\\r
260 If more input files are specified,\n\\r
261 the last input file will be as the output file.\n");\r
b303ea72 262 fprintf (stdout, " -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\\r
a709adfa 263 Guid is used to specify hii package list guid.\n\\r
b303ea72
LG
264 Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\\r
265 If not specified, the first Form FormSet guid is used.\n");\r
266 fprintf (stdout, " --hiipackage Combine all input binary hii pacakges into \n\\r
267 a single package list as the text resource data(RC).\n\\r
268 It can't be combined with other action options\n\\r
269 except for -o option. It is a action option.\n\\r
270 If it is combined with other action options, the later\n\\r
271 input action option will override the previous one.\n");\r
a709adfa
LG
272 fprintf (stdout, " --hiibinpackage Combine all input binary hii pacakges into \n\\r
273 a single package list as the binary resource section.\n\\r
274 It can't be combined with other action options\n\\r
275 except for -o option. It is a action option.\n\\r
276 If it is combined with other action options, the later\n\\r
277 input action option will override the previous one.\n");\r
52302d4d
LG
278 fprintf (stdout, " --rebase NewAddress Rebase image to new base address. New address \n\\r
279 is also set to the first none code section header.\n\\r
280 It can't be combined with other action options\n\\r
281 except for -o or -r option. It is a action option.\n\\r
282 If it is combined with other action options, the later\n\\r
283 input action option will override the previous one.\n");\r
284 fprintf (stdout, " --address NewAddress Set new address into the first none code \n\\r
285 section header of the input image.\n\\r
286 It can't be combined with other action options\n\\r
287 except for -o or -r option. It is a action option.\n\\r
288 If it is combined with other action options, the later\n\\r
289 input action option will override the previous one.\n");\r
30fdf114
LG
290 fprintf (stdout, " -v, --verbose Turn on verbose output with informational messages.\n");\r
291 fprintf (stdout, " -q, --quiet Disable all messages except key message and fatal error\n");\r
292 fprintf (stdout, " -d, --debug level Enable debug messages, at input debug level.\n");\r
293 fprintf (stdout, " --version Show program's version number and exit\n");\r
294 fprintf (stdout, " -h, --help Show this help message and exit\n");\r
295}\r
296\r
297STATIC\r
298STATUS\r
299CheckAcpiTable (\r
300 VOID *AcpiTable,\r
301 UINT32 Length\r
302 )\r
303/*++\r
304\r
305Routine Description:\r
306\r
307 Check Acpi Table\r
308\r
309Arguments:\r
310\r
311 AcpiTable Buffer for AcpiSection\r
312 Length AcpiSection Length\r
313\r
314Returns:\r
315\r
316 0 success\r
317 non-zero otherwise\r
318\r
319--*/\r
320{\r
321 EFI_ACPI_DESCRIPTION_HEADER *AcpiHeader;\r
322 EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs;\r
323 UINT32 ExpectedLength;\r
324\r
325 AcpiHeader = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiTable;\r
326\r
327 //\r
328 // Generic check for AcpiTable length.\r
329 //\r
330 if (AcpiHeader->Length > Length) {\r
331 Error (NULL, 0, 3000, "Invalid", "AcpiTable length check failed.", NULL);\r
332 return STATUS_ERROR;\r
333 }\r
334\r
335 //\r
336 // Currently, we only check must-have tables: FADT, FACS, DSDT,\r
337 // and some important tables: MADT, MCFG.\r
338 //\r
339 switch (AcpiHeader->Signature) {\r
340\r
341 //\r
342 // "FACP" Fixed ACPI Description Table\r
343 //\r
344 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE:\r
345 switch (AcpiHeader->Revision) {\r
346 case EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:\r
347 ExpectedLength = sizeof(EFI_ACPI_1_0_FIXED_ACPI_DESCRIPTION_TABLE);\r
348 break;\r
349 case EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:\r
350 ExpectedLength = sizeof(EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE);\r
351 break;\r
352 case EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION:\r
353 ExpectedLength = sizeof(EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE);\r
354 break;\r
355 default:\r
fd171542 356 if (AcpiHeader->Revision > EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) {\r
357 ExpectedLength = AcpiHeader->Length;\r
358 break;\r
359 }\r
30fdf114
LG
360 Error (NULL, 0, 3000, "Invalid", "FACP revision check failed.");\r
361 return STATUS_ERROR;\r
362 }\r
363 if (ExpectedLength != AcpiHeader->Length) {\r
364 Error (NULL, 0, 3000, "Invalid", "FACP length check failed.");\r
365 return STATUS_ERROR;\r
366 }\r
367 break;\r
368\r
369 //\r
370 // "FACS" Firmware ACPI Control Structure\r
371 //\r
372 case EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE:\r
373 Facs = (EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)AcpiTable;\r
fd171542 374 if (Facs->Version > EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) {\r
375 break;\r
376 }\r
377 if ((Facs->Version != EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
30fdf114
LG
378 (Facs->Version != EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION) &&\r
379 (Facs->Version != EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION)){\r
380 Error (NULL, 0, 3000, "Invalid", "FACS version check failed.");\r
381 return STATUS_ERROR;\r
382 }\r
383 if ((Facs->Length != sizeof(EFI_ACPI_1_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) &&\r
384 (Facs->Length != sizeof(EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE)) &&\r
385 (Facs->Length != sizeof(EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE))) {\r
386 Error (NULL, 0, 3000, "Invalid", "FACS length check failed.");\r
387 return STATUS_ERROR;\r
388 }\r
389 break;\r
390\r
391 //\r
392 // "DSDT" Differentiated System Description Table\r
393 //\r
394 case EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE:\r
395 if (AcpiHeader->Revision > EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION) {\r
fd171542 396 break;\r
30fdf114
LG
397 }\r
398 if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER)) {\r
399 Error (NULL, 0, 3000, "Invalid", "DSDT length check failed.");\r
400 return STATUS_ERROR;\r
401 }\r
402 break;\r
403\r
404 //\r
405 // "APIC" Multiple APIC Description Table\r
406 //\r
407 case EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE:\r
fd171542 408 if (AcpiHeader->Revision > EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) {\r
409 break;\r
410 }\r
30fdf114
LG
411 if ((AcpiHeader->Revision != EFI_ACPI_1_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) &&\r
412 (AcpiHeader->Revision != EFI_ACPI_2_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION) &&\r
413 (AcpiHeader->Revision != EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION)) {\r
414 Error (NULL, 0, 3000, "Invalid", "APIC revision check failed.");\r
415 return STATUS_ERROR;\r
416 }\r
417 if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT32) + sizeof(UINT32)) {\r
418 Error (NULL, 0, 3000, "Invalid", "APIC length check failed.");\r
419 return STATUS_ERROR;\r
420 }\r
421 break;\r
422\r
423 //\r
424 // "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table\r
425 //\r
426 case EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE:\r
fd171542 427 if (AcpiHeader->Revision > EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) {\r
428 break;\r
429 }\r
30fdf114
LG
430 if (AcpiHeader->Revision != EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION) {\r
431 Error (NULL, 0, 3000, "Invalid", "MCFG revision check failed.");\r
432 return STATUS_ERROR;\r
433 }\r
434 if (AcpiHeader->Length <= sizeof(EFI_ACPI_DESCRIPTION_HEADER) + sizeof(UINT64)) {\r
435 Error (NULL, 0, 3000, "Invalid", "MCFG length check failed.");\r
436 return STATUS_ERROR;\r
437 }\r
438 break;\r
439\r
440 //\r
441 // Other table pass check\r
442 //\r
443 default:\r
444 break;\r
445 }\r
446\r
447 return STATUS_SUCCESS;\r
448}\r
449\r
b303ea72 450VOID\r
a709adfa
LG
451SetHiiResourceHeader (\r
452 UINT8 *HiiBinData,\r
b303ea72
LG
453 UINT32 OffsetToFile\r
454 )\r
455{\r
b303ea72
LG
456 UINT32 Index;\r
457 EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
458 EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;\r
459 EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
460 EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
461\r
b303ea72
LG
462 //\r
463 // Fill Resource section entry\r
464 //\r
a709adfa
LG
465 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData);\r
466 ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
467 for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index ++) {\r
468 if (ResourceDirectoryEntry->u1.s.NameIsString) {\r
469 ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiBinData + ResourceDirectoryEntry->u1.s.NameOffset);\r
b303ea72 470\r
a709adfa
LG
471 if (ResourceDirectoryString->Length == 3 &&\r
472 ResourceDirectoryString->String[0] == L'H' &&\r
473 ResourceDirectoryString->String[1] == L'I' &&\r
474 ResourceDirectoryString->String[2] == L'I') {\r
475 //\r
476 // Resource Type "HII" found\r
477 //\r
478 if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
479 //\r
480 // Move to next level - resource Name\r
481 //\r
482 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
483 ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
b303ea72 484\r
a709adfa
LG
485 if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
486 //\r
487 // Move to next level - resource Language\r
488 //\r
489 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiBinData + ResourceDirectoryEntry->u2.s.OffsetToDirectory);\r
490 ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);\r
491 }\r
492 }\r
b303ea72 493\r
a709adfa
LG
494 //\r
495 // Now it ought to be resource Data and update its OffsetToData value \r
496 //\r
497 if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {\r
498 ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiBinData + ResourceDirectoryEntry->u2.OffsetToData);\r
499 ResourceDataEntry->OffsetToData = ResourceDataEntry->OffsetToData + OffsetToFile;\r
500 break;\r
501 }\r
b303ea72
LG
502 }\r
503 }\r
a709adfa 504 ResourceDirectoryEntry++;\r
b303ea72
LG
505 }\r
506 \r
507 return;\r
508}\r
509\r
a709adfa
LG
510EFI_IMAGE_OPTIONAL_HEADER_UNION *\r
511GetPeCoffHeader (\r
512 void *Data\r
513 )\r
514{\r
515 EFI_IMAGE_DOS_HEADER *DosHdr;\r
516 EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
517\r
518 //\r
519 // Read the dos & pe hdrs of the image\r
520 //\r
521 DosHdr = (EFI_IMAGE_DOS_HEADER *)Data;\r
522 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
523 // NO DOS header, check for PE/COFF header\r
524 PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Data);\r
525 if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
526 return NULL;\r
527 }\r
528 } else {\r
529\r
530 PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(((UINT8 *)Data) + DosHdr->e_lfanew);\r
531 if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
532 return NULL;\r
533 }\r
534 }\r
535 \r
536 return PeHdr;\r
537}\r
538\r
539void\r
540PeCoffConvertImageToXip (\r
541 UINT8 **FileBuffer,\r
542 UINT32 *FileLength\r
543 )\r
544{\r
545 EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
546 EFI_IMAGE_OPTIONAL_HEADER_UNION *NewPeHdr;\r
547 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
548 UINTN TotalNecessaryFileSize;\r
549 UINTN SectionSize;\r
550 UINT8 *XipFile;\r
551 UINT32 XipLength;\r
552 UINTN Index;\r
553 UINTN FirstSectionOffset;\r
554 BOOLEAN ConversionNeeded;\r
555\r
556 PeHdr = GetPeCoffHeader ((void *) *FileBuffer);\r
557 if (PeHdr == NULL) {\r
558 return;\r
559 }\r
560 \r
561 if (PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment) {\r
562 //\r
563 // The only reason to expand zero fill sections is to make them compatible with XIP images.\r
564 // If SectionAlignment is not equal to FileAlginment then it is not an XIP type image.\r
565 //\r
566 return;\r
567 }\r
568\r
569 //\r
570 // Calculate size of XIP file, and determine if the conversion is needed.\r
571 //\r
572 ConversionNeeded = FALSE;\r
573 XipLength = 0;\r
574 FirstSectionOffset = *FileLength;\r
575 TotalNecessaryFileSize = 0;\r
576 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
577 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
578 SectionSize = MAX (SectionHeader->Misc.VirtualSize, SectionHeader->SizeOfRawData);\r
579 TotalNecessaryFileSize += SectionSize;\r
580 if (SectionSize > 0) {\r
581 FirstSectionOffset = MIN (FirstSectionOffset, SectionHeader->VirtualAddress);\r
582 XipLength = MAX (XipLength, SectionHeader->VirtualAddress + SectionSize);\r
583 if (SectionHeader->VirtualAddress != SectionHeader->PointerToRawData) {\r
584 ConversionNeeded = TRUE;\r
585 }\r
586 }\r
587 if (SectionHeader->Misc.VirtualSize > SectionHeader->SizeOfRawData) {\r
588 ConversionNeeded = TRUE;\r
589 }\r
590 }\r
591\r
592 if (FirstSectionOffset < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
593 //\r
594 // If one of the sections should be loaded to an offset overlapping with\r
595 // the executable header, then it cannot be made into an XIP image.\r
596 //\r
597 VerboseMsg ("PE/COFF conversion to XIP is impossible due to overlap");\r
598 VerboseMsg ("of section data with the executable header.");\r
599 return;\r
600 }\r
601\r
602 if (FirstSectionOffset == *FileLength) {\r
603 //\r
604 // If we never found a section with a non-zero size, then we\r
605 // skip the conversion.\r
606 //\r
607 return;\r
608 }\r
609\r
610 TotalNecessaryFileSize += FirstSectionOffset;\r
611\r
612 if (!ConversionNeeded) {\r
613 return;\r
614 }\r
615\r
616 if (XipLength > (2 * TotalNecessaryFileSize)) {\r
617 VerboseMsg ("PE/COFF conversion to XIP appears to be larger than necessary.");\r
618 VerboseMsg ("The image linking process may have left unused memory ranges.");\r
619 }\r
620\r
621 if (PeHdr->Pe32.FileHeader.PointerToSymbolTable != 0) {\r
622 //\r
623 // This field is obsolete and should be zero\r
624 //\r
625 PeHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
626 }\r
627\r
628 //\r
629 // Allocate the extra space that we need to grow the image\r
630 //\r
631 XipFile = malloc (XipLength);\r
632 memset (XipFile, 0, XipLength);\r
633\r
634 //\r
635 // Copy the file headers\r
636 //\r
637 memcpy (XipFile, *FileBuffer, PeHdr->Pe32.OptionalHeader.SizeOfHeaders);\r
638\r
639 NewPeHdr = GetPeCoffHeader ((void *)XipFile);\r
640 if (NewPeHdr == NULL) {\r
641 free (XipFile);\r
642 return;\r
643 }\r
644\r
645 //\r
646 // Copy the section data over to the appropriate XIP offsets\r
647 //\r
648 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(NewPeHdr->Pe32.OptionalHeader) + NewPeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
649 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
650 if (SectionHeader->SizeOfRawData > 0) {\r
651 memcpy (\r
652 XipFile + SectionHeader->VirtualAddress,\r
653 *FileBuffer + SectionHeader->PointerToRawData,\r
654 SectionHeader->SizeOfRawData\r
655 );\r
656 }\r
b36d134f
LG
657 //\r
658 // Make the size of raw data in section header alignment.\r
659 //\r
660 SectionHeader->SizeOfRawData = (SectionHeader->Misc.VirtualSize + PeHdr->Pe32.OptionalHeader.FileAlignment - 1) & (~(PeHdr->Pe32.OptionalHeader.FileAlignment - 1));\r
a709adfa
LG
661 SectionHeader->PointerToRawData = SectionHeader->VirtualAddress;\r
662 }\r
663\r
664 free (*FileBuffer);\r
665 *FileLength = XipLength;\r
666 *FileBuffer = XipFile;\r
667}\r
668\r
669UINT8 *\r
670CreateHiiResouceSectionHeader (\r
671 UINT32 *pSectionHeaderSize, \r
672 UINT32 HiiDataSize\r
673 )\r
674/*++\r
675\r
676Routine Description:\r
677\r
678 Create COFF resource section header\r
679\r
680Arguments:\r
681\r
682 pSectionHeaderSize - Pointer to section header size.\r
683 HiiDataSize - Size of the total HII data in section.\r
684\r
685Returns:\r
686 The created section header buffer.\r
687\r
688--*/\r
689{\r
690 UINT32 HiiSectionHeaderSize;\r
691 UINT32 HiiSectionOffset;\r
692 UINT8 *HiiSectionHeader;\r
693 EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;\r
694 EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *TypeResourceDirectoryEntry;\r
695 EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *NameResourceDirectoryEntry;\r
696 EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LanguageResourceDirectoryEntry;\r
697 EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;\r
698 EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;\r
699\r
700 //\r
701 // Calculate the total size for the resource header (include Type, Name and Language)\r
702 // then allocate memory for the resource header.\r
703 //\r
704 HiiSectionHeaderSize = 3 * (sizeof (EFI_IMAGE_RESOURCE_DIRECTORY) + sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY)) \r
705 + 3 * (sizeof (UINT16) + 3 * sizeof (CHAR16)) \r
706 + sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
707 HiiSectionHeader = malloc (HiiSectionHeaderSize);\r
708 memset (HiiSectionHeader, 0, HiiSectionHeaderSize);\r
709\r
710 HiiSectionOffset = 0;\r
711 //\r
712 // Create Type entry \r
713 //\r
714 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
715 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
716 ResourceDirectory->NumberOfNamedEntries = 1;\r
717 TypeResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
718 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
719 TypeResourceDirectoryEntry->u1.s.NameIsString = 1;\r
720 TypeResourceDirectoryEntry->u2.s.DataIsDirectory = 1;\r
721 TypeResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
722 //\r
723 // Create Name entry\r
724 //\r
725 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
726 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
727 ResourceDirectory->NumberOfNamedEntries = 1;\r
728 NameResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
729 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
730 NameResourceDirectoryEntry->u1.s.NameIsString = 1;\r
731 NameResourceDirectoryEntry->u2.s.DataIsDirectory = 1;\r
732 NameResourceDirectoryEntry->u2.s.OffsetToDirectory = HiiSectionOffset;\r
733 //\r
734 // Create Language entry\r
735 //\r
736 ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (HiiSectionHeader + HiiSectionOffset);\r
737 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);\r
738 ResourceDirectory->NumberOfNamedEntries = 1;\r
739 LanguageResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
740 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY);\r
741 LanguageResourceDirectoryEntry->u1.s.NameIsString = 1;\r
742 //\r
743 // Create string entry for Type\r
744 //\r
745 TypeResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
746 ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
747 ResourceDirectoryString->Length = 3;\r
748 ResourceDirectoryString->String[0] = L'H';\r
749 ResourceDirectoryString->String[1] = L'I';\r
750 ResourceDirectoryString->String[2] = L'I';\r
751 HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
752 //\r
753 // Create string entry for Name\r
754 //\r
755 NameResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
756 ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
757 ResourceDirectoryString->Length = 3;\r
758 ResourceDirectoryString->String[0] = L'E';\r
759 ResourceDirectoryString->String[1] = L'F';\r
760 ResourceDirectoryString->String[2] = L'I';\r
761 HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
762 //\r
763 // Create string entry for Language\r
764 //\r
765 LanguageResourceDirectoryEntry->u1.s.NameOffset = HiiSectionOffset;\r
766 ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (HiiSectionHeader + HiiSectionOffset);\r
767 ResourceDirectoryString->Length = 3;\r
768 ResourceDirectoryString->String[0] = L'B';\r
769 ResourceDirectoryString->String[1] = L'I';\r
770 ResourceDirectoryString->String[2] = L'N';\r
771 HiiSectionOffset = HiiSectionOffset + sizeof (ResourceDirectoryString->Length) + ResourceDirectoryString->Length * sizeof (ResourceDirectoryString->String[0]);\r
772 //\r
773 // Create Leaf data\r
774 //\r
775 LanguageResourceDirectoryEntry->u2.OffsetToData = HiiSectionOffset;\r
776 ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (HiiSectionHeader + HiiSectionOffset);\r
777 HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DATA_ENTRY);\r
778 ResourceDataEntry->OffsetToData = HiiSectionOffset;\r
779 ResourceDataEntry->Size = HiiDataSize;\r
780\r
781 *pSectionHeaderSize = HiiSectionHeaderSize;\r
782 return HiiSectionHeader;\r
783}\r
784\r
52302d4d
LG
785EFI_STATUS\r
786RebaseImageRead (\r
787 IN VOID *FileHandle,\r
788 IN UINTN FileOffset,\r
789 IN OUT UINT32 *ReadSize,\r
790 OUT VOID *Buffer\r
791 )\r
792/*++\r
793\r
794Routine Description:\r
795\r
796 Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
797\r
798Arguments:\r
799\r
800 FileHandle - The handle to the PE/COFF file\r
801\r
802 FileOffset - The offset, in bytes, into the file to read\r
803\r
804 ReadSize - The number of bytes to read from the file starting at FileOffset\r
805\r
806 Buffer - A pointer to the buffer to read the data into.\r
807\r
808Returns:\r
809\r
810 EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
811\r
812--*/\r
813{\r
814 CHAR8 *Destination8;\r
815 CHAR8 *Source8;\r
816 UINT32 Length;\r
817\r
818 Destination8 = Buffer;\r
819 Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
820 Length = *ReadSize;\r
821 while (Length--) {\r
822 *(Destination8++) = *(Source8++);\r
823 }\r
824\r
825 return EFI_SUCCESS;\r
826}\r
827\r
828EFI_STATUS\r
829SetAddressToSectionHeader (\r
830 IN CHAR8 *FileName,\r
831 IN OUT UINT8 *FileBuffer,\r
832 IN UINT64 NewPe32BaseAddress\r
833 )\r
834/*++\r
835\r
836Routine Description:\r
837\r
838 Set new base address into the section header of PeImage\r
839\r
840Arguments:\r
841\r
842 FileName - Name of file\r
843 FileBuffer - Pointer to PeImage.\r
844 NewPe32BaseAddress - New Base Address for PE image.\r
845\r
846Returns:\r
847\r
848 EFI_SUCCESS Set new base address into this image successfully.\r
849\r
850--*/\r
851{\r
852 EFI_STATUS Status;\r
853 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
854 UINTN Index;\r
855 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
856 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
857\r
858 //\r
859 // Initialize context\r
860 //\r
861 memset (&ImageContext, 0, sizeof (ImageContext));\r
862 ImageContext.Handle = (VOID *) FileBuffer;\r
863 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
864 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
865 if (EFI_ERROR (Status)) {\r
866 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
867 return Status;\r
868 }\r
869\r
870 if (ImageContext.RelocationsStripped) {\r
871 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
872 return Status; \r
873 }\r
874\r
875 //\r
876 // Get PeHeader pointer\r
877 //\r
878 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
879\r
880 //\r
881 // Get section header list\r
882 //\r
883 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
884 (UINTN) ImgHdr +\r
885 sizeof (UINT32) + \r
886 sizeof (EFI_IMAGE_FILE_HEADER) + \r
887 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
888 );\r
889\r
890 //\r
891 // Set base address into the first section header that doesn't point to code section.\r
892 //\r
893 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
894 if ((SectionHeader->Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {\r
895 *(UINT64 *) &SectionHeader->PointerToRelocations = NewPe32BaseAddress;\r
896 break;\r
897 }\r
898 }\r
899\r
900 //\r
901 // No available section header is found.\r
902 //\r
903 if (Index == ImgHdr->Pe32.FileHeader.NumberOfSections) {\r
904 return EFI_NOT_FOUND;\r
905 }\r
906 \r
907 //\r
908 // BaseAddress is set to section header.\r
909 //\r
910 return EFI_SUCCESS;\r
911}\r
912\r
913EFI_STATUS\r
914RebaseImage (\r
915 IN CHAR8 *FileName,\r
916 IN OUT UINT8 *FileBuffer,\r
917 IN UINT64 NewPe32BaseAddress\r
918 )\r
919/*++\r
920\r
921Routine Description:\r
922\r
923 Set new base address into PeImage, and fix up PeImage based on new address.\r
924\r
925Arguments:\r
926\r
927 FileName - Name of file\r
928 FileBuffer - Pointer to PeImage.\r
929 NewPe32BaseAddress - New Base Address for PE image.\r
930\r
931Returns:\r
932\r
933 EFI_INVALID_PARAMETER - BaseAddress is not valid.\r
934 EFI_SUCCESS - Update PeImage is correctly.\r
935\r
936--*/\r
937{\r
938 EFI_STATUS Status;\r
939 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
940 UINTN Index;\r
941 EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;\r
942 UINT8 *MemoryImagePointer;\r
943 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
944\r
945 //\r
946 // Initialize context\r
947 //\r
948 memset (&ImageContext, 0, sizeof (ImageContext));\r
949 ImageContext.Handle = (VOID *) FileBuffer;\r
950 ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) RebaseImageRead;\r
951 Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
952 if (EFI_ERROR (Status)) {\r
953 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s is not valid", FileName);\r
954 return Status;\r
955 }\r
956\r
957 if (ImageContext.RelocationsStripped) {\r
958 Error (NULL, 0, 3000, "Invalid", "The input PeImage %s has no relocation to be fixed up", FileName);\r
959 return Status; \r
960 }\r
961\r
962 //\r
963 // Get PeHeader pointer\r
964 //\r
965 ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + ImageContext.PeCoffHeaderOffset);\r
966\r
967 //\r
968 // Load and Relocate Image Data\r
969 //\r
970 MemoryImagePointer = (UINT8 *) malloc ((UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
971 if (MemoryImagePointer == NULL) {\r
972 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated on rebase of %s", FileName);\r
973 return EFI_OUT_OF_RESOURCES;\r
974 }\r
975 memset ((VOID *) MemoryImagePointer, 0, (UINTN) ImageContext.ImageSize + ImageContext.SectionAlignment);\r
976 ImageContext.ImageAddress = ((UINTN) MemoryImagePointer + ImageContext.SectionAlignment - 1) & (~((INT64)ImageContext.SectionAlignment - 1));\r
977\r
978 Status = PeCoffLoaderLoadImage (&ImageContext);\r
979 if (EFI_ERROR (Status)) {\r
980 Error (NULL, 0, 3000, "Invalid", "LocateImage() call failed on rebase of %s", FileName);\r
981 free ((VOID *) MemoryImagePointer);\r
982 return Status;\r
983 }\r
984\r
985 ImageContext.DestinationAddress = NewPe32BaseAddress;\r
986 Status = PeCoffLoaderRelocateImage (&ImageContext);\r
987 if (EFI_ERROR (Status)) {\r
988 Error (NULL, 0, 3000, "Invalid", "RelocateImage() call failed on rebase of %s", FileName);\r
989 free ((VOID *) MemoryImagePointer);\r
990 return Status;\r
991 }\r
992\r
993 //\r
994 // Copy Relocated data to raw image file.\r
995 //\r
996 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (\r
997 (UINTN) ImgHdr +\r
998 sizeof (UINT32) + \r
999 sizeof (EFI_IMAGE_FILE_HEADER) + \r
1000 ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader\r
1001 );\r
1002\r
1003 for (Index = 0; Index < ImgHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
1004 CopyMem (\r
1005 FileBuffer + SectionHeader->PointerToRawData, \r
1006 (VOID*) (UINTN) (ImageContext.ImageAddress + SectionHeader->VirtualAddress), \r
1007 SectionHeader->SizeOfRawData\r
1008 );\r
1009 }\r
1010\r
1011 free ((VOID *) MemoryImagePointer);\r
1012\r
1013 //\r
1014 // Update Image Base Address\r
1015 //\r
1016 if ((ImgHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (ImgHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
1017 ImgHdr->Pe32.OptionalHeader.ImageBase = (UINT32) NewPe32BaseAddress;\r
1018 } else if (ImgHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
1019 ImgHdr->Pe32Plus.OptionalHeader.ImageBase = NewPe32BaseAddress;\r
1020 } else {\r
1021 Error (NULL, 0, 3000, "Invalid", "unknown PE magic signature %X in PE32 image %s",\r
1022 ImgHdr->Pe32.OptionalHeader.Magic,\r
1023 FileName\r
1024 );\r
1025 return EFI_ABORTED;\r
1026 }\r
1027\r
1028 //\r
1029 // Set new base address into section header\r
1030 //\r
1031 Status = SetAddressToSectionHeader (FileName, FileBuffer, NewPe32BaseAddress);\r
1032\r
1033 return Status;\r
1034}\r
1035\r
30fdf114
LG
1036int\r
1037main (\r
1038 int argc,\r
1039 char *argv[]\r
1040 )\r
1041/*++\r
1042\r
1043Routine Description:\r
1044\r
1045 Main function.\r
1046\r
1047Arguments:\r
1048\r
1049 argc - Number of command line parameters.\r
1050 argv - Array of pointers to command line parameter strings.\r
1051\r
1052Returns:\r
1053 STATUS_SUCCESS - Utility exits successfully.\r
1054 STATUS_ERROR - Some error occurred during execution.\r
1055\r
1056--*/\r
1057{\r
1058 UINT32 Type;\r
1059 UINT32 InputFileNum;\r
1060 CHAR8 **InputFileName;\r
1061 char *OutImageName;\r
1062 char *ModuleType;\r
1063 CHAR8 *TimeStamp;\r
30fdf114
LG
1064 FILE *fpIn;\r
1065 FILE *fpOut;\r
1066 FILE *fpInOut;\r
1067 UINT32 Data;\r
1068 UINT32 *DataPointer;\r
1069 UINT32 *OldDataPointer;\r
1070 UINT32 CheckSum;\r
1071 UINT32 Index;\r
1072 UINT32 Index1;\r
1073 UINT32 Index2;\r
1074 UINT64 Temp64;\r
1075 UINT32 MciAlignment;\r
1076 UINT8 MciPadValue;\r
1077 UINT32 AllignedRelocSize;\r
1078 UINT8 *FileBuffer;\r
1079 UINT32 FileLength;\r
1080 UINT8 *OutputFileBuffer;\r
1081 UINT32 OutputFileLength;\r
52302d4d
LG
1082 UINT8 *InputFileBuffer;\r
1083 UINT32 InputFileLength;\r
30fdf114
LG
1084 RUNTIME_FUNCTION *RuntimeFunction;\r
1085 UNWIND_INFO *UnwindInfo;\r
1086 STATUS Status;\r
1087 BOOLEAN ReplaceFlag;\r
1088 BOOLEAN KeepExceptionTableFlag;\r
1089 BOOLEAN KeepZeroPendingFlag;\r
1090 UINT64 LogLevel;\r
1091 EFI_TE_IMAGE_HEADER TEImageHeader;\r
1092 EFI_TE_IMAGE_HEADER *TeHdr;\r
1093 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
1094 EFI_IMAGE_DOS_HEADER *DosHdr;\r
1095 EFI_IMAGE_OPTIONAL_HEADER_UNION *PeHdr;\r
1096 EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;\r
1097 EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;\r
1098 EFI_IMAGE_DOS_HEADER BackupDosHdr;\r
1099 MICROCODE_IMAGE_HEADER *MciHeader;\r
b303ea72
LG
1100 UINT8 *HiiPackageListBuffer;\r
1101 UINT8 *HiiPackageDataPointer;\r
1102 EFI_GUID HiiPackageListGuid;\r
1103 EFI_HII_PACKAGE_LIST_HEADER HiiPackageListHeader;\r
1104 EFI_HII_PACKAGE_HEADER HiiPackageHeader;\r
1105 EFI_IFR_FORM_SET IfrFormSet;\r
1106 UINT8 NumberOfFormPacakge;\r
1107 EFI_HII_PACKAGE_HEADER EndPackage;\r
a709adfa
LG
1108 UINT32 HiiSectionHeaderSize;\r
1109 UINT8 *HiiSectionHeader;\r
52302d4d
LG
1110 UINT64 NewBaseAddress;\r
1111 BOOLEAN NegativeAddr;\r
1112 FILE *ReportFile;\r
1113 CHAR8 *ReportFileName;\r
1114 UINTN FileLen;\r
636f2be6
LG
1115 time_t InputFileTime;\r
1116 time_t OutputFileTime;\r
1117 struct stat Stat_Buf;\r
30fdf114
LG
1118\r
1119 SetUtilityName (UTILITY_NAME);\r
1120\r
1121 //\r
1122 // Assign to fix compile warning\r
1123 //\r
52302d4d 1124 FileLen = 0;\r
30fdf114
LG
1125 InputFileNum = 0;\r
1126 InputFileName = NULL;\r
1127 mInImageName = NULL;\r
1128 OutImageName = NULL;\r
1129 ModuleType = NULL;\r
30fdf114
LG
1130 Type = 0;\r
1131 Status = STATUS_SUCCESS;\r
1132 FileBuffer = NULL;\r
1133 fpIn = NULL;\r
1134 fpOut = NULL;\r
1135 fpInOut = NULL;\r
1136 TimeStamp = NULL;\r
1137 MciAlignment = DEFAULT_MC_ALIGNMENT;\r
1138 MciPadValue = DEFAULT_MC_PAD_BYTE_VALUE;\r
1139 FileLength = 0;\r
1140 MciHeader = NULL;\r
1141 CheckSum = 0;\r
1142 ReplaceFlag = FALSE;\r
1143 LogLevel = 0;\r
1144 OutputFileBuffer = NULL;\r
1145 OutputFileLength = 0;\r
52302d4d
LG
1146 InputFileBuffer = NULL;\r
1147 InputFileLength = 0;\r
30fdf114
LG
1148 Optional32 = NULL;\r
1149 Optional64 = NULL;\r
1150 KeepExceptionTableFlag = FALSE;\r
1151 KeepZeroPendingFlag = FALSE;\r
b303ea72
LG
1152 NumberOfFormPacakge = 0;\r
1153 HiiPackageListBuffer = NULL;\r
1154 HiiPackageDataPointer = NULL;\r
1155 EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);\r
1156 EndPackage.Type = EFI_HII_PACKAGE_END;\r
1157 memset (&HiiPackageListGuid, 0, sizeof (HiiPackageListGuid));\r
a709adfa
LG
1158 HiiSectionHeaderSize = 0;\r
1159 HiiSectionHeader = NULL;\r
52302d4d
LG
1160 NewBaseAddress = 0;\r
1161 NegativeAddr = FALSE;\r
636f2be6
LG
1162 InputFileTime = 0;\r
1163 OutputFileTime = 0;\r
30fdf114
LG
1164\r
1165 if (argc == 1) {\r
1166 Error (NULL, 0, 1001, "Missing options", "No input options.");\r
1167 Usage ();\r
1168 return STATUS_ERROR;\r
1169 }\r
1170\r
1171 argc --;\r
1172 argv ++;\r
1173\r
1174 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
1175 Version ();\r
1176 Usage ();\r
1177 return STATUS_SUCCESS;\r
1178 }\r
1179\r
1180 if (stricmp (argv[0], "--version") == 0) {\r
1181 Version ();\r
1182 return STATUS_SUCCESS;\r
1183 }\r
1184\r
1185 while (argc > 0) {\r
1186 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--outputfile") == 0)) {\r
1187 if (argv[1] == NULL || argv[1][0] == '-') {\r
1188 Error (NULL, 0, 1003, "Invalid option value", "Output file name is missing for -o option");\r
1189 goto Finish;\r
1190 }\r
1191 OutImageName = argv[1];\r
1192 argc -= 2;\r
1193 argv += 2;\r
1194 continue;\r
1195 }\r
1196\r
1197 if ((stricmp (argv[0], "-e") == 0) || (stricmp (argv[0], "--efiImage") == 0)) {\r
1198 if (argv[1] == NULL || argv[1][0] == '-') {\r
1199 Error (NULL, 0, 1003, "Invalid option value", "Module Type is missing for -o option");\r
1200 goto Finish;\r
1201 }\r
1202 ModuleType = argv[1];\r
da92f276
LG
1203 if (mOutImageType != FW_TE_IMAGE) {\r
1204 mOutImageType = FW_EFI_IMAGE;\r
30fdf114
LG
1205 }\r
1206 argc -= 2;\r
1207 argv += 2;\r
1208 continue;\r
1209 }\r
1210\r
1211 if ((stricmp (argv[0], "-l") == 0) || (stricmp (argv[0], "--stripped") == 0)) {\r
da92f276 1212 mOutImageType = FW_RELOC_STRIPEED_IMAGE;\r
30fdf114
LG
1213 argc --;\r
1214 argv ++;\r
1215 continue;\r
1216 }\r
1217\r
1218 if ((stricmp (argv[0], "-c") == 0) || (stricmp (argv[0], "--acpi") == 0)) {\r
da92f276 1219 mOutImageType = FW_ACPI_IMAGE;\r
30fdf114
LG
1220 argc --;\r
1221 argv ++;\r
1222 continue;\r
1223 }\r
1224\r
1225 if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--terse") == 0)) {\r
da92f276 1226 mOutImageType = FW_TE_IMAGE;\r
30fdf114
LG
1227 argc --;\r
1228 argv ++;\r
1229 continue;\r
1230 }\r
1231\r
1232 if ((stricmp (argv[0], "-u") == 0) || (stricmp (argv[0], "--dump") == 0)) {\r
da92f276 1233 mOutImageType = DUMP_TE_HEADER;\r
30fdf114
LG
1234 argc --;\r
1235 argv ++;\r
1236 continue;\r
1237 }\r
1238\r
1239 if ((stricmp (argv[0], "-b") == 0) || (stricmp (argv[0], "--exe2bin") == 0)) {\r
da92f276 1240 mOutImageType = FW_BIN_IMAGE;\r
30fdf114
LG
1241 argc --;\r
1242 argv ++;\r
1243 continue;\r
1244 }\r
1245\r
1246 if ((stricmp (argv[0], "-z") == 0) || (stricmp (argv[0], "--zero") == 0)) {\r
da92f276 1247 mOutImageType = FW_ZERO_DEBUG_IMAGE;\r
30fdf114
LG
1248 argc --;\r
1249 argv ++;\r
1250 continue;\r
1251 }\r
1252\r
1253 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--stamp") == 0)) {\r
da92f276 1254 mOutImageType = FW_SET_STAMP_IMAGE;\r
30fdf114
LG
1255 if (argv[1] == NULL || argv[1][0] == '-') {\r
1256 Error (NULL, 0, 1003, "Invalid option value", "time stamp is missing for -s option");\r
1257 goto Finish;\r
1258 }\r
1259 TimeStamp = argv[1];\r
1260 argc -= 2;\r
1261 argv += 2;\r
1262 continue;\r
1263 }\r
1264\r
1265 if ((stricmp (argv[0], "-r") == 0) || (stricmp (argv[0], "--replace") == 0)) {\r
1266 ReplaceFlag = TRUE;\r
1267 argc --;\r
1268 argv ++;\r
1269 continue;\r
1270 }\r
1271\r
1272 if (stricmp (argv[0], "--keepexceptiontable") == 0) {\r
1273 KeepExceptionTableFlag = TRUE;\r
1274 argc --;\r
1275 argv ++;\r
1276 continue;\r
1277 }\r
1278\r
1279 if (stricmp (argv[0], "--keepzeropending") == 0) {\r
1280 KeepZeroPendingFlag = TRUE;\r
1281 argc --;\r
1282 argv ++;\r
1283 continue;\r
1284 }\r
1285\r
1286 if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) {\r
da92f276 1287 mOutImageType = FW_MCI_IMAGE;\r
30fdf114
LG
1288 argc --;\r
1289 argv ++;\r
1290 continue;\r
1291 }\r
1292\r
1293 if ((stricmp (argv[0], "-j") == 0) || (stricmp (argv[0], "--join") == 0)) {\r
da92f276 1294 mOutImageType = FW_MERGE_IMAGE;\r
30fdf114
LG
1295 argc --;\r
1296 argv ++;\r
1297 continue;\r
1298 }\r
1299\r
1300 if ((stricmp (argv[0], "-a") == 0) || (stricmp (argv[0], "--align") == 0)) {\r
1301 if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {\r
1302 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1303 goto Finish;\r
1304 }\r
1305 MciAlignment = (UINT32) Temp64;\r
1306 argc -= 2;\r
1307 argv += 2;\r
1308 continue;\r
1309 }\r
1310\r
52302d4d
LG
1311 if ((stricmp (argv[0], "--rebase") == 0)) {\r
1312 if (argv[1][0] == '-') {\r
1313 NegativeAddr = TRUE;\r
1314 Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);\r
1315 } else {\r
1316 NegativeAddr = FALSE;\r
1317 Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);\r
1318 }\r
1319 if (Status != EFI_SUCCESS) {\r
1320 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1321 goto Finish;\r
1322 }\r
da92f276 1323 mOutImageType = FW_REBASE_IMAGE;\r
52302d4d
LG
1324 NewBaseAddress = (UINT64) Temp64;\r
1325 argc -= 2;\r
1326 argv += 2;\r
1327 continue;\r
1328 }\r
1329\r
1330 if ((stricmp (argv[0], "--address") == 0)) {\r
1331 if (argv[1][0] == '-') {\r
1332 NegativeAddr = TRUE;\r
1333 Status = AsciiStringToUint64 (argv[1] + 1, FALSE, &Temp64);\r
1334 } else {\r
1335 NegativeAddr = FALSE;\r
1336 Status = AsciiStringToUint64 (argv[1], FALSE, &Temp64);\r
1337 }\r
1338 if (Status != EFI_SUCCESS) {\r
1339 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1340 goto Finish;\r
1341 }\r
da92f276 1342 mOutImageType = FW_SET_ADDRESS_IMAGE;\r
52302d4d
LG
1343 NewBaseAddress = (UINT64) Temp64;\r
1344 argc -= 2;\r
1345 argv += 2;\r
1346 continue;\r
1347 }\r
1348\r
30fdf114
LG
1349 if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--pad") == 0)) {\r
1350 if (AsciiStringToUint64 (argv[1], FALSE, &Temp64) != EFI_SUCCESS) {\r
1351 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1352 goto Finish;\r
1353 }\r
1354 MciPadValue = (UINT8) Temp64;\r
1355 argc -= 2;\r
1356 argv += 2;\r
1357 continue;\r
1358 }\r
1359\r
1360 if ((stricmp (argv[0], "-v") == 0) || (stricmp (argv[0], "--verbose") == 0)) {\r
1361 SetPrintLevel (VERBOSE_LOG_LEVEL);\r
1362 VerboseMsg ("Verbose output Mode Set!");\r
1363 argc --;\r
1364 argv ++;\r
1365 continue;\r
1366 }\r
1367\r
1368 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
1369 SetPrintLevel (KEY_LOG_LEVEL);\r
1370 KeyMsg ("Quiet output Mode Set!");\r
1371 argc --;\r
1372 argv ++;\r
1373 continue;\r
1374 }\r
1375\r
1376 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
1377 Status = AsciiStringToUint64 (argv[1], FALSE, &LogLevel);\r
1378 if (EFI_ERROR (Status)) {\r
1379 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1380 goto Finish;\r
1381 }\r
1382 if (LogLevel > 9) {\r
fd171542 1383 Error (NULL, 0, 1003, "Invalid option value", "Debug Level range is 0-9, currnt input level is %d", (int) LogLevel);\r
30fdf114
LG
1384 goto Finish;\r
1385 }\r
1386 SetPrintLevel (LogLevel);\r
1387 DebugMsg (NULL, 0, 9, "Debug Mode Set", "Debug Output Mode Level %s is set!", argv[1]);\r
1388 argc -= 2;\r
1389 argv += 2;\r
1390 continue;\r
1391 }\r
52302d4d 1392\r
b303ea72
LG
1393 if ((stricmp (argv[0], "-g") == 0) || (stricmp (argv[0], "--hiiguid") == 0)) {\r
1394 Status = StringToGuid (argv[1], &HiiPackageListGuid);\r
1395 if (EFI_ERROR (Status)) {\r
1396 Error (NULL, 0, 1003, "Invalid option value", "%s = %s", argv[0], argv[1]);\r
1397 goto Finish;\r
1398 }\r
1399 argc -= 2;\r
1400 argv += 2;\r
1401 continue;\r
1402 }\r
1403\r
1404 if (stricmp (argv[0], "--hiipackage") == 0) {\r
da92f276 1405 mOutImageType = FW_HII_PACKAGE_LIST_RCIMAGE;\r
b303ea72
LG
1406 argc --;\r
1407 argv ++;\r
1408 continue;\r
1409 }\r
1410\r
a709adfa 1411 if (stricmp (argv[0], "--hiibinpackage") == 0) {\r
da92f276 1412 mOutImageType = FW_HII_PACKAGE_LIST_BINIMAGE;\r
a709adfa
LG
1413 argc --;\r
1414 argv ++;\r
1415 continue;\r
1416 }\r
1417\r
30fdf114
LG
1418 if (argv[0][0] == '-') {\r
1419 Error (NULL, 0, 1000, "Unknown option", argv[0]);\r
1420 goto Finish;\r
1421 }\r
1422 //\r
1423 // Get Input file name\r
1424 //\r
1425 if ((InputFileNum == 0) && (InputFileName == NULL)) {\r
1426 InputFileName = (CHAR8 **) malloc (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *));\r
1427 if (InputFileName == NULL) {\r
1428 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
fd171542 1429 goto Finish;\r
30fdf114
LG
1430 }\r
1431\r
1432 memset (InputFileName, 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
1433 } else if (InputFileNum % MAXIMUM_INPUT_FILE_NUM == 0) {\r
1434 //\r
1435 // InputFileName buffer too small, need to realloc\r
1436 //\r
1437 InputFileName = (CHAR8 **) realloc (\r
52302d4d
LG
1438 InputFileName,\r
1439 (InputFileNum + MAXIMUM_INPUT_FILE_NUM) * sizeof (CHAR8 *)\r
1440 );\r
30fdf114
LG
1441\r
1442 if (InputFileName == NULL) {\r
1443 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
fd171542 1444 goto Finish;\r
30fdf114
LG
1445 }\r
1446\r
1447 memset (&(InputFileName[InputFileNum]), 0, (MAXIMUM_INPUT_FILE_NUM * sizeof (CHAR8 *)));\r
1448 }\r
1449\r
1450 InputFileName [InputFileNum ++] = argv[0];\r
1451 argc --;\r
1452 argv ++;\r
1453 }\r
1454\r
1455 VerboseMsg ("%s tool start.", UTILITY_NAME);\r
1456\r
da92f276 1457 if (mOutImageType == FW_DUMMY_IMAGE) {\r
30fdf114
LG
1458 Error (NULL, 0, 1001, "Missing option", "No create file action specified; pls specify -e, -c or -t option to create efi image, or acpi table or TeImage!");\r
1459 if (ReplaceFlag) {\r
1460 Error (NULL, 0, 1001, "Missing option", "-r option is not supported as the independent option. It can be used together with other create file option specified at the above.");\r
1461 }\r
1462 goto Finish;\r
1463 }\r
1464\r
1465 //\r
1466 // check input files\r
1467 //\r
1468 if (InputFileNum == 0) {\r
1469 Error (NULL, 0, 1001, "Missing option", "Input files");\r
1470 goto Finish;\r
1471 }\r
1472\r
1473 //\r
1474 // Combine MciBinary files to one file\r
1475 //\r
da92f276 1476 if ((mOutImageType == FW_MERGE_IMAGE) && ReplaceFlag) {\r
30fdf114
LG
1477 Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with -j merge files option.");\r
1478 goto Finish;\r
1479 }\r
1480\r
b303ea72
LG
1481 //\r
1482 // Combine HiiBinary packages to a single package list\r
1483 //\r
da92f276 1484 if ((mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) && ReplaceFlag) {\r
b303ea72
LG
1485 Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiipackage merge files option.");\r
1486 goto Finish;\r
1487 }\r
1488\r
da92f276 1489 if ((mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) && ReplaceFlag) {\r
a709adfa
LG
1490 Error (NULL, 0, 1002, "Conflicting option", "-r replace option cannot be used with --hiibinpackage merge files option.");\r
1491 goto Finish;\r
1492 }\r
1493\r
30fdf114
LG
1494 //\r
1495 // Input image file\r
1496 //\r
1497 mInImageName = InputFileName [InputFileNum - 1];\r
1498 VerboseMsg ("the input file name is %s", mInImageName);\r
1499\r
1500 //\r
1501 // Action will be taken for the input file.\r
1502 //\r
da92f276 1503 switch (mOutImageType) {\r
30fdf114
LG
1504 case FW_EFI_IMAGE:\r
1505 VerboseMsg ("Create efi image on module type %s based on the input PE image.", ModuleType);\r
1506 break;\r
1507 case FW_TE_IMAGE:\r
1508 VerboseMsg ("Create Te Image based on the input PE image.");\r
1509 break;\r
1510 case FW_ACPI_IMAGE:\r
1511 VerboseMsg ("Get acpi table data from the input PE image.");\r
1512 break;\r
1513 case FW_RELOC_STRIPEED_IMAGE:\r
1514 VerboseMsg ("Remove relocation section from Pe or Te image.");\r
1515 break;\r
1516 case FW_BIN_IMAGE:\r
1517 VerboseMsg ("Convert the input EXE to the output BIN file.");\r
1518 break;\r
1519 case FW_ZERO_DEBUG_IMAGE:\r
1520 VerboseMsg ("Zero the Debug Data Fields and Time Stamp in input PE image.");\r
1521 break;\r
1522 case FW_SET_STAMP_IMAGE:\r
1523 VerboseMsg ("Set new time stamp %s in the input PE image.", TimeStamp);\r
1524 break;\r
1525 case DUMP_TE_HEADER:\r
1526 VerboseMsg ("Dump the TE header information of the input TE image.");\r
1527 break;\r
1528 case FW_MCI_IMAGE:\r
1529 VerboseMsg ("Conver input MicroCode.txt file to MicroCode.bin file.");\r
1530 break;\r
1531 case FW_MERGE_IMAGE:\r
1532 VerboseMsg ("Combine the input multi microcode bin files to one bin file.");\r
1533 break;\r
b303ea72
LG
1534 case FW_HII_PACKAGE_LIST_RCIMAGE:\r
1535 VerboseMsg ("Combine the input multi hii bin packages to one text pacakge list RC file.");\r
1536 break;\r
a709adfa
LG
1537 case FW_HII_PACKAGE_LIST_BINIMAGE:\r
1538 VerboseMsg ("Combine the input multi hii bin packages to one binary pacakge list file.");\r
1539 break;\r
52302d4d
LG
1540 case FW_REBASE_IMAGE:\r
1541 VerboseMsg ("Rebase the input image to new base address.");\r
1542 break;\r
1543 case FW_SET_ADDRESS_IMAGE:\r
1544 VerboseMsg ("Set the preferred address into the section header of the input image");\r
1545 break;\r
30fdf114
LG
1546 default:\r
1547 break;\r
1548 }\r
1549\r
1550 if (ReplaceFlag) {\r
1551 VerboseMsg ("Overwrite the input file with the output content.");\r
1552 }\r
1553\r
1554 //\r
1555 // Open output file and Write image into the output file.\r
1556 //\r
1557 if (OutImageName != NULL) {\r
1be2ed90 1558 fpOut = fopen (LongFilePath (OutImageName), "rb");\r
30fdf114 1559 if (fpOut != NULL) {\r
636f2be6
LG
1560 //\r
1561 // Get Output file time stamp\r
1562 //\r
1563 fstat(fileno (fpOut), &Stat_Buf);\r
1564 OutputFileTime = Stat_Buf.st_mtime;\r
1565 //\r
1566 // Get Output file data\r
1567 //\r
30fdf114
LG
1568 OutputFileLength = _filelength (fileno (fpOut));\r
1569 OutputFileBuffer = malloc (OutputFileLength);\r
1570 if (OutputFileBuffer == NULL) {\r
1571 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1572 fclose (fpOut);\r
1573 fpOut = NULL;\r
1574 goto Finish;\r
1575 }\r
1576 fread (OutputFileBuffer, 1, OutputFileLength, fpOut);\r
1577 fclose (fpOut);\r
52302d4d 1578 fpOut = NULL;\r
30fdf114
LG
1579 }\r
1580 VerboseMsg ("Output file name is %s", OutImageName);\r
da92f276 1581 } else if (!ReplaceFlag && mOutImageType != DUMP_TE_HEADER) {\r
52302d4d
LG
1582 Error (NULL, 0, 1001, "Missing option", "output file");\r
1583 goto Finish;\r
30fdf114
LG
1584 }\r
1585\r
52302d4d
LG
1586 //\r
1587 // Open input file and read file data into file buffer.\r
1588 //\r
1be2ed90 1589 fpIn = fopen (LongFilePath (mInImageName), "rb");\r
52302d4d
LG
1590 if (fpIn == NULL) {\r
1591 Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
1592 goto Finish;\r
1593 }\r
636f2be6
LG
1594 //\r
1595 // Get Iutput file time stamp\r
1596 //\r
1597 fstat(fileno (fpIn), &Stat_Buf);\r
1598 InputFileTime = Stat_Buf.st_mtime;\r
1599 //\r
1600 // Get Input file data\r
1601 //\r
52302d4d
LG
1602 InputFileLength = _filelength (fileno (fpIn));\r
1603 InputFileBuffer = malloc (InputFileLength);\r
1604 if (InputFileBuffer == NULL) {\r
1605 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1606 fclose (fpIn);\r
1607 goto Finish;\r
1608 }\r
1609 fread (InputFileBuffer, 1, InputFileLength, fpIn);\r
1610 fclose (fpIn);\r
1611 DebugMsg (NULL, 0, 9, "input file info", "the input file size is %u bytes", (unsigned) InputFileLength);\r
1612\r
b303ea72 1613 //\r
a709adfa 1614 // Combine multi binary HII package files.\r
b303ea72 1615 //\r
da92f276 1616 if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE || mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
52302d4d
LG
1617 //\r
1618 // Open output file handle.\r
1619 //\r
1be2ed90 1620 fpOut = fopen (LongFilePath (OutImageName), "wb");\r
52302d4d
LG
1621 if (!fpOut) {\r
1622 Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
1623 goto Finish;\r
1624 }\r
b303ea72
LG
1625 //\r
1626 // Get hii package list lenght\r
1627 //\r
1628 HiiPackageListHeader.PackageLength = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
1629 for (Index = 0; Index < InputFileNum; Index ++) {\r
1be2ed90 1630 fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
52302d4d 1631 if (fpIn == NULL) {\r
b303ea72
LG
1632 Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
1633 goto Finish;\r
1634 }\r
1635 FileLength = _filelength (fileno (fpIn));\r
1636 fread (&HiiPackageHeader, 1, sizeof (HiiPackageHeader), fpIn);\r
1637 if (HiiPackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
1638 if (HiiPackageHeader.Length != FileLength) {\r
1639 Error (NULL, 0, 3000, "Invalid", "The wrong package size is in HII package file %s", InputFileName [Index]);\r
1640 fclose (fpIn);\r
1641 goto Finish;\r
1642 }\r
1643 if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {\r
1644 fread (&IfrFormSet, 1, sizeof (IfrFormSet), fpIn);\r
1645 memcpy (&HiiPackageListGuid, &IfrFormSet.Guid, sizeof (EFI_GUID));\r
1646 }\r
1647 NumberOfFormPacakge ++;\r
1648 }\r
1649 HiiPackageListHeader.PackageLength += FileLength;\r
1650 fclose (fpIn);\r
1651 }\r
1652 HiiPackageListHeader.PackageLength += sizeof (EndPackage);\r
1653 //\r
1654 // Check whether hii packages are valid\r
1655 //\r
1656 if (NumberOfFormPacakge > 1) {\r
1657 Error (NULL, 0, 3000, "Invalid", "The input hii packages contains more than one hii form package");\r
1658 goto Finish;\r
1659 }\r
1660 if (memcmp (&HiiPackageListGuid, &mZeroGuid, sizeof (EFI_GUID)) == 0) {\r
1661 Error (NULL, 0, 3000, "Invalid", "HII pacakge list guid is not specified!");\r
1662 goto Finish;\r
1663 }\r
1664 memcpy (&HiiPackageListHeader.PackageListGuid, &HiiPackageListGuid, sizeof (EFI_GUID));\r
1665 //\r
1666 // read hii packages\r
1667 //\r
1668 HiiPackageListBuffer = malloc (HiiPackageListHeader.PackageLength);\r
1669 if (HiiPackageListBuffer == NULL) {\r
1670 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1671 goto Finish;\r
1672 }\r
1673 memcpy (HiiPackageListBuffer, &HiiPackageListHeader, sizeof (HiiPackageListHeader));\r
1674 HiiPackageDataPointer = HiiPackageListBuffer + sizeof (HiiPackageListHeader);\r
1675 for (Index = 0; Index < InputFileNum; Index ++) {\r
1be2ed90 1676 fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
52302d4d 1677 if (fpIn == NULL) {\r
b303ea72
LG
1678 Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
1679 free (HiiPackageListBuffer);\r
1680 goto Finish;\r
1681 }\r
1682\r
1683 FileLength = _filelength (fileno (fpIn));\r
1684 fread (HiiPackageDataPointer, 1, FileLength, fpIn);\r
1685 fclose (fpIn);\r
1686 HiiPackageDataPointer = HiiPackageDataPointer + FileLength;\r
1687 }\r
1688 memcpy (HiiPackageDataPointer, &EndPackage, sizeof (EndPackage));\r
a709adfa 1689\r
b303ea72 1690 //\r
a709adfa 1691 // write the hii package into the binary package list file with the resource section header\r
b303ea72 1692 //\r
da92f276 1693 if (mOutImageType == FW_HII_PACKAGE_LIST_BINIMAGE) {\r
a709adfa
LG
1694 //\r
1695 // Create the resource section header\r
1696 //\r
1697 HiiSectionHeader = CreateHiiResouceSectionHeader (&HiiSectionHeaderSize, HiiPackageListHeader.PackageLength);\r
1698 //\r
1699 // Wrtie section header and HiiData into File.\r
1700 //\r
1701 fwrite (HiiSectionHeader, 1, HiiSectionHeaderSize, fpOut);\r
1702 fwrite (HiiPackageListBuffer, 1, HiiPackageListHeader.PackageLength, fpOut);\r
1703 //\r
1704 // Free allocated resources.\r
1705 //\r
1706 free (HiiSectionHeader);\r
1707 free (HiiPackageListBuffer);\r
1708 //\r
1709 // Done successfully\r
1710 //\r
1711 goto Finish;\r
b303ea72 1712 }\r
b303ea72 1713\r
a709adfa
LG
1714 //\r
1715 // write the hii package into the text package list rc file.\r
1716 //\r
da92f276 1717 if (mOutImageType == FW_HII_PACKAGE_LIST_RCIMAGE) {\r
a709adfa
LG
1718 for (Index = 0; gHiiPackageRCFileHeader[Index] != NULL; Index++) {\r
1719 fprintf (fpOut, "%s\n", gHiiPackageRCFileHeader[Index]);\r
1720 }\r
1721 fprintf (fpOut, "\n%d %s\n{", HII_RESOURCE_SECTION_INDEX, HII_RESOURCE_SECTION_NAME);\r
1722\r
1723 HiiPackageDataPointer = HiiPackageListBuffer;\r
1724 for (Index = 0; Index + 2 < HiiPackageListHeader.PackageLength; Index += 2) {\r
1725 if (Index % 16 == 0) {\r
1726 fprintf (fpOut, "\n ");\r
1727 }\r
1728 fprintf (fpOut, " 0x%04X,", *(UINT16 *) HiiPackageDataPointer);\r
1729 HiiPackageDataPointer += 2;\r
1730 }\r
52302d4d 1731\r
b303ea72
LG
1732 if (Index % 16 == 0) {\r
1733 fprintf (fpOut, "\n ");\r
1734 }\r
a709adfa
LG
1735 if ((Index + 2) == HiiPackageListHeader.PackageLength) {\r
1736 fprintf (fpOut, " 0x%04X\n}\n", *(UINT16 *) HiiPackageDataPointer);\r
1737 }\r
1738 if ((Index + 1) == HiiPackageListHeader.PackageLength) {\r
1739 fprintf (fpOut, " 0x%04X\n}\n", *(UINT8 *) HiiPackageDataPointer);\r
1740 }\r
1741 free (HiiPackageListBuffer);\r
1742 //\r
1743 // Done successfully\r
1744 //\r
1745 goto Finish;\r
b303ea72 1746 }\r
b303ea72
LG
1747 }\r
1748\r
30fdf114
LG
1749 //\r
1750 // Combine MciBinary files to one file\r
1751 //\r
da92f276 1752 if (mOutImageType == FW_MERGE_IMAGE) {\r
52302d4d
LG
1753 //\r
1754 // Open output file handle.\r
1755 //\r
1be2ed90 1756 fpOut = fopen (LongFilePath (OutImageName), "wb");\r
52302d4d
LG
1757 if (!fpOut) {\r
1758 Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
1759 goto Finish;\r
1760 }\r
30fdf114 1761 for (Index = 0; Index < InputFileNum; Index ++) {\r
1be2ed90 1762 fpIn = fopen (LongFilePath (InputFileName [Index]), "rb");\r
30fdf114
LG
1763 if (!fpIn) {\r
1764 Error (NULL, 0, 0001, "Error opening file", InputFileName [Index]);\r
1765 goto Finish;\r
1766 }\r
1767\r
1768 FileLength = _filelength (fileno (fpIn));\r
1769 FileBuffer = malloc (FileLength);\r
1770 if (FileBuffer == NULL) {\r
1771 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1772 fclose (fpIn);\r
1773 goto Finish;\r
1774 }\r
1775\r
1776 fread (FileBuffer, 1, FileLength, fpIn);\r
1777 fclose (fpIn);\r
1778 //\r
1779 // write input file to out file\r
1780 //\r
1781 fwrite (FileBuffer, 1, FileLength, fpOut);\r
1782 //\r
1783 // write pad value to out file.\r
1784 //\r
1785 while (FileLength ++ % MciAlignment != 0) {\r
1786 fwrite (&MciPadValue, 1, 1, fpOut);\r
1787 }\r
1788 //\r
1789 // free allocated memory space\r
1790 //\r
1791 free (FileBuffer);\r
1792 FileBuffer = NULL;\r
1793 }\r
1794 //\r
1795 // Done successfully\r
1796 //\r
1797 goto Finish;\r
1798 }\r
1799\r
1800 //\r
1801 // Convert MicroCode.txt file to MicroCode.bin file\r
1802 //\r
da92f276 1803 if (mOutImageType == FW_MCI_IMAGE) {\r
1be2ed90 1804 fpIn = fopen (LongFilePath (mInImageName), "r");\r
52302d4d 1805 if (fpIn == NULL) {\r
30fdf114
LG
1806 Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
1807 goto Finish;\r
1808 }\r
1809\r
1810 //\r
1811 // The first pass is to determine\r
1812 // how much data is in the file so we can allocate a working buffer.\r
1813 //\r
1814 FileLength = 0;\r
1815 do {\r
1816 Status = MicrocodeReadData (fpIn, &Data);\r
1817 if (Status == STATUS_SUCCESS) {\r
1818 FileLength += sizeof (Data);\r
1819 }\r
1820 if (Status == STATUS_IGNORE) {\r
1821 Status = STATUS_SUCCESS;\r
1822 }\r
1823 } while (Status == STATUS_SUCCESS);\r
1824 //\r
1825 // Error if no data.\r
1826 //\r
1827 if (FileLength == 0) {\r
1828 Error (NULL, 0, 3000, "Invalid", "no parseable data found in file %s", mInImageName);\r
1829 goto Finish;\r
1830 }\r
1831 if (FileLength < sizeof (MICROCODE_IMAGE_HEADER)) {\r
1832 Error (NULL, 0, 3000, "Invalid", "amount of parseable data in %s is insufficient to contain a microcode header", mInImageName);\r
1833 goto Finish;\r
1834 }\r
1835\r
1836 //\r
1837 // Allocate a buffer for the data\r
1838 //\r
1839 FileBuffer = malloc (FileLength);\r
1840 if (FileBuffer == NULL) {\r
1841 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
1842 goto Finish;\r
1843 }\r
1844 //\r
1845 // Re-read the file, storing the data into our buffer\r
1846 //\r
1847 fseek (fpIn, 0, SEEK_SET);\r
1848 DataPointer = (UINT32 *) FileBuffer;\r
1849 OldDataPointer = DataPointer;\r
1850 do {\r
1851 OldDataPointer = DataPointer;\r
1852 Status = MicrocodeReadData (fpIn, DataPointer++);\r
1853 if (Status == STATUS_IGNORE) {\r
1854 DataPointer = OldDataPointer;\r
1855 Status = STATUS_SUCCESS;\r
1856 }\r
1857 } while (Status == STATUS_SUCCESS);\r
1858 //\r
1859 // close input file after read data\r
1860 //\r
1861 fclose (fpIn);\r
1862\r
1863 //\r
1864 // Can't do much checking on the header because, per the spec, the\r
1865 // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,\r
1866 // and the TotalSize field is invalid (actually missing). Thus we can't\r
1867 // even verify the Reserved fields are 0.\r
1868 //\r
1869 MciHeader = (MICROCODE_IMAGE_HEADER *) FileBuffer;\r
1870 if (MciHeader->DataSize == 0) {\r
1871 Index = 2048;\r
1872 } else {\r
1873 Index = MciHeader->TotalSize;\r
1874 }\r
1875\r
1876 if (Index != FileLength) {\r
fd171542 1877 Error (NULL, 0, 3000, "Invalid", "file length of %s (0x%x) does not equal expected TotalSize: 0x%04X.", mInImageName, (unsigned) FileLength, (unsigned) Index);\r
30fdf114
LG
1878 goto Finish;\r
1879 }\r
1880\r
1881 //\r
1882 // Checksum the contents\r
1883 //\r
1884 DataPointer = (UINT32 *) FileBuffer;\r
1885 CheckSum = 0;\r
1886 Index = 0;\r
1887 while (Index < FileLength) {\r
1888 CheckSum += *DataPointer;\r
1889 DataPointer ++;\r
1890 Index += sizeof (*DataPointer);\r
1891 }\r
1892 if (CheckSum != 0) {\r
fd171542 1893 Error (NULL, 0, 3000, "Invalid", "checksum (0x%x) failed on file %s.", (unsigned) CheckSum, mInImageName);\r
30fdf114
LG
1894 goto Finish;\r
1895 }\r
1896 //\r
1897 // Open the output file and write the buffer contents\r
1898 //\r
fd171542 1899 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
52302d4d 1900 goto WriteFile;\r
30fdf114
LG
1901 }\r
1902\r
1903 //\r
1904 // Open input file and read file data into file buffer.\r
1905 //\r
52302d4d 1906 FileLength = InputFileLength;\r
30fdf114
LG
1907 FileBuffer = malloc (FileLength);\r
1908 if (FileBuffer == NULL) {\r
1909 Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
30fdf114
LG
1910 goto Finish;\r
1911 }\r
52302d4d 1912 memcpy (FileBuffer, InputFileBuffer, InputFileLength);\r
30fdf114 1913\r
30fdf114
LG
1914 //\r
1915 // Dump TeImage Header into output file.\r
1916 //\r
da92f276 1917 if (mOutImageType == DUMP_TE_HEADER) {\r
30fdf114
LG
1918 memcpy (&TEImageHeader, FileBuffer, sizeof (TEImageHeader));\r
1919 if (TEImageHeader.Signature != EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
1920 Error (NULL, 0, 3000, "Invalid", "TE header signature of file %s is not correct.", mInImageName);\r
1921 goto Finish;\r
1922 }\r
52302d4d
LG
1923 //\r
1924 // Open the output file handle.\r
1925 //\r
1926 if (ReplaceFlag) {\r
1be2ed90 1927 fpInOut = fopen (LongFilePath (mInImageName), "wb");\r
52302d4d
LG
1928 if (fpInOut == NULL) {\r
1929 Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
1930 goto Finish;\r
1931 }\r
1932 } else {\r
1933 if (OutImageName != NULL) {\r
1be2ed90 1934 fpOut = fopen (LongFilePath (OutImageName), "wb");\r
52302d4d
LG
1935 } else {\r
1936 fpOut = stdout;\r
1937 }\r
1938 if (fpOut == NULL) {\r
1939 Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
1940 goto Finish;\r
1941 }\r
1942 }\r
30fdf114
LG
1943 if (fpInOut != NULL) {\r
1944 fprintf (fpInOut, "Dump of file %s\n\n", mInImageName);\r
1945 fprintf (fpInOut, "TE IMAGE HEADER VALUES\n");\r
1946 fprintf (fpInOut, "%17X machine\n", TEImageHeader.Machine);\r
1947 fprintf (fpInOut, "%17X number of sections\n", TEImageHeader.NumberOfSections);\r
1948 fprintf (fpInOut, "%17X subsystems\n", TEImageHeader.Subsystem);\r
1949 fprintf (fpInOut, "%17X stripped size\n", TEImageHeader.StrippedSize);\r
fd171542 1950 fprintf (fpInOut, "%17X entry point\n", (unsigned) TEImageHeader.AddressOfEntryPoint);\r
1951 fprintf (fpInOut, "%17X base of code\n", (unsigned) TEImageHeader.BaseOfCode);\r
1952 fprintf (fpInOut, "%17llX image base\n", (unsigned long long)TEImageHeader.ImageBase);\r
1953 fprintf (fpInOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);\r
1954 fprintf (fpInOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);\r
30fdf114 1955 }\r
30fdf114
LG
1956 if (fpOut != NULL) {\r
1957 fprintf (fpOut, "Dump of file %s\n\n", mInImageName);\r
1958 fprintf (fpOut, "TE IMAGE HEADER VALUES\n");\r
1959 fprintf (fpOut, "%17X machine\n", TEImageHeader.Machine);\r
1960 fprintf (fpOut, "%17X number of sections\n", TEImageHeader.NumberOfSections);\r
1961 fprintf (fpOut, "%17X subsystems\n", TEImageHeader.Subsystem);\r
1962 fprintf (fpOut, "%17X stripped size\n", TEImageHeader.StrippedSize);\r
fd171542 1963 fprintf (fpOut, "%17X entry point\n", (unsigned) TEImageHeader.AddressOfEntryPoint);\r
1964 fprintf (fpOut, "%17X base of code\n", (unsigned) TEImageHeader.BaseOfCode);\r
1965 fprintf (fpOut, "%17llX image base\n", (unsigned long long)TEImageHeader.ImageBase);\r
1966 fprintf (fpOut, "%17X [%8X] RVA [size] of Base Relocation Directory\n", (unsigned) TEImageHeader.DataDirectory[0].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[0].Size);\r
1967 fprintf (fpOut, "%17X [%8X] RVA [size] of Debug Directory\n", (unsigned) TEImageHeader.DataDirectory[1].VirtualAddress, (unsigned) TEImageHeader.DataDirectory[1].Size);\r
30fdf114
LG
1968 }\r
1969 goto Finish;\r
1970 }\r
1971\r
1972 //\r
1973 // Following code to convert dll to efi image or te image.\r
1974 // Get new image type\r
1975 //\r
da92f276 1976 if ((mOutImageType == FW_EFI_IMAGE) || (mOutImageType == FW_TE_IMAGE)) {\r
30fdf114 1977 if (ModuleType == NULL) {\r
da92f276 1978 if (mOutImageType == FW_EFI_IMAGE) {\r
30fdf114
LG
1979 Error (NULL, 0, 1001, "Missing option", "EFI_FILETYPE");\r
1980 goto Finish;\r
da92f276 1981 } else if (mOutImageType == FW_TE_IMAGE) {\r
30fdf114
LG
1982 //\r
1983 // Default TE Image Type is Boot service driver\r
1984 //\r
1985 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
1986 VerboseMsg ("Efi Image subsystem type is efi boot service driver.");\r
1987 }\r
1988 } else {\r
1989 if (stricmp (ModuleType, "BASE") == 0 ||\r
52302d4d
LG
1990 stricmp (ModuleType, "SEC") == 0 ||\r
1991 stricmp (ModuleType, "SECURITY_CORE") == 0 ||\r
1992 stricmp (ModuleType, "PEI_CORE") == 0 ||\r
1993 stricmp (ModuleType, "PEIM") == 0 ||\r
1994 stricmp (ModuleType, "COMBINED_PEIM_DRIVER") == 0 ||\r
1995 stricmp (ModuleType, "PIC_PEIM") == 0 ||\r
1996 stricmp (ModuleType, "RELOCATABLE_PEIM") == 0 ||\r
1997 stricmp (ModuleType, "DXE_CORE") == 0 ||\r
1998 stricmp (ModuleType, "BS_DRIVER") == 0 ||\r
1999 stricmp (ModuleType, "DXE_DRIVER") == 0 ||\r
2000 stricmp (ModuleType, "DXE_SMM_DRIVER") == 0 ||\r
2001 stricmp (ModuleType, "UEFI_DRIVER") == 0 ||\r
2002 stricmp (ModuleType, "SMM_CORE") == 0) {\r
2003 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
2004 VerboseMsg ("Efi Image subsystem type is efi boot service driver.");\r
30fdf114
LG
2005\r
2006 } else if (stricmp (ModuleType, "UEFI_APPLICATION") == 0 ||\r
52302d4d
LG
2007 stricmp (ModuleType, "APPLICATION") == 0) {\r
2008 Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
2009 VerboseMsg ("Efi Image subsystem type is efi application.");\r
30fdf114
LG
2010\r
2011 } else if (stricmp (ModuleType, "DXE_RUNTIME_DRIVER") == 0 ||\r
52302d4d
LG
2012 stricmp (ModuleType, "RT_DRIVER") == 0) {\r
2013 Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
2014 VerboseMsg ("Efi Image subsystem type is efi runtime driver.");\r
30fdf114
LG
2015\r
2016 } else if (stricmp (ModuleType, "DXE_SAL_DRIVER") == 0 ||\r
52302d4d
LG
2017 stricmp (ModuleType, "SAL_RT_DRIVER") == 0) {\r
2018 Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
2019 VerboseMsg ("Efi Image subsystem type is efi sal runtime driver.");\r
30fdf114
LG
2020\r
2021 } else {\r
2022 Error (NULL, 0, 1003, "Invalid option value", "EFI_FILETYPE = %s", ModuleType);\r
2023 goto Finish;\r
2024 }\r
2025 }\r
2026 }\r
2027\r
2028 //\r
da92f276 2029 // Convert ELF image to PeImage\r
30fdf114
LG
2030 //\r
2031 if (IsElfHeader(FileBuffer)) {\r
40d841f6
LG
2032 VerboseMsg ("Convert %s from ELF to PE/COFF.", mInImageName);\r
2033 if (!ConvertElf(&FileBuffer, &FileLength)) {\r
2034 Error (NULL, 0, 3000, "Invalid", "Unable to convert %s from ELF to PE/COFF.", mInImageName);\r
2035 goto Finish;\r
2036 }\r
30fdf114 2037 }\r
52302d4d 2038\r
a709adfa
LG
2039 //\r
2040 // Make sure File Offsets and Virtual Offsets are the same in the image so it is XIP\r
2041 // XIP == eXecute In Place\r
2042 //\r
2043 PeCoffConvertImageToXip (&FileBuffer, &FileLength);\r
30fdf114
LG
2044\r
2045 //\r
2046 // Remove reloc section from PE or TE image\r
2047 //\r
da92f276 2048 if (mOutImageType == FW_RELOC_STRIPEED_IMAGE) {\r
30fdf114
LG
2049 //\r
2050 // Check TeImage\r
2051 //\r
2052 TeHdr = (EFI_TE_IMAGE_HEADER *) FileBuffer;\r
2053 if (TeHdr->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
2054 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) (TeHdr + 1);\r
2055 for (Index = 0; Index < TeHdr->NumberOfSections; Index ++, SectionHeader ++) {\r
2056 if (strcmp ((char *)SectionHeader->Name, ".reloc") == 0) {\r
2057 //\r
2058 // Check the reloc section is in the end of image.\r
2059 //\r
2060 if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) ==\r
2061 (FileLength + TeHdr->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER))) {\r
52302d4d
LG
2062 //\r
2063 // Remove .reloc section and update TeImage Header\r
2064 //\r
2065 FileLength = FileLength - SectionHeader->SizeOfRawData;\r
2066 SectionHeader->SizeOfRawData = 0;\r
2067 SectionHeader->Misc.VirtualSize = 0;\r
2068 TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;\r
2069 TeHdr->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;\r
2070 break;\r
30fdf114
LG
2071 }\r
2072 }\r
2073 }\r
2074 } else {\r
2075 //\r
2076 // Check PE Image\r
2077 //\r
2078 DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer;\r
2079 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
2080 PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer);\r
2081 if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
2082 Error (NULL, 0, 3000, "Invalid", "TE and DOS header signatures were not found in %s image.", mInImageName);\r
2083 goto Finish;\r
2084 }\r
2085 DosHdr = NULL;\r
2086 } else {\r
2087 PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + DosHdr->e_lfanew);\r
2088 if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
2089 Error (NULL, 0, 3000, "Invalid", "PE header signature was not found in %s image.", mInImageName);\r
2090 goto Finish;\r
2091 }\r
2092 }\r
2093 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2094 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
2095 if (strcmp ((char *)SectionHeader->Name, ".reloc") == 0) {\r
2096 //\r
2097 // Check the reloc section is in the end of image.\r
2098 //\r
2099 if ((SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData) == FileLength) {\r
2100 //\r
2101 // Remove .reloc section and update PeImage Header\r
2102 //\r
2103 FileLength = FileLength - SectionHeader->SizeOfRawData;\r
2104\r
2105 PeHdr->Pe32.FileHeader.Characteristics |= EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
2106 if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
2107 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
2108 Optional32->SizeOfImage -= SectionHeader->SizeOfRawData;\r
2109 Optional32->SizeOfInitializedData -= SectionHeader->SizeOfRawData;\r
2110 if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
2111 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;\r
2112 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;\r
2113 }\r
2114 }\r
2115 if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
2116 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
2117 Optional64->SizeOfImage -= SectionHeader->SizeOfRawData;\r
2118 Optional64->SizeOfInitializedData -= SectionHeader->SizeOfRawData;\r
2119 if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
2120 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0;\r
2121 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0;\r
2122 }\r
2123 }\r
2124 SectionHeader->Misc.VirtualSize = 0;\r
2125 SectionHeader->SizeOfRawData = 0;\r
2126 break;\r
2127 }\r
2128 }\r
2129 }\r
2130 }\r
2131 //\r
2132 // Write file\r
2133 //\r
2134 goto WriteFile;\r
2135 }\r
2136 //\r
2137 // Read the dos & pe hdrs of the image\r
2138 //\r
2139 DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
2140 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
2141 // NO DOS header, check for PE/COFF header\r
2142 PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer);\r
2143 if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
2144 Error (NULL, 0, 3000, "Invalid", "DOS header signature was not found in %s image.", mInImageName);\r
2145 goto Finish;\r
2146 }\r
2147 DosHdr = NULL;\r
2148 } else {\r
2149\r
2150 PeHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(FileBuffer + DosHdr->e_lfanew);\r
2151 if (PeHdr->Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
2152 Error (NULL, 0, 3000, "Invalid", "PE header signature was not found in %s image.", mInImageName);\r
2153 goto Finish;\r
2154 }\r
2155 }\r
52302d4d 2156\r
30fdf114
LG
2157 if (PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARM) {\r
2158 // Some tools kick out IMAGE_FILE_MACHINE_ARM (0x1c0) vs IMAGE_FILE_MACHINE_ARMT (0x1c2)\r
2159 // so patch back to the offical UEFI value.\r
2160 PeHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMT;\r
2161 }\r
2162\r
52302d4d
LG
2163 //\r
2164 // Set new base address into image\r
2165 //\r
da92f276 2166 if (mOutImageType == FW_REBASE_IMAGE || mOutImageType == FW_SET_ADDRESS_IMAGE) {\r
52302d4d
LG
2167 if ((PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) && (PeHdr->Pe32.FileHeader.Machine != IMAGE_FILE_MACHINE_IA64)) {\r
2168 if (NewBaseAddress >= 0x100000000ULL) {\r
2169 Error (NULL, 0, 3000, "Invalid", "New base address is larger than 4G for 32bit PE image");\r
2170 goto Finish;\r
2171 }\r
2172 }\r
2173 \r
2174 if (NegativeAddr) {\r
2175 //\r
2176 // Set Base Address to a negative value.\r
2177 //\r
2178 NewBaseAddress = (UINT64) (0 - NewBaseAddress);\r
2179 }\r
da92f276 2180 if (mOutImageType == FW_REBASE_IMAGE) {\r
52302d4d
LG
2181 Status = RebaseImage (mInImageName, FileBuffer, NewBaseAddress);\r
2182 } else {\r
2183 Status = SetAddressToSectionHeader (mInImageName, FileBuffer, NewBaseAddress);\r
2184 }\r
2185 if (EFI_ERROR (Status)) {\r
2186 if (NegativeAddr) {\r
2187 Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address -0x%llx can't success", mInImageName, 0 - NewBaseAddress);\r
2188 } else {\r
2189 Error (NULL, 0, 3000, "Invalid", "Rebase/Set Image %s to Base address 0x%llx can't success", mInImageName, NewBaseAddress);\r
2190 }\r
2191 goto Finish;\r
2192 }\r
2193\r
2194 //\r
2195 // Write file\r
2196 //\r
2197 goto WriteFile;\r
2198 }\r
2199\r
30fdf114
LG
2200 //\r
2201 // Extract bin data from Pe image.\r
2202 //\r
da92f276 2203 if (mOutImageType == FW_BIN_IMAGE) {\r
30fdf114
LG
2204 if (FileLength < PeHdr->Pe32.OptionalHeader.SizeOfHeaders) {\r
2205 Error (NULL, 0, 3000, "Invalid", "FileSize of %s is not a legal size.", mInImageName);\r
2206 goto Finish;\r
2207 }\r
2208 //\r
2209 // Output bin data from exe file\r
2210 //\r
52302d4d 2211 FileLength = FileLength - PeHdr->Pe32.OptionalHeader.SizeOfHeaders;\r
da92f276 2212 memmove (FileBuffer, FileBuffer + PeHdr->Pe32.OptionalHeader.SizeOfHeaders, FileLength);\r
52302d4d
LG
2213 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
2214 goto WriteFile;\r
30fdf114
LG
2215 }\r
2216\r
2217 //\r
2218 // Zero Debug Information of Pe Image\r
2219 //\r
da92f276 2220 if (mOutImageType == FW_ZERO_DEBUG_IMAGE) {\r
30fdf114
LG
2221 Status = ZeroDebugData (FileBuffer, TRUE);\r
2222 if (EFI_ERROR (Status)) {\r
fd171542 2223 Error (NULL, 0, 3000, "Invalid", "Zero DebugData Error status is 0x%x", (int) Status);\r
30fdf114
LG
2224 goto Finish;\r
2225 }\r
2226\r
52302d4d
LG
2227 //\r
2228 // Write the updated Image\r
2229 //\r
fd171542 2230 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
52302d4d 2231 goto WriteFile;\r
30fdf114
LG
2232 }\r
2233\r
2234 //\r
2235 // Set Time Stamp of Pe Image\r
2236 //\r
da92f276 2237 if (mOutImageType == FW_SET_STAMP_IMAGE) {\r
30fdf114
LG
2238 Status = SetStamp (FileBuffer, TimeStamp);\r
2239 if (EFI_ERROR (Status)) {\r
2240 goto Finish;\r
2241 }\r
2242\r
52302d4d
LG
2243 //\r
2244 // Write the updated Image\r
2245 //\r
fd171542 2246 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
52302d4d 2247 goto WriteFile;\r
30fdf114
LG
2248 }\r
2249\r
2250 //\r
2251 // Extract acpi data from pe image.\r
2252 //\r
da92f276 2253 if (mOutImageType == FW_ACPI_IMAGE) {\r
30fdf114
LG
2254 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2255 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index ++, SectionHeader ++) {\r
2256 if (strcmp ((char *)SectionHeader->Name, ".data") == 0 || strcmp ((char *)SectionHeader->Name, ".sdata") == 0) {\r
2257 //\r
2258 // Check Acpi Table\r
2259 //\r
2260 if (SectionHeader->Misc.VirtualSize < SectionHeader->SizeOfRawData) {\r
2261 FileLength = SectionHeader->Misc.VirtualSize;\r
2262 } else {\r
2263 FileLength = SectionHeader->SizeOfRawData;\r
2264 }\r
2265\r
2266 if (CheckAcpiTable (FileBuffer + SectionHeader->PointerToRawData, FileLength) != STATUS_SUCCESS) {\r
2267 Error (NULL, 0, 3000, "Invalid", "ACPI table check failed in %s.", mInImageName);\r
2268 goto Finish;\r
2269 }\r
2270\r
2271 //\r
2272 // Output Apci data to file\r
2273 //\r
da92f276 2274 memmove (FileBuffer, FileBuffer + SectionHeader->PointerToRawData, FileLength);\r
fd171542 2275 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
52302d4d 2276 goto WriteFile;\r
30fdf114
LG
2277 }\r
2278 }\r
2279 Error (NULL, 0, 3000, "Invalid", "failed to get ACPI table from %s.", mInImageName);\r
2280 goto Finish;\r
2281 }\r
2282 //\r
2283 // Zero all unused fields of the DOS header\r
2284 //\r
2285 if (DosHdr != NULL) {\r
2286 memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER));\r
2287 memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));\r
2288 DosHdr->e_magic = BackupDosHdr.e_magic;\r
2289 DosHdr->e_lfanew = BackupDosHdr.e_lfanew;\r
52302d4d 2290\r
30fdf114 2291 for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (UINT32 ) DosHdr->e_lfanew; Index++) {\r
fd171542 2292 FileBuffer[Index] = (UINT8) DosHdr->e_cp;\r
30fdf114
LG
2293 }\r
2294 }\r
2295\r
2296 //\r
2297 // Initialize TeImage Header\r
2298 //\r
2299 memset (&TEImageHeader, 0, sizeof (EFI_TE_IMAGE_HEADER));\r
2300 TEImageHeader.Signature = EFI_TE_IMAGE_HEADER_SIGNATURE;\r
2301 TEImageHeader.Machine = PeHdr->Pe32.FileHeader.Machine;\r
2302 TEImageHeader.NumberOfSections = (UINT8) PeHdr->Pe32.FileHeader.NumberOfSections;\r
2303 TEImageHeader.StrippedSize = (UINT16) ((UINTN) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader) - (UINTN) FileBuffer);\r
2304 TEImageHeader.Subsystem = (UINT8) Type;\r
52302d4d 2305\r
30fdf114
LG
2306 //\r
2307 // Patch the PE header\r
2308 //\r
2309 PeHdr->Pe32.OptionalHeader.Subsystem = (UINT16) Type;\r
2310\r
2311 if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
2312 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
30fdf114
LG
2313 Optional32->MajorOperatingSystemVersion = 0;\r
2314 Optional32->MinorOperatingSystemVersion = 0;\r
2315 Optional32->MajorImageVersion = 0;\r
2316 Optional32->MinorImageVersion = 0;\r
2317 Optional32->MajorSubsystemVersion = 0;\r
2318 Optional32->MinorSubsystemVersion = 0;\r
2319 Optional32->Win32VersionValue = 0;\r
2320 Optional32->CheckSum = 0;\r
2321 Optional32->SizeOfStackReserve = 0;\r
2322 Optional32->SizeOfStackCommit = 0;\r
2323 Optional32->SizeOfHeapReserve = 0;\r
2324 Optional32->SizeOfHeapCommit = 0;\r
2325\r
2326 TEImageHeader.AddressOfEntryPoint = Optional32->AddressOfEntryPoint;\r
2327 TEImageHeader.BaseOfCode = Optional32->BaseOfCode;\r
2328 TEImageHeader.ImageBase = (UINT64) (Optional32->ImageBase);\r
2329\r
2330 if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
2331 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
2332 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
2333 }\r
2334\r
2335 if (Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
2336 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
2337 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
2338 }\r
2339\r
2340 //\r
2341 // Zero .pdata section data.\r
2342 //\r
2343 if (!KeepExceptionTableFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&\r
52302d4d
LG
2344 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
2345 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
2346 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2347 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
2348 if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {\r
2349 //\r
2350 // Zero .pdata Section data\r
2351 //\r
2352 memset (FileBuffer + SectionHeader->PointerToRawData, 0, SectionHeader->SizeOfRawData);\r
2353 //\r
2354 // Zero .pdata Section header name\r
2355 //\r
2356 memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
2357 //\r
2358 // Zero Execption Table\r
2359 //\r
2360 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
2361 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
2362 DebugMsg (NULL, 0, 9, "Zero the .pdata section for PE image", NULL);\r
2363 break;\r
2364 }\r
30fdf114 2365 }\r
30fdf114
LG
2366 }\r
2367\r
2368 //\r
2369 // Strip zero padding at the end of the .reloc section\r
2370 //\r
2371 if (!KeepZeroPendingFlag && Optional32->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
2372 if (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) {\r
2373 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2374 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
2375 //\r
2376 // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
2377 //\r
2378 if (SectionHeader->VirtualAddress == Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {\r
2379 SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
2380 AllignedRelocSize = (Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1));\r
2381 //\r
2382 // Check to see if there is zero padding at the end of the base relocations\r
2383 //\r
2384 if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
2385 //\r
2386 // Check to see if the base relocations are at the end of the file\r
2387 //\r
2388 if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) {\r
2389 //\r
2390 // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
2391 //\r
2392 Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
2393 Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
2394 SectionHeader->SizeOfRawData = AllignedRelocSize;\r
2395 FileLength = Optional32->SizeOfImage;\r
fd171542 2396 DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize));\r
30fdf114
LG
2397 }\r
2398 }\r
2399 }\r
2400 }\r
2401 }\r
2402 }\r
2403 } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
2404 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
30fdf114
LG
2405 Optional64->MajorOperatingSystemVersion = 0;\r
2406 Optional64->MinorOperatingSystemVersion = 0;\r
2407 Optional64->MajorImageVersion = 0;\r
2408 Optional64->MinorImageVersion = 0;\r
2409 Optional64->MajorSubsystemVersion = 0;\r
2410 Optional64->MinorSubsystemVersion = 0;\r
2411 Optional64->Win32VersionValue = 0;\r
2412 Optional64->CheckSum = 0;\r
2413 Optional64->SizeOfStackReserve = 0;\r
2414 Optional64->SizeOfStackCommit = 0;\r
2415 Optional64->SizeOfHeapReserve = 0;\r
2416 Optional64->SizeOfHeapCommit = 0;\r
2417\r
2418 TEImageHeader.AddressOfEntryPoint = Optional64->AddressOfEntryPoint;\r
2419 TEImageHeader.BaseOfCode = Optional64->BaseOfCode;\r
2420 TEImageHeader.ImageBase = (UINT64) (Optional64->ImageBase);\r
2421\r
2422 if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {\r
2423 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;\r
2424 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
2425 }\r
2426\r
2427 if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
2428 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
2429 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size;\r
2430 }\r
2431\r
2432 //\r
2433 // Zero the .pdata section for X64 machine and don't check the Debug Directory is empty\r
2434 // For Itaninum and X64 Image, remove .pdata section.\r
2435 //\r
2436 if ((!KeepExceptionTableFlag && PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_X64) || PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_IA64) {\r
2437 if (Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION &&\r
52302d4d
LG
2438 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress != 0 &&\r
2439 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size != 0) {\r
2440 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2441 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
2442 if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress) {\r
2443 //\r
2444 // Zero .pdata Section header name\r
2445 //\r
2446 memset (SectionHeader->Name, 0, sizeof (SectionHeader->Name));\r
2447\r
2448 RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);\r
2449 for (Index1 = 0; Index1 < Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {\r
2450 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2451 for (Index2 = 0; Index2 < PeHdr->Pe32.FileHeader.NumberOfSections; Index2++, SectionHeader++) {\r
2452 if (RuntimeFunction->UnwindInfoAddress >= SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
2453 UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));\r
2454 if (UnwindInfo->Version == 1) {\r
2455 memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));\r
2456 memset (UnwindInfo, 0, sizeof (UNWIND_INFO));\r
2457 }\r
2458 break;\r
30fdf114
LG
2459 }\r
2460 }\r
52302d4d 2461 memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
30fdf114 2462 }\r
52302d4d
LG
2463 //\r
2464 // Zero Execption Table\r
2465 //\r
2466 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size = 0;\r
2467 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress = 0;\r
2468 DebugMsg (NULL, 0, 9, "Zero the .pdata section if the machine type is X64 for PE32+ image", NULL);\r
2469 break;\r
30fdf114 2470 }\r
30fdf114 2471 }\r
30fdf114
LG
2472 }\r
2473 }\r
2474\r
2475 //\r
2476 // Strip zero padding at the end of the .reloc section\r
2477 //\r
2478 if (!KeepZeroPendingFlag && Optional64->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {\r
2479 if (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size != 0) {\r
2480 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2481 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
2482 //\r
2483 // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
2484 //\r
2485 if (SectionHeader->VirtualAddress == Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress) {\r
2486 SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;\r
2487 AllignedRelocSize = (Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1));\r
2488 //\r
2489 // Check to see if there is zero padding at the end of the base relocations\r
2490 //\r
2491 if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
2492 //\r
2493 // Check to see if the base relocations are at the end of the file\r
2494 //\r
2495 if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) {\r
2496 //\r
2497 // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
2498 //\r
2499 Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
2500 Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
2501 SectionHeader->SizeOfRawData = AllignedRelocSize;\r
2502 FileLength = Optional64->SizeOfImage;\r
fd171542 2503 DebugMsg (NULL, 0, 9, "Remove the zero padding bytes at the end of the base relocations", "The size of padding bytes is %u", (unsigned) (SectionHeader->SizeOfRawData - AllignedRelocSize));\r
30fdf114
LG
2504 }\r
2505 }\r
2506 }\r
2507 }\r
2508 }\r
2509 }\r
2510 } else {\r
2511 Error (NULL, 0, 3000, "Invalid", "Magic 0x%x of PeImage %s is unknown.", PeHdr->Pe32.OptionalHeader.Magic, mInImageName);\r
2512 goto Finish;\r
2513 }\r
52302d4d 2514\r
30fdf114
LG
2515 if (((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) == 0) && \\r
2516 (TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == 0) && \\r
2517 (TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size == 0)) {\r
52302d4d
LG
2518 //\r
2519 // PeImage can be loaded into memory, but it has no relocation section. \r
2520 // Fix TeImage Header to set VA of relocation data directory to not zero, the size is still zero.\r
2521 //\r
2522 if (Optional32 != NULL) {\r
2523 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional32->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
2524 } else if (Optional64 != NULL) {\r
2525 TEImageHeader.DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Optional64->SizeOfImage - sizeof (EFI_IMAGE_BASE_RELOCATION);\r
2526 }\r
30fdf114 2527 }\r
a709adfa
LG
2528\r
2529 //\r
2530 // Fill HII section data\r
2531 //\r
2532 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
2533 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {\r
2534 if (stricmp ((char *)SectionHeader[Index].Name, ".hii") == 0) {\r
2535 //\r
2536 // Update resource section header offset\r
2537 //\r
2538 SetHiiResourceHeader ((UINT8*) FileBuffer + SectionHeader[Index].PointerToRawData, SectionHeader[Index].VirtualAddress);\r
2539 //\r
2540 // Update resource section name\r
2541 //\r
2542 strcpy((char *) SectionHeader[Index].Name, ".rsrc");\r
2543 //\r
2544 // Update resource data directory.\r
2545 //\r
2546 if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
2547 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
2548 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
2549 Optional32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
2550 } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
2551 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
2552 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = SectionHeader[Index].VirtualAddress;\r
2553 Optional64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = SectionHeader[Index].Misc.VirtualSize;\r
2554 }\r
2555 break;\r
2556 }\r
2557 }\r
2558\r
30fdf114
LG
2559 //\r
2560 // Zero ExceptionTable Xdata\r
2561 //\r
2562 if (!KeepExceptionTableFlag) {\r
2563 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) &(PeHdr->Pe32.OptionalHeader) + PeHdr->Pe32.FileHeader.SizeOfOptionalHeader);\r
b303ea72
LG
2564 for (Index = 0; Index < PeHdr->Pe32.FileHeader.NumberOfSections; Index++) {\r
2565 if (stricmp ((char *)SectionHeader[Index].Name, ".xdata") == 0) {\r
2566 //\r
2567 // zero .xdata section\r
2568 //\r
2569 memset (FileBuffer + SectionHeader[Index].PointerToRawData, 0, SectionHeader[Index].SizeOfRawData);\r
2570 DebugMsg (NULL, 0, 9, NULL, "Zero the .xdata section for PE image at Offset 0x%x and Length 0x%x", (unsigned) SectionHeader[Index].PointerToRawData, (unsigned) SectionHeader[Index].SizeOfRawData);\r
2571 break;\r
2572 }\r
2573 }\r
30fdf114
LG
2574 }\r
2575\r
2576 //\r
2577 // Zero Time/Data field\r
2578 //\r
2579 ZeroDebugData (FileBuffer, FALSE);\r
2580\r
da92f276 2581 if (mOutImageType == FW_TE_IMAGE) {\r
30fdf114
LG
2582 if ((PeHdr->Pe32.FileHeader.NumberOfSections &~0xFF) || (Type &~0xFF)) {\r
2583 //\r
2584 // Pack the subsystem and NumberOfSections into 1 byte. Make sure they fit both.\r
2585 //\r
2586 Error (NULL, 0, 3000, "Invalid", "Image's subsystem or NumberOfSections of PeImage %s cannot be packed into 1 byte.", mInImageName);\r
2587 goto Finish;\r
2588 }\r
2589\r
2590 if ((PeHdr->Pe32.OptionalHeader.SectionAlignment != PeHdr->Pe32.OptionalHeader.FileAlignment)) {\r
2591 //\r
2592 // TeImage has the same section alignment and file alignment.\r
2593 //\r
2594 Error (NULL, 0, 3000, "Invalid", "Section-Alignment and File-Alignment of PeImage %s do not match, they must be equal for a TeImage.", mInImageName);\r
2595 goto Finish;\r
2596 }\r
2597\r
fd171542 2598 DebugMsg (NULL, 0, 9, "TeImage Header Info", "Machine type is %X, Number of sections is %X, Stripped size is %X, EntryPoint is %X, BaseOfCode is %X, ImageBase is %llX",\r
52302d4d 2599 TEImageHeader.Machine, TEImageHeader.NumberOfSections, TEImageHeader.StrippedSize, (unsigned) TEImageHeader.AddressOfEntryPoint, (unsigned) TEImageHeader.BaseOfCode, (unsigned long long) TEImageHeader.ImageBase);\r
30fdf114
LG
2600 //\r
2601 // Update Image to TeImage\r
2602 //\r
52302d4d 2603 FileLength = FileLength - TEImageHeader.StrippedSize;\r
da92f276 2604 memmove (FileBuffer + sizeof (EFI_TE_IMAGE_HEADER), FileBuffer + TEImageHeader.StrippedSize, FileLength);\r
52302d4d
LG
2605 FileLength = FileLength + sizeof (EFI_TE_IMAGE_HEADER);\r
2606 memcpy (FileBuffer, &TEImageHeader, sizeof (EFI_TE_IMAGE_HEADER));\r
2607 VerboseMsg ("the size of output file is %u bytes", (unsigned) (FileLength));\r
636f2be6
LG
2608 } else {\r
2609\r
2610 //\r
2611 // Following codes are to fix the objcopy's issue:\r
2612 // objcopy in binutil 2.50.18 will set PE image's charactices to "RELOC_STRIPPED" if image has no ".reloc" section\r
2613 // It cause issue for EFI image which has no ".reloc" sections.\r
2614 // Following codes will be removed when objcopy in binutil fix this problem for PE image.\r
2615 //\r
2616 if ((PeHdr->Pe32.FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0) {\r
2617 if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
2618 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader;\r
2619 if (Optional32->ImageBase == 0) {\r
2620 PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
2621 }\r
2622 } else if (PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
2623 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader;\r
2624 if (Optional64->ImageBase == 0) {\r
2625 PeHdr->Pe32.FileHeader.Characteristics &= ~EFI_IMAGE_FILE_RELOCS_STRIPPED;\r
2626 }\r
2627 }\r
2628 }\r
30fdf114 2629 }\r
52302d4d 2630\r
30fdf114
LG
2631WriteFile:\r
2632 //\r
52302d4d 2633 // Update Image to EfiImage or TE image\r
30fdf114 2634 //\r
52302d4d
LG
2635 if (ReplaceFlag) {\r
2636 if ((FileLength != InputFileLength) || (memcmp (FileBuffer, InputFileBuffer, FileLength) != 0)) {\r
2637 //\r
2638 // Update File when File is changed.\r
2639 //\r
1be2ed90 2640 fpInOut = fopen (LongFilePath (mInImageName), "wb");\r
52302d4d
LG
2641 if (fpInOut == NULL) {\r
2642 Error (NULL, 0, 0001, "Error opening file", mInImageName);\r
2643 goto Finish;\r
2644 }\r
2645 fwrite (FileBuffer, 1, FileLength, fpInOut);\r
2646 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
2647 }\r
2648 } else {\r
636f2be6
LG
2649 if ((OutputFileTime < InputFileTime) || (FileLength != OutputFileLength) || (memcmp (FileBuffer, OutputFileBuffer, FileLength) != 0)) {\r
2650 //\r
2651 // Update File when File is changed or File is old.\r
2652 //\r
1be2ed90 2653 fpOut = fopen (LongFilePath (OutImageName), "wb");\r
52302d4d
LG
2654 if (fpOut == NULL) {\r
2655 Error (NULL, 0, 0001, "Error opening output file", OutImageName);\r
2656 goto Finish;\r
2657 }\r
2658 fwrite (FileBuffer, 1, FileLength, fpOut);\r
2659 VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLength);\r
2660 }\r
30fdf114 2661 }\r
52302d4d 2662 mImageSize = FileLength;\r
30fdf114
LG
2663\r
2664Finish:\r
2665 if (fpInOut != NULL) {\r
2666 if (GetUtilityStatus () != STATUS_SUCCESS) {\r
2667 //\r
52302d4d 2668 // when file updates failed, original file is still recovered.\r
30fdf114 2669 //\r
52302d4d 2670 fwrite (InputFileBuffer, 1, InputFileLength, fpInOut);\r
30fdf114
LG
2671 }\r
2672 //\r
2673 // Write converted data into fpInOut file and close input file.\r
2674 //\r
2675 fclose (fpInOut);\r
2676 }\r
2677\r
2678 if (FileBuffer != NULL) {\r
2679 free (FileBuffer);\r
2680 }\r
2681\r
2682 if (InputFileName != NULL) {\r
2683 free (InputFileName);\r
2684 }\r
2685\r
2686 if (fpOut != NULL) {\r
2687 //\r
2688 // Write converted data into fpOut file and close output file.\r
2689 //\r
2690 fclose (fpOut);\r
2691 if (GetUtilityStatus () != STATUS_SUCCESS) {\r
2692 if (OutputFileBuffer == NULL) {\r
2693 remove (OutImageName);\r
2694 } else {\r
1be2ed90 2695 fpOut = fopen (LongFilePath (OutImageName), "wb");\r
30fdf114
LG
2696 fwrite (OutputFileBuffer, 1, OutputFileLength, fpOut);\r
2697 fclose (fpOut);\r
30fdf114
LG
2698 }\r
2699 }\r
2700 }\r
52302d4d
LG
2701 \r
2702 if (InputFileBuffer != NULL) {\r
2703 free (InputFileBuffer);\r
2704 }\r
2705\r
2706 if (OutputFileBuffer != NULL) {\r
2707 free (OutputFileBuffer);\r
2708 }\r
30fdf114 2709\r
52302d4d
LG
2710 //\r
2711 // Write module size and time stamp to report file.\r
2712 //\r
2713 if (OutImageName != NULL) {\r
2714 FileLen = strlen (OutImageName);\r
2715 }\r
2716 if (FileLen >= 4 && strcmp (OutImageName + (FileLen - 4), ".efi") == 0) {\r
2717 ReportFileName = (CHAR8 *) malloc (FileLen + 1);\r
2718 if (ReportFileName != NULL) {\r
2719 strcpy (ReportFileName, OutImageName);\r
2720 strcpy (ReportFileName + (FileLen - 4), ".txt"); \r
1be2ed90 2721 ReportFile = fopen (LongFilePath (ReportFileName), "w+");\r
52302d4d
LG
2722 if (ReportFile != NULL) {\r
2723 fprintf (ReportFile, "MODULE_SIZE = %u\n", (unsigned) mImageSize);\r
2724 fprintf (ReportFile, "TIME_STAMP = %u\n", (unsigned) mImageTimeStamp);\r
2725 fclose(ReportFile);\r
2726 }\r
2727 free (ReportFileName);\r
2728 }\r
2729 }\r
30fdf114
LG
2730 VerboseMsg ("%s tool done with return code is 0x%x.", UTILITY_NAME, GetUtilityStatus ());\r
2731\r
2732 return GetUtilityStatus ();\r
2733}\r
2734\r
2735STATIC\r
2736EFI_STATUS\r
2737ZeroDebugData (\r
2738 IN OUT UINT8 *FileBuffer,\r
2739 BOOLEAN ZeroDebugFlag\r
2740 )\r
2741/*++\r
2742\r
2743Routine Description:\r
2744\r
2745 Zero debug information in PeImage.\r
2746\r
2747Arguments:\r
2748\r
2749 FileBuffer - Pointer to PeImage.\r
2750 ZeroDebugFlag - TRUE to zero Debug information, FALSE to only zero time/stamp\r
2751\r
2752Returns:\r
2753\r
2754 EFI_ABORTED - PeImage is invalid.\r
2755 EFI_SUCCESS - Zero debug data successfully.\r
2756\r
2757--*/\r
2758{\r
2759 UINT32 Index;\r
2760 UINT32 DebugDirectoryEntryRva;\r
2761 UINT32 DebugDirectoryEntryFileOffset;\r
2762 UINT32 ExportDirectoryEntryRva;\r
2763 UINT32 ExportDirectoryEntryFileOffset;\r
2764 UINT32 ResourceDirectoryEntryRva;\r
2765 UINT32 ResourceDirectoryEntryFileOffset;\r
2766 EFI_IMAGE_DOS_HEADER *DosHdr;\r
2767 EFI_IMAGE_FILE_HEADER *FileHdr;\r
2768 EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr;\r
2769 EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;\r
2770 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
2771 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
2772 UINT32 *NewTimeStamp; \r
2773\r
2774 //\r
2775 // Init variable.\r
2776 //\r
58e4d800 2777 DebugDirectoryEntryRva = 0;\r
2778 ExportDirectoryEntryRva = 0;\r
2779 ResourceDirectoryEntryRva = 0;\r
2780 DebugDirectoryEntryFileOffset = 0;\r
2781 ExportDirectoryEntryFileOffset = 0;\r
2782 ResourceDirectoryEntryFileOffset = 0;\r
30fdf114
LG
2783 DosHdr = (EFI_IMAGE_DOS_HEADER *) FileBuffer;\r
2784 FileHdr = (EFI_IMAGE_FILE_HEADER *) (FileBuffer + DosHdr->e_lfanew + sizeof (UINT32));\r
2785\r
2786\r
2787 DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
2788 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
2789 // NO DOS header, must start with PE/COFF header\r
2790 FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32));\r
2791 } else {\r
2792 FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof (UINT32));\r
2793 }\r
2794\r
2795 //\r
2796 // Get Debug, Export and Resource EntryTable RVA address.\r
2797 // Resource Directory entry need to review.\r
2798 //\r
2799 if (FileHdr->Machine == EFI_IMAGE_MACHINE_IA32) {\r
2800 Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
2801 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);\r
2802 if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \\r
2803 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {\r
2804 ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r
2805 }\r
2806 if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \\r
2807 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {\r
2808 ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;\r
2809 }\r
2810 if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \\r
2811 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {\r
2812 DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
2813 if (ZeroDebugFlag) {\r
2814 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;\r
2815 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;\r
2816 }\r
2817 }\r
2818 } else {\r
2819 Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
2820 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);\r
2821 if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \\r
2822 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {\r
2823 ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r
2824 }\r
2825 if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \\r
2826 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {\r
2827 ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;\r
2828 }\r
2829 if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \\r
2830 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {\r
2831 DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
2832 if (ZeroDebugFlag) {\r
2833 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0;\r
2834 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = 0;\r
2835 }\r
2836 }\r
2837 }\r
2838\r
2839 //\r
2840 // Get DirectoryEntryTable file offset.\r
2841 //\r
2842 for (Index = 0; Index < FileHdr->NumberOfSections; Index ++, SectionHeader ++) {\r
2843 if (DebugDirectoryEntryRva >= SectionHeader->VirtualAddress &&\r
2844 DebugDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {\r
2845 DebugDirectoryEntryFileOffset =\r
2846 DebugDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;\r
2847 }\r
2848 if (ExportDirectoryEntryRva >= SectionHeader->VirtualAddress &&\r
2849 ExportDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {\r
2850 ExportDirectoryEntryFileOffset =\r
2851 ExportDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;\r
2852 }\r
2853 if (ResourceDirectoryEntryRva >= SectionHeader->VirtualAddress &&\r
2854 ResourceDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {\r
2855 ResourceDirectoryEntryFileOffset =\r
2856 ResourceDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;\r
2857 }\r
2858 }\r
2859\r
2860 //\r
2861 //Zero Debug Data and TimeStamp\r
2862 //\r
2863 FileHdr->TimeDateStamp = 0;\r
52302d4d 2864 mImageTimeStamp = 0;\r
58e4d800 2865 if (ExportDirectoryEntryFileOffset != 0) {\r
30fdf114
LG
2866 NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));\r
2867 *NewTimeStamp = 0;\r
2868 }\r
2869\r
58e4d800 2870 if (ResourceDirectoryEntryFileOffset != 0) {\r
30fdf114
LG
2871 NewTimeStamp = (UINT32 *) (FileBuffer + ResourceDirectoryEntryFileOffset + sizeof (UINT32));\r
2872 *NewTimeStamp = 0;\r
2873 }\r
2874\r
58e4d800 2875 if (DebugDirectoryEntryFileOffset != 0) {\r
30fdf114
LG
2876 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (FileBuffer + DebugDirectoryEntryFileOffset);\r
2877 DebugEntry->TimeDateStamp = 0;\r
52302d4d 2878 mImageTimeStamp = 0;\r
30fdf114
LG
2879 if (ZeroDebugFlag) {\r
2880 memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);\r
2881 memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
2882 }\r
2883 }\r
2884\r
2885 return EFI_SUCCESS;\r
2886}\r
2887\r
2888STATIC\r
2889EFI_STATUS\r
2890SetStamp (\r
2891 IN OUT UINT8 *FileBuffer,\r
2892 IN CHAR8 *TimeStamp\r
2893 )\r
2894/*++\r
2895\r
2896Routine Description:\r
2897\r
2898 Set new time stamp into PeImage FileHdr and Directory table:\r
2899 Debug, Export and Resource.\r
2900\r
2901Arguments:\r
2902\r
2903 FileBuffer - Pointer to PeImage.\r
2904 TimeStamp - Time stamp string.\r
2905\r
2906Returns:\r
2907\r
2908 EFI_INVALID_PARAMETER - TimeStamp format is not recognized.\r
2909 EFI_SUCCESS - Set new time stamp in this image successfully.\r
2910\r
2911--*/\r
2912{\r
2913 struct tm stime;\r
2914 struct tm *ptime;\r
2915 time_t newtime;\r
fd171542 2916 UINT32 Index;\r
2917 UINT32 DebugDirectoryEntryRva;\r
2918 UINT32 DebugDirectoryEntryFileOffset;\r
2919 UINT32 ExportDirectoryEntryRva;\r
2920 UINT32 ExportDirectoryEntryFileOffset;\r
2921 UINT32 ResourceDirectoryEntryRva;\r
2922 UINT32 ResourceDirectoryEntryFileOffset;\r
30fdf114
LG
2923 EFI_IMAGE_DOS_HEADER *DosHdr;\r
2924 EFI_IMAGE_FILE_HEADER *FileHdr;\r
2925 EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr;\r
2926 EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;\r
2927 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
2928 UINT32 *NewTimeStamp;\r
2929 \r
2930 //\r
2931 // Init variable.\r
2932 //\r
fd171542 2933 DebugDirectoryEntryRva = 0;\r
2934 DebugDirectoryEntryFileOffset = 0;\r
2935 ExportDirectoryEntryRva = 0;\r
2936 ExportDirectoryEntryFileOffset = 0;\r
2937 ResourceDirectoryEntryRva = 0;\r
2938 ResourceDirectoryEntryFileOffset = 0;\r
30fdf114
LG
2939 //\r
2940 // Get time and date that will be set.\r
2941 //\r
2942 if (TimeStamp == NULL) {\r
2943 Error (NULL, 0, 3000, "Invalid", "TimeStamp cannot be NULL.");\r
2944 return EFI_INVALID_PARAMETER;\r
2945 }\r
2946 //\r
2947 // compare the value with "NOW", if yes, current system time is set.\r
2948 //\r
2949 if (stricmp (TimeStamp, "NOW") == 0) {\r
2950 //\r
2951 // get system current time and date\r
2952 //\r
2953 time (&newtime);\r
2954 } else {\r
2955 //\r
2956 // Check Time Format strictly yyyy-mm-dd 00:00:00\r
2957 //\r
2958 for (Index = 0; TimeStamp[Index] != '\0' && Index < 20; Index ++) {\r
2959 if (Index == 4 || Index == 7) {\r
2960 if (TimeStamp[Index] == '-') {\r
2961 continue;\r
2962 }\r
2963 } else if (Index == 13 || Index == 16) {\r
2964 if (TimeStamp[Index] == ':') {\r
2965 continue;\r
2966 }\r
2967 } else if (Index == 10 && TimeStamp[Index] == ' ') {\r
2968 continue;\r
2969 } else if ((TimeStamp[Index] < '0') || (TimeStamp[Index] > '9')) {\r
2970 break;\r
2971 }\r
2972 }\r
2973\r
2974 if (Index < 19 || TimeStamp[19] != '\0') {\r
2975 Error (NULL, 0, 1003, "Invalid option value", "Incorrect Time \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp);\r
2976 return EFI_INVALID_PARAMETER;\r
2977 }\r
2978\r
2979 //\r
2980 // get the date and time from TimeStamp\r
2981 //\r
2982 if (sscanf (TimeStamp, "%d-%d-%d %d:%d:%d",\r
2983 &stime.tm_year,\r
2984 &stime.tm_mon,\r
2985 &stime.tm_mday,\r
2986 &stime.tm_hour,\r
2987 &stime.tm_min,\r
2988 &stime.tm_sec\r
2989 ) != 6) {\r
2990 Error (NULL, 0, 1003, "Invalid option value", "Incorrect Tiem \"%s\"\n Correct Format \"yyyy-mm-dd 00:00:00\"", TimeStamp);\r
2991 return EFI_INVALID_PARAMETER;\r
2992 }\r
2993\r
2994 //\r
2995 // in struct, Month (0 - 11; Jan = 0). So decrease 1 from it\r
2996 //\r
2997 if (stime.tm_mon <= 0 || stime.tm_mday <=0) {\r
2998 Error (NULL, 0, 3000, "Invalid", "%s Invalid date!", TimeStamp);\r
2999 return EFI_INVALID_PARAMETER;\r
3000 }\r
3001 stime.tm_mon -= 1;\r
3002\r
3003 //\r
3004 // in struct, Year (current year minus 1900)\r
3005 // and only the dates can be handled from Jan 1, 1970 to Jan 18, 2038\r
3006 //\r
3007 //\r
3008 // convert 0 -> 100 (2000), 1 -> 101 (2001), ..., 38 -> 138 (2038)\r
3009 //\r
3010 if (stime.tm_year >= 1970 && stime.tm_year <= 2038) {\r
3011 //\r
3012 // convert 1970 -> 70, 2000 -> 100, ...\r
3013 //\r
3014 stime.tm_year -= 1900;\r
3015 } else {\r
3016 Error (NULL, 0, 3000, "Invalid", "%s Invalid or unsupported datetime!", TimeStamp);\r
3017 return EFI_INVALID_PARAMETER;\r
3018 }\r
3019\r
3020 //\r
3021 // convert the date and time to time_t format\r
3022 //\r
3023 newtime = mktime (&stime);\r
3024 if (newtime == (time_t) - 1) {\r
3025 Error (NULL, 0, 3000, "Invalid", "%s Invalid or unsupported datetime!", TimeStamp);\r
3026 return EFI_INVALID_PARAMETER;\r
3027 }\r
3028 }\r
3029\r
3030 ptime = localtime (&newtime);\r
3031 DebugMsg (NULL, 0, 9, "New Image Time Stamp", "%04d-%02d-%02d %02d:%02d:%02d",\r
3032 ptime->tm_year + 1900, ptime->tm_mon + 1, ptime->tm_mday, ptime->tm_hour, ptime->tm_min, ptime->tm_sec);\r
3033 //\r
3034 // Set new time and data into PeImage.\r
3035 //\r
3036 DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
3037 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
3038 // NO DOS header, must start with PE/COFF header\r
3039 FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32));\r
3040 } else {\r
3041 FileHdr = (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof (UINT32));\r
3042 }\r
3043\r
3044 //\r
3045 // Get Debug, Export and Resource EntryTable RVA address.\r
3046 // Resource Directory entry need to review.\r
3047 //\r
3048 if (FileHdr->Machine == EFI_IMAGE_MACHINE_IA32) {\r
3049 Optional32Hdr = (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
3050 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hdr + FileHdr->SizeOfOptionalHeader);\r
3051 if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \\r
3052 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {\r
3053 ExportDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r
3054 }\r
3055 if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \\r
3056 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {\r
3057 ResourceDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;\r
3058 }\r
3059 if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \\r
3060 Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {\r
3061 DebugDirectoryEntryRva = Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
3062 }\r
3063 } else {\r
3064 Optional64Hdr = (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + sizeof (EFI_IMAGE_FILE_HEADER));\r
3065 SectionHeader = (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hdr + FileHdr->SizeOfOptionalHeader);\r
3066 if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_EXPORT && \\r
3067 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size != 0) {\r
3068 ExportDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;\r
3069 }\r
3070 if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE && \\r
3071 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size != 0) {\r
3072 ResourceDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress;\r
3073 }\r
3074 if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG && \\r
3075 Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size != 0) {\r
3076 DebugDirectoryEntryRva = Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;\r
3077 }\r
3078 }\r
3079\r
3080 //\r
3081 // Get DirectoryEntryTable file offset.\r
3082 //\r
3083 for (Index = 0; Index < FileHdr->NumberOfSections; Index ++, SectionHeader ++) {\r
3084 if (DebugDirectoryEntryRva >= SectionHeader->VirtualAddress &&\r
3085 DebugDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {\r
3086 DebugDirectoryEntryFileOffset =\r
3087 DebugDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;\r
3088 }\r
3089 if (ExportDirectoryEntryRva >= SectionHeader->VirtualAddress &&\r
3090 ExportDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {\r
3091 ExportDirectoryEntryFileOffset =\r
3092 ExportDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;\r
3093 }\r
3094 if (ResourceDirectoryEntryRva >= SectionHeader->VirtualAddress &&\r
3095 ResourceDirectoryEntryRva < SectionHeader->VirtualAddress + SectionHeader->Misc.VirtualSize) {\r
3096 ResourceDirectoryEntryFileOffset =\r
3097 ResourceDirectoryEntryRva - SectionHeader->VirtualAddress + SectionHeader->PointerToRawData;\r
3098 }\r
3099 }\r
3100\r
3101 //\r
3102 // Set new stamp\r
3103 //\r
3104 FileHdr->TimeDateStamp = (UINT32) newtime;\r
52302d4d 3105 mImageTimeStamp = (UINT32) newtime;\r
30fdf114
LG
3106 if (ExportDirectoryEntryRva != 0) {\r
3107 NewTimeStamp = (UINT32 *) (FileBuffer + ExportDirectoryEntryFileOffset + sizeof (UINT32));\r
3108 *NewTimeStamp = (UINT32) newtime;\r
3109 }\r
3110\r
3111 if (ResourceDirectoryEntryRva != 0) {\r
3112 NewTimeStamp = (UINT32 *) (FileBuffer + ResourceDirectoryEntryFileOffset + sizeof (UINT32));\r
3113 *NewTimeStamp = (UINT32) newtime;\r
3114 }\r
3115\r
3116 if (DebugDirectoryEntryRva != 0) {\r
3117 NewTimeStamp = (UINT32 *) (FileBuffer + DebugDirectoryEntryFileOffset + sizeof (UINT32));\r
3118 *NewTimeStamp = (UINT32) newtime;\r
3119 }\r
3120\r
3121 return EFI_SUCCESS;\r
3122}\r
3123\r
3124STATIC\r
3125STATUS\r
3126MicrocodeReadData (\r
3127 FILE *InFptr,\r
3128 UINT32 *Data\r
3129 )\r
3130/*++\r
3131\r
3132Routine Description:\r
3133 Read a 32-bit microcode data value from a text file and convert to raw binary form.\r
3134\r
3135Arguments:\r
3136 InFptr - file pointer to input text file\r
3137 Data - pointer to where to return the data parsed\r
3138\r
3139Returns:\r
3140 STATUS_SUCCESS - no errors or warnings, Data contains valid information\r
3141 STATUS_ERROR - errors were encountered\r
3142\r
3143--*/\r
3144{\r
3145 CHAR8 Line[MAX_LINE_LEN];\r
3146 CHAR8 *cptr;\r
fd171542 3147 unsigned ScannedData = 0;\r
30fdf114
LG
3148\r
3149 Line[MAX_LINE_LEN - 1] = 0;\r
3150 while (1) {\r
3151 if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {\r
3152 return STATUS_ERROR;\r
3153 }\r
3154 //\r
3155 // If it was a binary file, then it may have overwritten our null terminator\r
3156 //\r
3157 if (Line[MAX_LINE_LEN - 1] != 0) {\r
3158 return STATUS_ERROR;\r
3159 }\r
3160\r
3161 //\r
3162 // strip space\r
3163 //\r
a709adfa 3164 for (cptr = Line; *cptr && isspace((int)*cptr); cptr++) {\r
30fdf114
LG
3165 }\r
3166\r
3167 // Skip Blank Lines and Comment Lines\r
3168 if ((strlen(cptr) != 0) && (*cptr != ';')) {\r
3169 break;\r
3170 }\r
3171 }\r
3172\r
3173 // Look for\r
3174 // dd 000000001h ; comment\r
3175 // dd XXXXXXXX\r
3176 // DD XXXXXXXXX\r
3177 // DD XXXXXXXXX\r
3178 //\r
a709adfa 3179 if ((tolower((int)cptr[0]) == 'd') && (tolower((int)cptr[1]) == 'd') && isspace ((int)cptr[2])) {\r
30fdf114
LG
3180 //\r
3181 // Skip blanks and look for a hex digit\r
3182 //\r
3183 cptr += 3;\r
a709adfa 3184 for (; *cptr && isspace((int)*cptr); cptr++) {\r
30fdf114 3185 }\r
a709adfa 3186 if (isxdigit ((int)*cptr)) {\r
fd171542 3187 if (sscanf (cptr, "%X", &ScannedData) != 1) {\r
30fdf114
LG
3188 return STATUS_ERROR;\r
3189 }\r
3190 }\r
fd171542 3191 *Data = (UINT32) ScannedData;\r
30fdf114
LG
3192 return STATUS_SUCCESS;\r
3193 }\r
3194\r
3195 return STATUS_ERROR;\r
3196}\r