Home | History | Annotate | Download | only in GenFw
      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