mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-27 11:38:41 +02:00
BaseTools has been duplicating and adapting code that is defined in MdePkg and MdeModulePkg. This leads to desync issues where the same symbols may be backed by different functions with slightly different semantics and also fixes that apply only to BaseTools or only to MdePkg and MdeModulePkg. To address these issues, update BaseTools/Source/C to utilize the code from MdePkg and MdeModulePkg. Signed-off-by: Marvin Häuser <mhaeuser@posteo.de>
254 lines
5.4 KiB
C
254 lines
5.4 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 <Common/PeImageEx.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 ();
|
|
|
|
//
|
|
// For PRM Driver to Write export info.
|
|
//
|
|
if (mExportFlag) {
|
|
VerboseMsg ("Write export info.");
|
|
ElfFunctions.WriteExport ();
|
|
}
|
|
|
|
//
|
|
// 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;
|
|
}
|