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