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