]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenFw/Elf32Convert.c
MdeModulePkg:Add ESC key support in setup browser pop-up message box
[mirror_edk2.git] / BaseTools / Source / C / GenFw / Elf32Convert.c
CommitLineData
f51461c8 1/** @file\r
97fa0ee9 2Elf32 Convert solution\r
f51461c8 3\r
97fa0ee9 4Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
f51461c8
LG
5Portions copyright (c) 2013, ARM Ltd. All rights reserved.<BR>\r
6\r
7This program and the accompanying materials are licensed and made available\r
8under the terms and conditions of the BSD License which accompanies this\r
9distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "WinNtInclude.h"\r
18\r
19#ifndef __GNUC__\r
20#include <windows.h>\r
21#include <io.h>\r
22#endif\r
23#include <assert.h>\r
24#include <stdio.h>\r
25#include <stdlib.h>\r
26#include <string.h>\r
27#include <time.h>\r
28#include <ctype.h>\r
29\r
30#include <Common/UefiBaseTypes.h>\r
31#include <IndustryStandard/PeImage.h>\r
32\r
33#include "PeCoffLib.h"\r
34#include "EfiUtilityMsgs.h"\r
35\r
36#include "GenFw.h"\r
37#include "ElfConvert.h"\r
38#include "Elf32Convert.h"\r
39\r
40STATIC\r
41VOID\r
42ScanSections32 (\r
43 VOID\r
44 );\r
45\r
46STATIC\r
47BOOLEAN\r
48WriteSections32 (\r
49 SECTION_FILTER_TYPES FilterType\r
50 );\r
51\r
52STATIC\r
53VOID\r
54WriteRelocations32 (\r
55 VOID\r
56 );\r
57\r
58STATIC\r
59VOID\r
60WriteDebug32 (\r
61 VOID\r
62 );\r
63\r
64STATIC\r
65VOID\r
66SetImageSize32 (\r
67 VOID\r
68 );\r
69\r
70STATIC\r
71VOID\r
72CleanUp32 (\r
73 VOID\r
74 );\r
75\r
76//\r
77// Rename ELF32 strucutres to common names to help when porting to ELF64.\r
78//\r
79typedef Elf32_Shdr Elf_Shdr;\r
80typedef Elf32_Ehdr Elf_Ehdr;\r
81typedef Elf32_Rel Elf_Rel;\r
82typedef Elf32_Sym Elf_Sym;\r
83typedef Elf32_Phdr Elf_Phdr;\r
84typedef Elf32_Dyn Elf_Dyn;\r
85#define ELFCLASS ELFCLASS32\r
86#define ELF_R_TYPE(r) ELF32_R_TYPE(r)\r
87#define ELF_R_SYM(r) ELF32_R_SYM(r)\r
88\r
89//\r
90// Well known ELF structures.\r
91//\r
92STATIC Elf_Ehdr *mEhdr;\r
93STATIC Elf_Shdr *mShdrBase;\r
94STATIC Elf_Phdr *mPhdrBase;\r
95\r
96//\r
97// Coff information\r
98//\r
54b1b57a 99STATIC UINT32 mCoffAlignment = 0x20;\r
f51461c8
LG
100\r
101//\r
102// PE section alignment.\r
103//\r
104STATIC const UINT16 mCoffNbrSections = 5;\r
105\r
106//\r
107// ELF sections to offset in Coff file.\r
108//\r
109STATIC UINT32 *mCoffSectionsOffset = NULL;\r
110\r
111//\r
112// Offsets in COFF file\r
113//\r
114STATIC UINT32 mNtHdrOffset;\r
115STATIC UINT32 mTextOffset;\r
116STATIC UINT32 mDataOffset;\r
117STATIC UINT32 mHiiRsrcOffset;\r
118STATIC UINT32 mRelocOffset;\r
119\r
120//\r
121// Initialization Function\r
122//\r
123BOOLEAN\r
124InitializeElf32 (\r
125 UINT8 *FileBuffer,\r
126 ELF_FUNCTION_TABLE *ElfFunctions\r
127 )\r
128{\r
129 //\r
130 // Initialize data pointer and structures.\r
131 //\r
132 mEhdr = (Elf_Ehdr*) FileBuffer; \r
133\r
134 //\r
135 // Check the ELF32 specific header information.\r
136 //\r
137 if (mEhdr->e_ident[EI_CLASS] != ELFCLASS32) {\r
138 Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS32");\r
139 return FALSE;\r
140 }\r
141 if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) {\r
142 Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");\r
143 return FALSE;\r
144 } \r
145 if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) {\r
146 Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
147 return FALSE;\r
148 }\r
149 if (!((mEhdr->e_machine == EM_386) || (mEhdr->e_machine == EM_ARM))) { \r
150 Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_386 or EM_ARM");\r
151 return FALSE;\r
152 }\r
153 if (mEhdr->e_version != EV_CURRENT) {\r
154 Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT);\r
155 return FALSE;\r
156 }\r
157 \r
158 //\r
159 // Update section header pointers\r
160 //\r
161 mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff);\r
162 mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff);\r
163 \r
164 //\r
165 // Create COFF Section offset buffer and zero.\r
166 //\r
167 mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32));\r
168 memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32));\r
169\r
170 //\r
171 // Fill in function pointers.\r
172 //\r
173 ElfFunctions->ScanSections = ScanSections32;\r
174 ElfFunctions->WriteSections = WriteSections32;\r
175 ElfFunctions->WriteRelocations = WriteRelocations32;\r
176 ElfFunctions->WriteDebug = WriteDebug32;\r
177 ElfFunctions->SetImageSize = SetImageSize32;\r
178 ElfFunctions->CleanUp = CleanUp32;\r
179\r
180 return TRUE;\r
181}\r
182\r
183\r
184//\r
185// Header by Index functions\r
186//\r
187STATIC\r
188Elf_Shdr*\r
189GetShdrByIndex (\r
190 UINT32 Num\r
191 )\r
192{\r
193 if (Num >= mEhdr->e_shnum)\r
194 return NULL;\r
195 return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize);\r
196}\r
197\r
198STATIC\r
199Elf_Phdr*\r
200GetPhdrByIndex (\r
201 UINT32 num\r
202 )\r
203{\r
204 if (num >= mEhdr->e_phnum) {\r
205 return NULL;\r
206 }\r
207\r
208 return (Elf_Phdr *)((UINT8*)mPhdrBase + num * mEhdr->e_phentsize);\r
209}\r
210\r
211STATIC\r
212UINT32\r
213CoffAlign (\r
214 UINT32 Offset\r
215 )\r
216{\r
217 return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1);\r
218}\r
219\r
220//\r
221// filter functions\r
222//\r
223STATIC\r
224BOOLEAN\r
225IsTextShdr (\r
226 Elf_Shdr *Shdr\r
227 )\r
228{\r
229 return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC);\r
230}\r
231\r
232STATIC\r
233BOOLEAN\r
234IsHiiRsrcShdr (\r
235 Elf_Shdr *Shdr\r
236 )\r
237{\r
238 Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);\r
239\r
240 return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0);\r
241}\r
242\r
243STATIC\r
244BOOLEAN\r
245IsDataShdr (\r
246 Elf_Shdr *Shdr\r
247 )\r
248{\r
249 if (IsHiiRsrcShdr(Shdr)) {\r
250 return FALSE;\r
251 }\r
252 return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);\r
253}\r
254\r
255//\r
256// Elf functions interface implementation\r
257//\r
258\r
259STATIC\r
260VOID\r
261ScanSections32 (\r
262 VOID\r
263 )\r
264{\r
265 UINT32 i;\r
266 EFI_IMAGE_DOS_HEADER *DosHdr;\r
267 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
268 UINT32 CoffEntry;\r
269 UINT32 SectionCount;\r
234f9ff9 270 BOOLEAN FoundSection;\r
f51461c8
LG
271\r
272 CoffEntry = 0;\r
273 mCoffOffset = 0;\r
f51461c8
LG
274\r
275 //\r
276 // Coff file start with a DOS header.\r
277 //\r
278 mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;\r
279 mNtHdrOffset = mCoffOffset;\r
280 switch (mEhdr->e_machine) {\r
281 case EM_386:\r
282 case EM_ARM:\r
283 mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
284 break;\r
285 default:\r
286 VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine);\r
287 mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS32);\r
288 break;\r
289 }\r
290\r
291 mTableOffset = mCoffOffset;\r
292 mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);\r
293\r
54b1b57a
AB
294 //\r
295 // Set mCoffAlignment to the maximum alignment of the input sections\r
296 // we care about\r
297 //\r
298 for (i = 0; i < mEhdr->e_shnum; i++) {\r
299 Elf_Shdr *shdr = GetShdrByIndex(i);\r
300 if (shdr->sh_addralign <= mCoffAlignment) {\r
301 continue;\r
302 }\r
303 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {\r
304 mCoffAlignment = (UINT32)shdr->sh_addralign;\r
305 }\r
306 }\r
307\r
f51461c8
LG
308 //\r
309 // First text sections.\r
310 //\r
311 mCoffOffset = CoffAlign(mCoffOffset);\r
234f9ff9
EB
312 mTextOffset = mCoffOffset;\r
313 FoundSection = FALSE;\r
f51461c8
LG
314 SectionCount = 0;\r
315 for (i = 0; i < mEhdr->e_shnum; i++) {\r
316 Elf_Shdr *shdr = GetShdrByIndex(i);\r
317 if (IsTextShdr(shdr)) {\r
318 if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
319 // the alignment field is valid\r
320 if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
321 // if the section address is aligned we must align PE/COFF\r
322 mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
323 } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) {\r
324 // ARM RVCT tools have behavior outside of the ELF specification to try\r
325 // and make images smaller. If sh_addr is not aligned to sh_addralign\r
326 // then the section needs to preserve sh_addr MOD sh_addralign.\r
327 // Normally doing nothing here works great.\r
328 Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
329 }\r
330 }\r
331\r
332 /* Relocate entry. */\r
333 if ((mEhdr->e_entry >= shdr->sh_addr) &&\r
334 (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) {\r
335 CoffEntry = mCoffOffset + mEhdr->e_entry - shdr->sh_addr;\r
336 }\r
337\r
338 //\r
339 // Set mTextOffset with the offset of the first '.text' section\r
340 //\r
234f9ff9 341 if (!FoundSection) {\r
f51461c8 342 mTextOffset = mCoffOffset;\r
234f9ff9 343 FoundSection = TRUE;\r
f51461c8
LG
344 }\r
345\r
346 mCoffSectionsOffset[i] = mCoffOffset;\r
347 mCoffOffset += shdr->sh_size;\r
348 SectionCount ++;\r
349 }\r
350 }\r
351\r
234f9ff9 352 if (!FoundSection) {\r
f51461c8
LG
353 Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section.");\r
354 assert (FALSE);\r
355 }\r
356\r
357 if (mEhdr->e_machine != EM_ARM) {\r
358 mCoffOffset = CoffAlign(mCoffOffset);\r
359 }\r
360\r
361 if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {\r
362 Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName);\r
363 }\r
364\r
365 //\r
366 // Then data sections.\r
367 //\r
368 mDataOffset = mCoffOffset;\r
234f9ff9 369 FoundSection = FALSE;\r
f51461c8
LG
370 SectionCount = 0;\r
371 for (i = 0; i < mEhdr->e_shnum; i++) {\r
372 Elf_Shdr *shdr = GetShdrByIndex(i);\r
373 if (IsDataShdr(shdr)) {\r
374 if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
375 // the alignment field is valid\r
376 if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
377 // if the section address is aligned we must align PE/COFF\r
378 mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
379 } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) {\r
380 // ARM RVCT tools have behavior outside of the ELF specification to try\r
381 // and make images smaller. If sh_addr is not aligned to sh_addralign\r
382 // then the section needs to preserve sh_addr MOD sh_addralign.\r
383 // Normally doing nothing here works great.\r
384 Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
385 }\r
386 }\r
234f9ff9
EB
387\r
388 //\r
389 // Set mDataOffset with the offset of the first '.data' section\r
390 //\r
391 if (!FoundSection) {\r
392 mDataOffset = mCoffOffset;\r
393 FoundSection = TRUE;\r
394 }\r
395\r
f51461c8
LG
396 mCoffSectionsOffset[i] = mCoffOffset;\r
397 mCoffOffset += shdr->sh_size;\r
398 SectionCount ++;\r
399 }\r
400 }\r
401 mCoffOffset = CoffAlign(mCoffOffset);\r
402\r
403 if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {\r
404 Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);\r
405 }\r
406\r
407 //\r
408 // The HII resource sections.\r
409 //\r
410 mHiiRsrcOffset = mCoffOffset;\r
411 for (i = 0; i < mEhdr->e_shnum; i++) {\r
412 Elf_Shdr *shdr = GetShdrByIndex(i);\r
413 if (IsHiiRsrcShdr(shdr)) {\r
414 if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
415 // the alignment field is valid\r
416 if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
417 // if the section address is aligned we must align PE/COFF\r
418 mCoffOffset = (mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1);\r
419 } else if ((shdr->sh_addr % shdr->sh_addralign) != (mCoffOffset % shdr->sh_addralign)) {\r
420 // ARM RVCT tools have behavior outside of the ELF specification to try\r
421 // and make images smaller. If sh_addr is not aligned to sh_addralign\r
422 // then the section needs to preserve sh_addr MOD sh_addralign.\r
423 // Normally doing nothing here works great.\r
424 Error (NULL, 0, 3000, "Invalid", "Unsupported section alignment.");\r
425 }\r
426 }\r
427 if (shdr->sh_size != 0) {\r
234f9ff9 428 mHiiRsrcOffset = mCoffOffset;\r
f51461c8
LG
429 mCoffSectionsOffset[i] = mCoffOffset;\r
430 mCoffOffset += shdr->sh_size;\r
431 mCoffOffset = CoffAlign(mCoffOffset);\r
432 SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset);\r
433 }\r
434 break;\r
435 }\r
436 }\r
437\r
438 mRelocOffset = mCoffOffset;\r
439\r
440 //\r
441 // Allocate base Coff file. Will be expanded later for relocations.\r
442 //\r
443 mCoffFile = (UINT8 *)malloc(mCoffOffset);\r
444 memset(mCoffFile, 0, mCoffOffset);\r
445\r
446 //\r
447 // Fill headers.\r
448 //\r
449 DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile;\r
450 DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
451 DosHdr->e_lfanew = mNtHdrOffset;\r
452\r
453 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset);\r
454\r
455 NtHdr->Pe32.Signature = EFI_IMAGE_NT_SIGNATURE;\r
456\r
457 switch (mEhdr->e_machine) {\r
458 case EM_386:\r
459 NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
460 NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
461 break;\r
462 case EM_ARM:\r
463 NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_ARMT;\r
464 NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
465 break;\r
466 default:\r
467 VerboseMsg ("%s unknown e_machine type. Assume IA-32", (UINTN)mEhdr->e_machine);\r
468 NtHdr->Pe32.FileHeader.Machine = EFI_IMAGE_MACHINE_IA32;\r
469 NtHdr->Pe32.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
470 }\r
471\r
472 NtHdr->Pe32.FileHeader.NumberOfSections = mCoffNbrSections;\r
473 NtHdr->Pe32.FileHeader.TimeDateStamp = (UINT32) time(NULL);\r
474 mImageTimeStamp = NtHdr->Pe32.FileHeader.TimeDateStamp;\r
475 NtHdr->Pe32.FileHeader.PointerToSymbolTable = 0;\r
476 NtHdr->Pe32.FileHeader.NumberOfSymbols = 0;\r
477 NtHdr->Pe32.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32.OptionalHeader);\r
478 NtHdr->Pe32.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE\r
479 | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED\r
480 | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED\r
481 | EFI_IMAGE_FILE_32BIT_MACHINE;\r
482\r
483 NtHdr->Pe32.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;\r
484 NtHdr->Pe32.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;\r
485 NtHdr->Pe32.OptionalHeader.SizeOfUninitializedData = 0;\r
486 NtHdr->Pe32.OptionalHeader.AddressOfEntryPoint = CoffEntry;\r
487\r
488 NtHdr->Pe32.OptionalHeader.BaseOfCode = mTextOffset;\r
489\r
490 NtHdr->Pe32.OptionalHeader.BaseOfData = mDataOffset;\r
491 NtHdr->Pe32.OptionalHeader.ImageBase = 0;\r
492 NtHdr->Pe32.OptionalHeader.SectionAlignment = mCoffAlignment;\r
493 NtHdr->Pe32.OptionalHeader.FileAlignment = mCoffAlignment;\r
494 NtHdr->Pe32.OptionalHeader.SizeOfImage = 0;\r
495\r
496 NtHdr->Pe32.OptionalHeader.SizeOfHeaders = mTextOffset;\r
497 NtHdr->Pe32.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
498\r
499 //\r
500 // Section headers.\r
501 //\r
502 if ((mDataOffset - mTextOffset) > 0) {\r
503 CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset,\r
504 EFI_IMAGE_SCN_CNT_CODE\r
505 | EFI_IMAGE_SCN_MEM_EXECUTE\r
506 | EFI_IMAGE_SCN_MEM_READ);\r
507 } else {\r
508 // Don't make a section of size 0.\r
509 NtHdr->Pe32.FileHeader.NumberOfSections--;\r
510 }\r
511\r
512 if ((mHiiRsrcOffset - mDataOffset) > 0) {\r
513 CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,\r
514 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
515 | EFI_IMAGE_SCN_MEM_WRITE\r
516 | EFI_IMAGE_SCN_MEM_READ);\r
517 } else {\r
518 // Don't make a section of size 0.\r
519 NtHdr->Pe32.FileHeader.NumberOfSections--;\r
520 }\r
521\r
522 if ((mRelocOffset - mHiiRsrcOffset) > 0) {\r
523 CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset,\r
524 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
525 | EFI_IMAGE_SCN_MEM_READ);\r
526\r
527 NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset;\r
528 NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset;\r
529 } else {\r
530 // Don't make a section of size 0.\r
531 NtHdr->Pe32.FileHeader.NumberOfSections--;\r
532 }\r
533\r
534}\r
535\r
536STATIC\r
537BOOLEAN\r
538WriteSections32 (\r
539 SECTION_FILTER_TYPES FilterType\r
540 )\r
541{\r
542 UINT32 Idx;\r
543 Elf_Shdr *SecShdr;\r
544 UINT32 SecOffset;\r
545 BOOLEAN (*Filter)(Elf_Shdr *);\r
546\r
547 //\r
548 // Initialize filter pointer\r
549 //\r
550 switch (FilterType) {\r
551 case SECTION_TEXT:\r
552 Filter = IsTextShdr;\r
553 break;\r
554 case SECTION_HII:\r
555 Filter = IsHiiRsrcShdr;\r
556 break;\r
557 case SECTION_DATA:\r
558 Filter = IsDataShdr;\r
559 break;\r
560 default:\r
561 return FALSE;\r
562 }\r
563\r
564 //\r
565 // First: copy sections.\r
566 //\r
567 for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {\r
568 Elf_Shdr *Shdr = GetShdrByIndex(Idx);\r
569 if ((*Filter)(Shdr)) {\r
570 switch (Shdr->sh_type) {\r
571 case SHT_PROGBITS:\r
572 /* Copy. */\r
573 memcpy(mCoffFile + mCoffSectionsOffset[Idx],\r
574 (UINT8*)mEhdr + Shdr->sh_offset,\r
575 Shdr->sh_size);\r
576 break;\r
577\r
578 case SHT_NOBITS:\r
579 memset(mCoffFile + mCoffSectionsOffset[Idx], 0, Shdr->sh_size);\r
580 break;\r
581\r
582 default:\r
583 //\r
584 // Ignore for unkown section type.\r
585 //\r
586 VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type);\r
587 break;\r
588 }\r
589 }\r
590 }\r
591\r
592 //\r
593 // Second: apply relocations.\r
594 //\r
595 for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {\r
596 //\r
597 // Determine if this is a relocation section.\r
598 //\r
599 Elf_Shdr *RelShdr = GetShdrByIndex(Idx);\r
600 if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {\r
601 continue;\r
602 }\r
603 \r
604 //\r
605 // Relocation section found. Now extract section information that the relocations\r
606 // apply to in the ELF data and the new COFF data.\r
607 //\r
608 SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
609 SecOffset = mCoffSectionsOffset[RelShdr->sh_info];\r
610 \r
611 //\r
612 // Only process relocations for the current filter type.\r
613 //\r
614 if (RelShdr->sh_type == SHT_REL && (*Filter)(SecShdr)) {\r
615 UINT32 RelOffset;\r
616 \r
617 //\r
618 // Determine the symbol table referenced by the relocation data.\r
619 //\r
620 Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);\r
621 UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;\r
622\r
623 //\r
624 // Process all relocation entries for this section.\r
625 //\r
626 for (RelOffset = 0; RelOffset < RelShdr->sh_size; RelOffset += RelShdr->sh_entsize) {\r
627 //\r
628 // Set pointer to relocation entry\r
629 //\r
630 Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelOffset);\r
631 \r
632 //\r
633 // Set pointer to symbol table entry associated with the relocation entry.\r
634 //\r
635 Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);\r
636 \r
637 Elf_Shdr *SymShdr;\r
638 UINT8 *Targ;\r
639 UINT16 Address;\r
640\r
641 //\r
642 // Check section header index found in symbol table and get the section \r
643 // header location.\r
644 //\r
645 if (Sym->st_shndx == SHN_UNDEF\r
646 || Sym->st_shndx == SHN_ABS\r
647 || Sym->st_shndx > mEhdr->e_shnum) {\r
648 Error (NULL, 0, 3000, "Invalid", "%s bad symbol definition.", mInImageName);\r
649 }\r
650 SymShdr = GetShdrByIndex(Sym->st_shndx);\r
651\r
652 //\r
653 // Convert the relocation data to a pointer into the coff file.\r
654 //\r
655 // Note: \r
656 // r_offset is the virtual address of the storage unit to be relocated.\r
657 // sh_addr is the virtual address for the base of the section.\r
658 //\r
659 Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);\r
660\r
661 //\r
662 // Determine how to handle each relocation type based on the machine type.\r
663 //\r
664 if (mEhdr->e_machine == EM_386) {\r
665 switch (ELF_R_TYPE(Rel->r_info)) {\r
666 case R_386_NONE:\r
667 break;\r
668 case R_386_32:\r
669 //\r
670 // Absolute relocation.\r
671 // Converts Targ from a absolute virtual address to the absolute\r
672 // COFF address.\r
673 //\r
674 *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr\r
675 + mCoffSectionsOffset[Sym->st_shndx];\r
676 break;\r
677 case R_386_PC32:\r
678 //\r
679 // Relative relocation: Symbol - Ip + Addend\r
680 //\r
681 *(UINT32 *)Targ = *(UINT32 *)Targ\r
682 + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)\r
683 - (SecOffset - SecShdr->sh_addr);\r
684 break;\r
685 default:\r
686 Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
687 }\r
688 } else if (mEhdr->e_machine == EM_ARM) {\r
689 switch (ELF32_R_TYPE(Rel->r_info)) {\r
690 case R_ARM_RBASE:\r
691 // No relocation - no action required\r
692 // break skipped\r
693\r
694 case R_ARM_PC24:\r
695 case R_ARM_XPC25:\r
696 case R_ARM_THM_PC22:\r
697 case R_ARM_THM_JUMP19:\r
698 case R_ARM_CALL:\r
699 case R_ARM_JMP24:\r
700 case R_ARM_THM_JUMP24: \r
701 case R_ARM_PREL31: \r
702 case R_ARM_MOVW_PREL_NC: \r
703 case R_ARM_MOVT_PREL:\r
704 case R_ARM_THM_MOVW_PREL_NC:\r
705 case R_ARM_THM_MOVT_PREL:\r
706 case R_ARM_THM_JMP6:\r
707 case R_ARM_THM_ALU_PREL_11_0:\r
708 case R_ARM_THM_PC12:\r
709 case R_ARM_REL32_NOI:\r
710 case R_ARM_ALU_PC_G0_NC:\r
711 case R_ARM_ALU_PC_G0:\r
712 case R_ARM_ALU_PC_G1_NC:\r
713 case R_ARM_ALU_PC_G1:\r
714 case R_ARM_ALU_PC_G2:\r
715 case R_ARM_LDR_PC_G1:\r
716 case R_ARM_LDR_PC_G2:\r
717 case R_ARM_LDRS_PC_G0:\r
718 case R_ARM_LDRS_PC_G1:\r
719 case R_ARM_LDRS_PC_G2:\r
720 case R_ARM_LDC_PC_G0:\r
721 case R_ARM_LDC_PC_G1:\r
722 case R_ARM_LDC_PC_G2:\r
723 case R_ARM_GOT_PREL:\r
724 case R_ARM_THM_JUMP11:\r
725 case R_ARM_THM_JUMP8:\r
726 case R_ARM_TLS_GD32:\r
727 case R_ARM_TLS_LDM32:\r
728 case R_ARM_TLS_IE32:\r
729 // Thease are all PC-relative relocations and don't require modification\r
730 // GCC does not seem to have the concept of a application that just needs to get relocated.\r
731 break;\r
732\r
733 case R_ARM_THM_MOVW_ABS_NC:\r
734 // MOVW is only lower 16-bits of the addres\r
735 Address = (UINT16)(Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);\r
736 ThumbMovtImmediatePatch ((UINT16 *)Targ, Address);\r
737 break;\r
738\r
739 case R_ARM_THM_MOVT_ABS:\r
740 // MOVT is only upper 16-bits of the addres\r
741 Address = (UINT16)((Sym->st_value - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]) >> 16);\r
742 ThumbMovtImmediatePatch ((UINT16 *)Targ, Address);\r
743 break;\r
744\r
745 case R_ARM_ABS32:\r
746 case R_ARM_RABS32:\r
747 //\r
748 // Absolute relocation.\r
749 //\r
750 *(UINT32 *)Targ = *(UINT32 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
751 break;\r
752\r
753 default:\r
754 Error (NULL, 0, 3000, "Invalid", "WriteSections (): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
755 }\r
756 }\r
757 }\r
758 }\r
759 }\r
760\r
761 return TRUE;\r
762}\r
763\r
764UINTN gMovwOffset = 0;\r
765\r
766STATIC\r
767VOID\r
768WriteRelocations32 (\r
769 VOID\r
770 )\r
771{\r
772 UINT32 Index;\r
773 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
774 EFI_IMAGE_DATA_DIRECTORY *Dir;\r
775 BOOLEAN FoundRelocations;\r
776 Elf_Dyn *Dyn;\r
777 Elf_Rel *Rel;\r
778 UINTN RelElementSize;\r
779 UINTN RelSize;\r
780 UINTN RelOffset;\r
781 UINTN K;\r
782 UINT8 *Targ;\r
783 Elf32_Phdr *DynamicSegment;\r
784 Elf32_Phdr *TargetSegment;\r
785\r
786 for (Index = 0, FoundRelocations = FALSE; Index < mEhdr->e_shnum; Index++) {\r
787 Elf_Shdr *RelShdr = GetShdrByIndex(Index);\r
788 if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) {\r
789 Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info);\r
790 if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {\r
791 UINT32 RelIdx;\r
792\r
793 FoundRelocations = TRUE;\r
794 for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
795 Elf_Rel *Rel = (Elf_Rel *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);\r
796\r
797 if (mEhdr->e_machine == EM_386) { \r
798 switch (ELF_R_TYPE(Rel->r_info)) {\r
799 case R_386_NONE:\r
800 case R_386_PC32:\r
801 //\r
802 // No fixup entry required.\r
803 //\r
804 break;\r
805 case R_386_32:\r
806 //\r
807 // Creates a relative relocation entry from the absolute entry.\r
808 //\r
809 CoffAddFixup(mCoffSectionsOffset[RelShdr->sh_info]\r
810 + (Rel->r_offset - SecShdr->sh_addr),\r
811 EFI_IMAGE_REL_BASED_HIGHLOW);\r
812 break;\r
813 default:\r
814 Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_386 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
815 }\r
816 } else if (mEhdr->e_machine == EM_ARM) {\r
817 switch (ELF32_R_TYPE(Rel->r_info)) {\r
818 case R_ARM_RBASE:\r
819 // No relocation - no action required\r
820 // break skipped\r
821\r
822 case R_ARM_PC24:\r
823 case R_ARM_XPC25:\r
824 case R_ARM_THM_PC22:\r
825 case R_ARM_THM_JUMP19:\r
826 case R_ARM_CALL:\r
827 case R_ARM_JMP24:\r
828 case R_ARM_THM_JUMP24: \r
829 case R_ARM_PREL31: \r
830 case R_ARM_MOVW_PREL_NC: \r
831 case R_ARM_MOVT_PREL:\r
832 case R_ARM_THM_MOVW_PREL_NC:\r
833 case R_ARM_THM_MOVT_PREL:\r
834 case R_ARM_THM_JMP6:\r
835 case R_ARM_THM_ALU_PREL_11_0:\r
836 case R_ARM_THM_PC12:\r
837 case R_ARM_REL32_NOI:\r
838 case R_ARM_ALU_PC_G0_NC:\r
839 case R_ARM_ALU_PC_G0:\r
840 case R_ARM_ALU_PC_G1_NC:\r
841 case R_ARM_ALU_PC_G1:\r
842 case R_ARM_ALU_PC_G2:\r
843 case R_ARM_LDR_PC_G1:\r
844 case R_ARM_LDR_PC_G2:\r
845 case R_ARM_LDRS_PC_G0:\r
846 case R_ARM_LDRS_PC_G1:\r
847 case R_ARM_LDRS_PC_G2:\r
848 case R_ARM_LDC_PC_G0:\r
849 case R_ARM_LDC_PC_G1:\r
850 case R_ARM_LDC_PC_G2:\r
851 case R_ARM_GOT_PREL:\r
852 case R_ARM_THM_JUMP11:\r
853 case R_ARM_THM_JUMP8:\r
854 case R_ARM_TLS_GD32:\r
855 case R_ARM_TLS_LDM32:\r
856 case R_ARM_TLS_IE32:\r
857 // Thease are all PC-relative relocations and don't require modification\r
858 break;\r
859\r
860 case R_ARM_THM_MOVW_ABS_NC:\r
861 CoffAddFixup (\r
862 mCoffSectionsOffset[RelShdr->sh_info]\r
863 + (Rel->r_offset - SecShdr->sh_addr),\r
864 EFI_IMAGE_REL_BASED_ARM_MOV32T\r
865 );\r
866\r
867 // PE/COFF treats MOVW/MOVT relocation as single 64-bit instruction\r
868 // Track this address so we can log an error for unsupported sequence of MOVW/MOVT\r
869 gMovwOffset = mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr);\r
870 break;\r
871\r
872 case R_ARM_THM_MOVT_ABS:\r
873 if ((gMovwOffset + 4) != (mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr))) {\r
874 Error (NULL, 0, 3000, "Not Supported", "PE/COFF requires MOVW+MOVT instruction sequence %x +4 != %x.", gMovwOffset, mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));\r
875 }\r
876 break;\r
877\r
878 case R_ARM_ABS32:\r
879 case R_ARM_RABS32:\r
880 CoffAddFixup (\r
881 mCoffSectionsOffset[RelShdr->sh_info]\r
882 + (Rel->r_offset - SecShdr->sh_addr),\r
883 EFI_IMAGE_REL_BASED_HIGHLOW\r
884 );\r
885 break;\r
886\r
887 default:\r
888 Error (NULL, 0, 3000, "Invalid", "WriteRelocations(): %s unsupported ELF EM_ARM relocation 0x%x.", mInImageName, (unsigned) ELF32_R_TYPE(Rel->r_info));\r
889 }\r
890 } else {\r
891 Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);\r
892 }\r
893 }\r
894 }\r
895 }\r
896 }\r
897\r
898 if (!FoundRelocations && (mEhdr->e_machine == EM_ARM)) {\r
899 /* Try again, but look for PT_DYNAMIC instead of SHT_REL */\r
900\r
901 for (Index = 0; Index < mEhdr->e_phnum; Index++) {\r
902 RelElementSize = 0;\r
903 RelSize = 0;\r
904 RelOffset = 0;\r
905\r
906 DynamicSegment = GetPhdrByIndex (Index);\r
907\r
908 if (DynamicSegment->p_type == PT_DYNAMIC) {\r
909 Dyn = (Elf32_Dyn *) ((UINT8 *)mEhdr + DynamicSegment->p_offset);\r
910\r
911 while (Dyn->d_tag != DT_NULL) {\r
912 switch (Dyn->d_tag) {\r
913 case DT_REL:\r
914 RelOffset = Dyn->d_un.d_val;\r
915 break;\r
916\r
917 case DT_RELSZ:\r
918 RelSize = Dyn->d_un.d_val;\r
919 break;\r
920\r
921 case DT_RELENT:\r
922 RelElementSize = Dyn->d_un.d_val;\r
923 break;\r
924\r
925 default:\r
926 break;\r
927 }\r
928 Dyn++;\r
929 }\r
930 if (( RelOffset == 0 ) || ( RelSize == 0 ) || ( RelElementSize == 0 )) {\r
931 Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations.", mInImageName);\r
932 }\r
933\r
934 for (K = 0; K < RelSize; K += RelElementSize) {\r
935\r
936 if (DynamicSegment->p_paddr == 0) {\r
937 // Older versions of the ARM ELF (SWS ESPC 0003 B-02) specification define DT_REL\r
938 // as an offset in the dynamic segment. p_paddr is defined to be zero for ARM tools\r
939 Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + DynamicSegment->p_offset + RelOffset + K);\r
940 } else {\r
941 // This is how it reads in the generic ELF specification\r
942 Rel = (Elf32_Rel *) ((UINT8 *) mEhdr + RelOffset + K);\r
943 }\r
944\r
945 switch (ELF32_R_TYPE (Rel->r_info)) {\r
946 case R_ARM_RBASE:\r
947 break;\r
948\r
949 case R_ARM_RABS32:\r
950 TargetSegment = GetPhdrByIndex (ELF32_R_SYM (Rel->r_info) - 1);\r
951\r
952 // Note: r_offset in a memory address. Convert it to a pointer in the coff file.\r
953 Targ = mCoffFile + mCoffSectionsOffset[ ELF32_R_SYM( Rel->r_info ) ] + Rel->r_offset - TargetSegment->p_vaddr;\r
954\r
955 *(UINT32 *)Targ = *(UINT32 *)Targ + mCoffSectionsOffset [ELF32_R_SYM( Rel->r_info )];\r
956\r
957 CoffAddFixup (mCoffSectionsOffset[ELF32_R_SYM (Rel->r_info)] + (Rel->r_offset - TargetSegment->p_vaddr), EFI_IMAGE_REL_BASED_HIGHLOW);\r
958 break;\r
959 \r
960 default:\r
961 Error (NULL, 0, 3000, "Invalid", "%s bad ARM dynamic relocations, unkown type %d.", mInImageName, ELF32_R_TYPE (Rel->r_info));\r
962 break;\r
963 }\r
964 }\r
965 break;\r
966 }\r
967 }\r
968 }\r
969\r
970 //\r
971 // Pad by adding empty entries.\r
972 //\r
973 while (mCoffOffset & (mCoffAlignment - 1)) {\r
974 CoffAddFixupEntry(0);\r
975 }\r
976\r
977 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
978 Dir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
979 Dir->Size = mCoffOffset - mRelocOffset;\r
980 if (Dir->Size == 0) {\r
981 // If no relocations, null out the directory entry and don't add the .reloc section\r
982 Dir->VirtualAddress = 0;\r
983 NtHdr->Pe32.FileHeader.NumberOfSections--;\r
984 } else {\r
985 Dir->VirtualAddress = mRelocOffset;\r
986 CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset,\r
987 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
988 | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
989 | EFI_IMAGE_SCN_MEM_READ);\r
990 }\r
991\r
992}\r
993\r
994STATIC\r
995VOID\r
996WriteDebug32 (\r
997 VOID\r
998 )\r
999{\r
1000 UINT32 Len;\r
1001 UINT32 DebugOffset;\r
1002 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
1003 EFI_IMAGE_DATA_DIRECTORY *DataDir;\r
1004 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;\r
1005 EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
1006\r
1007 Len = strlen(mInImageName) + 1;\r
1008 DebugOffset = mCoffOffset;\r
1009\r
1010 mCoffOffset += sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)\r
1011 + sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY)\r
1012 + Len;\r
1013 mCoffOffset = CoffAlign(mCoffOffset);\r
1014\r
1015 mCoffFile = realloc(mCoffFile, mCoffOffset);\r
1016 memset(mCoffFile + DebugOffset, 0, mCoffOffset - DebugOffset);\r
1017\r
1018 Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + DebugOffset);\r
1019 Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
1020 Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
1021 Dir->RVA = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
1022 Dir->FileOffset = DebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
1023\r
1024 Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
1025 Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
1026 strcpy ((char *)(Nb10 + 1), mInImageName);\r
1027\r
1028\r
1029 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
1030 DataDir = &NtHdr->Pe32.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
1031 DataDir->VirtualAddress = DebugOffset;\r
1032 DataDir->Size = mCoffOffset - DebugOffset;\r
1033 if (DataDir->Size == 0) {\r
1034 // If no debug, null out the directory entry and don't add the .debug section\r
1035 DataDir->VirtualAddress = 0;\r
1036 NtHdr->Pe32.FileHeader.NumberOfSections--;\r
1037 } else {\r
1038 DataDir->VirtualAddress = DebugOffset;\r
1039 CreateSectionHeader (".debug", DebugOffset, mCoffOffset - DebugOffset,\r
1040 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
1041 | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
1042 | EFI_IMAGE_SCN_MEM_READ);\r
1043\r
1044 }\r
1045}\r
1046\r
1047STATIC\r
1048VOID\r
1049SetImageSize32 (\r
1050 VOID\r
1051 )\r
1052{\r
1053 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
1054 \r
1055 //\r
1056 // Set image size\r
1057 //\r
1058 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
1059 NtHdr->Pe32.OptionalHeader.SizeOfImage = mCoffOffset;\r
1060}\r
1061\r
1062STATIC\r
1063VOID\r
1064CleanUp32 (\r
1065 VOID\r
1066 )\r
1067{\r
1068 if (mCoffSectionsOffset != NULL) {\r
1069 free (mCoffSectionsOffset);\r
1070 }\r
1071}\r
1072\r
1073\r