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