3 Copyright (c) 1999-2006 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 This utility is part of build process for IA32 SEC FFS file.
21 It fixup the reset vector data. The reset vector data binary file
22 will be wrapped as a RAW section and be located immediately after
25 The SEC EXE file can be either PE or TE file.
31 #include <Common/UefiBaseTypes.h>
32 #include <Common/EfiImage.h>
33 #include <Common/FirmwareVolumeImageFormat.h>
35 #include "EfiUtilityMsgs.c"
46 Displays the standard utility information to SDTOUT
59 "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",
61 UTILITY_MAJOR_VERSION
,
74 Displays the utility usage syntax to STDOUT
86 printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME
);
88 printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n");
89 printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n");
90 printf ("\tOutputFileName - Name of the output file.\n\n");
106 argc - Number of command line parameters.
107 argv - Array of pointers to parameter strings.
110 STATUS_SUCCESS - Utility exits successfully.
111 STATUS_ERROR - Some error occurred during execution.
118 UINT32 AddressOfEntryPoint
;
123 SetUtilityName (UTILITY_NAME
);
126 // Display utility information
131 // Verify the correct number of arguments
133 if (argc
!= MAX_ARGS
) {
134 Error (NULL
, 0, 0, "invalid number of input parameters specified", NULL
);
139 // Open the SEC exe file
141 if ((FpIn
= fopen (argv
[1], "rb")) == NULL
) {
142 Error (NULL
, 0, 0, "Unable to open file", argv
[1]);
146 // Get the entry point of the EXE file
148 Status
= GetEntryPoint (FpIn
, &AddressOfEntryPoint
);
149 if (Status
!= STATUS_SUCCESS
) {
154 // Get the SEC file size
156 fseek (FpIn
, 0, SEEK_END
);
157 SecFileSize
= ftell (FpIn
);
160 // Close the SEC file
165 // Open the reset vector data file
167 if ((FpIn
= fopen (argv
[2], "rb")) == NULL
) {
168 Error (NULL
, 0, 0, "Unable to open file", argv
[2]);
172 // Open the output file
174 if ((FpOut
= fopen (argv
[3], "w+b")) == NULL
) {
175 Error (NULL
, 0, 0, "Unable to open file", argv
[3]);
180 // Copy the input file to the output file
182 if (CopyFile (FpIn
, FpOut
) != STATUS_SUCCESS
) {
188 // Close the reset vector data file
193 // Fix the destination relative in the jmp instruction
194 // in the reset vector data structure
196 fseek (FpOut
, -DEST_REL_OFFSET
, SEEK_END
);
197 DestRel
= AddressOfEntryPoint
- (SecFileSize
+ sizeof (EFI_COMMON_SECTION_HEADER
) + (UINT32
) (ftell (FpOut
)) + 2);
198 if (DestRel
<= -65536) {
199 Error (NULL
, 0, 0, "The SEC EXE file size is too big", NULL
);
204 if (fwrite (&DestRel
, sizeof (UINT16
), 1, FpOut
) != 1) {
205 Error (NULL
, 0, 0, "Failed to write to the output file", NULL
);
210 // Close the output file
214 return STATUS_SUCCESS
;
220 OUT UINT32
*EntryPoint
226 Get the address of the entry point of a PE/TE file.
230 PeFile - File pointer to the specified PE/TE file.
231 EntryPoint - Buffer for the address of the entry point to be returned.
234 STATUS_SUCCESS - Function completed successfully.
235 STATUS_ERROR - Error occured.
238 // GC_TODO: ExeFile - add argument and description to function comment
240 EFI_IMAGE_DOS_HEADER DosHeader
;
241 EFI_IMAGE_NT_HEADERS32 NtHeader
;
242 EFI_TE_IMAGE_HEADER TeHeader
;
245 // Check if it is a TE file
247 fseek (ExeFile
, 0, SEEK_SET
);
249 // Attempt to read the TE header
251 if (fread (&TeHeader
, sizeof (TeHeader
), 1, ExeFile
) == 1) {
252 if (TeHeader
.Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
253 if (TeHeader
.Machine
!= EFI_IMAGE_MACHINE_IA32
) {
254 Error (NULL
, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL
);
258 *EntryPoint
= TeHeader
.AddressOfEntryPoint
+ sizeof (EFI_TE_IMAGE_HEADER
) - TeHeader
.StrippedSize
;
259 return STATUS_SUCCESS
;
263 // Check if it is a PE file
265 fseek (ExeFile
, 0, SEEK_SET
);
267 // Attempt to read the DOS header
269 if (fread (&DosHeader
, sizeof (DosHeader
), 1, ExeFile
) != 1) {
273 // Check the magic number
275 if (DosHeader
.e_magic
!= EFI_IMAGE_DOS_SIGNATURE
) {
279 // Position into the file and read the NT PE header
281 fseek (ExeFile
, (long) DosHeader
.e_lfanew
, SEEK_SET
);
282 if (fread (&NtHeader
, sizeof (NtHeader
), 1, ExeFile
) != 1) {
286 // Check the PE signature in the header
288 if (NtHeader
.Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
292 // Make sure the PE file is PE32 for IA32
294 if (NtHeader
.FileHeader
.Machine
!= EFI_IMAGE_MACHINE_IA32
||
295 NtHeader
.OptionalHeader
.Magic
!= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
297 Error (NULL
, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL
);
301 // Get the entry point from the optional header
303 *EntryPoint
= NtHeader
.OptionalHeader
.AddressOfEntryPoint
;
304 return STATUS_SUCCESS
;
307 Error (NULL
, 0, 0, "The SEC file is neither PE nor TE file", NULL
);
324 FpIn - File pointer to the source file.
325 FpOut - File pointer to the destination file.
328 STATUS_SUCCESS - Function completed successfully.
329 STATUS_ERROR - Error occured.
338 UINT8 Buffer
[BUF_SIZE
];
340 fseek (FpIn
, 0, SEEK_END
);
341 FileSize
= ftell (FpIn
);
343 fseek (FpIn
, 0, SEEK_SET
);
344 fseek (FpOut
, 0, SEEK_SET
);
347 while (Offset
< FileSize
) {
348 Length
= sizeof (Buffer
);
349 if (FileSize
- Offset
< Length
) {
350 Length
= FileSize
- Offset
;
353 if (fread (Buffer
, Length
, 1, FpIn
) != 1 || fwrite (Buffer
, Length
, 1, FpOut
) != 1) {
354 Error (NULL
, 0, 0, "Copy file error", NULL
);
361 return STATUS_SUCCESS
;