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 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 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 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 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 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