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