mirror of
				https://github.com/acidanthera/audk.git
				synced 2025-10-25 17:23:53 +02:00 
			
		
		
		
	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;
 | |
| }
 |