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