[LoongArch] Parse LoongArch base ABI in ObjectYAML and llvm-readobj

LoongArch e_flags definition:
https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version

Differential Revision: https://reviews.llvm.org/D130238
This commit is contained in:
Weining Lu 2022-07-25 17:24:25 +08:00
parent ae8a6602fb
commit aff68f5ad6
5 changed files with 136 additions and 0 deletions

View File

@ -900,6 +900,26 @@ enum {
#include "ELFRelocs/CSKY.def"
};
// LoongArch Specific e_flags
enum : unsigned {
// Reference: https://github.com/loongson/LoongArch-Documentation.
// The last commit hash (main branch) is
// 99016636af64d02dee05e39974d4c1e55875c45b.
// Note that there is an open PR
// https://github.com/loongson/LoongArch-Documentation/pull/47
// talking about using 0x1, 0x2, 0x3 for ILP32S/F/D and use EI_CLASS to
// distinguish LP64 and ILP32. If this PR get merged, we will update
// the definition here.
// Base ABI Types.
EF_LOONGARCH_BASE_ABI_LP64S = 0x1, // LP64 soft-float ABI
EF_LOONGARCH_BASE_ABI_LP64F = 0x2, // LP64 single-float ABI
EF_LOONGARCH_BASE_ABI_LP64D = 0x3, // LP64 double-float ABI
EF_LOONGARCH_BASE_ABI_ILP32S = 0x5, // ILP32 soft-float ABI
EF_LOONGARCH_BASE_ABI_ILP32F = 0x6, // ILP32 single-float ABI
EF_LOONGARCH_BASE_ABI_ILP32D = 0x7, // ILP32 double-float ABI
EF_LOONGARCH_BASE_ABI_MASK = 0x7, // Mask for selecting base ABI
};
// ELF Relocation types for LoongArch
enum {
#include "ELFRelocs/LoongArch.def"

View File

@ -518,6 +518,14 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK);
BCase(EF_AVR_LINKRELAX_PREPARED);
break;
case ELF::EM_LOONGARCH:
BCaseMask(EF_LOONGARCH_BASE_ABI_ILP32S, EF_LOONGARCH_BASE_ABI_MASK);
BCaseMask(EF_LOONGARCH_BASE_ABI_ILP32F, EF_LOONGARCH_BASE_ABI_MASK);
BCaseMask(EF_LOONGARCH_BASE_ABI_ILP32D, EF_LOONGARCH_BASE_ABI_MASK);
BCaseMask(EF_LOONGARCH_BASE_ABI_LP64S, EF_LOONGARCH_BASE_ABI_MASK);
BCaseMask(EF_LOONGARCH_BASE_ABI_LP64F, EF_LOONGARCH_BASE_ABI_MASK);
BCaseMask(EF_LOONGARCH_BASE_ABI_LP64D, EF_LOONGARCH_BASE_ABI_MASK);
break;
case ELF::EM_RISCV:
BCase(EF_RISCV_RVC);
BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);

View File

@ -0,0 +1,64 @@
## Check llvm-readobj is able to decode all possible LoongArch e_flags field values.
# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DFLAG=LP64S
# RUN: llvm-readobj -h %t-lp64s | FileCheck --check-prefix=READOBJ-LP64S %s
# RUN: llvm-readelf -h %t-lp64s | FileCheck --check-prefix=READELF-LP64S --match-full-lines %s
# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DFLAG=LP64F
# RUN: llvm-readobj -h %t-lp64f | FileCheck --check-prefix=READOBJ-LP64F %s
# RUN: llvm-readelf -h %t-lp64f | FileCheck --check-prefix=READELF-LP64F --match-full-lines %s
# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DFLAG=LP64D
# RUN: llvm-readobj -h %t-lp64d | FileCheck --check-prefix=READOBJ-LP64D %s
# RUN: llvm-readelf -h %t-lp64d | FileCheck --check-prefix=READELF-LP64D --match-full-lines %s
# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DFLAG=ILP32S
# RUN: llvm-readobj -h %t-ilp32s | FileCheck --check-prefix=READOBJ-ILP32S %s
# RUN: llvm-readelf -h %t-ilp32s | FileCheck --check-prefix=READELF-ILP32S --match-full-lines %s
# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DFLAG=ILP32F
# RUN: llvm-readobj -h %t-ilp32f | FileCheck --check-prefix=READOBJ-ILP32F %s
# RUN: llvm-readelf -h %t-ilp32f | FileCheck --check-prefix=READELF-ILP32F --match-full-lines %s
# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DFLAG=ILP32D
# RUN: llvm-readobj -h %t-ilp32d | FileCheck --check-prefix=READOBJ-ILP32D %s
# RUN: llvm-readelf -h %t-ilp32d | FileCheck --check-prefix=READELF-ILP32D --match-full-lines %s
# READOBJ-LP64S: Flags [ (0x1)
# READOBJ-LP64S-NEXT: EF_LOONGARCH_BASE_ABI_LP64S (0x1)
# READOBJ-LP64S-NEXT: ]
# READOBJ-LP64F: Flags [ (0x2)
# READOBJ-LP64F-NEXT: EF_LOONGARCH_BASE_ABI_LP64F (0x2)
# READOBJ-LP64F-NEXT: ]
# READOBJ-LP64D: Flags [ (0x3)
# READOBJ-LP64D-NEXT: EF_LOONGARCH_BASE_ABI_LP64D (0x3)
# READOBJ-LP64D-NEXT: ]
# READOBJ-ILP32S: Flags [ (0x5)
# READOBJ-ILP32S-NEXT: EF_LOONGARCH_BASE_ABI_ILP32S (0x5)
# READOBJ-ILP32S-NEXT: ]
# READOBJ-ILP32F: Flags [ (0x6)
# READOBJ-ILP32F-NEXT: EF_LOONGARCH_BASE_ABI_ILP32F (0x6)
# READOBJ-ILP32F-NEXT: ]
# READOBJ-ILP32D: Flags [ (0x7)
# READOBJ-ILP32D-NEXT: EF_LOONGARCH_BASE_ABI_ILP32D (0x7)
# READOBJ-ILP32D-NEXT: ]
# READELF-LP64S: Flags: 0x1, LP64, SOFT-FLOAT
# READELF-LP64F: Flags: 0x2, LP64, SINGLE-FLOAT
# READELF-LP64D: Flags: 0x3, LP64, DOUBLE-FLOAT
# READELF-ILP32S: Flags: 0x5, ILP32, SOFT-FLOAT
# READELF-ILP32F: Flags: 0x6, ILP32, SINGLE-FLOAT
# READELF-ILP32D: Flags: 0x7, ILP32, DOUBLE-FLOAT
--- !ELF
FileHeader:
Class: ELFCLASS[[CLASS]]
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_LOONGARCH
Flags: [ EF_LOONGARCH_BASE_ABI_[[FLAG]] ]

View File

@ -0,0 +1,29 @@
## Check obj2yaml is able to decode all possible LoongArch e_flags field values.
# RUN: yaml2obj %s -o %t-lp64s -DCLASS=64 -DFLAG=LP64S
# RUN: obj2yaml %t-lp64s | FileCheck -DFLAG=LP64S %s
# RUN: yaml2obj %s -o %t-lp64f -DCLASS=64 -DFLAG=LP64F
# RUN: obj2yaml %t-lp64f | FileCheck -DFLAG=LP64F %s
# RUN: yaml2obj %s -o %t-lp64d -DCLASS=64 -DFLAG=LP64D
# RUN: obj2yaml %t-lp64d | FileCheck -DFLAG=LP64D %s
# RUN: yaml2obj %s -o %t-ilp32s -DCLASS=32 -DFLAG=ILP32S
# RUN: obj2yaml %t-ilp32s | FileCheck -DFLAG=ILP32S %s
# RUN: yaml2obj %s -o %t-ilp32f -DCLASS=32 -DFLAG=ILP32F
# RUN: obj2yaml %t-ilp32f | FileCheck -DFLAG=ILP32F %s
# RUN: yaml2obj %s -o %t-ilp32d -DCLASS=32 -DFLAG=ILP32D
# RUN: obj2yaml %t-ilp32d | FileCheck -DFLAG=ILP32D %s
# CHECK: Flags: [ EF_LOONGARCH_BASE_ABI_[[FLAG]] ]
--- !ELF
FileHeader:
Class: ELFCLASS[[CLASS]]
Data: ELFDATA2LSB
Type: ET_EXEC
Machine: EM_LOONGARCH
Flags: [ EF_LOONGARCH_BASE_ABI_[[FLAG]] ]

View File

@ -1648,6 +1648,15 @@ const EnumEntry<unsigned> ElfHeaderAVRFlags[] = {
ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"),
};
const EnumEntry<unsigned> ElfHeaderLoongArchFlags[] = {
ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32S, "ILP32, SOFT-FLOAT"),
ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32F, "ILP32, SINGLE-FLOAT"),
ENUM_ENT(EF_LOONGARCH_BASE_ABI_ILP32D, "ILP32, DOUBLE-FLOAT"),
ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64S, "LP64, SOFT-FLOAT"),
ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64F, "LP64, SINGLE-FLOAT"),
ENUM_ENT(EF_LOONGARCH_BASE_ABI_LP64D, "LP64, DOUBLE-FLOAT"),
};
const EnumEntry<unsigned> ElfSymOtherFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
@ -3357,6 +3366,9 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {
else if (e.e_machine == EM_AVR)
ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags),
unsigned(ELF::EF_AVR_ARCH_MASK));
else if (e.e_machine == EM_LOONGARCH)
ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderLoongArchFlags),
unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK));
Str = "0x" + utohexstr(e.e_flags);
if (!ElfFlags.empty())
Str = Str + ", " + ElfFlags;
@ -6507,6 +6519,9 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {
else if (E.e_machine == EM_AVR)
W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags),
unsigned(ELF::EF_AVR_ARCH_MASK));
else if (E.e_machine == EM_LOONGARCH)
W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderLoongArchFlags),
unsigned(ELF::EF_LOONGARCH_BASE_ABI_MASK));
else
W.printFlags("Flags", E.e_flags);
W.printNumber("HeaderSize", E.e_ehsize);