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