3 Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
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 <UefiBaseTypes.h>
34 #include "FirmwareVolumeImageFormat.h"
35 #include "EfiUtilityMsgs.c"
47 Displays the standard utility information to SDTOUT
60 "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",
62 UTILITY_MAJOR_VERSION
,
75 Displays the utility usage syntax to STDOUT
87 printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME
);
89 printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n");
90 printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n");
91 printf ("\tOutputFileName - Name of the output file.\n\n");
107 argc - Number of command line parameters.
108 argv - Array of pointers to parameter strings.
111 STATUS_SUCCESS - Utility exits successfully.
112 STATUS_ERROR - Some error occurred during execution.
119 UINT32 AddressOfEntryPoint
;
124 SetUtilityName (UTILITY_NAME
);
127 // Display utility information
132 // Verify the correct number of arguments
134 if (argc
!= MAX_ARGS
) {
135 Error (NULL
, 0, 0, "invalid number of input parameters specified", NULL
);
140 // Open the SEC exe file
142 if ((FpIn
= fopen (argv
[1], "rb")) == NULL
) {
143 Error (NULL
, 0, 0, "Unable to open file", argv
[1]);
147 // Get the entry point of the EXE file
149 Status
= GetEntryPoint (FpIn
, &AddressOfEntryPoint
);
150 if (Status
!= STATUS_SUCCESS
) {
155 // Get the SEC file size
157 fseek (FpIn
, 0, SEEK_END
);
158 SecFileSize
= ftell (FpIn
);
161 // Close the SEC file
166 // Open the reset vector data file
168 if ((FpIn
= fopen (argv
[2], "rb")) == NULL
) {
169 Error (NULL
, 0, 0, "Unable to open file", argv
[2]);
173 // Open the output file
175 if ((FpOut
= fopen (argv
[3], "w+b")) == NULL
) {
176 Error (NULL
, 0, 0, "Unable to open file", argv
[3]);
181 // Copy the input file to the output file
183 if (CopyFile (FpIn
, FpOut
) != STATUS_SUCCESS
) {
189 // Close the reset vector data file
194 // Fix the destination relative in the jmp instruction
195 // in the reset vector data structure
197 fseek (FpOut
, -DEST_REL_OFFSET
, SEEK_END
);
198 DestRel
= AddressOfEntryPoint
- (SecFileSize
+ sizeof (EFI_COMMON_SECTION_HEADER
) + (UINT32
) (ftell (FpOut
)) + 2);
199 if (DestRel
<= -65536) {
200 Error (NULL
, 0, 0, "The SEC EXE file size is too big", NULL
);
205 if (fwrite (&DestRel
, sizeof (UINT16
), 1, FpOut
) != 1) {
206 Error (NULL
, 0, 0, "Failed to write to the output file", NULL
);
211 // Close the output file
215 return STATUS_SUCCESS
;
221 OUT UINT32
*EntryPoint
227 Get the address of the entry point of a PE/TE file.
231 PeFile - File pointer to the specified PE/TE file.
232 EntryPoint - Buffer for the address of the entry point to be returned.
235 STATUS_SUCCESS - Function completed successfully.
236 STATUS_ERROR - Error occured.
239 // GC_TODO: ExeFile - add argument and description to function comment
241 EFI_IMAGE_DOS_HEADER DosHeader
;
242 EFI_IMAGE_NT_HEADERS32 NtHeader
;
243 EFI_TE_IMAGE_HEADER TeHeader
;
246 // Check if it is a TE file
248 fseek (ExeFile
, 0, SEEK_SET
);
250 // Attempt to read the TE header
252 if (fread (&TeHeader
, sizeof (TeHeader
), 1, ExeFile
) == 1) {
253 if (TeHeader
.Signature
== EFI_TE_IMAGE_HEADER_SIGNATURE
) {
254 if (TeHeader
.Machine
!= EFI_IMAGE_MACHINE_IA32
) {
255 Error (NULL
, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL
);
259 *EntryPoint
= TeHeader
.AddressOfEntryPoint
+ sizeof (EFI_TE_IMAGE_HEADER
) - TeHeader
.StrippedSize
;
260 return STATUS_SUCCESS
;
264 // Check if it is a PE file
266 fseek (ExeFile
, 0, SEEK_SET
);
268 // Attempt to read the DOS header
270 if (fread (&DosHeader
, sizeof (DosHeader
), 1, ExeFile
) != 1) {
274 // Check the magic number
276 if (DosHeader
.e_magic
!= EFI_IMAGE_DOS_SIGNATURE
) {
280 // Position into the file and read the NT PE header
282 fseek (ExeFile
, (long) DosHeader
.e_lfanew
, SEEK_SET
);
283 if (fread (&NtHeader
, sizeof (NtHeader
), 1, ExeFile
) != 1) {
287 // Check the PE signature in the header
289 if (NtHeader
.Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
293 // Make sure the PE file is PE32 for IA32
295 if (NtHeader
.FileHeader
.Machine
!= EFI_IMAGE_MACHINE_IA32
||
296 NtHeader
.OptionalHeader
.Magic
!= EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
298 Error (NULL
, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL
);
302 // Get the entry point from the optional header
304 *EntryPoint
= NtHeader
.OptionalHeader
.AddressOfEntryPoint
;
305 return STATUS_SUCCESS
;
308 Error (NULL
, 0, 0, "The SEC file is neither PE nor TE file", NULL
);
325 FpIn - File pointer to the source file.
326 FpOut - File pointer to the destination file.
329 STATUS_SUCCESS - Function completed successfully.
330 STATUS_ERROR - Error occured.
339 UINT8 Buffer
[BUF_SIZE
];
341 fseek (FpIn
, 0, SEEK_END
);
342 FileSize
= ftell (FpIn
);
344 fseek (FpIn
, 0, SEEK_SET
);
345 fseek (FpOut
, 0, SEEK_SET
);
348 while (Offset
< FileSize
) {
349 Length
= sizeof (Buffer
);
350 if (FileSize
- Offset
< Length
) {
351 Length
= FileSize
- Offset
;
354 if (fread (Buffer
, Length
, 1, FpIn
) != 1 || fwrite (Buffer
, Length
, 1, FpOut
) != 1) {
355 Error (NULL
, 0, 0, "Copy file error", NULL
);
362 return STATUS_SUCCESS
;