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