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