]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenFw/Elf64Convert.c
BaseTools/GenFw: Enhance error message for bad symbol definitions
[mirror_edk2.git] / BaseTools / Source / C / GenFw / Elf64Convert.c
CommitLineData
f51461c8 1/** @file\r
97fa0ee9 2Elf64 convert solution\r
f51461c8 3\r
97fa0ee9 4Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>\r
87280982 5Portions copyright (c) 2013-2014, ARM Ltd. All rights reserved.<BR>\r
f51461c8
LG
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 "Elf64Convert.h"\r
39\r
40STATIC\r
41VOID\r
42ScanSections64 (\r
43 VOID\r
44 );\r
45\r
46STATIC\r
47BOOLEAN\r
48WriteSections64 (\r
49 SECTION_FILTER_TYPES FilterType\r
50 );\r
51\r
52STATIC\r
53VOID\r
54WriteRelocations64 (\r
55 VOID\r
56 );\r
57\r
58STATIC\r
59VOID\r
60WriteDebug64 (\r
61 VOID\r
62 );\r
63\r
64STATIC\r
65VOID\r
66SetImageSize64 (\r
67 VOID\r
68 );\r
69\r
70STATIC\r
71VOID\r
72CleanUp64 (\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 Elf64_Shdr Elf_Shdr;\r
80typedef Elf64_Ehdr Elf_Ehdr;\r
81typedef Elf64_Rel Elf_Rel;\r
82typedef Elf64_Rela Elf_Rela;\r
83typedef Elf64_Sym Elf_Sym;\r
84typedef Elf64_Phdr Elf_Phdr;\r
85typedef Elf64_Dyn Elf_Dyn;\r
86#define ELFCLASS ELFCLASS64\r
87#define ELF_R_TYPE(r) ELF64_R_TYPE(r)\r
88#define ELF_R_SYM(r) ELF64_R_SYM(r)\r
89\r
90//\r
91// Well known ELF structures.\r
92//\r
93STATIC Elf_Ehdr *mEhdr;\r
94STATIC Elf_Shdr *mShdrBase;\r
95STATIC Elf_Phdr *mPhdrBase;\r
96\r
97//\r
98// Coff information\r
99//\r
54b1b57a 100STATIC UINT32 mCoffAlignment = 0x20;\r
f51461c8
LG
101\r
102//\r
103// PE section alignment.\r
104//\r
0192b71c 105STATIC const UINT16 mCoffNbrSections = 4;\r
f51461c8
LG
106\r
107//\r
108// ELF sections to offset in Coff file.\r
109//\r
110STATIC UINT32 *mCoffSectionsOffset = NULL;\r
111\r
112//\r
113// Offsets in COFF file\r
114//\r
115STATIC UINT32 mNtHdrOffset;\r
116STATIC UINT32 mTextOffset;\r
117STATIC UINT32 mDataOffset;\r
118STATIC UINT32 mHiiRsrcOffset;\r
119STATIC UINT32 mRelocOffset;\r
0192b71c 120STATIC UINT32 mDebugOffset;\r
f51461c8
LG
121\r
122//\r
123// Initialization Function\r
124//\r
125BOOLEAN\r
126InitializeElf64 (\r
127 UINT8 *FileBuffer,\r
128 ELF_FUNCTION_TABLE *ElfFunctions\r
129 )\r
130{\r
131 //\r
132 // Initialize data pointer and structures.\r
133 //\r
134 VerboseMsg ("Set EHDR");\r
135 mEhdr = (Elf_Ehdr*) FileBuffer;\r
136\r
137 //\r
138 // Check the ELF64 specific header information.\r
139 //\r
140 VerboseMsg ("Check ELF64 Header Information");\r
141 if (mEhdr->e_ident[EI_CLASS] != ELFCLASS64) {\r
142 Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFCLASS64");\r
143 return FALSE;\r
144 }\r
145 if (mEhdr->e_ident[EI_DATA] != ELFDATA2LSB) {\r
146 Error (NULL, 0, 3000, "Unsupported", "ELF EI_DATA not ELFDATA2LSB");\r
147 return FALSE;\r
148 }\r
149 if ((mEhdr->e_type != ET_EXEC) && (mEhdr->e_type != ET_DYN)) {\r
150 Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");\r
151 return FALSE;\r
152 }\r
153 if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64))) {\r
154 Error (NULL, 0, 3000, "Unsupported", "ELF e_machine not EM_X86_64 or EM_AARCH64");\r
155 return FALSE;\r
156 }\r
157 if (mEhdr->e_version != EV_CURRENT) {\r
158 Error (NULL, 0, 3000, "Unsupported", "ELF e_version (%u) not EV_CURRENT (%d)", (unsigned) mEhdr->e_version, EV_CURRENT);\r
159 return FALSE;\r
160 }\r
161\r
162 //\r
163 // Update section header pointers\r
164 //\r
165 VerboseMsg ("Update Header Pointers");\r
166 mShdrBase = (Elf_Shdr *)((UINT8 *)mEhdr + mEhdr->e_shoff);\r
167 mPhdrBase = (Elf_Phdr *)((UINT8 *)mEhdr + mEhdr->e_phoff);\r
168\r
169 //\r
170 // Create COFF Section offset buffer and zero.\r
171 //\r
172 VerboseMsg ("Create COFF Section Offset Buffer");\r
173 mCoffSectionsOffset = (UINT32 *)malloc(mEhdr->e_shnum * sizeof (UINT32));\r
174 memset(mCoffSectionsOffset, 0, mEhdr->e_shnum * sizeof(UINT32));\r
175\r
176 //\r
177 // Fill in function pointers.\r
178 //\r
179 VerboseMsg ("Fill in Function Pointers");\r
180 ElfFunctions->ScanSections = ScanSections64;\r
181 ElfFunctions->WriteSections = WriteSections64;\r
182 ElfFunctions->WriteRelocations = WriteRelocations64;\r
183 ElfFunctions->WriteDebug = WriteDebug64;\r
184 ElfFunctions->SetImageSize = SetImageSize64;\r
185 ElfFunctions->CleanUp = CleanUp64;\r
186\r
187 return TRUE;\r
188}\r
189\r
190\r
191//\r
192// Header by Index functions\r
193//\r
194STATIC\r
195Elf_Shdr*\r
196GetShdrByIndex (\r
197 UINT32 Num\r
198 )\r
199{\r
17751c5f
ML
200 if (Num >= mEhdr->e_shnum) {\r
201 Error (NULL, 0, 3000, "Invalid", "GetShdrByIndex: Index %u is too high.", Num);\r
202 exit(EXIT_FAILURE);\r
203 }\r
204\r
f51461c8
LG
205 return (Elf_Shdr*)((UINT8*)mShdrBase + Num * mEhdr->e_shentsize);\r
206}\r
207\r
208STATIC\r
209UINT32\r
210CoffAlign (\r
211 UINT32 Offset\r
212 )\r
213{\r
214 return (Offset + mCoffAlignment - 1) & ~(mCoffAlignment - 1);\r
215}\r
216\r
4f7d5c67
AB
217STATIC\r
218UINT32\r
219DebugRvaAlign (\r
220 UINT32 Offset\r
221 )\r
222{\r
223 return (Offset + 3) & ~3;\r
224}\r
225\r
f51461c8
LG
226//\r
227// filter functions\r
228//\r
229STATIC\r
230BOOLEAN\r
231IsTextShdr (\r
232 Elf_Shdr *Shdr\r
233 )\r
234{\r
235 return (BOOLEAN) ((Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == SHF_ALLOC);\r
236}\r
237\r
238STATIC\r
239BOOLEAN\r
240IsHiiRsrcShdr (\r
241 Elf_Shdr *Shdr\r
242 )\r
243{\r
244 Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);\r
245\r
246 return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0);\r
247}\r
248\r
249STATIC\r
250BOOLEAN\r
251IsDataShdr (\r
252 Elf_Shdr *Shdr\r
253 )\r
254{\r
255 if (IsHiiRsrcShdr(Shdr)) {\r
256 return FALSE;\r
257 }\r
258 return (BOOLEAN) (Shdr->sh_flags & (SHF_WRITE | SHF_ALLOC)) == (SHF_ALLOC | SHF_WRITE);\r
259}\r
260\r
621bb723
ML
261STATIC\r
262BOOLEAN\r
263IsStrtabShdr (\r
264 Elf_Shdr *Shdr\r
265 )\r
266{\r
267 Elf_Shdr *Namedr = GetShdrByIndex(mEhdr->e_shstrndx);\r
268\r
269 return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_STRTAB_SECTION_NAME) == 0);\r
270}\r
271\r
272STATIC\r
273Elf_Shdr *\r
274FindStrtabShdr (\r
275 VOID\r
276 )\r
277{\r
278 UINT32 i;\r
279 for (i = 0; i < mEhdr->e_shnum; i++) {\r
280 Elf_Shdr *shdr = GetShdrByIndex(i);\r
281 if (IsStrtabShdr(shdr)) {\r
282 return shdr;\r
283 }\r
284 }\r
285 return NULL;\r
286}\r
287\r
288STATIC\r
289const UINT8 *\r
290GetSymName (\r
291 Elf_Sym *Sym\r
292 )\r
293{\r
294 if (Sym->st_name == 0) {\r
295 return NULL;\r
296 }\r
297\r
298 Elf_Shdr *StrtabShdr = FindStrtabShdr();\r
299 if (StrtabShdr == NULL) {\r
300 return NULL;\r
301 }\r
302\r
303 assert(Sym->st_name < StrtabShdr->sh_size);\r
304\r
305 return (UINT8*)mEhdr + StrtabShdr->sh_offset + Sym->st_name;\r
306}\r
307\r
f51461c8
LG
308//\r
309// Elf functions interface implementation\r
310//\r
311\r
312STATIC\r
313VOID\r
314ScanSections64 (\r
315 VOID\r
316 )\r
317{\r
318 UINT32 i;\r
319 EFI_IMAGE_DOS_HEADER *DosHdr;\r
320 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
321 UINT32 CoffEntry;\r
322 UINT32 SectionCount;\r
234f9ff9 323 BOOLEAN FoundSection;\r
f51461c8
LG
324\r
325 CoffEntry = 0;\r
326 mCoffOffset = 0;\r
f51461c8
LG
327\r
328 //\r
329 // Coff file start with a DOS header.\r
330 //\r
331 mCoffOffset = sizeof(EFI_IMAGE_DOS_HEADER) + 0x40;\r
332 mNtHdrOffset = mCoffOffset;\r
333 switch (mEhdr->e_machine) {\r
334 case EM_X86_64:\r
335 case EM_IA_64:\r
336 case EM_AARCH64:\r
337 mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
338 break;\r
339 default:\r
340 VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);\r
341 mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);\r
342 break;\r
343 }\r
344\r
345 mTableOffset = mCoffOffset;\r
346 mCoffOffset += mCoffNbrSections * sizeof(EFI_IMAGE_SECTION_HEADER);\r
347\r
54b1b57a
AB
348 //\r
349 // Set mCoffAlignment to the maximum alignment of the input sections\r
350 // we care about\r
351 //\r
352 for (i = 0; i < mEhdr->e_shnum; i++) {\r
353 Elf_Shdr *shdr = GetShdrByIndex(i);\r
354 if (shdr->sh_addralign <= mCoffAlignment) {\r
355 continue;\r
356 }\r
357 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {\r
358 mCoffAlignment = (UINT32)shdr->sh_addralign;\r
359 }\r
360 }\r
361\r
02a5421f
AB
362 //\r
363 // Move the PE/COFF header right before the first section. This will help us\r
364 // save space when converting to TE.\r
365 //\r
366 if (mCoffAlignment > mCoffOffset) {\r
367 mNtHdrOffset += mCoffAlignment - mCoffOffset;\r
368 mTableOffset += mCoffAlignment - mCoffOffset;\r
369 mCoffOffset = mCoffAlignment;\r
370 }\r
371\r
f51461c8
LG
372 //\r
373 // First text sections.\r
374 //\r
375 mCoffOffset = CoffAlign(mCoffOffset);\r
234f9ff9
EB
376 mTextOffset = mCoffOffset;\r
377 FoundSection = FALSE;\r
f51461c8
LG
378 SectionCount = 0;\r
379 for (i = 0; i < mEhdr->e_shnum; i++) {\r
380 Elf_Shdr *shdr = GetShdrByIndex(i);\r
381 if (IsTextShdr(shdr)) {\r
382 if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
383 // the alignment field is valid\r
384 if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
385 // if the section address is aligned we must align PE/COFF\r
386 mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));\r
0c960e86
AB
387 } else {\r
388 Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");\r
f51461c8
LG
389 }\r
390 }\r
391\r
392 /* Relocate entry. */\r
393 if ((mEhdr->e_entry >= shdr->sh_addr) &&\r
394 (mEhdr->e_entry < shdr->sh_addr + shdr->sh_size)) {\r
395 CoffEntry = (UINT32) (mCoffOffset + mEhdr->e_entry - shdr->sh_addr);\r
396 }\r
397\r
398 //\r
399 // Set mTextOffset with the offset of the first '.text' section\r
400 //\r
234f9ff9 401 if (!FoundSection) {\r
f51461c8 402 mTextOffset = mCoffOffset;\r
234f9ff9 403 FoundSection = TRUE;\r
f51461c8
LG
404 }\r
405\r
406 mCoffSectionsOffset[i] = mCoffOffset;\r
407 mCoffOffset += (UINT32) shdr->sh_size;\r
408 SectionCount ++;\r
409 }\r
410 }\r
411\r
234f9ff9 412 if (!FoundSection) {\r
f51461c8
LG
413 Error (NULL, 0, 3000, "Invalid", "Did not find any '.text' section.");\r
414 assert (FALSE);\r
415 }\r
416\r
4f7d5c67 417 mDebugOffset = DebugRvaAlign(mCoffOffset);\r
0c960e86 418 mCoffOffset = CoffAlign(mCoffOffset);\r
f51461c8
LG
419\r
420 if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {\r
421 Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 text section. Source level debug might not work correctly.", mInImageName);\r
422 }\r
423\r
424 //\r
425 // Then data sections.\r
426 //\r
427 mDataOffset = mCoffOffset;\r
234f9ff9 428 FoundSection = FALSE;\r
f51461c8
LG
429 SectionCount = 0;\r
430 for (i = 0; i < mEhdr->e_shnum; i++) {\r
431 Elf_Shdr *shdr = GetShdrByIndex(i);\r
432 if (IsDataShdr(shdr)) {\r
433 if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
434 // the alignment field is valid\r
435 if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
436 // if the section address is aligned we must align PE/COFF\r
437 mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));\r
0c960e86
AB
438 } else {\r
439 Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");\r
f51461c8
LG
440 }\r
441 }\r
234f9ff9
EB
442\r
443 //\r
444 // Set mDataOffset with the offset of the first '.data' section\r
445 //\r
446 if (!FoundSection) {\r
447 mDataOffset = mCoffOffset;\r
448 FoundSection = TRUE;\r
449 }\r
f51461c8
LG
450 mCoffSectionsOffset[i] = mCoffOffset;\r
451 mCoffOffset += (UINT32) shdr->sh_size;\r
452 SectionCount ++;\r
453 }\r
454 }\r
0192b71c
AB
455\r
456 //\r
457 // Make room for .debug data in .data (or .text if .data is empty) instead of\r
458 // putting it in a section of its own. This is explicitly allowed by the\r
459 // PE/COFF spec, and prevents bloat in the binary when using large values for\r
460 // section alignment.\r
461 //\r
462 if (SectionCount > 0) {\r
4f7d5c67 463 mDebugOffset = DebugRvaAlign(mCoffOffset);\r
0192b71c
AB
464 }\r
465 mCoffOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +\r
466 sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +\r
467 strlen(mInImageName) + 1;\r
468\r
f51461c8 469 mCoffOffset = CoffAlign(mCoffOffset);\r
0192b71c
AB
470 if (SectionCount == 0) {\r
471 mDataOffset = mCoffOffset;\r
472 }\r
f51461c8
LG
473\r
474 if (SectionCount > 1 && mOutImageType == FW_EFI_IMAGE) {\r
475 Warning (NULL, 0, 0, NULL, "Mulitple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName);\r
476 }\r
477\r
478 //\r
479 // The HII resource sections.\r
480 //\r
481 mHiiRsrcOffset = mCoffOffset;\r
482 for (i = 0; i < mEhdr->e_shnum; i++) {\r
483 Elf_Shdr *shdr = GetShdrByIndex(i);\r
484 if (IsHiiRsrcShdr(shdr)) {\r
485 if ((shdr->sh_addralign != 0) && (shdr->sh_addralign != 1)) {\r
486 // the alignment field is valid\r
487 if ((shdr->sh_addr & (shdr->sh_addralign - 1)) == 0) {\r
488 // if the section address is aligned we must align PE/COFF\r
489 mCoffOffset = (UINT32) ((mCoffOffset + shdr->sh_addralign - 1) & ~(shdr->sh_addralign - 1));\r
0c960e86
AB
490 } else {\r
491 Error (NULL, 0, 3000, "Invalid", "Section address not aligned to its own alignment.");\r
f51461c8
LG
492 }\r
493 }\r
494 if (shdr->sh_size != 0) {\r
234f9ff9 495 mHiiRsrcOffset = mCoffOffset;\r
f51461c8
LG
496 mCoffSectionsOffset[i] = mCoffOffset;\r
497 mCoffOffset += (UINT32) shdr->sh_size;\r
498 mCoffOffset = CoffAlign(mCoffOffset);\r
499 SetHiiResourceHeader ((UINT8*) mEhdr + shdr->sh_offset, mHiiRsrcOffset);\r
500 }\r
501 break;\r
502 }\r
503 }\r
504\r
505 mRelocOffset = mCoffOffset;\r
506\r
507 //\r
508 // Allocate base Coff file. Will be expanded later for relocations.\r
509 //\r
510 mCoffFile = (UINT8 *)malloc(mCoffOffset);\r
511 memset(mCoffFile, 0, mCoffOffset);\r
512\r
513 //\r
514 // Fill headers.\r
515 //\r
516 DosHdr = (EFI_IMAGE_DOS_HEADER *)mCoffFile;\r
517 DosHdr->e_magic = EFI_IMAGE_DOS_SIGNATURE;\r
518 DosHdr->e_lfanew = mNtHdrOffset;\r
519\r
520 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION*)(mCoffFile + mNtHdrOffset);\r
521\r
522 NtHdr->Pe32Plus.Signature = EFI_IMAGE_NT_SIGNATURE;\r
523\r
524 switch (mEhdr->e_machine) {\r
525 case EM_X86_64:\r
526 NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;\r
527 NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
528 break;\r
529 case EM_IA_64:\r
530 NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_IPF;\r
531 NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
532 break;\r
533 case EM_AARCH64:\r
534 NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_AARCH64;\r
535 NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
536 break;\r
537 default:\r
538 VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);\r
539 NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_X64;\r
540 NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
541 }\r
542\r
543 NtHdr->Pe32Plus.FileHeader.NumberOfSections = mCoffNbrSections;\r
544 NtHdr->Pe32Plus.FileHeader.TimeDateStamp = (UINT32) time(NULL);\r
545 mImageTimeStamp = NtHdr->Pe32Plus.FileHeader.TimeDateStamp;\r
546 NtHdr->Pe32Plus.FileHeader.PointerToSymbolTable = 0;\r
547 NtHdr->Pe32Plus.FileHeader.NumberOfSymbols = 0;\r
548 NtHdr->Pe32Plus.FileHeader.SizeOfOptionalHeader = sizeof(NtHdr->Pe32Plus.OptionalHeader);\r
549 NtHdr->Pe32Plus.FileHeader.Characteristics = EFI_IMAGE_FILE_EXECUTABLE_IMAGE\r
550 | EFI_IMAGE_FILE_LINE_NUMS_STRIPPED\r
551 | EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED\r
552 | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE;\r
553\r
554 NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;\r
555 NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;\r
556 NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0;\r
557 NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry;\r
558\r
559 NtHdr->Pe32Plus.OptionalHeader.BaseOfCode = mTextOffset;\r
560\r
561 NtHdr->Pe32Plus.OptionalHeader.ImageBase = 0;\r
562 NtHdr->Pe32Plus.OptionalHeader.SectionAlignment = mCoffAlignment;\r
563 NtHdr->Pe32Plus.OptionalHeader.FileAlignment = mCoffAlignment;\r
564 NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = 0;\r
565\r
566 NtHdr->Pe32Plus.OptionalHeader.SizeOfHeaders = mTextOffset;\r
567 NtHdr->Pe32Plus.OptionalHeader.NumberOfRvaAndSizes = EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES;\r
568\r
569 //\r
570 // Section headers.\r
571 //\r
572 if ((mDataOffset - mTextOffset) > 0) {\r
573 CreateSectionHeader (".text", mTextOffset, mDataOffset - mTextOffset,\r
574 EFI_IMAGE_SCN_CNT_CODE\r
575 | EFI_IMAGE_SCN_MEM_EXECUTE\r
576 | EFI_IMAGE_SCN_MEM_READ);\r
577 } else {\r
578 // Don't make a section of size 0.\r
579 NtHdr->Pe32Plus.FileHeader.NumberOfSections--;\r
580 }\r
581\r
582 if ((mHiiRsrcOffset - mDataOffset) > 0) {\r
583 CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,\r
584 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
585 | EFI_IMAGE_SCN_MEM_WRITE\r
586 | EFI_IMAGE_SCN_MEM_READ);\r
587 } else {\r
588 // Don't make a section of size 0.\r
589 NtHdr->Pe32Plus.FileHeader.NumberOfSections--;\r
590 }\r
591\r
592 if ((mRelocOffset - mHiiRsrcOffset) > 0) {\r
593 CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset,\r
594 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
595 | EFI_IMAGE_SCN_MEM_READ);\r
596\r
597 NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = mRelocOffset - mHiiRsrcOffset;\r
598 NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = mHiiRsrcOffset;\r
599 } else {\r
600 // Don't make a section of size 0.\r
601 NtHdr->Pe32Plus.FileHeader.NumberOfSections--;\r
602 }\r
603\r
604}\r
605\r
606STATIC\r
607BOOLEAN\r
608WriteSections64 (\r
609 SECTION_FILTER_TYPES FilterType\r
610 )\r
611{\r
612 UINT32 Idx;\r
613 Elf_Shdr *SecShdr;\r
614 UINT32 SecOffset;\r
615 BOOLEAN (*Filter)(Elf_Shdr *);\r
616\r
617 //\r
618 // Initialize filter pointer\r
619 //\r
620 switch (FilterType) {\r
621 case SECTION_TEXT:\r
622 Filter = IsTextShdr;\r
623 break;\r
624 case SECTION_HII:\r
625 Filter = IsHiiRsrcShdr;\r
626 break;\r
627 case SECTION_DATA:\r
628 Filter = IsDataShdr;\r
629 break;\r
630 default:\r
631 return FALSE;\r
632 }\r
633\r
634 //\r
635 // First: copy sections.\r
636 //\r
637 for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {\r
638 Elf_Shdr *Shdr = GetShdrByIndex(Idx);\r
639 if ((*Filter)(Shdr)) {\r
640 switch (Shdr->sh_type) {\r
641 case SHT_PROGBITS:\r
642 /* Copy. */\r
643 memcpy(mCoffFile + mCoffSectionsOffset[Idx],\r
644 (UINT8*)mEhdr + Shdr->sh_offset,\r
645 (size_t) Shdr->sh_size);\r
646 break;\r
647\r
648 case SHT_NOBITS:\r
649 memset(mCoffFile + mCoffSectionsOffset[Idx], 0, (size_t) Shdr->sh_size);\r
650 break;\r
651\r
652 default:\r
653 //\r
654 // Ignore for unkown section type.\r
655 //\r
656 VerboseMsg ("%s unknown section type %x. We directly copy this section into Coff file", mInImageName, (unsigned)Shdr->sh_type);\r
657 break;\r
658 }\r
659 }\r
660 }\r
661\r
662 //\r
663 // Second: apply relocations.\r
664 //\r
665 VerboseMsg ("Applying Relocations...");\r
666 for (Idx = 0; Idx < mEhdr->e_shnum; Idx++) {\r
667 //\r
668 // Determine if this is a relocation section.\r
669 //\r
670 Elf_Shdr *RelShdr = GetShdrByIndex(Idx);\r
671 if ((RelShdr->sh_type != SHT_REL) && (RelShdr->sh_type != SHT_RELA)) {\r
672 continue;\r
673 }\r
674\r
675 //\r
676 // Relocation section found. Now extract section information that the relocations\r
677 // apply to in the ELF data and the new COFF data.\r
678 //\r
679 SecShdr = GetShdrByIndex(RelShdr->sh_info);\r
680 SecOffset = mCoffSectionsOffset[RelShdr->sh_info];\r
681\r
682 //\r
683 // Only process relocations for the current filter type.\r
684 //\r
685 if (RelShdr->sh_type == SHT_RELA && (*Filter)(SecShdr)) {\r
686 UINT64 RelIdx;\r
687\r
688 //\r
689 // Determine the symbol table referenced by the relocation data.\r
690 //\r
691 Elf_Shdr *SymtabShdr = GetShdrByIndex(RelShdr->sh_link);\r
692 UINT8 *Symtab = (UINT8*)mEhdr + SymtabShdr->sh_offset;\r
693\r
694 //\r
695 // Process all relocation entries for this section.\r
696 //\r
697 for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINT32) RelShdr->sh_entsize) {\r
698\r
699 //\r
700 // Set pointer to relocation entry\r
701 //\r
702 Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);\r
703\r
704 //\r
705 // Set pointer to symbol table entry associated with the relocation entry.\r
706 //\r
707 Elf_Sym *Sym = (Elf_Sym *)(Symtab + ELF_R_SYM(Rel->r_info) * SymtabShdr->sh_entsize);\r
708\r
709 Elf_Shdr *SymShdr;\r
710 UINT8 *Targ;\r
711\r
712 //\r
713 // Check section header index found in symbol table and get the section\r
714 // header location.\r
715 //\r
716 if (Sym->st_shndx == SHN_UNDEF\r
621bb723
ML
717 || Sym->st_shndx >= mEhdr->e_shnum) {\r
718 const UINT8 *SymName = GetSymName(Sym);\r
719 if (SymName == NULL) {\r
720 SymName = (const UINT8 *)"<unknown>";\r
721 }\r
722\r
723 Error (NULL, 0, 3000, "Invalid",\r
724 "%s: Bad definition for symbol '%s'@%p or unsupported symbol type. "\r
725 "For example, absolute and undefined symbols are not supported.",\r
726 mInImageName, SymName, Sym->st_value);\r
727\r
728 exit(EXIT_FAILURE);\r
f51461c8
LG
729 }\r
730 SymShdr = GetShdrByIndex(Sym->st_shndx);\r
731\r
732 //\r
733 // Convert the relocation data to a pointer into the coff file.\r
734 //\r
735 // Note:\r
736 // r_offset is the virtual address of the storage unit to be relocated.\r
737 // sh_addr is the virtual address for the base of the section.\r
738 //\r
739 // r_offset in a memory address.\r
740 // Convert it to a pointer in the coff file.\r
741 //\r
742 Targ = mCoffFile + SecOffset + (Rel->r_offset - SecShdr->sh_addr);\r
743\r
744 //\r
745 // Determine how to handle each relocation type based on the machine type.\r
746 //\r
747 if (mEhdr->e_machine == EM_X86_64) {\r
748 switch (ELF_R_TYPE(Rel->r_info)) {\r
749 case R_X86_64_NONE:\r
750 break;\r
751 case R_X86_64_64:\r
752 //\r
753 // Absolute relocation.\r
754 //\r
755 VerboseMsg ("R_X86_64_64");\r
756 VerboseMsg ("Offset: 0x%08X, Addend: 0x%016LX", \r
757 (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), \r
758 *(UINT64 *)Targ);\r
759 *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
760 VerboseMsg ("Relocation: 0x%016LX", *(UINT64*)Targ);\r
761 break;\r
762 case R_X86_64_32:\r
763 VerboseMsg ("R_X86_64_32");\r
764 VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", \r
765 (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), \r
766 *(UINT32 *)Targ);\r
767 *(UINT32 *)Targ = (UINT32)((UINT64)(*(UINT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);\r
768 VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ);\r
769 break;\r
770 case R_X86_64_32S:\r
771 VerboseMsg ("R_X86_64_32S");\r
772 VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", \r
773 (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), \r
774 *(UINT32 *)Targ);\r
775 *(INT32 *)Targ = (INT32)((INT64)(*(INT32 *)Targ) - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx]);\r
776 VerboseMsg ("Relocation: 0x%08X", *(UINT32*)Targ);\r
777 break;\r
778 case R_X86_64_PC32:\r
779 //\r
780 // Relative relocation: Symbol - Ip + Addend\r
781 //\r
782 VerboseMsg ("R_X86_64_PC32");\r
783 VerboseMsg ("Offset: 0x%08X, Addend: 0x%08X", \r
784 (UINT32)(SecOffset + (Rel->r_offset - SecShdr->sh_addr)), \r
785 *(UINT32 *)Targ);\r
786 *(UINT32 *)Targ = (UINT32) (*(UINT32 *)Targ\r
787 + (mCoffSectionsOffset[Sym->st_shndx] - SymShdr->sh_addr)\r
788 - (SecOffset - SecShdr->sh_addr));\r
789 VerboseMsg ("Relocation: 0x%08X", *(UINT32 *)Targ);\r
790 break;\r
791 default:\r
792 Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
793 }\r
794 } else if (mEhdr->e_machine == EM_AARCH64) {\r
795\r
f51461c8
LG
796 switch (ELF_R_TYPE(Rel->r_info)) {\r
797\r
24d610e6
AB
798 case R_AARCH64_ADR_PREL_PG_HI21:\r
799 case R_AARCH64_ADD_ABS_LO12_NC:\r
800 case R_AARCH64_LDST8_ABS_LO12_NC:\r
801 case R_AARCH64_LDST16_ABS_LO12_NC:\r
802 case R_AARCH64_LDST32_ABS_LO12_NC:\r
803 case R_AARCH64_LDST64_ABS_LO12_NC:\r
804 case R_AARCH64_LDST128_ABS_LO12_NC:\r
805 //\r
806 // AArch64 PG_H21 relocations are typically paired with ABS_LO12\r
807 // relocations, where a PC-relative reference with +/- 4 GB range is\r
808 // split into a relative high part and an absolute low part. Since\r
809 // the absolute low part represents the offset into a 4 KB page, we\r
810 // have to make sure that the 4 KB relative offsets of both the\r
811 // section containing the reference as well as the section to which\r
812 // it refers have not been changed during PE/COFF conversion (i.e.,\r
813 // in ScanSections64() above).\r
814 //\r
815 if (((SecShdr->sh_addr ^ SecOffset) & 0xfff) != 0 ||\r
816 ((SymShdr->sh_addr ^ mCoffSectionsOffset[Sym->st_shndx]) & 0xfff) != 0 ||\r
817 mCoffAlignment < 0x1000) {\r
818 Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s AARCH64 small code model requires 4 KB section alignment.",\r
819 mInImageName);\r
820 break;\r
87280982 821 }\r
24d610e6 822 /* fall through */\r
87280982 823\r
24d610e6 824 case R_AARCH64_ADR_PREL_LO21:\r
87280982 825 case R_AARCH64_CONDBR19:\r
f51461c8 826 case R_AARCH64_LD_PREL_LO19:\r
f51461c8 827 case R_AARCH64_CALL26:\r
f51461c8 828 case R_AARCH64_JUMP26:\r
0b6249f5
AB
829 case R_AARCH64_PREL64:\r
830 case R_AARCH64_PREL32:\r
831 case R_AARCH64_PREL16:\r
24d610e6
AB
832 //\r
833 // The GCC toolchains (i.e., binutils) may corrupt section relative\r
834 // relocations when emitting relocation sections into fully linked\r
835 // binaries. More specifically, they tend to fail to take into\r
836 // account the fact that a '.rodata + XXX' relocation needs to have\r
837 // its addend recalculated once .rodata is merged into the .text\r
838 // section, and the relocation emitted into the .rela.text section.\r
839 //\r
840 // We cannot really recover from this loss of information, so the\r
841 // only workaround is to prevent having to recalculate any relative\r
842 // relocations at all, by using a linker script that ensures that\r
843 // the offset between the Place and the Symbol is the same in both\r
844 // the ELF and the PE/COFF versions of the binary.\r
845 //\r
846 if ((SymShdr->sh_addr - SecShdr->sh_addr) !=\r
847 (mCoffSectionsOffset[Sym->st_shndx] - SecOffset)) {\r
848 Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s AARCH64 relative relocations require identical ELF and PE/COFF section offsets",\r
849 mInImageName);\r
f51461c8
LG
850 }\r
851 break;\r
852\r
f51461c8
LG
853 // Absolute relocations.\r
854 case R_AARCH64_ABS64:\r
855 *(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];\r
856 break;\r
857\r
858 default:\r
859 Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
860 }\r
861 } else {\r
862 Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");\r
863 }\r
864 }\r
865 }\r
866 }\r
867\r
868 return TRUE;\r
869}\r
870\r
871STATIC\r
872VOID\r
873WriteRelocations64 (\r
874 VOID\r
875 )\r
876{\r
877 UINT32 Index;\r
878 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
879 EFI_IMAGE_DATA_DIRECTORY *Dir;\r
880\r
881 for (Index = 0; Index < mEhdr->e_shnum; Index++) {\r
882 Elf_Shdr *RelShdr = GetShdrByIndex(Index);\r
883 if ((RelShdr->sh_type == SHT_REL) || (RelShdr->sh_type == SHT_RELA)) {\r
884 Elf_Shdr *SecShdr = GetShdrByIndex (RelShdr->sh_info);\r
885 if (IsTextShdr(SecShdr) || IsDataShdr(SecShdr)) {\r
886 UINT64 RelIdx;\r
887\r
888 for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += RelShdr->sh_entsize) {\r
889 Elf_Rela *Rel = (Elf_Rela *)((UINT8*)mEhdr + RelShdr->sh_offset + RelIdx);\r
890\r
891 if (mEhdr->e_machine == EM_X86_64) {\r
892 switch (ELF_R_TYPE(Rel->r_info)) {\r
893 case R_X86_64_NONE:\r
894 case R_X86_64_PC32:\r
895 break;\r
896 case R_X86_64_64:\r
897 VerboseMsg ("EFI_IMAGE_REL_BASED_DIR64 Offset: 0x%08X", \r
898 mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));\r
899 CoffAddFixup(\r
900 (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
901 + (Rel->r_offset - SecShdr->sh_addr)),\r
902 EFI_IMAGE_REL_BASED_DIR64);\r
903 break;\r
904 case R_X86_64_32S:\r
905 case R_X86_64_32:\r
906 VerboseMsg ("EFI_IMAGE_REL_BASED_HIGHLOW Offset: 0x%08X", \r
907 mCoffSectionsOffset[RelShdr->sh_info] + (Rel->r_offset - SecShdr->sh_addr));\r
908 CoffAddFixup(\r
909 (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
910 + (Rel->r_offset - SecShdr->sh_addr)),\r
911 EFI_IMAGE_REL_BASED_HIGHLOW);\r
912 break;\r
913 default:\r
914 Error (NULL, 0, 3000, "Invalid", "%s unsupported ELF EM_X86_64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
915 }\r
916 } else if (mEhdr->e_machine == EM_AARCH64) {\r
24d610e6 917\r
f51461c8 918 switch (ELF_R_TYPE(Rel->r_info)) {\r
87280982 919 case R_AARCH64_ADR_PREL_LO21:\r
87280982 920 case R_AARCH64_CONDBR19:\r
f51461c8 921 case R_AARCH64_LD_PREL_LO19:\r
f51461c8 922 case R_AARCH64_CALL26:\r
f51461c8 923 case R_AARCH64_JUMP26:\r
0b6249f5
AB
924 case R_AARCH64_PREL64:\r
925 case R_AARCH64_PREL32:\r
926 case R_AARCH64_PREL16:\r
f51461c8 927 case R_AARCH64_ADR_PREL_PG_HI21:\r
f51461c8 928 case R_AARCH64_ADD_ABS_LO12_NC:\r
24d610e6
AB
929 case R_AARCH64_LDST8_ABS_LO12_NC:\r
930 case R_AARCH64_LDST16_ABS_LO12_NC:\r
931 case R_AARCH64_LDST32_ABS_LO12_NC:\r
932 case R_AARCH64_LDST64_ABS_LO12_NC:\r
933 case R_AARCH64_LDST128_ABS_LO12_NC:\r
0b6249f5
AB
934 //\r
935 // No fixups are required for relative relocations, provided that\r
936 // the relative offsets between sections have been preserved in\r
937 // the ELF to PE/COFF conversion. We have already asserted that\r
938 // this is the case in WriteSections64 ().\r
939 //\r
f51461c8
LG
940 break;\r
941\r
942 case R_AARCH64_ABS64:\r
943 CoffAddFixup(\r
944 (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
945 + (Rel->r_offset - SecShdr->sh_addr)),\r
946 EFI_IMAGE_REL_BASED_DIR64);\r
947 break;\r
948\r
949 case R_AARCH64_ABS32:\r
950 CoffAddFixup(\r
951 (UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]\r
952 + (Rel->r_offset - SecShdr->sh_addr)),\r
953 EFI_IMAGE_REL_BASED_HIGHLOW);\r
954 break;\r
955\r
956 default:\r
957 Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));\r
958 }\r
959 } else {\r
960 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
961 }\r
962 }\r
963 }\r
964 }\r
965 }\r
966\r
967 //\r
968 // Pad by adding empty entries.\r
969 //\r
970 while (mCoffOffset & (mCoffAlignment - 1)) {\r
971 CoffAddFixupEntry(0);\r
972 }\r
973\r
974 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
975 Dir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];\r
976 Dir->Size = mCoffOffset - mRelocOffset;\r
977 if (Dir->Size == 0) {\r
978 // If no relocations, null out the directory entry and don't add the .reloc section\r
979 Dir->VirtualAddress = 0;\r
980 NtHdr->Pe32Plus.FileHeader.NumberOfSections--;\r
981 } else {\r
982 Dir->VirtualAddress = mRelocOffset;\r
983 CreateSectionHeader (".reloc", mRelocOffset, mCoffOffset - mRelocOffset,\r
984 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA\r
985 | EFI_IMAGE_SCN_MEM_DISCARDABLE\r
986 | EFI_IMAGE_SCN_MEM_READ);\r
987 }\r
988}\r
989\r
990STATIC\r
991VOID\r
992WriteDebug64 (\r
993 VOID\r
994 )\r
995{\r
996 UINT32 Len;\r
f51461c8
LG
997 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
998 EFI_IMAGE_DATA_DIRECTORY *DataDir;\r
999 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;\r
1000 EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;\r
1001\r
1002 Len = strlen(mInImageName) + 1;\r
f51461c8 1003\r
0192b71c 1004 Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);\r
f51461c8
LG
1005 Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;\r
1006 Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;\r
0192b71c
AB
1007 Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
1008 Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
f51461c8
LG
1009\r
1010 Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);\r
1011 Nb10->Signature = CODEVIEW_SIGNATURE_NB10;\r
1012 strcpy ((char *)(Nb10 + 1), mInImageName);\r
1013\r
1014\r
1015 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
1016 DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];\r
0192b71c
AB
1017 DataDir->VirtualAddress = mDebugOffset;\r
1018 DataDir->Size = Dir->SizeOfData + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);\r
f51461c8
LG
1019}\r
1020\r
1021STATIC\r
1022VOID\r
1023SetImageSize64 (\r
1024 VOID\r
1025 )\r
1026{\r
1027 EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;\r
1028\r
1029 //\r
1030 // Set image size\r
1031 //\r
1032 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);\r
1033 NtHdr->Pe32Plus.OptionalHeader.SizeOfImage = mCoffOffset;\r
1034}\r
1035\r
1036STATIC\r
1037VOID\r
1038CleanUp64 (\r
1039 VOID\r
1040 )\r
1041{\r
1042 if (mCoffSectionsOffset != NULL) {\r
1043 free (mCoffSectionsOffset);\r
1044 }\r
1045}\r
1046\r
1047\r