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

Weining Lu via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 25 05:41:32 PDT 2022


Author: Weining Lu
Date: 2022-07-25T20:40:57+08:00
New Revision: aff68f5ad646303a4992fc04d329b4df06bc4c71

URL: https://github.com/llvm/llvm-project/commit/aff68f5ad646303a4992fc04d329b4df06bc4c71
DIFF: https://github.com/llvm/llvm-project/commit/aff68f5ad646303a4992fc04d329b4df06bc4c71.diff

LOG: [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

Added: 
    llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test
    llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml

Modified: 
    llvm/include/llvm/BinaryFormat/ELF.h
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 1fd0257611274..fb74834bb57d9 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -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"

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index b778006cf66e5..9ad2c41351672 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -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);

diff  --git a/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test b/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test
new file mode 100644
index 0000000000000..b6627364054b6
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/loongarch-eflags.test
@@ -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]] ]

diff  --git a/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml b/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml
new file mode 100644
index 0000000000000..e4c4c292e0da5
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/ELF/loongarch-eflags.yaml
@@ -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]] ]

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index ae2dec5d15fbd..ba7bae96ade36 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -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);


        


More information about the llvm-commits mailing list