]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/CCode/Source/GenBsfFixup/GenBsfFixup.c
- Fixed EDKT513 by adding existing section files into the dependency check of genffsf...
[mirror_edk2.git] / Tools / CCode / Source / GenBsfFixup / GenBsfFixup.c
CommitLineData
71ea530c 1/*++\r
2\r
f091efb3 3Copyright (c) 1999 - 2006 Intel Corporation. All rights reserved\r
71ea530c 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 GenBsfFixup.c\r
16\r
17Abstract:\r
18\r
19 Utility to Fixup the SEC component for IA32. This is an \r
20 interim tool in place of the full GenBsfImage support for \r
21 IA32.\r
22 This tool supports the Synch3 update\r
23\r
24--*/\r
25\r
26#include "BaseTypes.h"\r
27#include "UefiBaseTypes.h"\r
28#include "EfiImage.h"\r
29#include "FirmwareVolumeHeader.h"\r
30#include "FirmwareVolumeImageFormat.h"\r
31#include "ParseInf.h"\r
32#include "CommonLib.h"\r
33#include "FirmwareFileSystem.h"\r
34#include "FvLib.h"\r
35#include <stdio.h>\r
36#include <stdlib.h>\r
37#include <string.h>\r
38#include <assert.h>\r
39\r
40//\r
41// BugBug -- this port to the new FFS is really weird.\r
42// A lot of the file-header stuff has been ported, but\r
43// not the section information.\r
44//\r
f091efb3 45\r
46#define UTILITY_NAME "GenBsfFixup"\r
47#define UTILITY_MAJOR_VERSION 0\r
48#define UTILITY_MINOR_VERSION 1\r
71ea530c 49\r
50UINT32 gFixup;\r
51\r
52UINT32\r
53GetOccupiedSize (\r
54 IN UINT32 ActualSize,\r
55 IN UINT32 Alignment\r
56 )\r
57/*++\r
58\r
59Routine Description:\r
60\r
61 GC_TODO: Add function description\r
62\r
63Arguments:\r
64\r
65 ActualSize - GC_TODO: add argument description\r
66 Alignment - GC_TODO: add argument description\r
67\r
68Returns:\r
69\r
70 GC_TODO: add return values\r
71\r
72--*/\r
73{\r
74 UINT32 OccupiedSize;\r
75\r
76 OccupiedSize = ActualSize;\r
77 while ((OccupiedSize & (Alignment - 1)) != 0) {\r
78 OccupiedSize++;\r
79 }\r
80\r
81 return OccupiedSize;\r
82}\r
83\r
f091efb3 84static\r
85void\r
86Version (\r
87 VOID\r
88 )\r
89{\r
90 printf ("%s v%d.%d -EDK Utility to Fixup the SEC component for IA32.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
91 printf ("Copyright (c) 1999-2006 Intel Corporation. All rights reserved.\n");\r
92}\r
93\r
94\r
95VOID\r
96Usage (\r
97 VOID\r
98 )\r
99{\r
100 Version();\r
101 printf ("\nUsage: " UTILITY_NAME " FvVolumeImageFile AddressOfFvInMemory OffsetOfFixup OutputFileName \n");\r
102}\r
103\r
71ea530c 104int\r
105ReadHeader (\r
106 FILE *In,\r
107 UINT32 *FvSize\r
108 )\r
109/*++\r
110\r
111Routine Description:\r
112\r
113 Reads in Firmware Volume information from the volume header file.\r
114\r
115Arguments:\r
116\r
117 In: Firmware Volume header file to read from\r
118 FvSize: Size of Firmware Volume\r
119\r
120Returns:\r
121\r
122 int: Number of bytes read\r
123\r
124--*/\r
125{\r
126 EFI_FIRMWARE_VOLUME_HEADER VolumeHeader;\r
127 EFI_FV_BLOCK_MAP_ENTRY BlockMap;\r
128 INT32 SigTemp[2];\r
129 INT32 Invert;\r
130 INT32 bytesread;\r
131 UINT32 size;\r
132\r
133 size = 0;\r
134 Invert = 0;\r
135 bytesread = 0;\r
136\r
137 if (In == NULL) {\r
138 printf ("Error: Input file is NULL.\n");\r
139 return -1;\r
140 }\r
141\r
142 fread (&VolumeHeader, sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In);\r
143 bytesread = sizeof (EFI_FIRMWARE_VOLUME_HEADER) - sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
144 SigTemp[0] = VolumeHeader.Signature;\r
145 SigTemp[1] = 0;\r
146\r
147 if (VolumeHeader.Attributes & EFI_FVB_ERASE_POLARITY) {\r
148 Invert = 1;\r
149 }\r
150\r
151 do {\r
152 fread (&BlockMap, sizeof (EFI_FV_BLOCK_MAP_ENTRY), 1, In);\r
153 bytesread += sizeof (EFI_FV_BLOCK_MAP_ENTRY);\r
154\r
155 if (BlockMap.NumBlocks != 0) {\r
156 size += BlockMap.NumBlocks * BlockMap.BlockLength;\r
157 }\r
158\r
159 } while (BlockMap.NumBlocks != 0);\r
160\r
161 *FvSize = size;\r
162 rewind (In);\r
163\r
164 if (Invert == 1) {\r
165 bytesread *= -1;\r
166 }\r
167\r
168 return bytesread;\r
169}\r
170\r
171UINT32\r
172GetSectionLength (\r
173 IN UINT32 *Length\r
174 )\r
175/*++\r
176\r
177Routine Description:\r
178\r
179 Converts a UINT8[3] array to a UINT32\r
180\r
181Arguments:\r
182\r
183 Length A pointer to a 3 byte array\r
184\r
185Returns:\r
186\r
187 UINT32: The length.\r
188\r
189--*/\r
190{\r
191 return *Length & 0x00FFFFFF;\r
192}\r
193\r
194int\r
195Readfile (\r
196 UINT8 *FvImage,\r
197 int bytes,\r
198 int Invert\r
199 )\r
200/*++\r
201\r
202Routine Description:\r
203\r
204 GC_TODO: Add function description\r
205\r
206Arguments:\r
207\r
208 FvImage - GC_TODO: add argument description\r
209 bytes - GC_TODO: add argument description\r
210 Invert - GC_TODO: add argument description\r
211\r
212Returns:\r
213\r
214 GC_TODO: add return values\r
215\r
216--*/\r
217{\r
218 UINT32 FileLength;\r
219 UINT32 OccupiedFileLength;\r
220 EFI_FFS_FILE_HEADER *FileHeader;\r
221 UINT8 FileState;\r
222 UINT8 Checksum;\r
223 UINT8 *Ptr;\r
224 UINT32 SectionLength;\r
225 EFI_COMMON_SECTION_HEADER *SectionHeader;\r
226 EFI_IMAGE_NT_HEADERS *PeHeader;\r
227 UINT32 PeiCoreOffset;\r
228\r
229 Ptr = FvImage + bytes;\r
230\r
231 FileHeader = (EFI_FFS_FILE_HEADER *) Ptr;\r
232\r
233 FileState = GetFileState ((UINT8) Invert, FileHeader);\r
234\r
235 switch (FileState) {\r
236 case EFI_FILE_HEADER_CONSTRUCTION:\r
237 case EFI_FILE_HEADER_INVALID:\r
238 return sizeof (EFI_FFS_FILE_HEADER);\r
239\r
240 case EFI_FILE_HEADER_VALID:\r
241 Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
242 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
243 Checksum = (UINT8) (Checksum - FileHeader->State);\r
244 if (Checksum != 0) {\r
245 return -1;\r
246 }\r
247 //\r
248 // Now do the fixup stuff - begin\r
249 //\r
250 if (FileHeader->Type == EFI_FV_FILETYPE_PEI_CORE) {\r
251 SectionHeader = (EFI_COMMON_SECTION_HEADER *) FileHeader + sizeof (EFI_FFS_FILE_HEADER);\r
252 SectionLength = GetSectionLength ((UINT32 *) &SectionHeader->Size[0]);\r
253\r
254 printf ("Section length is 0x%X\n", SectionLength);\r
255\r
256 if (SectionHeader->Type == EFI_SECTION_PE32) {\r
257\r
258 gFixup = bytes + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER);\r
259\r
260 PeHeader = (EFI_IMAGE_NT_HEADERS *) Ptr + sizeof (EFI_FFS_FILE_HEADER) + sizeof (EFI_COMMON_SECTION_HEADER);\r
261\r
262 if (((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
263 //\r
264 // DOS image header is present, so read the PE header after the DOS image header\r
265 //\r
266 PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) PeHeader + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) PeHeader)->e_lfanew) & 0x0ffff));\r
267\r
268 }\r
269\r
270 PeiCoreOffset = (UINTN) ((UINTN) (PeHeader->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));\r
271\r
272 gFixup += PeiCoreOffset;\r
273 }\r
274 }\r
275\r
276 FileLength = GetLength (FileHeader->Size);\r
277 OccupiedFileLength = GetOccupiedSize (FileLength, 8);\r
278 return OccupiedFileLength;\r
279\r
280 case EFI_FILE_DATA_VALID:\r
281 //\r
282 // Calculate header checksum\r
283 //\r
284 Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
285 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
286 Checksum = (UINT8) (Checksum - FileHeader->State);\r
287 if (Checksum != 0) {\r
288 return -1;\r
289 }\r
290 //\r
291 // Determine file length\r
292 //\r
293 FileLength = GetLength (FileHeader->Size);\r
294 OccupiedFileLength = GetOccupiedSize (FileLength, 8);\r
295\r
296 //\r
297 // Determine if file checksum is valid or fixed\r
298 //\r
299 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
300 Checksum = CalculateSum8 (Ptr, FileLength);\r
301 Checksum = (UINT8) (Checksum - FileHeader->State);\r
302 if (Checksum != 0) {\r
303 return -1;\r
304 }\r
305 } else {\r
306 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
307 return -1;\r
308 }\r
309 }\r
310 break;\r
311\r
312 case EFI_FILE_MARKED_FOR_UPDATE:\r
313 case EFI_FILE_DELETED:\r
314 //\r
315 // Calculate header checksum\r
316 //\r
317 Checksum = CalculateSum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
318 Checksum = (UINT8) (Checksum - FileHeader->IntegrityCheck.Checksum.File);\r
319 Checksum = (UINT8) (Checksum - FileHeader->State);\r
320 if (Checksum != 0) {\r
321 return -1;\r
322 }\r
323 //\r
324 // Determine file length\r
325 //\r
326 FileLength = GetLength (FileHeader->Size);\r
327 OccupiedFileLength = GetOccupiedSize (FileLength, 8);\r
328\r
329 //\r
330 // Determine if file checksum is valid or fixed\r
331 //\r
332 if (FileHeader->Attributes & FFS_ATTRIB_CHECKSUM) {\r
333 Checksum = CalculateSum8 (Ptr, FileLength);\r
334 Checksum = (UINT8) (Checksum - FileHeader->State);\r
335 if (Checksum != 0) {\r
336 return -1;\r
337 }\r
338 } else {\r
339 if (FileHeader->IntegrityCheck.Checksum.File != FFS_FIXED_CHECKSUM) {\r
340 return -1;\r
341 }\r
342 }\r
343\r
344 return OccupiedFileLength;\r
345\r
346 default:\r
347 return sizeof (EFI_FFS_FILE_HEADER);\r
348 }\r
349\r
350 return OccupiedFileLength;\r
351}\r
352\r
353int\r
354main (\r
355 int argc,\r
356 char*argv[]\r
357 )\r
358/*++\r
359\r
360Routine Description:\r
361\r
362 Runs GenBsfFixup\r
363\r
364Arguments:\r
365\r
366 argc: number of command line arguments\r
367\r
368 arg[0] = This file name\r
369 arg[1] = Firmware Volume Name\r
370 arg[2] = Base Address to relocate\r
371 arg[3] = Relative offset of the fixup to perform\r
372 arg[4] = Output File Name\r
373\r
374Returns:\r
375 \r
376 int: 0 code success, -1 code failure\r
377\r
378--*/\r
379{\r
380 FILE *In;\r
381 FILE *Out;\r
382 int ByteStart;\r
383 int Invert;\r
384 int Index;\r
385 int cnt;\r
386 UINT8 *FvImage;\r
387 int ByteRead;\r
388 UINT32 FvSize;\r
389 UINT64 delta;\r
390 UINT32 Idx;\r
391 UINT64 FvOffset;\r
392 EFI_STATUS Status;\r
393\r
394 Index = 0;\r
395 Invert = 0;\r
f091efb3 396 \r
db608e6b 397 if (argc == 1) {\r
f091efb3 398 Usage();\r
399 return -1;\r
400 }\r
401 \r
402 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
403 (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
404 Usage();\r
405 return -1;\r
406 }\r
407 \r
408 if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
409 Version();\r
410 return -1;\r
411 }\r
412 \r
71ea530c 413 if (argc != 5) {\r
f091efb3 414 Usage();\r
71ea530c 415 return -1;\r
416 }\r
417\r
418 In = fopen (argv[1], "rb");\r
419\r
420 if (In == NULL) {\r
421 printf ("Unable to open FV image file \"%s\"\n", argv[1]);\r
422 return -1;\r
423 }\r
424\r
425 ByteStart = ReadHeader (In, &FvSize);\r
426\r
427 if (ByteStart < 0) {\r
428 Invert = 1;\r
429 ByteStart *= -1;\r
430 }\r
431\r
432 FvImage = malloc (FvSize);\r
433 if (FvImage == NULL) {\r
434 printf ("Cannot allocate memory\n");\r
435 fclose (In);\r
436 return -1;\r
437 }\r
438\r
439 ByteRead = fread (FvImage, 1, FvSize, In);\r
440\r
441 if ((unsigned int) ByteRead != FvSize) {\r
442 printf ("Read File error\n");\r
443 fclose (In);\r
444 return -1;\r
445 }\r
446\r
447 cnt = 0;\r
448 while ((unsigned int) ByteStart < FvSize && cnt != -1) {\r
449 cnt = Readfile (FvImage, ByteStart, Invert);\r
450\r
451 if (cnt != -1) {\r
452 ByteStart += cnt;\r
453 }\r
454\r
455 if (cnt != sizeof (EFI_FFS_FILE_HEADER)) {\r
456 Index++;\r
457 }\r
458 }\r
459\r
460 if (cnt == -1) {\r
461 printf ("Firmware Volume image corrupted\n");\r
462 return -1;\r
463 }\r
464\r
465 fclose (In);\r
466\r
467 Out = fopen (argv[4], "wb");\r
468\r
469 if (Out == NULL) {\r
470 printf ("Unable to open FV image file \"%s\"\n", argv[4]);\r
471 return -1;\r
472 }\r
473\r
474 In = fopen (argv[1], "rb");\r
475\r
476 if (In == NULL) {\r
477 printf ("Unable to open FV image file \"%s\"\n", argv[1]);\r
478 return -1;\r
479 }\r
480\r
481 if (gFixup != 0) {\r
482\r
483 printf ("Fixup of 0x%X\n", gFixup);\r
484\r
485 Status = AsciiStringToUint64 (argv[2], TRUE, &FvOffset);\r
486\r
487 gFixup += (UINT32) FvOffset;\r
488\r
489 ByteStart = ReadHeader (In, &FvSize);\r
490\r
491 Readfile (FvImage, ByteStart, Invert);\r
492\r
493 cnt = 0;\r
494 Status = AsciiStringToUint64 (argv[3], TRUE, &delta);\r
495\r
496 fclose (In);\r
497 In = fopen (argv[1], "rb");\r
498\r
499 if (In == NULL) {\r
500 printf ("Unable to open FV image file \"%s\"\n", argv[1]);\r
501 return -1;\r
502 }\r
503\r
504 for (Idx = 0; Idx < delta - FvOffset; Idx++) {\r
505 fputc (fgetc (In), Out);\r
506 }\r
507\r
508 fwrite (&gFixup, sizeof (UINT32), 1, Out);\r
509 fseek (In, sizeof (UINT32), SEEK_CUR);\r
510\r
511 for (Idx = 0; Idx < FvSize - (delta - FvOffset) - sizeof (UINT32); Idx++) {\r
512 fputc (fgetc (In), Out);\r
513 }\r
514\r
515 fclose (In);\r
516 fclose (Out);\r
517 } else {\r
518 printf ("There was no fixup to perform\n");\r
519 }\r
520\r
521 free (FvImage);\r
522\r
523 return 0;\r
524}\r