https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Bob Feng <bob.c.feng@intel.com>
		
			
				
	
	
		
			246 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
Elf convert solution
 | 
						|
 | 
						|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "WinNtInclude.h"
 | 
						|
 | 
						|
#ifndef __GNUC__
 | 
						|
#include <windows.h>
 | 
						|
#include <io.h>
 | 
						|
#endif
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <time.h>
 | 
						|
#include <ctype.h>
 | 
						|
#include <assert.h>
 | 
						|
 | 
						|
#include <Common/UefiBaseTypes.h>
 | 
						|
#include <IndustryStandard/PeImage.h>
 | 
						|
 | 
						|
#include "EfiUtilityMsgs.h"
 | 
						|
 | 
						|
#include "GenFw.h"
 | 
						|
#include "ElfConvert.h"
 | 
						|
#include "Elf32Convert.h"
 | 
						|
#include "Elf64Convert.h"
 | 
						|
 | 
						|
//
 | 
						|
// Result Coff file in memory.
 | 
						|
//
 | 
						|
UINT8 *mCoffFile = NULL;
 | 
						|
 | 
						|
//
 | 
						|
// COFF relocation data
 | 
						|
//
 | 
						|
EFI_IMAGE_BASE_RELOCATION *mCoffBaseRel;
 | 
						|
UINT16                    *mCoffEntryRel;
 | 
						|
 | 
						|
//
 | 
						|
// Current offset in coff file.
 | 
						|
//
 | 
						|
UINT32 mCoffOffset;
 | 
						|
 | 
						|
//
 | 
						|
// Offset in Coff file of headers and sections.
 | 
						|
//
 | 
						|
UINT32 mTableOffset;
 | 
						|
 | 
						|
//
 | 
						|
//mFileBufferSize
 | 
						|
//
 | 
						|
UINT32 mFileBufferSize;
 | 
						|
 | 
						|
//
 | 
						|
//*****************************************************************************
 | 
						|
// Common ELF Functions
 | 
						|
//*****************************************************************************
 | 
						|
//
 | 
						|
 | 
						|
VOID
 | 
						|
CoffAddFixupEntry(
 | 
						|
  UINT16 Val
 | 
						|
  )
 | 
						|
{
 | 
						|
  *mCoffEntryRel = Val;
 | 
						|
  mCoffEntryRel++;
 | 
						|
  mCoffBaseRel->SizeOfBlock += 2;
 | 
						|
  mCoffOffset += 2;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CoffAddFixup(
 | 
						|
  UINT32 Offset,
 | 
						|
  UINT8  Type
 | 
						|
  )
 | 
						|
{
 | 
						|
  if (mCoffBaseRel == NULL
 | 
						|
      || mCoffBaseRel->VirtualAddress != (Offset & ~0xfff)) {
 | 
						|
    if (mCoffBaseRel != NULL) {
 | 
						|
      //
 | 
						|
      // Add a null entry (is it required ?)
 | 
						|
      //
 | 
						|
      CoffAddFixupEntry (0);
 | 
						|
 | 
						|
      //
 | 
						|
      // Pad for alignment.
 | 
						|
      //
 | 
						|
      if (mCoffOffset % 4 != 0)
 | 
						|
        CoffAddFixupEntry (0);
 | 
						|
    }
 | 
						|
 | 
						|
    mCoffFile = realloc (
 | 
						|
      mCoffFile,
 | 
						|
      mCoffOffset + sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT
 | 
						|
      );
 | 
						|
    if (mCoffFile == NULL) {
 | 
						|
      Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");
 | 
						|
    }
 | 
						|
    assert (mCoffFile != NULL);
 | 
						|
    memset (
 | 
						|
      mCoffFile + mCoffOffset, 0,
 | 
						|
      sizeof(EFI_IMAGE_BASE_RELOCATION) + 2 * MAX_COFF_ALIGNMENT
 | 
						|
      );
 | 
						|
 | 
						|
    mCoffBaseRel = (EFI_IMAGE_BASE_RELOCATION*)(mCoffFile + mCoffOffset);
 | 
						|
    mCoffBaseRel->VirtualAddress = Offset & ~0xfff;
 | 
						|
    mCoffBaseRel->SizeOfBlock = sizeof(EFI_IMAGE_BASE_RELOCATION);
 | 
						|
 | 
						|
    mCoffEntryRel = (UINT16 *)(mCoffBaseRel + 1);
 | 
						|
    mCoffOffset += sizeof(EFI_IMAGE_BASE_RELOCATION);
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Fill the entry.
 | 
						|
  //
 | 
						|
  CoffAddFixupEntry((UINT16) ((Type << 12) | (Offset & 0xfff)));
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CreateSectionHeader (
 | 
						|
  const CHAR8 *Name,
 | 
						|
  UINT32      Offset,
 | 
						|
  UINT32      Size,
 | 
						|
  UINT32      Flags
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_IMAGE_SECTION_HEADER *Hdr;
 | 
						|
  Hdr = (EFI_IMAGE_SECTION_HEADER*)(mCoffFile + mTableOffset);
 | 
						|
 | 
						|
  strcpy((char *)Hdr->Name, Name);
 | 
						|
  Hdr->Misc.VirtualSize = Size;
 | 
						|
  Hdr->VirtualAddress = Offset;
 | 
						|
  Hdr->SizeOfRawData = Size;
 | 
						|
  Hdr->PointerToRawData = Offset;
 | 
						|
  Hdr->PointerToRelocations = 0;
 | 
						|
  Hdr->PointerToLinenumbers = 0;
 | 
						|
  Hdr->NumberOfRelocations = 0;
 | 
						|
  Hdr->NumberOfLinenumbers = 0;
 | 
						|
  Hdr->Characteristics = Flags;
 | 
						|
 | 
						|
  mTableOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
//*****************************************************************************
 | 
						|
// Functions called from GenFw main code.
 | 
						|
//*****************************************************************************
 | 
						|
//
 | 
						|
 | 
						|
INTN
 | 
						|
IsElfHeader (
 | 
						|
  UINT8  *FileBuffer
 | 
						|
)
 | 
						|
{
 | 
						|
  return (FileBuffer[EI_MAG0] == ELFMAG0 &&
 | 
						|
          FileBuffer[EI_MAG1] == ELFMAG1 &&
 | 
						|
          FileBuffer[EI_MAG2] == ELFMAG2 &&
 | 
						|
          FileBuffer[EI_MAG3] == ELFMAG3);
 | 
						|
}
 | 
						|
 | 
						|
BOOLEAN
 | 
						|
ConvertElf (
 | 
						|
  UINT8  **FileBuffer,
 | 
						|
  UINT32 *FileLength
 | 
						|
  )
 | 
						|
{
 | 
						|
  ELF_FUNCTION_TABLE              ElfFunctions;
 | 
						|
  UINT8                           EiClass;
 | 
						|
 | 
						|
  mFileBufferSize = *FileLength;
 | 
						|
  //
 | 
						|
  // Determine ELF type and set function table pointer correctly.
 | 
						|
  //
 | 
						|
  VerboseMsg ("Check Elf Image Header");
 | 
						|
  EiClass = (*FileBuffer)[EI_CLASS];
 | 
						|
  if (EiClass == ELFCLASS32) {
 | 
						|
    if (!InitializeElf32 (*FileBuffer, &ElfFunctions)) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  } else if (EiClass == ELFCLASS64) {
 | 
						|
    if (!InitializeElf64 (*FileBuffer, &ElfFunctions)) {
 | 
						|
      return FALSE;
 | 
						|
    }
 | 
						|
  } else {
 | 
						|
    Error (NULL, 0, 3000, "Unsupported", "ELF EI_CLASS not supported.");
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Compute sections new address.
 | 
						|
  //
 | 
						|
  VerboseMsg ("Compute sections new address.");
 | 
						|
  ElfFunctions.ScanSections ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Write and relocate sections.
 | 
						|
  //
 | 
						|
  VerboseMsg ("Write and relocate sections.");
 | 
						|
  if (!ElfFunctions.WriteSections (SECTION_TEXT)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  if (!ElfFunctions.WriteSections (SECTION_DATA)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  if (!ElfFunctions.WriteSections (SECTION_HII)) {
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Translate and write relocations.
 | 
						|
  //
 | 
						|
  VerboseMsg ("Translate and write relocations.");
 | 
						|
  ElfFunctions.WriteRelocations ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Write debug info.
 | 
						|
  //
 | 
						|
  VerboseMsg ("Write debug info.");
 | 
						|
  ElfFunctions.WriteDebug ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Make sure image size is correct before returning the new image.
 | 
						|
  //
 | 
						|
  VerboseMsg ("Set image size.");
 | 
						|
  ElfFunctions.SetImageSize ();
 | 
						|
 | 
						|
  //
 | 
						|
  // Replace.
 | 
						|
  //
 | 
						|
  free (*FileBuffer);
 | 
						|
  *FileBuffer = mCoffFile;
 | 
						|
  *FileLength = mCoffOffset;
 | 
						|
 | 
						|
  //
 | 
						|
  // Free resources used by ELF functions.
 | 
						|
  //
 | 
						|
  ElfFunctions.CleanUp ();
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 |