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 67 CoffAddFixupEntry( 68 UINT16 Val 69 ) 70 { 71 *mCoffEntryRel = Val; 72 mCoffEntryRel++; 73 mCoffBaseRel->SizeOfBlock += 2; 74 mCoffOffset += 2; 75 } 76 77 VOID 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 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 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 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