diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -900,6 +900,26 @@ #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" diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -518,6 +518,14 @@ 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); diff --git a/llvm/test/Object/LoongArch/elf-flags.yaml b/llvm/test/Object/LoongArch/elf-flags.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/Object/LoongArch/elf-flags.yaml @@ -0,0 +1,121 @@ +# RUN: yaml2obj --docnum=1 %s > %t-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: obj2yaml %t-lp64s | FileCheck --check-prefix=YAML-LP64S %s + +# RUN: yaml2obj --docnum=2 %s > %t-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: obj2yaml %t-lp64f | FileCheck --check-prefix=YAML-LP64F %s + +# RUN: yaml2obj --docnum=3 %s > %t-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: obj2yaml %t-lp64d | FileCheck --check-prefix=YAML-LP64D %s + +# RUN: yaml2obj --docnum=4 %s > %t-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: obj2yaml %t-ilp32s | FileCheck --check-prefix=YAML-ILP32S %s + +# RUN: yaml2obj --docnum=5 %s > %t-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: obj2yaml %t-ilp32f | FileCheck --check-prefix=YAML-ILP32F %s + +# RUN: yaml2obj --docnum=6 %s > %t-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 +# RUN: obj2yaml %t-ilp32d | FileCheck --check-prefix=YAML-ILP32D %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 + +# YAML-LP64S: Flags: [ EF_LOONGARCH_BASE_ABI_LP64S ] +# YAML-LP64F: Flags: [ EF_LOONGARCH_BASE_ABI_LP64F ] +# YAML-LP64D: Flags: [ EF_LOONGARCH_BASE_ABI_LP64D ] +# YAML-ILP32S: Flags: [ EF_LOONGARCH_BASE_ABI_ILP32S ] +# YAML-ILP32F: Flags: [ EF_LOONGARCH_BASE_ABI_ILP32F ] +# YAML-ILP32D: Flags: [ EF_LOONGARCH_BASE_ABI_ILP32D ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_LOONGARCH + Flags: [ EF_LOONGARCH_BASE_ABI_LP64S ] +... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_LOONGARCH + Flags: [ EF_LOONGARCH_BASE_ABI_LP64F ] +... + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_LOONGARCH + Flags: [ EF_LOONGARCH_BASE_ABI_LP64D ] +... + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_LOONGARCH + Flags: [ EF_LOONGARCH_BASE_ABI_ILP32S ] +... + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_LOONGARCH + Flags: [ EF_LOONGARCH_BASE_ABI_ILP32F ] +... + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_LOONGARCH + Flags: [ EF_LOONGARCH_BASE_ABI_ILP32D ] +... diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -1648,6 +1648,15 @@ ENUM_ENT(EF_AVR_LINKRELAX_PREPARED, "relaxable"), }; +const EnumEntry 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 ElfSymOtherFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, STV_INTERNAL), @@ -3357,6 +3366,9 @@ 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 @@ 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);