mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
This change focuses on the support of building basetool natively for Windows ARM/ARM64 host system, which will enable the ARM based platforms to build UEFI and unit tests. Note that the warnings due to integer conversions are suppressed for this specific target to avoid too much local changes carried in MU. The formal change should drop all these binaries and move to pythonic scripts. The binary output is tested on Windows ARM based hardware systems. Cc: Rebecca Cran <rebecca@bsdio.com> Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Bob Feng <bob.c.feng@intel.com> Cc: Yuwei Chen <yuwei.chen@intel.com> Signed-off-by: Kun Qin <kun.qin@microsoft.com>
254 lines
5.5 KiB
C
254 lines
5.5 KiB
C
/** @file
|
|
Elf convert solution
|
|
|
|
Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#ifndef __GNUC__
|
|
#define RUNTIME_FUNCTION _WINNT_DUP_RUNTIME_FUNCTION
|
|
#include <windows.h>
|
|
#undef RUNTIME_FUNCTION
|
|
#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 ();
|
|
|
|
//
|
|
// 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;
|
|
}
|