BaseTools: Update GenFw/GenFv to support LoongArch platform.

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4053

C code changes for building EDK2 LoongArch platform.

For definitions of PE/COFF and LOONGARCH relocation types, see the
"Machine Types" and "Basic Relocation Types" sections of this URL for
LOONGARCH values:
https://docs.microsoft.com/en-us/windows/win32/debug/pe-format

Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>

Signed-off-by: Chao Li <lichao@loongson.cn>
Co-authored-by: Dongyan Qian <qiandongyan@loongson.cn>
Co-authored-by: Baoqi Zhang <zhangbaoqi@loongson.cn>
Co-authored-by: Yang Zhou <zhouyang@loongson.cn>
Co-authored-by: Xiaotian Wu <wuxiaotian@loongson.cn>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
This commit is contained in:
Chao Li 2022-09-06 21:00:07 +08:00 committed by mergify[bot]
parent 082b563fc4
commit 1aa311d175
7 changed files with 636 additions and 33 deletions

View File

@ -5,6 +5,7 @@
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -68,6 +69,14 @@ PeCoffLoaderRelocateRiscVImage (
IN UINT64 Adjust
);
RETURN_STATUS
PeCoffLoaderRelocateLoongArch64Image (
IN UINT16 *Reloc,
IN OUT CHAR8 *Fixup,
IN OUT CHAR8 **FixupData,
IN UINT64 Adjust
);
STATIC
RETURN_STATUS
PeCoffLoaderGetPeHeader (
@ -184,7 +193,8 @@ Returns:
ImageContext->Machine != EFI_IMAGE_MACHINE_ARMT && \
ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \
ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \
ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) {
ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64 && \
ImageContext->Machine != EFI_IMAGE_MACHINE_LOONGARCH64) {
if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) {
//
// There are two types of ARM images. Pure ARM and ARM/Thumb.
@ -815,6 +825,9 @@ Returns:
case EFI_IMAGE_MACHINE_RISCV64:
Status = PeCoffLoaderRelocateRiscVImage (Reloc, Fixup, &FixupData, Adjust);
break;
case EFI_IMAGE_MACHINE_LOONGARCH64:
Status = PeCoffLoaderRelocateLoongArch64Image (Reloc, Fixup, &FixupData, Adjust);
break;
default:
Status = RETURN_UNSUPPORTED;
break;

View File

@ -4,6 +4,7 @@ IA32 and X64 Specific relocation fixups
Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
--*/
@ -332,3 +333,81 @@ PeCoffLoaderRelocateArmImage (
return RETURN_SUCCESS;
}
/**
Performs a LoongArch specific relocation fixup.
@param[in] Reloc Pointer to the relocation record.
@param[in, out] Fixup Pointer to the address to fix up.
@param[in, out] FixupData Pointer to a buffer to log the fixups.
@param[in] Adjust The offset to adjust the fixup.
@return Status code.
**/
RETURN_STATUS
PeCoffLoaderRelocateLoongArch64Image (
IN UINT16 *Reloc,
IN OUT CHAR8 *Fixup,
IN OUT CHAR8 **FixupData,
IN UINT64 Adjust
)
{
UINT8 RelocType;
UINT64 Value;
UINT64 Tmp1;
UINT64 Tmp2;
RelocType = ((*Reloc) >> 12);
Value = 0;
Tmp1 = 0;
Tmp2 = 0;
switch (RelocType) {
case EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA:
// The next four instructions are used to load a 64 bit address, relocate all of them
Value = (*(UINT32 *)Fixup & 0x1ffffe0) << 7 | // lu12i.w 20bits from bit5
(*((UINT32 *)Fixup + 1) & 0x3ffc00) >> 10; // ori 12bits from bit10
Tmp1 = *((UINT32 *)Fixup + 2) & 0x1ffffe0; // lu32i.d 20bits from bit5
Tmp2 = *((UINT32 *)Fixup + 3) & 0x3ffc00; // lu52i.d 12bits from bit10
Value = Value | (Tmp1 << 27) | (Tmp2 << 42);
Value += Adjust;
*(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 12) & 0xfffff) << 5);
if (*FixupData != NULL) {
*FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));
*(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
*FixupData = *FixupData + sizeof (UINT32);
}
Fixup += sizeof (UINT32);
*(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | ((Value & 0xfff) << 10);
if (*FixupData != NULL) {
*FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));
*(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
*FixupData = *FixupData + sizeof (UINT32);
}
Fixup += sizeof (UINT32);
*(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x1ffffe0) | (((Value >> 32) & 0xfffff) << 5);
if (*FixupData != NULL) {
*FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));
*(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
*FixupData = *FixupData + sizeof (UINT32);
}
Fixup += sizeof (UINT32);
*(UINT32 *)Fixup = (*(UINT32 *)Fixup & ~0x3ffc00) | (((Value >> 52) & 0xfff) << 10);
if (*FixupData != NULL) {
*FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT32));
*(UINT32 *)(*FixupData) = *(UINT32 *)Fixup;
*FixupData = *FixupData + sizeof (UINT32);
}
break;
default:
Error (NULL, 0, 3000, "", "PeCoffLoaderRelocateLoongArch64Image: Fixup[0x%x] Adjust[0x%llx] *Reloc[0x%x], type[0x%x].", *(UINT32 *)Fixup, Adjust, *Reloc, RelocType);
return RETURN_UNSUPPORTED;
}
return RETURN_SUCCESS;
}

View File

@ -5,6 +5,7 @@ Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Portions Copyright (c) 2016 HP Development Company, L.P.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -57,6 +58,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
BOOLEAN mArm = FALSE;
BOOLEAN mRiscV = FALSE;
BOOLEAN mLoongArch = FALSE;
STATIC UINT32 MaxFfsAlignment = 0;
BOOLEAN VtfFileFlag = FALSE;
@ -2416,6 +2418,98 @@ Returns:
return EFI_SUCCESS;
}
EFI_STATUS
UpdateLoongArchResetVectorIfNeeded (
IN MEMORY_FILE *FvImage,
IN FV_INFO *FvInfo
)
/*++
Routine Description:
This parses the FV looking for SEC and patches that address into the
beginning of the FV header.
For LoongArch ISA, the reset vector is at 0x1c000000.
We relocate it to SecCoreEntry and copy the ResetVector code to the
beginning of the FV.
Arguments:
FvImage Memory file for the FV memory image
FvInfo Information read from INF file.
Returns:
EFI_SUCCESS Function Completed successfully.
EFI_ABORTED Error encountered.
EFI_INVALID_PARAMETER A required parameter was NULL.
EFI_NOT_FOUND PEI Core file not found.
--*/
{
EFI_STATUS Status;
EFI_FILE_SECTION_POINTER SecPe32;
BOOLEAN UpdateVectorSec = FALSE;
UINT16 MachineType = 0;
EFI_PHYSICAL_ADDRESS SecCoreEntryAddress = 0;
//
// Verify input parameters
//
if (FvImage == NULL || FvInfo == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Locate an SEC Core instance and if found extract the machine type and entry point address
//
Status = FindCorePeSection(FvImage->FileImage, FvInfo->Size, EFI_FV_FILETYPE_SECURITY_CORE, &SecPe32);
if (!EFI_ERROR(Status)) {
Status = GetCoreMachineType(SecPe32, &MachineType);
if (EFI_ERROR(Status)) {
Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 machine type for SEC Core.");
return EFI_ABORTED;
}
Status = GetCoreEntryPointAddress(FvImage->FileImage, FvInfo, SecPe32, &SecCoreEntryAddress);
if (EFI_ERROR(Status)) {
Error(NULL, 0, 3000, "Invalid", "Could not get the PE32 entry point address for SEC Core.");
return EFI_ABORTED;
}
UpdateVectorSec = TRUE;
}
if (!UpdateVectorSec)
return EFI_SUCCESS;
if (MachineType == EFI_IMAGE_MACHINE_LOONGARCH64) {
UINT32 ResetVector[1];
memset(ResetVector, 0, sizeof (ResetVector));
/* if we found an SEC core entry point then generate a branch instruction */
if (UpdateVectorSec) {
VerboseMsg("UpdateLoongArchResetVectorIfNeeded updating LOONGARCH64 SEC vector");
ResetVector[0] = ((SecCoreEntryAddress - FvInfo->BaseAddress) & 0x3FFFFFF) >> 2;
ResetVector[0] = ((ResetVector[0] & 0x0FFFF) << 10) | ((ResetVector[0] >> 16) & 0x3FF);
ResetVector[0] |= 0x50000000; /* b offset */
}
//
// Copy to the beginning of the FV
//
memcpy(FvImage->FileImage, ResetVector, sizeof (ResetVector));
} else {
Error(NULL, 0, 3000, "Invalid", "Unknown machine type");
return EFI_ABORTED;
}
return EFI_SUCCESS;
}
EFI_STATUS
GetPe32Info (
IN UINT8 *Pe32,
@ -2509,7 +2603,7 @@ Returns:
//
if ((*MachineType != EFI_IMAGE_MACHINE_IA32) && (*MachineType != EFI_IMAGE_MACHINE_X64) && (*MachineType != EFI_IMAGE_MACHINE_EBC) &&
(*MachineType != EFI_IMAGE_MACHINE_ARMT) && (*MachineType != EFI_IMAGE_MACHINE_AARCH64) &&
(*MachineType != EFI_IMAGE_MACHINE_RISCV64)) {
(*MachineType != EFI_IMAGE_MACHINE_RISCV64) && (*MachineType != EFI_IMAGE_MACHINE_LOONGARCH64)) {
Error (NULL, 0, 3000, "Invalid", "Unrecognized machine type in the PE32 file.");
return EFI_UNSUPPORTED;
}
@ -2953,7 +3047,7 @@ Returns:
goto Finish;
}
if (!mArm && !mRiscV) {
if (!mArm && !mRiscV && !mLoongArch) {
//
// Update reset vector (SALE_ENTRY for IPF)
// Now for IA32 and IA64 platform, the fv which has bsf file must have the
@ -3004,6 +3098,19 @@ Returns:
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
}
if (mLoongArch) {
Status = UpdateLoongArchResetVectorIfNeeded (&FvImageMemoryFile, &mFvDataInfo);
if (EFI_ERROR (Status)) {
Error (NULL, 0, 3000, "Invalid", "Could not update the reset vector.");
goto Finish;
}
//
// Update Checksum for FvHeader
//
FvHeader->Checksum = 0;
FvHeader->Checksum = CalculateChecksum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength / sizeof (UINT16));
}
//
// Update FV Alignment attribute to the largest alignment of all the FFS files in the FV
//
@ -3450,6 +3557,12 @@ Returns:
VerboseMsg("Located ARM/AArch64 SEC/PEI core in child FV");
mArm = TRUE;
}
// Machine type is LOONGARCH64, set a flag so LoongArch64 reset vector processed.
if ((MachineType == EFI_IMAGE_MACHINE_LOONGARCH64)) {
VerboseMsg("Located LoongArch64 SEC core in child FV");
mLoongArch = TRUE;
}
}
//
@ -3608,6 +3721,10 @@ Returns:
mRiscV = TRUE;
}
if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {
mLoongArch = TRUE;
}
//
// Keep Image Context for PE image in FV
//
@ -3885,6 +4002,10 @@ Returns:
mArm = TRUE;
}
if ( (ImageContext.Machine == EFI_IMAGE_MACHINE_LOONGARCH64) ) {
mLoongArch = TRUE;
}
//
// Keep Image Context for TE image in FV
//

View File

@ -4,6 +4,7 @@ Elf64 convert solution
Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2013-2022, ARM Ltd. All rights reserved.<BR>
Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -177,7 +178,7 @@ InitializeElf64 (
Error (NULL, 0, 3000, "Unsupported", "ELF e_type not ET_EXEC or ET_DYN");
return FALSE;
}
if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64))) {
if (!((mEhdr->e_machine == EM_X86_64) || (mEhdr->e_machine == EM_AARCH64) || (mEhdr->e_machine == EM_RISCV64) || (mEhdr->e_machine == EM_LOONGARCH))) {
Warning (NULL, 0, 3000, "Unsupported", "ELF e_machine is not Elf64 machine.");
}
if (mEhdr->e_version != EV_CURRENT) {
@ -799,6 +800,7 @@ ScanSections64 (
case EM_X86_64:
case EM_AARCH64:
case EM_RISCV64:
case EM_LOONGARCH:
mCoffOffset += sizeof (EFI_IMAGE_NT_HEADERS64);
break;
default:
@ -1088,6 +1090,10 @@ ScanSections64 (
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_RISCV64;
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
break;
case EM_LOONGARCH:
NtHdr->Pe32Plus.FileHeader.Machine = EFI_IMAGE_MACHINE_LOONGARCH64;
NtHdr->Pe32Plus.OptionalHeader.Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
break;
default:
VerboseMsg ("%s unknown e_machine type. Assume X64", (UINTN)mEhdr->e_machine);
@ -1333,10 +1339,10 @@ WriteSections64 (
}
//
// Skip error on EM_RISCV64 becasue no symble name is built
// from RISC-V toolchain.
// Skip error on EM_RISCV64 and EM_LOONGARCH because no symbol name is built
// from RISC-V and LoongArch toolchain.
//
if (mEhdr->e_machine != EM_RISCV64) {
if ((mEhdr->e_machine != EM_RISCV64) && (mEhdr->e_machine != EM_LOONGARCH)) {
Error (NULL, 0, 3000, "Invalid",
"%s: Bad definition for symbol '%s'@%#llx or unsupported symbol type. "
"For example, absolute and undefined symbols are not supported.",
@ -1618,6 +1624,178 @@ WriteSections64 (
// Write section for RISC-V 64 architecture.
//
WriteSectionRiscV64 (Rel, Targ, SymShdr, Sym);
} else if (mEhdr->e_machine == EM_LOONGARCH) {
switch (ELF_R_TYPE(Rel->r_info)) {
INT64 Offset;
INT32 Lo, Hi;
case R_LARCH_SOP_PUSH_ABSOLUTE:
//
// Absolute relocation.
//
*(UINT64 *)Targ = *(UINT64 *)Targ - SymShdr->sh_addr + mCoffSectionsOffset[Sym->st_shndx];
break;
case R_LARCH_MARK_LA:
case R_LARCH_64:
case R_LARCH_NONE:
case R_LARCH_32:
case R_LARCH_RELATIVE:
case R_LARCH_COPY:
case R_LARCH_JUMP_SLOT:
case R_LARCH_TLS_DTPMOD32:
case R_LARCH_TLS_DTPMOD64:
case R_LARCH_TLS_DTPREL32:
case R_LARCH_TLS_DTPREL64:
case R_LARCH_TLS_TPREL32:
case R_LARCH_TLS_TPREL64:
case R_LARCH_IRELATIVE:
case R_LARCH_MARK_PCREL:
case R_LARCH_SOP_PUSH_PCREL:
case R_LARCH_SOP_PUSH_DUP:
case R_LARCH_SOP_PUSH_GPREL:
case R_LARCH_SOP_PUSH_TLS_TPREL:
case R_LARCH_SOP_PUSH_TLS_GOT:
case R_LARCH_SOP_PUSH_TLS_GD:
case R_LARCH_SOP_PUSH_PLT_PCREL:
case R_LARCH_SOP_ASSERT:
case R_LARCH_SOP_NOT:
case R_LARCH_SOP_SUB:
case R_LARCH_SOP_SL:
case R_LARCH_SOP_SR:
case R_LARCH_SOP_ADD:
case R_LARCH_SOP_AND:
case R_LARCH_SOP_IF_ELSE:
case R_LARCH_SOP_POP_32_S_10_5:
case R_LARCH_SOP_POP_32_U_10_12:
case R_LARCH_SOP_POP_32_S_10_12:
case R_LARCH_SOP_POP_32_S_10_16:
case R_LARCH_SOP_POP_32_S_10_16_S2:
case R_LARCH_SOP_POP_32_S_5_20:
case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
case R_LARCH_SOP_POP_32_U:
case R_LARCH_ADD8:
case R_LARCH_ADD16:
case R_LARCH_ADD24:
case R_LARCH_ADD32:
case R_LARCH_ADD64:
case R_LARCH_SUB8:
case R_LARCH_SUB16:
case R_LARCH_SUB24:
case R_LARCH_SUB32:
case R_LARCH_SUB64:
case R_LARCH_GNU_VTINHERIT:
case R_LARCH_GNU_VTENTRY:
case R_LARCH_B16:
case R_LARCH_B21:
case R_LARCH_B26:
case R_LARCH_ABS_HI20:
case R_LARCH_ABS_LO12:
case R_LARCH_ABS64_LO20:
case R_LARCH_ABS64_HI12:
case R_LARCH_PCALA_LO12:
case R_LARCH_PCALA64_LO20:
case R_LARCH_PCALA64_HI12:
case R_LARCH_GOT_PC_LO12:
case R_LARCH_GOT64_PC_LO20:
case R_LARCH_GOT64_PC_HI12:
case R_LARCH_GOT64_HI20:
case R_LARCH_GOT64_LO12:
case R_LARCH_GOT64_LO20:
case R_LARCH_GOT64_HI12:
case R_LARCH_TLS_LE_HI20:
case R_LARCH_TLS_LE_LO12:
case R_LARCH_TLS_LE64_LO20:
case R_LARCH_TLS_LE64_HI12:
case R_LARCH_TLS_IE_PC_HI20:
case R_LARCH_TLS_IE_PC_LO12:
case R_LARCH_TLS_IE64_PC_LO20:
case R_LARCH_TLS_IE64_PC_HI12:
case R_LARCH_TLS_IE64_HI20:
case R_LARCH_TLS_IE64_LO12:
case R_LARCH_TLS_IE64_LO20:
case R_LARCH_TLS_IE64_HI12:
case R_LARCH_TLS_LD_PC_HI20:
case R_LARCH_TLS_LD64_HI20:
case R_LARCH_TLS_GD_PC_HI20:
case R_LARCH_TLS_GD64_HI20:
case R_LARCH_RELAX:
//
// These types are not used or do not require fixup.
//
break;
case R_LARCH_GOT_PC_HI20:
Offset = Sym->st_value - (UINTN)(Targ - mCoffFile);
if (Offset < 0) {
Offset = (UINTN)(Targ - mCoffFile) - Sym->st_value;
Hi = Offset & ~0xfff;
Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
if ((Lo < 0) && (Lo > -2048)) {
Hi += 0x1000;
Lo = ~(0x1000 - Lo) + 1;
}
Hi = ~Hi + 1;
Lo = ~Lo + 1;
} else {
Hi = Offset & ~0xfff;
Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
if (Lo < 0) {
Hi += 0x1000;
Lo = ~(0x1000 - Lo) + 1;
}
}
// Re-encode the offset as PCADDU12I + ADDI.D(Convert LD.D) instruction
*(UINT32 *)Targ &= 0x1f;
*(UINT32 *)Targ |= 0x1c000000;
*(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
*(UINT32 *)(Targ + 4) &= 0x3ff;
*(UINT32 *)(Targ + 4) |= 0x2c00000 | ((Lo & 0xfff) << 10);
break;
//
// Attempt to convert instruction.
//
case R_LARCH_PCALA_HI20:
// Decode the PCALAU12I instruction and the instruction that following it.
Offset = ((INT32)((*(UINT32 *)Targ & 0x1ffffe0) << 7));
Offset += ((INT32)((*(UINT32 *)(Targ + 4) & 0x3ffc00) << 10) >> 20);
//
// PCALA offset is relative to the previous page boundary,
// whereas PCADD offset is relative to the instruction itself.
// So fix up the offset so it points to the page containing
// the symbol.
//
Offset -= (UINTN)(Targ - mCoffFile) & 0xfff;
if (Offset < 0) {
Offset = -Offset;
Hi = Offset & ~0xfff;
Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
if ((Lo < 0) && (Lo > -2048)) {
Hi += 0x1000;
Lo = ~(0x1000 - Lo) + 1;
}
Hi = ~Hi + 1;
Lo = ~Lo + 1;
} else {
Hi = Offset & ~0xfff;
Lo = (INT32)((Offset & 0xfff) << 20) >> 20;
if (Lo < 0) {
Hi += 0x1000;
Lo = ~(0x1000 - Lo) + 1;
}
}
// Convert the first instruction from PCALAU12I to PCADDU12I and re-encode the offset into them.
*(UINT32 *)Targ &= 0x1f;
*(UINT32 *)Targ |= 0x1c000000;
*(UINT32 *)Targ |= (((Hi >> 12) & 0xfffff) << 5);
*(UINT32 *)(Targ + 4) &= 0xffc003ff;
*(UINT32 *)(Targ + 4) |= (Lo & 0xfff) << 10;
break;
default:
Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));
}
} else {
Error (NULL, 0, 3000, "Invalid", "Not a supported machine type");
}
@ -1850,6 +2028,113 @@ WriteRelocations64 (
default:
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_RISCV64 relocation 0x%x.", mInImageName, (unsigned) ELF_R_TYPE(Rel->r_info));
}
} else if (mEhdr->e_machine == EM_LOONGARCH) {
switch (ELF_R_TYPE(Rel->r_info)) {
case R_LARCH_MARK_LA:
CoffAddFixup(
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ (Rel->r_offset - SecShdr->sh_addr)),
EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA);
break;
case R_LARCH_64:
CoffAddFixup(
(UINT32) ((UINT64) mCoffSectionsOffset[RelShdr->sh_info]
+ (Rel->r_offset - SecShdr->sh_addr)),
EFI_IMAGE_REL_BASED_DIR64);
break;
case R_LARCH_NONE:
case R_LARCH_32:
case R_LARCH_RELATIVE:
case R_LARCH_COPY:
case R_LARCH_JUMP_SLOT:
case R_LARCH_TLS_DTPMOD32:
case R_LARCH_TLS_DTPMOD64:
case R_LARCH_TLS_DTPREL32:
case R_LARCH_TLS_DTPREL64:
case R_LARCH_TLS_TPREL32:
case R_LARCH_TLS_TPREL64:
case R_LARCH_IRELATIVE:
case R_LARCH_MARK_PCREL:
case R_LARCH_SOP_PUSH_PCREL:
case R_LARCH_SOP_PUSH_ABSOLUTE:
case R_LARCH_SOP_PUSH_DUP:
case R_LARCH_SOP_PUSH_GPREL:
case R_LARCH_SOP_PUSH_TLS_TPREL:
case R_LARCH_SOP_PUSH_TLS_GOT:
case R_LARCH_SOP_PUSH_TLS_GD:
case R_LARCH_SOP_PUSH_PLT_PCREL:
case R_LARCH_SOP_ASSERT:
case R_LARCH_SOP_NOT:
case R_LARCH_SOP_SUB:
case R_LARCH_SOP_SL:
case R_LARCH_SOP_SR:
case R_LARCH_SOP_ADD:
case R_LARCH_SOP_AND:
case R_LARCH_SOP_IF_ELSE:
case R_LARCH_SOP_POP_32_S_10_5:
case R_LARCH_SOP_POP_32_U_10_12:
case R_LARCH_SOP_POP_32_S_10_12:
case R_LARCH_SOP_POP_32_S_10_16:
case R_LARCH_SOP_POP_32_S_10_16_S2:
case R_LARCH_SOP_POP_32_S_5_20:
case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
case R_LARCH_SOP_POP_32_U:
case R_LARCH_ADD8:
case R_LARCH_ADD16:
case R_LARCH_ADD24:
case R_LARCH_ADD32:
case R_LARCH_ADD64:
case R_LARCH_SUB8:
case R_LARCH_SUB16:
case R_LARCH_SUB24:
case R_LARCH_SUB32:
case R_LARCH_SUB64:
case R_LARCH_GNU_VTINHERIT:
case R_LARCH_GNU_VTENTRY:
case R_LARCH_B16:
case R_LARCH_B21:
case R_LARCH_B26:
case R_LARCH_ABS_HI20:
case R_LARCH_ABS_LO12:
case R_LARCH_ABS64_LO20:
case R_LARCH_ABS64_HI12:
case R_LARCH_PCALA_HI20:
case R_LARCH_PCALA_LO12:
case R_LARCH_PCALA64_LO20:
case R_LARCH_PCALA64_HI12:
case R_LARCH_GOT_PC_HI20:
case R_LARCH_GOT_PC_LO12:
case R_LARCH_GOT64_PC_LO20:
case R_LARCH_GOT64_PC_HI12:
case R_LARCH_GOT64_HI20:
case R_LARCH_GOT64_LO12:
case R_LARCH_GOT64_LO20:
case R_LARCH_GOT64_HI12:
case R_LARCH_TLS_LE_HI20:
case R_LARCH_TLS_LE_LO12:
case R_LARCH_TLS_LE64_LO20:
case R_LARCH_TLS_LE64_HI12:
case R_LARCH_TLS_IE_PC_HI20:
case R_LARCH_TLS_IE_PC_LO12:
case R_LARCH_TLS_IE64_PC_LO20:
case R_LARCH_TLS_IE64_PC_HI12:
case R_LARCH_TLS_IE64_HI20:
case R_LARCH_TLS_IE64_LO12:
case R_LARCH_TLS_IE64_LO20:
case R_LARCH_TLS_IE64_HI12:
case R_LARCH_TLS_LD_PC_HI20:
case R_LARCH_TLS_LD64_HI20:
case R_LARCH_TLS_GD_PC_HI20:
case R_LARCH_TLS_GD64_HI20:
case R_LARCH_RELAX:
//
// These types are not used or do not require fixup in PE format files.
//
break;
default:
Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_LOONGARCH relocation 0x%x.", mInImageName, (unsigned) ELF64_R_TYPE(Rel->r_info));
}
} else {
Error (NULL, 0, 3000, "Not Supported", "This tool does not support relocations for ELF with e_machine %u (processor type).", (unsigned) mEhdr->e_machine);
}

View File

@ -4,6 +4,7 @@ Ported ELF include files from FreeBSD
Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
Portions Copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Portion Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Portions Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -181,6 +182,7 @@ typedef struct {
#define EM_AARCH64 183 /* ARM 64bit Architecture */
#define EM_RISCV64 243 /* 64bit RISC-V Architecture */
#define EM_RISCV 244 /* 32bit RISC-V Architecture */
#define EM_LOONGARCH 258 /* LoongArch Architecture */
/* Non-standard or deprecated. */
#define EM_486 6 /* Intel i486. */
@ -1042,4 +1044,96 @@ typedef struct {
#define R_RISCV_SET8 54
#define R_RISCV_SET16 55
#define R_RISCV_SET32 56
/*
* LoongArch relocation types
*/
#define R_LARCH_NONE 0
#define R_LARCH_32 1
#define R_LARCH_64 2
#define R_LARCH_RELATIVE 3
#define R_LARCH_COPY 4
#define R_LARCH_JUMP_SLOT 5
#define R_LARCH_TLS_DTPMOD32 6
#define R_LARCH_TLS_DTPMOD64 7
#define R_LARCH_TLS_DTPREL32 8
#define R_LARCH_TLS_DTPREL64 9
#define R_LARCH_TLS_TPREL32 10
#define R_LARCH_TLS_TPREL64 11
#define R_LARCH_IRELATIVE 12
#define R_LARCH_MARK_LA 20
#define R_LARCH_MARK_PCREL 21
#define R_LARCH_SOP_PUSH_PCREL 22
#define R_LARCH_SOP_PUSH_ABSOLUTE 23
#define R_LARCH_SOP_PUSH_DUP 24
#define R_LARCH_SOP_PUSH_GPREL 25
#define R_LARCH_SOP_PUSH_TLS_TPREL 26
#define R_LARCH_SOP_PUSH_TLS_GOT 27
#define R_LARCH_SOP_PUSH_TLS_GD 28
#define R_LARCH_SOP_PUSH_PLT_PCREL 29
#define R_LARCH_SOP_ASSERT 30
#define R_LARCH_SOP_NOT 31
#define R_LARCH_SOP_SUB 32
#define R_LARCH_SOP_SL 33
#define R_LARCH_SOP_SR 34
#define R_LARCH_SOP_ADD 35
#define R_LARCH_SOP_AND 36
#define R_LARCH_SOP_IF_ELSE 37
#define R_LARCH_SOP_POP_32_S_10_5 38
#define R_LARCH_SOP_POP_32_U_10_12 39
#define R_LARCH_SOP_POP_32_S_10_12 40
#define R_LARCH_SOP_POP_32_S_10_16 41
#define R_LARCH_SOP_POP_32_S_10_16_S2 42
#define R_LARCH_SOP_POP_32_S_5_20 43
#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44
#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45
#define R_LARCH_SOP_POP_32_U 46
#define R_LARCH_ADD8 47
#define R_LARCH_ADD16 48
#define R_LARCH_ADD24 49
#define R_LARCH_ADD32 50
#define R_LARCH_ADD64 51
#define R_LARCH_SUB8 52
#define R_LARCH_SUB16 53
#define R_LARCH_SUB24 54
#define R_LARCH_SUB32 55
#define R_LARCH_SUB64 56
#define R_LARCH_GNU_VTINHERIT 57
#define R_LARCH_GNU_VTENTRY 58
#define R_LARCH_B16 64
#define R_LARCH_B21 65
#define R_LARCH_B26 66
#define R_LARCH_ABS_HI20 67
#define R_LARCH_ABS_LO12 68
#define R_LARCH_ABS64_LO20 69
#define R_LARCH_ABS64_HI12 70
#define R_LARCH_PCALA_HI20 71
#define R_LARCH_PCALA_LO12 72
#define R_LARCH_PCALA64_LO20 73
#define R_LARCH_PCALA64_HI12 74
#define R_LARCH_GOT_PC_HI20 75
#define R_LARCH_GOT_PC_LO12 76
#define R_LARCH_GOT64_PC_LO20 77
#define R_LARCH_GOT64_PC_HI12 78
#define R_LARCH_GOT64_HI20 79
#define R_LARCH_GOT64_LO12 80
#define R_LARCH_GOT64_LO20 81
#define R_LARCH_GOT64_HI12 82
#define R_LARCH_TLS_LE_HI20 83
#define R_LARCH_TLS_LE_LO12 84
#define R_LARCH_TLS_LE64_LO20 85
#define R_LARCH_TLS_LE64_HI12 86
#define R_LARCH_TLS_IE_PC_HI20 87
#define R_LARCH_TLS_IE_PC_LO12 88
#define R_LARCH_TLS_IE64_PC_LO20 89
#define R_LARCH_TLS_IE64_PC_HI12 90
#define R_LARCH_TLS_IE64_HI20 91
#define R_LARCH_TLS_IE64_LO12 92
#define R_LARCH_TLS_IE64_LO20 93
#define R_LARCH_TLS_IE64_HI12 94
#define R_LARCH_TLS_LD_PC_HI20 95
#define R_LARCH_TLS_LD64_HI20 96
#define R_LARCH_TLS_GD_PC_HI20 97
#define R_LARCH_TLS_GD64_HI20 98
#define R_LARCH_RELAX 99
#endif /* !_SYS_ELF_COMMON_H_ */

View File

@ -7,6 +7,7 @@
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>
Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -36,23 +37,25 @@
//
// PE32+ Machine type for EFI images
//
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_EBC 0x0EBC
#define IMAGE_FILE_MACHINE_X64 0x8664
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only
#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian
#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_EBC 0x0EBC
#define IMAGE_FILE_MACHINE_X64 0x8664
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only
#define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian
#define IMAGE_FILE_MACHINE_RISCV64 0x5064 // 64bit RISC-V ISA
#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // 64bit LoongArch Architecture
//
// Support old names for backward compatible
//
#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386
#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC
#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64
#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT
#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64
#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64
#define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386
#define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC
#define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64
#define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT
#define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64
#define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64
#define EFI_IMAGE_MACHINE_LOONGARCH64 IMAGE_FILE_MACHINE_LOONGARCH64
#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE
@ -500,19 +503,21 @@ typedef struct {
//
// Based relocation types.
//
#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
#define EFI_IMAGE_REL_BASED_HIGH 1
#define EFI_IMAGE_REL_BASED_LOW 2
#define EFI_IMAGE_REL_BASED_HIGHLOW 3
#define EFI_IMAGE_REL_BASED_HIGHADJ 4
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
#define EFI_IMAGE_REL_BASED_RISCV_HI20 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7
#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
#define EFI_IMAGE_REL_BASED_DIR64 10
#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
#define EFI_IMAGE_REL_BASED_HIGH 1
#define EFI_IMAGE_REL_BASED_LOW 2
#define EFI_IMAGE_REL_BASED_HIGHLOW 3
#define EFI_IMAGE_REL_BASED_HIGHADJ 4
#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32A 5
#define EFI_IMAGE_REL_BASED_RISCV_HI20 5
#define EFI_IMAGE_REL_BASED_ARM_MOV32T 7
#define EFI_IMAGE_REL_BASED_RISCV_LOW12I 7
#define EFI_IMAGE_REL_BASED_RISCV_LOW12S 8
#define EFI_IMAGE_REL_BASED_LOONGARCH32_MARK_LA 8
#define EFI_IMAGE_REL_BASED_LOONGARCH64_MARK_LA 8
#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
#define EFI_IMAGE_REL_BASED_DIR64 10
///

View File

@ -31,6 +31,9 @@ ifndef HOST_ARCH
ifneq (,$(findstring riscv64,$(uname_m)))
HOST_ARCH=RISCV64
endif
ifneq (,$(findstring loongarch64,$(uname_m)))
HOST_ARCH=LOONGARCH64
endif
ifndef HOST_ARCH
$(info Could not detected HOST_ARCH from uname results)
$(error HOST_ARCH is not defined!)
@ -70,6 +73,9 @@ ARCH_INCLUDE = -I $(MAKEROOT)/Include/AArch64/
else ifeq ($(HOST_ARCH), RISCV64)
ARCH_INCLUDE = -I $(MAKEROOT)/Include/RiscV64/
else ifeq ($(HOST_ARCH), LOONGARCH64)
ARCH_INCLUDE = -I $(MAKEROOT)/Include/LoongArch64/
else
$(error Bad HOST_ARCH)
endif