]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/GenFw/ElfConvert.c
Sync BaseTools Branch (version r2149) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / C / GenFw / ElfConvert.c
CommitLineData
40d841f6
LG
1/** @file
2
da92f276 3Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
40d841f6
LG
4
5This program and the accompanying materials are licensed and made available
6under the terms and conditions of the BSD License which accompanies this
7distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT 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//
40UINT8 *mCoffFile = NULL;
41
42//
43// COFF relocation data
44//
45EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel;
46UINT16 *mCoffEntryRel;
47
48//
49// Current offset in coff file.
50//
51UINT32 mCoffOffset;
52
53//
54// Offset in Coff file of headers and sections.
55//
56UINT32 mTableOffset;
57
58//
59//*****************************************************************************
60// Common ELF Functions
61//*****************************************************************************
62//
63
64VOID
65CoffAddFixupEntry(
66 UINT16 Val
67 )
68{
69 *mCoffEntryRel = Val;
70 mCoffEntryRel++;
71 mCoffBaseRel->SizeOfBlock += 2;
72 mCoffOffset += 2;
73}
74
75VOID
76CoffAddFixup(
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
119VOID
120CreateSectionHeader (
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
150INTN
151IsElfHeader (
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
161BOOLEAN
162ConvertElf (
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 //
da92f276 173 VerboseMsg ("Check Elf Image Header");
40d841f6
LG
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}