Use ASM_PFX to optionnaly set the underscore prefix
[mirror_edk2.git] / Tools / CCode / Source / FwImage / fwimage.c
CommitLineData
878ddf1f 1/*++\r
2\r
3Copyright (c) 2004, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 fwimage.c\r
15\r
16Abstract:\r
17\r
18 Converts a pe32+ image to an FW image type\r
19\r
20--*/\r
21\r
ce53a8c3 22#include "WinNtInclude.h"\r
23\r
878ddf1f 24#ifndef __GNUC__\r
25#include <windows.h>\r
26#endif\r
27#include <stdio.h>\r
28#include <stdlib.h>\r
29#include <string.h>\r
30#include <time.h>\r
31\r
ce53a8c3 32#include <Common/UefiBaseTypes.h>\r
33#include <Common/EfiImage.h>\r
34\r
35#include "CommonLib.h"\r
36#include "EfiUtilityMsgs.c"\r
878ddf1f 37\r
f091efb3 38//\r
39// Version of this utility\r
40//\r
41#define UTILITY_NAME "FwImage"\r
42#define UTILITY_MAJOR_VERSION 1\r
43#define UTILITY_MINOR_VERSION 0\r
878ddf1f 44\r
45#ifdef __GNUC__\r
46typedef unsigned long ULONG;\r
47typedef unsigned char UCHAR;\r
48typedef unsigned char *PUCHAR;\r
49typedef unsigned short USHORT;\r
50#endif\r
51\r
f091efb3 52static\r
53void\r
54Version (\r
55 VOID\r
56 )\r
57{\r
58 printf ("%s v%d.%d -EDK Utility for Converting a pe32+ image to an FW image type.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
59 printf ("Copyright (c) 1999-2006 Intel Corporation. All rights reserved.\n");\r
60}\r
61\r
62\r
878ddf1f 63VOID\r
64Usage (\r
65 VOID\r
66 )\r
67{\r
f091efb3 68 Version();\r
69 printf ("\nUsage: " UTILITY_NAME " {-t time-date} {-h|--help|-?|/?|-V|--version} \n\\r
70 [BASE|SEC|PEI_CORE|PEIM|DXE_CORE|DXE_DRIVER|DXE_RUNTIME_DRIVER|\n\\r
71 DXE_SAL_DRIVER|DXE_SMM_DRIVER|TOOL|UEFI_DRIVER|UEFI_APPLICATION|\n\\r
72 USER_DEFINED] peimage [outimage]");\r
878ddf1f 73}\r
74\r
75static\r
76STATUS\r
77FCopyFile (\r
78 FILE *in,\r
79 FILE *out\r
80 )\r
81{\r
82 ULONG filesize;\r
83 ULONG offset;\r
84 ULONG length;\r
85 UCHAR Buffer[8 * 1024];\r
86\r
87 fseek (in, 0, SEEK_END);\r
88 filesize = ftell (in);\r
89\r
90 fseek (in, 0, SEEK_SET);\r
91 fseek (out, 0, SEEK_SET);\r
92\r
93 offset = 0;\r
94 while (offset < filesize) {\r
95 length = sizeof (Buffer);\r
96 if (filesize - offset < length) {\r
97 length = filesize - offset;\r
98 }\r
99\r
100 fread (Buffer, length, 1, in);\r
101 fwrite (Buffer, length, 1, out);\r
102 offset += length;\r
103 }\r
104\r
105 if ((ULONG) ftell (out) != filesize) {\r
106 Error (NULL, 0, 0, "write error", NULL);\r
107 return STATUS_ERROR;\r
108 }\r
109\r
110 return STATUS_SUCCESS;\r
111}\r
112\r
3edf127e 113static\r
114STATUS\r
115FReadFile (\r
116 FILE *in,\r
117 VOID **Buffer,\r
118 UINTN *Length\r
119 )\r
120{\r
121 fseek (in, 0, SEEK_END);\r
122 *Length = ftell (in);\r
123 *Buffer = malloc (*Length);\r
124 fseek (in, 0, SEEK_SET);\r
125 fread (*Buffer, *Length, 1, in);\r
126 return STATUS_SUCCESS;\r
127}\r
128\r
129static\r
130STATUS\r
131FWriteFile (\r
132 FILE *out,\r
133 VOID *Buffer,\r
134 UINTN Length\r
135 )\r
136{\r
137 fseek (out, 0, SEEK_SET);\r
138 fwrite (Buffer, Length, 1, out);\r
139 if ((ULONG) ftell (out) != Length) {\r
140 Error (NULL, 0, 0, "write error", NULL);\r
141 return STATUS_ERROR;\r
142 }\r
143 free (Buffer);\r
144 return STATUS_SUCCESS;\r
145}\r
146\r
878ddf1f 147int\r
148main (\r
149 int argc,\r
150 char *argv[]\r
151 )\r
152/*++\r
153\r
154Routine Description:\r
155\r
156 Main function.\r
157\r
158Arguments:\r
159\r
160 argc - Number of command line parameters.\r
161 argv - Array of pointers to command line parameter strings.\r
162\r
163Returns:\r
164 STATUS_SUCCESS - Utility exits successfully.\r
165 STATUS_ERROR - Some error occurred during execution.\r
166\r
167--*/\r
168{\r
169 ULONG Type;\r
170 PUCHAR Ext;\r
171 PUCHAR p;\r
172 PUCHAR pe;\r
173 PUCHAR OutImageName;\r
174 UCHAR outname[500];\r
175 FILE *fpIn;\r
176 FILE *fpOut;\r
3edf127e 177 VOID *ZeroBuffer;\r
178 EFI_IMAGE_DOS_HEADER *DosHdr;\r
179 EFI_IMAGE_NT_HEADERS *PeHdr;\r
180 EFI_IMAGE_OPTIONAL_HEADER32 *Optional32;\r
181 EFI_IMAGE_OPTIONAL_HEADER64 *Optional64;\r
878ddf1f 182 time_t TimeStamp;\r
183 struct tm TimeStruct;\r
184 EFI_IMAGE_DOS_HEADER BackupDosHdr;\r
185 ULONG Index;\r
3edf127e 186 ULONG Index1;\r
307fd197 187 ULONG Index2;\r
188 ULONG Index3;\r
878ddf1f 189 BOOLEAN TimeStampPresent;\r
0411bcaf 190 UINTN AllignedRelocSize;\r
3edf127e 191 UINTN Delta;\r
192 EFI_IMAGE_SECTION_HEADER *SectionHeader;\r
193 UINT8 *FileBuffer;\r
194 UINTN FileLength;\r
307fd197 195 RUNTIME_FUNCTION *RuntimeFunction;\r
196 UNWIND_INFO *UnwindInfo;\r
878ddf1f 197\r
198 SetUtilityName (UTILITY_NAME);\r
199 //\r
200 // Assign to fix compile warning\r
201 //\r
202 OutImageName = NULL;\r
203 Type = 0;\r
204 Ext = 0;\r
205 TimeStamp = 0;\r
206 TimeStampPresent = FALSE;\r
207\r
f091efb3 208 if (argc < 1) {\r
209 Usage();\r
210 return STATUS_ERROR;\r
211 }\r
212 \r
213 if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) ||\r
214 (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) {\r
215 Usage();\r
216 return STATUS_ERROR;\r
217 }\r
218 \r
219 if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) {\r
220 Version();\r
221 return STATUS_ERROR;\r
222 }\r
223 \r
878ddf1f 224 //\r
225 // Look for -t time-date option first. If the time is "0", then\r
226 // skip it.\r
227 //\r
228 if ((argc > 2) && !strcmp (argv[1], "-t")) {\r
229 TimeStampPresent = TRUE;\r
230 if (strcmp (argv[2], "0") != 0) {\r
231 //\r
232 // Convert the string to a value\r
233 //\r
234 memset ((char *) &TimeStruct, 0, sizeof (TimeStruct));\r
235 if (sscanf(\r
236 argv[2], "%d/%d/%d,%d:%d:%d",\r
237 &TimeStruct.tm_mon, /* months since January - [0,11] */\r
238 &TimeStruct.tm_mday, /* day of the month - [1,31] */\r
239 &TimeStruct.tm_year, /* years since 1900 */\r
240 &TimeStruct.tm_hour, /* hours since midnight - [0,23] */\r
241 &TimeStruct.tm_min, /* minutes after the hour - [0,59] */\r
242 &TimeStruct.tm_sec /* seconds after the minute - [0,59] */\r
243 ) != 6) {\r
244 Error (NULL, 0, 0, argv[2], "failed to convert to mm/dd/yyyy,hh:mm:ss format");\r
245 return STATUS_ERROR;\r
246 }\r
247 //\r
248 // Now fixup some of the fields\r
249 //\r
250 TimeStruct.tm_mon--;\r
251 TimeStruct.tm_year -= 1900;\r
252 //\r
253 // Sanity-check values?\r
254 // Convert\r
255 //\r
256 TimeStamp = mktime (&TimeStruct);\r
257 if (TimeStamp == (time_t) - 1) {\r
258 Error (NULL, 0, 0, argv[2], "failed to convert time");\r
259 return STATUS_ERROR;\r
260 }\r
261 }\r
262 //\r
263 // Skip over the args\r
264 //\r
265 argc -= 2;\r
266 argv += 2;\r
267 }\r
268 //\r
269 // Check for enough args\r
270 //\r
271 if (argc < 3) {\r
272 Usage ();\r
273 return STATUS_ERROR;\r
274 }\r
275\r
276 if (argc == 4) {\r
277 OutImageName = argv[3];\r
278 }\r
279 //\r
280 // Get new image type\r
281 //\r
282 p = argv[1];\r
283 if (*p == '/' || *p == '\\') {\r
284 p += 1;\r
285 }\r
286\r
8a286638 287 if (stricmp (p, "app") == 0 || stricmp (p, "UEFI_APPLICATION") == 0) {\r
878ddf1f 288 Type = EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION;\r
289 Ext = ".efi";\r
290\r
8a286638 291 } else if (stricmp (p, "bsdrv") == 0 || stricmp (p, "DXE_DRIVER") == 0) {\r
878ddf1f 292 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
293 Ext = ".efi";\r
294\r
8a286638 295 } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_RUNTIME_DRIVER") == 0) {\r
878ddf1f 296 Type = EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;\r
297 Ext = ".efi";\r
298\r
8a286638 299 } else if (stricmp (p, "rtdrv") == 0 || stricmp (p, "DXE_SAL_DRIVER") == 0) {\r
878ddf1f 300 Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER;\r
301 Ext = ".efi";\r
8a286638 302 } else if (stricmp (p, "SEC") == 0) {\r
878ddf1f 303 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
304 Ext = ".sec";\r
305 } else if (stricmp (p, "peim") == 0 ||\r
8a286638 306 stricmp (p, "BASE") == 0 ||\r
878ddf1f 307 stricmp (p, "PEI_CORE") == 0 ||\r
8a286638 308 stricmp (p, "PEIM") == 0 ||\r
309 stricmp (p, "DXE_SMM_DRIVER") == 0 ||\r
310 stricmp (p, "TOOL") == 0 ||\r
311 stricmp (p, "UEFI_APPLICATION") == 0 ||\r
312 stricmp (p, "USER_DEFINED") == 0 ||\r
313 stricmp (p, "UEFI_DRIVER") == 0 ||\r
314 stricmp (p, "DXE_CORE") == 0\r
878ddf1f 315 ) {\r
316 Type = EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER;\r
317 Ext = ".pei";\r
318 } else {\r
8a286638 319 printf ("%s", p);\r
878ddf1f 320 Usage ();\r
321 return STATUS_ERROR;\r
322 }\r
323 //\r
324 // open source file\r
325 //\r
326 fpIn = fopen (argv[2], "rb");\r
327 if (!fpIn) {\r
328 Error (NULL, 0, 0, argv[2], "failed to open input file for reading");\r
329 return STATUS_ERROR;\r
330 }\r
3edf127e 331\r
332 FReadFile (fpIn, (VOID **)&FileBuffer, &FileLength);\r
333\r
878ddf1f 334 //\r
335 // Read the dos & pe hdrs of the image\r
336 //\r
3edf127e 337 DosHdr = (EFI_IMAGE_DOS_HEADER *)FileBuffer;\r
338 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
878ddf1f 339 Error (NULL, 0, 0, argv[2], "DOS header signature not found in source image");\r
340 fclose (fpIn);\r
341 return STATUS_ERROR;\r
342 }\r
343\r
3edf127e 344 PeHdr = (EFI_IMAGE_NT_HEADERS *)(FileBuffer + DosHdr->e_lfanew);\r
345 if (PeHdr->Signature != EFI_IMAGE_NT_SIGNATURE) {\r
878ddf1f 346 Error (NULL, 0, 0, argv[2], "PE header signature not found in source image");\r
347 fclose (fpIn);\r
348 return STATUS_ERROR;\r
349 }\r
3edf127e 350\r
878ddf1f 351 //\r
352 // open output file\r
353 //\r
354 strcpy (outname, argv[2]);\r
355 pe = NULL;\r
356 for (p = outname; *p; p++) {\r
357 if (*p == '.') {\r
358 pe = p;\r
359 }\r
360 }\r
361\r
362 if (!pe) {\r
363 pe = p;\r
364 }\r
365\r
366 strcpy (pe, Ext);\r
367\r
368 if (!OutImageName) {\r
369 OutImageName = outname;\r
370 }\r
371\r
372 fpOut = fopen (OutImageName, "w+b");\r
373 if (!fpOut) {\r
374 Error (NULL, 0, 0, OutImageName, "could not open output file for writing");\r
375 fclose (fpIn);\r
376 return STATUS_ERROR;\r
377 }\r
3edf127e 378\r
878ddf1f 379 //\r
380 // Zero all unused fields of the DOS header\r
381 //\r
3edf127e 382 memcpy (&BackupDosHdr, DosHdr, sizeof (EFI_IMAGE_DOS_HEADER));\r
383 memset (DosHdr, 0, sizeof (EFI_IMAGE_DOS_HEADER));\r
384 DosHdr->e_magic = BackupDosHdr.e_magic;\r
385 DosHdr->e_lfanew = BackupDosHdr.e_lfanew;\r
386\r
387 for (Index = sizeof (EFI_IMAGE_DOS_HEADER); Index < (ULONG) DosHdr->e_lfanew; Index++) {\r
388 FileBuffer[Index] = DosHdr->e_cp;\r
878ddf1f 389 }\r
3edf127e 390\r
878ddf1f 391 //\r
392 // Path the PE header\r
393 //\r
3edf127e 394 PeHdr->OptionalHeader.Subsystem = (USHORT) Type;\r
878ddf1f 395 if (TimeStampPresent) {\r
3edf127e 396 PeHdr->FileHeader.TimeDateStamp = (UINT32) TimeStamp;\r
397 }\r
398\r
3edf127e 399 if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
400 Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->OptionalHeader;\r
401 Optional32->MajorLinkerVersion = 0;\r
402 Optional32->MinorLinkerVersion = 0;\r
403 Optional32->MajorOperatingSystemVersion = 0;\r
404 Optional32->MinorOperatingSystemVersion = 0;\r
405 Optional32->MajorImageVersion = 0;\r
406 Optional32->MinorImageVersion = 0;\r
407 Optional32->MajorSubsystemVersion = 0;\r
408 Optional32->MinorSubsystemVersion = 0;\r
409 Optional32->Win32VersionValue = 0;\r
410 Optional32->CheckSum = 0;\r
411 Optional32->SizeOfStackReserve = 0;\r
412 Optional32->SizeOfStackCommit = 0;\r
413 Optional32->SizeOfHeapReserve = 0;\r
414 Optional32->SizeOfHeapCommit = 0;\r
415\r
3edf127e 416 //\r
417 // Strip zero padding at the end of the .reloc section \r
418 //\r
419 if (Optional32->NumberOfRvaAndSizes >= 6) {\r
420 if (Optional32->DataDirectory[5].Size != 0) {\r
421 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
422 for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
0411bcaf 423 //\r
424 // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
425 //\r
3edf127e 426 if (SectionHeader->VirtualAddress == Optional32->DataDirectory[5].VirtualAddress) {\r
0411bcaf 427 SectionHeader->Misc.VirtualSize = Optional32->DataDirectory[5].Size;\r
428 AllignedRelocSize = (Optional32->DataDirectory[5].Size + Optional32->FileAlignment - 1) & (~(Optional32->FileAlignment - 1));\r
429 //\r
430 // Check to see if there is zero padding at the end of the base relocations\r
431 //\r
432 if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
433 //\r
434 // Check to see if the base relocations are at the end of the file\r
435 //\r
436 if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional32->SizeOfImage) {\r
437 //\r
438 // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
439 //\r
440 Optional32->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
441 Optional32->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
442 SectionHeader->SizeOfRawData = AllignedRelocSize;\r
443 FileLength = Optional32->SizeOfImage;\r
444 }\r
445 }\r
3edf127e 446 }\r
447 }\r
448 }\r
449 }\r
450 } \r
451 if (PeHdr->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
452 Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->OptionalHeader;\r
453 Optional64->MajorLinkerVersion = 0;\r
454 Optional64->MinorLinkerVersion = 0;\r
455 Optional64->MajorOperatingSystemVersion = 0;\r
456 Optional64->MinorOperatingSystemVersion = 0;\r
457 Optional64->MajorImageVersion = 0;\r
458 Optional64->MinorImageVersion = 0;\r
459 Optional64->MajorSubsystemVersion = 0;\r
460 Optional64->MinorSubsystemVersion = 0;\r
461 Optional64->Win32VersionValue = 0;\r
462 Optional64->CheckSum = 0;\r
463 Optional64->SizeOfStackReserve = 0;\r
464 Optional64->SizeOfStackCommit = 0;\r
465 Optional64->SizeOfHeapReserve = 0;\r
466 Optional64->SizeOfHeapCommit = 0;\r
467\r
468 //\r
469 // Zero the .pdata section if the machine type is X64 and the Debug Directory is empty\r
470 //\r
471 if (PeHdr->FileHeader.Machine == 0x8664) { // X64\r
472 if (Optional64->NumberOfRvaAndSizes >= 4) {\r
473 if (Optional64->NumberOfRvaAndSizes < 7 || (Optional64->NumberOfRvaAndSizes >= 7 && Optional64->DataDirectory[6].Size == 0)) {\r
474 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
475 for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
476 if (SectionHeader->VirtualAddress == Optional64->DataDirectory[3].VirtualAddress) {\r
307fd197 477 RuntimeFunction = (RUNTIME_FUNCTION *)(FileBuffer + SectionHeader->PointerToRawData);\r
478 for (Index1 = 0; Index1 < Optional64->DataDirectory[3].Size / sizeof (RUNTIME_FUNCTION); Index1++, RuntimeFunction++) {\r
479 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
480 for (Index2 = 0; Index2 < PeHdr->FileHeader.NumberOfSections; Index2++, SectionHeader++) {\r
481 if (RuntimeFunction->UnwindInfoAddress > SectionHeader->VirtualAddress && RuntimeFunction->UnwindInfoAddress < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData)) {\r
482 UnwindInfo = (UNWIND_INFO *)(FileBuffer + SectionHeader->PointerToRawData + (RuntimeFunction->UnwindInfoAddress - SectionHeader->VirtualAddress));\r
483 if (UnwindInfo->Version == 1) {\r
484 memset (UnwindInfo + 1, 0, UnwindInfo->CountOfUnwindCodes * sizeof (UINT16));\r
485 memset (UnwindInfo, 0, sizeof (UNWIND_INFO));\r
486 }\r
487 }\r
488 }\r
489 memset (RuntimeFunction, 0, sizeof (RUNTIME_FUNCTION));\r
3edf127e 490 }\r
d9e0f88e 491\r
492 break;\r
3edf127e 493 }\r
494 }\r
495 Optional64->DataDirectory[3].Size = 0;\r
496 Optional64->DataDirectory[3].VirtualAddress = 0;\r
497 }\r
498 }\r
499 }\r
500\r
501 //\r
502 // Strip zero padding at the end of the .reloc section \r
503 //\r
504 if (Optional64->NumberOfRvaAndSizes >= 6) {\r
505 if (Optional64->DataDirectory[5].Size != 0) {\r
506 SectionHeader = (EFI_IMAGE_SECTION_HEADER *)(FileBuffer + DosHdr->e_lfanew + sizeof(UINT32) + sizeof (EFI_IMAGE_FILE_HEADER) + PeHdr->FileHeader.SizeOfOptionalHeader);\r
507 for (Index = 0; Index < PeHdr->FileHeader.NumberOfSections; Index++, SectionHeader++) {\r
0411bcaf 508 //\r
509 // Look for the Section Header that starts as the same virtual address as the Base Relocation Data Directory\r
510 //\r
3edf127e 511 if (SectionHeader->VirtualAddress == Optional64->DataDirectory[5].VirtualAddress) {\r
0411bcaf 512 SectionHeader->Misc.VirtualSize = Optional64->DataDirectory[5].Size;\r
513 AllignedRelocSize = (Optional64->DataDirectory[5].Size + Optional64->FileAlignment - 1) & (~(Optional64->FileAlignment - 1));\r
514 //\r
515 // Check to see if there is zero padding at the end of the base relocations\r
516 //\r
517 if (AllignedRelocSize < SectionHeader->SizeOfRawData) {\r
518 //\r
519 // Check to see if the base relocations are at the end of the file\r
520 //\r
521 if (SectionHeader->PointerToRawData + SectionHeader->SizeOfRawData == Optional64->SizeOfImage) {\r
522 //\r
523 // All the required conditions are met to strip the zero padding of the end of the base relocations section\r
524 //\r
525 Optional64->SizeOfImage -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
526 Optional64->SizeOfInitializedData -= (SectionHeader->SizeOfRawData - AllignedRelocSize);\r
527 SectionHeader->SizeOfRawData = AllignedRelocSize;\r
528 FileLength = Optional64->SizeOfImage;\r
529 }\r
530 }\r
3edf127e 531 }\r
532 }\r
533 }\r
534 }\r
535 }\r
536\r
3edf127e 537 FWriteFile (fpOut, FileBuffer, FileLength);\r
878ddf1f 538\r
539 //\r
540 // Done\r
541 //\r
542 fclose (fpIn);\r
543 fclose (fpOut);\r
544 //\r
545 // printf ("Created %s\n", OutImageName);\r
546 //\r
547 return STATUS_SUCCESS;\r
548}\r