1 /** @file
2 Elf convert solution
3 
4 Copyright (c) 2010 - 2014, 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 
28 #include <Common/UefiBaseTypes.h>
29 #include <IndustryStandard/PeImage.h>
30 
31 #include "EfiUtilityMsgs.h"
32 
33 #include "GenFw.h"
34 #include "ElfConvert.h"
35 #include "Elf32Convert.h"
36 #include "Elf64Convert.h"
37 
38 //
39 // Result Coff file in memory.
40 //
41 UINT8 *mCoffFile = NULL;
42 
43 //
44 // COFF relocation data
45 //
46 EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel;
47 UINT16                    *mCoffEntryRel;
48 
49 //
50 // Current offset in coff file.
51 //
52 UINT32 mCoffOffset;
53 
54 //
55 // Offset in Coff file of headers and sections.
56 //
57 UINT32 mTableOffset;
58 
59 //
60 //*****************************************************************************
61 // Common ELF Functions
62 //*****************************************************************************
63 //
64 
65 VOID
CoffAddFixupEntry(UINT16 Val)66 CoffAddFixupEntry(
67   UINT16 Val
68   )
69 {
70   *mCoffEntryRel = Val;
71   mCoffEntryRel++;
72   mCoffBaseRel->SizeOfBlock += 2;
73   mCoffOffset += 2;
74 }
75 
76 VOID
CoffAddFixup(UINT32 Offset,UINT8 Type)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     memset (
102       mCoffFile + mCoffOffset, 0,
103       sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT
104       );
105 
106     mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset);
107     mCoffBaseRel->VirtualAddress = Offset & ~0xfff;
108     mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);
109 
110     mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1);
111     mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);
112   }
113 
114   //
115   // Fill the entry.
116   //
117   CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));
118 }
119 
120 VOID
CreateSectionHeader(const CHAR8 * Name,UINT32 Offset,UINT32 Size,UINT32 Flags)121 CreateSectionHeader (
122   const CHAR8 *Name,
123   UINT32      Offset,
124   UINT32      Size,
125   UINT32      Flags
126   )
127 {
128   EFI_IMAGE_SECTION_HEADER *Hdr;
129   Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset);
130 
131   strcpy((char *)Hdr->Name, Name);
132   Hdr->Misc.VirtualSize = Size;
133   Hdr->VirtualAddress = Offset;
134   Hdr->SizeOfRawData = Size;
135   Hdr->PointerToRawData = Offset;
136   Hdr->PointerToRelocations = 0;
137   Hdr->PointerToLinenumbers = 0;
138   Hdr->NumberOfRelocations = 0;
139   Hdr->NumberOfLinenumbers = 0;
140   Hdr->Characteristics = Flags;
141 
142   mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
143 }
144 
145 //
146 //*****************************************************************************
147 // Functions called from GenFw main code.
148 //*****************************************************************************
149 //
150 
151 INTN
IsElfHeader(UINT8 * FileBuffer)152 IsElfHeader (
153   UINT8  *FileBuffer
154 )
155 {
156   return (FileBuffer[EI_MAG0] == ELFMAG0 &&
157           FileBuffer[EI_MAG1] == ELFMAG1 &&
158           FileBuffer[EI_MAG2] == ELFMAG2 &&
159           FileBuffer[EI_MAG3] == ELFMAG3);
160 }
161 
162 BOOLEAN
ConvertElf(UINT8 ** FileBuffer,UINT32 * FileLength)163 ConvertElf (
164   UINT8  **FileBuffer,
165   UINT32 *FileLength
166   )
167 {
168   ELF_FUNCTION_TABLE              ElfFunctions;
169   UINT8                           EiClass;
170 
171   //
172   // Determine ELF type and set function table pointer correctly.
173   //
174   VerboseMsg ("Check Elf Image Header");
175   EiClass = (*FileBuffer)[EI_CLASS];
176   if (EiClass == ELFCLASS32) {
177     if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) {
178       return FALSE;
179     }
180   } else if (EiClass == ELFCLASS64) {
181     if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) {
182       return FALSE;
183     }
184   } else {
185     Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported.");
186     return FALSE;
187   }
188 
189   //
190   // Compute sections new address.
191   //
192   VerboseMsg ("Compute sections new address.");
193   ElfFunctions.ScanSections ();
194 
195   //
196   // Write and relocate sections.
197   //
198   VerboseMsg ("Write and relocate sections.");
199   ElfFunctions.WriteSections (SECTION_TEXT);
200   ElfFunctions.WriteSections (SECTION_DATA);
201   ElfFunctions.WriteSections (SECTION_HII);
202 
203   //
204   // Translate and write relocations.
205   //
206   VerboseMsg ("Translate and write relocations.");
207   ElfFunctions.WriteRelocations ();
208 
209   //
210   // Write debug info.
211   //
212   VerboseMsg ("Write debug info.");
213   ElfFunctions.WriteDebug ();
214 
215   //
216   // Make sure image size is correct before returning the new image.
217   //
218   VerboseMsg ("Set image size.");
219   ElfFunctions.SetImageSize ();
220 
221   //
222   // Replace.
223   //
224   free (*FileBuffer);
225   *FileBuffer = mCoffFile;
226   *FileLength = mCoffOffset;
227 
228   //
229   // Free resources used by ELF functions.
230   //
231   ElfFunctions.CleanUp ();
232 
233   return TRUE;
234 }
235