• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
CoffAddFixupEntry(UINT16 Val)67 CoffAddFixupEntry(
68   UINT16 Val
69   )
70 {
71   *mCoffEntryRel = Val;
72   mCoffEntryRel++;
73   mCoffBaseRel->SizeOfBlock += 2;
74   mCoffOffset += 2;
75 }
76 
77 VOID
CoffAddFixup(UINT32 Offset,UINT8 Type)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
CreateSectionHeader(const CHAR8 * Name,UINT32 Offset,UINT32 Size,UINT32 Flags)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
IsElfHeader(UINT8 * FileBuffer)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
ConvertElf(UINT8 ** FileBuffer,UINT32 * FileLength)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 }
240