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