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