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