]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/SecFixup/SecFixup.c
1. Removed the unnecessary #include statements and include files
[mirror_edk2.git] / Tools / Source / TianoTools / SecFixup / SecFixup.c
CommitLineData
d25c4bf0 1/*++\r
2\r
3Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved\r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
12\r
13Module Name:\r
14\r
15 SecFixup.c\r
16\r
17Abstract:\r
18\r
19 This utility is part of build process for IA32 SEC FFS file.\r
20 \r
21 It fixup the reset vector data. The reset vector data binary file\r
22 will be wrapped as a RAW section and be located immediately after\r
23 the PE/TE section.\r
24\r
25 The SEC EXE file can be either PE or TE file.\r
26 \r
27--*/\r
28\r
29#include <stdio.h>\r
30\r
ce53a8c3 31#include <Common/UefiBaseTypes.h>\r
32#include <Common/EfiImage.h>\r
33#include <Common/FirmwareVolumeImageFormat.h>\r
d25c4bf0 34\r
ce53a8c3 35#include "EfiUtilityMsgs.c"\r
d25c4bf0 36#include "SecFixup.h"\r
37\r
38VOID\r
39PrintUtilityInfo (\r
40 VOID\r
41 )\r
42/*++\r
43\r
44Routine Description:\r
45\r
46 Displays the standard utility information to SDTOUT\r
47\r
48Arguments:\r
49\r
50 None\r
51\r
52Returns:\r
53\r
54 None\r
55\r
56--*/\r
57{\r
58 printf (\r
59 "%s - Tiano IA32 SEC Fixup Utility."" Version %i.%i\n\n",\r
60 UTILITY_NAME,\r
61 UTILITY_MAJOR_VERSION,\r
62 UTILITY_MINOR_VERSION\r
63 );\r
64}\r
65\r
66VOID\r
67PrintUsage (\r
68 VOID\r
69 )\r
70/*++\r
71\r
72Routine Description:\r
73\r
74 Displays the utility usage syntax to STDOUT\r
75\r
76Arguments:\r
77\r
78 None\r
79\r
80Returns:\r
81\r
82 None\r
83\r
84--*/\r
85{\r
86 printf ("Usage: %s SecExeFile ResetVectorDataFile OutputFile\n", UTILITY_NAME);\r
87 printf (" Where:\n");\r
88 printf ("\tSecExeFile - Name of the IA32 SEC EXE file.\n");\r
89 printf ("\tResetVectorDataFile - Name of the reset vector data binary file.\n");\r
90 printf ("\tOutputFileName - Name of the output file.\n\n");\r
91}\r
92\r
93STATUS\r
94main (\r
95 IN INTN argc,\r
96 IN CHAR8 **argv\r
97 )\r
98/*++\r
99\r
100Routine Description:\r
101\r
102 Main function.\r
103\r
104Arguments:\r
105\r
106 argc - Number of command line parameters.\r
107 argv - Array of pointers to parameter strings.\r
108\r
109Returns:\r
110 STATUS_SUCCESS - Utility exits successfully.\r
111 STATUS_ERROR - Some error occurred during execution.\r
112\r
113--*/\r
114{\r
115 FILE *FpIn;\r
116\r
117 FILE *FpOut;\r
118 UINT32 AddressOfEntryPoint;\r
119 INT32 DestRel;\r
120 STATUS Status;\r
121 UINT32 SecFileSize;\r
122\r
123 SetUtilityName (UTILITY_NAME);\r
124\r
125 //\r
126 // Display utility information\r
127 //\r
128 PrintUtilityInfo ();\r
129\r
130 //\r
131 // Verify the correct number of arguments\r
132 //\r
133 if (argc != MAX_ARGS) {\r
134 Error (NULL, 0, 0, "invalid number of input parameters specified", NULL);\r
135 PrintUsage ();\r
136 return STATUS_ERROR;\r
137 }\r
138 //\r
139 // Open the SEC exe file\r
140 //\r
141 if ((FpIn = fopen (argv[1], "rb")) == NULL) {\r
142 Error (NULL, 0, 0, "Unable to open file", argv[1]);\r
143 return STATUS_ERROR;\r
144 }\r
145 //\r
146 // Get the entry point of the EXE file\r
147 //\r
148 Status = GetEntryPoint (FpIn, &AddressOfEntryPoint);\r
149 if (Status != STATUS_SUCCESS) {\r
150 fclose (FpIn);\r
151 return STATUS_ERROR;\r
152 }\r
153 //\r
154 // Get the SEC file size\r
155 //\r
156 fseek (FpIn, 0, SEEK_END);\r
157 SecFileSize = ftell (FpIn);\r
158\r
159 //\r
160 // Close the SEC file\r
161 //\r
162 fclose (FpIn);\r
163\r
164 //\r
165 // Open the reset vector data file\r
166 //\r
167 if ((FpIn = fopen (argv[2], "rb")) == NULL) {\r
168 Error (NULL, 0, 0, "Unable to open file", argv[2]);\r
169 return STATUS_ERROR;\r
170 }\r
171 //\r
172 // Open the output file\r
173 //\r
174 if ((FpOut = fopen (argv[3], "w+b")) == NULL) {\r
175 Error (NULL, 0, 0, "Unable to open file", argv[3]);\r
176 fclose (FpIn);\r
177 return STATUS_ERROR;\r
178 }\r
179 //\r
180 // Copy the input file to the output file\r
181 //\r
182 if (CopyFile (FpIn, FpOut) != STATUS_SUCCESS) {\r
183 fclose (FpIn);\r
184 fclose (FpOut);\r
185 return STATUS_ERROR;\r
186 }\r
187 //\r
188 // Close the reset vector data file\r
189 //\r
190 fclose (FpIn);\r
191\r
192 //\r
193 // Fix the destination relative in the jmp instruction\r
194 // in the reset vector data structure\r
195 //\r
196 fseek (FpOut, -DEST_REL_OFFSET, SEEK_END);\r
197 DestRel = AddressOfEntryPoint - (SecFileSize + sizeof (EFI_COMMON_SECTION_HEADER) + (UINT32) (ftell (FpOut)) + 2);\r
198 if (DestRel <= -65536) {\r
199 Error (NULL, 0, 0, "The SEC EXE file size is too big", NULL);\r
200 fclose (FpOut);\r
201 return STATUS_ERROR;\r
202 }\r
203\r
204 if (fwrite (&DestRel, sizeof (UINT16), 1, FpOut) != 1) {\r
205 Error (NULL, 0, 0, "Failed to write to the output file", NULL);\r
206 fclose (FpOut);\r
207 return STATUS_ERROR;\r
208 }\r
209 //\r
210 // Close the output file\r
211 //\r
212 fclose (FpOut);\r
213\r
214 return STATUS_SUCCESS;\r
215}\r
216\r
217STATUS\r
218GetEntryPoint (\r
219 IN FILE *ExeFile,\r
220 OUT UINT32 *EntryPoint\r
221 )\r
222/*++\r
223\r
224Routine Description:\r
225\r
226 Get the address of the entry point of a PE/TE file.\r
227\r
228Arguments:\r
229\r
230 PeFile - File pointer to the specified PE/TE file.\r
231 EntryPoint - Buffer for the address of the entry point to be returned.\r
232\r
233Returns:\r
234 STATUS_SUCCESS - Function completed successfully.\r
235 STATUS_ERROR - Error occured.\r
236\r
237--*/\r
238// GC_TODO: ExeFile - add argument and description to function comment\r
239{\r
240 EFI_IMAGE_DOS_HEADER DosHeader;\r
241 EFI_IMAGE_NT_HEADERS32 NtHeader;\r
242 EFI_TE_IMAGE_HEADER TeHeader;\r
243\r
244 //\r
245 // Check if it is a TE file\r
246 //\r
247 fseek (ExeFile, 0, SEEK_SET);\r
248 //\r
249 // Attempt to read the TE header\r
250 //\r
251 if (fread (&TeHeader, sizeof (TeHeader), 1, ExeFile) == 1) {\r
252 if (TeHeader.Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
253 if (TeHeader.Machine != EFI_IMAGE_MACHINE_IA32) {\r
254 Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);\r
255 return STATUS_ERROR;\r
256 }\r
257\r
258 *EntryPoint = TeHeader.AddressOfEntryPoint + sizeof (EFI_TE_IMAGE_HEADER) - TeHeader.StrippedSize;\r
259 return STATUS_SUCCESS;\r
260 }\r
261 }\r
262 //\r
263 // Check if it is a PE file\r
264 //\r
265 fseek (ExeFile, 0, SEEK_SET);\r
266 //\r
267 // Attempt to read the DOS header\r
268 //\r
269 if (fread (&DosHeader, sizeof (DosHeader), 1, ExeFile) != 1) {\r
270 goto InvalidFile;\r
271 }\r
272 //\r
273 // Check the magic number\r
274 //\r
275 if (DosHeader.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
276 goto InvalidFile;\r
277 }\r
278 //\r
279 // Position into the file and read the NT PE header\r
280 //\r
281 fseek (ExeFile, (long) DosHeader.e_lfanew, SEEK_SET);\r
282 if (fread (&NtHeader, sizeof (NtHeader), 1, ExeFile) != 1) {\r
283 goto InvalidFile;\r
284 }\r
285 //\r
286 // Check the PE signature in the header\r
287 //\r
288 if (NtHeader.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
289 goto InvalidFile;\r
290 }\r
291 //\r
292 // Make sure the PE file is PE32 for IA32\r
293 //\r
294 if (NtHeader.FileHeader.Machine != EFI_IMAGE_MACHINE_IA32 ||\r
295 NtHeader.OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC\r
296 ) {\r
297 Error (NULL, 0, 0, "The SEC file is PE but is not PE32 for IA32", NULL);\r
298 return STATUS_ERROR;\r
299 }\r
300 //\r
301 // Get the entry point from the optional header\r
302 //\r
303 *EntryPoint = NtHeader.OptionalHeader.AddressOfEntryPoint;\r
304 return STATUS_SUCCESS;\r
305\r
306InvalidFile:\r
307 Error (NULL, 0, 0, "The SEC file is neither PE nor TE file", NULL);\r
308 return STATUS_ERROR;\r
309}\r
310\r
311STATUS\r
312CopyFile (\r
313 FILE *FpIn,\r
314 FILE *FpOut\r
315 )\r
316/*++\r
317\r
318Routine Description:\r
319\r
320 Copy file.\r
321\r
322Arguments:\r
323\r
324 FpIn - File pointer to the source file.\r
325 FpOut - File pointer to the destination file.\r
326\r
327Returns:\r
328 STATUS_SUCCESS - Function completed successfully.\r
329 STATUS_ERROR - Error occured.\r
330\r
331--*/\r
332{\r
333 INTN FileSize;\r
334\r
335 INTN Offset;\r
336\r
337 INTN Length;\r
338 UINT8 Buffer[BUF_SIZE];\r
339\r
340 fseek (FpIn, 0, SEEK_END);\r
341 FileSize = ftell (FpIn);\r
342\r
343 fseek (FpIn, 0, SEEK_SET);\r
344 fseek (FpOut, 0, SEEK_SET);\r
345\r
346 Offset = 0;\r
347 while (Offset < FileSize) {\r
348 Length = sizeof (Buffer);\r
349 if (FileSize - Offset < Length) {\r
350 Length = FileSize - Offset;\r
351 }\r
352\r
353 if (fread (Buffer, Length, 1, FpIn) != 1 || fwrite (Buffer, Length, 1, FpOut) != 1) {\r
354 Error (NULL, 0, 0, "Copy file error", NULL);\r
355 return STATUS_ERROR;\r
356 }\r
357\r
358 Offset += Length;\r
359 }\r
360\r
361 return STATUS_SUCCESS;\r
362}\r