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