forked from OSchip/llvm-project
[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:
parent
ae8a6602fb
commit
aff68f5ad6
|
@ -900,6 +900,26 @@ enum {
|
||||||
#include "ELFRelocs/CSKY.def"
|
#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
|
// ELF Relocation types for LoongArch
|
||||||
enum {
|
enum {
|
||||||
#include "ELFRelocs/LoongArch.def"
|
#include "ELFRelocs/LoongArch.def"
|
||||||
|
|
|
@ -518,6 +518,14 @@ void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
|
||||||
BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK);
|
BCaseMask(EF_AVR_ARCH_XMEGA7, EF_AVR_ARCH_MASK);
|
||||||
BCase(EF_AVR_LINKRELAX_PREPARED);
|
BCase(EF_AVR_LINKRELAX_PREPARED);
|
||||||
break;
|
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:
|
case ELF::EM_RISCV:
|
||||||
BCase(EF_RISCV_RVC);
|
BCase(EF_RISCV_RVC);
|
||||||
BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
|
BCaseMask(EF_RISCV_FLOAT_ABI_SOFT, EF_RISCV_FLOAT_ABI);
|
||||||
|
|
|
@ -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]] ]
|
|
@ -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]] ]
|
|
@ -1648,6 +1648,15 @@ const EnumEntry<unsigned> ElfHeaderAVRFlags[] = {
|
||||||
ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"),
|
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[] = {
|
const EnumEntry<unsigned> ElfSymOtherFlags[] = {
|
||||||
LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL),
|
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)
|
else if (e.e_machine == EM_AVR)
|
||||||
ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags),
|
ElfFlags = printFlags(e.e_flags, makeArrayRef(ElfHeaderAVRFlags),
|
||||||
unsigned(ELF::EF_AVR_ARCH_MASK));
|
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);
|
Str = "0x" + utohexstr(e.e_flags);
|
||||||
if (!ElfFlags.empty())
|
if (!ElfFlags.empty())
|
||||||
Str = Str + ", " + ElfFlags;
|
Str = Str + ", " + ElfFlags;
|
||||||
|
@ -6507,6 +6519,9 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printFileHeaders() {
|
||||||
else if (E.e_machine == EM_AVR)
|
else if (E.e_machine == EM_AVR)
|
||||||
W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags),
|
W.printFlags("Flags", E.e_flags, makeArrayRef(ElfHeaderAVRFlags),
|
||||||
unsigned(ELF::EF_AVR_ARCH_MASK));
|
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
|
else
|
||||||
W.printFlags("Flags", E.e_flags);
|
W.printFlags("Flags", E.e_flags);
|
||||||
W.printNumber("HeaderSize", E.e_ehsize);
|
W.printNumber("HeaderSize", E.e_ehsize);
|
||||||
|
|
Loading…
Reference in New Issue