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