]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenFw/ElfConvert.c
Sync BaseTool trunk (version r2649) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / C / GenFw / ElfConvert.c
CommitLineData
f51461c8
LG
1/** @file\r
2\r
3Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
4\r
5This program and the accompanying materials are licensed and made available \r
6under the terms and conditions of the BSD License which accompanies this \r
7distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "WinNtInclude.h"\r
16\r
17#ifndef __GNUC__\r
18#include <windows.h>\r
19#include <io.h>\r
20#endif\r
21#include <stdio.h>\r
22#include <stdlib.h>\r
23#include <string.h>\r
24#include <time.h>\r
25#include <ctype.h>\r
26\r
27#include <Common/UefiBaseTypes.h>\r
28#include <IndustryStandard/PeImage.h>\r
29\r
30#include "EfiUtilityMsgs.h"\r
31\r
32#include "GenFw.h"\r
33#include "ElfConvert.h"\r
34#include "Elf32Convert.h"\r
35#include "Elf64Convert.h"\r
36\r
37//\r
38// Result Coff file in memory.\r
39//\r
40UINT8 *mCoffFile = NULL;\r
41\r
42//\r
43// COFF relocation data\r
44//\r
45EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel;\r
46UINT16 *mCoffEntryRel;\r
47\r
48//\r
49// Current offset in coff file.\r
50//\r
51UINT32 mCoffOffset;\r
52\r
53//\r
54// Offset in Coff file of headers and sections.\r
55//\r
56UINT32 mTableOffset;\r
57\r
58//\r
59//*****************************************************************************\r
60// Common ELF Functions\r
61//*****************************************************************************\r
62//\r
63\r
64VOID\r
65CoffAddFixupEntry(\r
66 UINT16 Val\r
67 )\r
68{\r
69 *mCoffEntryRel = Val;\r
70 mCoffEntryRel++;\r
71 mCoffBaseRel->SizeOfBlock += 2;\r
72 mCoffOffset += 2;\r
73}\r
74\r
75VOID\r
76CoffAddFixup(\r
77 UINT32 Offset,\r
78 UINT8 Type\r
79 )\r
80{\r
81 if (mCoffBaseRel == NULL\r
82 || mCoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {\r
83 if (mCoffBaseRel != NULL) {\r
84 //\r
85 // Add a null entry (is it required ?)\r
86 //\r
87 CoffAddFixupEntry (0);\r
88 \r
89 //\r
90 // Pad for alignment.\r
91 //\r
92 if (mCoffOffset % 4 != 0)\r
93 CoffAddFixupEntry (0);\r
94 }\r
95\r
96 mCoffFile = realloc (\r
97 mCoffFile,\r
98 mCoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000\r
99 );\r
100 memset (\r
101 mCoffFile + mCoffOffset, 0,\r
102 sizeof(EFI_IMAGE_BASE_RELOCATION) + 2*0x1000\r
103 );\r
104\r
105 mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset);\r
106 mCoffBaseRel->VirtualAddress = Offset & ~0xfff;\r
107 mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);\r
108\r
109 mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1);\r
110 mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);\r
111 }\r
112\r
113 //\r
114 // Fill the entry.\r
115 //\r
116 CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));\r
117}\r
118\r
119VOID\r
120CreateSectionHeader (\r
121 const CHAR8 *Name,\r
122 UINT32 Offset,\r
123 UINT32 Size,\r
124 UINT32 Flags\r
125 )\r
126{\r
127 EFI_IMAGE_SECTION_HEADER *Hdr;\r
128 Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset);\r
129\r
130 strcpy((char *)Hdr->Name, Name);\r
131 Hdr->Misc.VirtualSize = Size;\r
132 Hdr->VirtualAddress = Offset;\r
133 Hdr->SizeOfRawData = Size;\r
134 Hdr->PointerToRawData = Offset;\r
135 Hdr->PointerToRelocations = 0;\r
136 Hdr->PointerToLinenumbers = 0;\r
137 Hdr->NumberOfRelocations = 0;\r
138 Hdr->NumberOfLinenumbers = 0;\r
139 Hdr->Characteristics = Flags;\r
140\r
141 mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);\r
142}\r
143\r
144//\r
145//*****************************************************************************\r
146// Functions called from GenFw main code.\r
147//*****************************************************************************\r
148//\r
149\r
150INTN\r
151IsElfHeader (\r
152 UINT8 *FileBuffer\r
153)\r
154{\r
155 return (FileBuffer[EI_MAG0] == ELFMAG0 && \r
156 FileBuffer[EI_MAG1] == ELFMAG1 &&\r
157 FileBuffer[EI_MAG2] == ELFMAG2 &&\r
158 FileBuffer[EI_MAG3] == ELFMAG3);\r
159}\r
160\r
161BOOLEAN\r
162ConvertElf (\r
163 UINT8 **FileBuffer,\r
164 UINT32 *FileLength\r
165 )\r
166{\r
167 ELF_FUNCTION_TABLE ElfFunctions;\r
168 UINT8 EiClass;\r
169\r
170 //\r
171 // Determine ELF type and set function table pointer correctly.\r
172 //\r
173 VerboseMsg ("Check Elf Image Header");\r
174 EiClass = (*FileBuffer)[EI_CLASS];\r
175 if (EiClass == ELFCLASS32) {\r
176 if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) {\r
177 return FALSE;\r
178 }\r
179 } else if (EiClass == ELFCLASS64) {\r
180 if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) {\r
181 return FALSE;\r
182 }\r
183 } else {\r
184 Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported.");\r
185 return FALSE;\r
186 }\r
187\r
188 //\r
189 // Compute sections new address.\r
190 // \r
191 VerboseMsg ("Compute sections new address.");\r
192 ElfFunctions.ScanSections ();\r
193\r
194 //\r
195 // Write and relocate sections.\r
196 //\r
197 VerboseMsg ("Write and relocate sections.");\r
198 ElfFunctions.WriteSections (SECTION_TEXT);\r
199 ElfFunctions.WriteSections (SECTION_DATA);\r
200 ElfFunctions.WriteSections (SECTION_HII);\r
201\r
202 //\r
203 // Translate and write relocations.\r
204 //\r
205 VerboseMsg ("Translate and write relocations.");\r
206 ElfFunctions.WriteRelocations ();\r
207\r
208 //\r
209 // Write debug info.\r
210 //\r
211 VerboseMsg ("Write debug info.");\r
212 ElfFunctions.WriteDebug ();\r
213\r
214 //\r
215 // Make sure image size is correct before returning the new image.\r
216 //\r
217 VerboseMsg ("Set image size.");\r
218 ElfFunctions.SetImageSize ();\r
219\r
220 //\r
221 // Replace.\r
222 //\r
223 free (*FileBuffer);\r
224 *FileBuffer = mCoffFile;\r
225 *FileLength = mCoffOffset;\r
226\r
227 //\r
228 // Free resources used by ELF functions.\r
229 //\r
230 ElfFunctions.CleanUp ();\r
231 \r
232 return TRUE;\r
233}\r