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