[llvm] 8971b99 - [llvm-objdump/llvm-readobj/obj2yaml/yaml2obj] Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 29 16:56:57 PDT 2021


Author: Fangrui Song
Date: 2021-09-29T16:56:52-07:00
New Revision: 8971b99c8387f3daf2e802956f2688b3b77335a4

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

LOG: [llvm-objdump/llvm-readobj/obj2yaml/yaml2obj] Support STO_RISCV_VARIANT_CC and DT_RISCV_VARIANT_CC

STO_RISCV_VARIANT_CC marks that a symbol uses a non-standard calling
convention or the vector calling convention.

See https://github.com/riscv/riscv-elf-psabi-doc/pull/190

Differential Revision: https://reviews.llvm.org/D107949

Added: 
    llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test
    llvm/test/tools/obj2yaml/ELF/riscv-sym-other.yaml

Modified: 
    llvm/include/llvm/BinaryFormat/DynamicTags.def
    llvm/include/llvm/BinaryFormat/ELF.h
    llvm/lib/Object/ELF.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/test/tools/llvm-objdump/ELF/dynamic-section-machine-specific.test
    llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test
    llvm/test/tools/obj2yaml/ELF/dynamic-section-arch-tags.yaml
    llvm/tools/llvm-readobj/ELFDumper.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/BinaryFormat/DynamicTags.def b/llvm/include/llvm/BinaryFormat/DynamicTags.def
index c08f8a53bdb53..814d8b113ec4e 100644
--- a/llvm/include/llvm/BinaryFormat/DynamicTags.def
+++ b/llvm/include/llvm/BinaryFormat/DynamicTags.def
@@ -31,6 +31,11 @@
 #define PPC64_DYNAMIC_TAG_DEFINED
 #endif
 
+#ifndef RISCV_DYNAMIC_TAG
+#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#define RISCV_DYNAMIC_TAG_DEFINED
+#endif
+
 #ifndef DYNAMIC_TAG_MARKER
 #define DYNAMIC_TAG_MARKER(name, value) DYNAMIC_TAG(name, value)
 #define DYNAMIC_TAG_MARKER_DEFINED
@@ -213,6 +218,9 @@ PPC_DYNAMIC_TAG(PPC_OPT, 0x70000001) // Has TLS optimization.
 PPC64_DYNAMIC_TAG(PPC64_GLINK, 0x70000000) // Address of 32 bytes before the
                                            // first glink lazy resolver stub.
 
+// RISC-V specific dynamic array tags.
+RISCV_DYNAMIC_TAG(RISCV_VARIANT_CC, 0x70000001)
+
 // Sun machine-independent extensions.
 DYNAMIC_TAG(AUXILIARY, 0x7FFFFFFD) // Shared object to load before self
 DYNAMIC_TAG(USED, 0x7FFFFFFE)      // Same as DT_NEEDED
@@ -243,3 +251,7 @@ DYNAMIC_TAG(FILTER, 0x7FFFFFFF)    // Shared object to get values from
 #undef PPC64_DYNAMIC_TAG
 #undef PPC64_DYNAMIC_TAG_DEFINED
 #endif
+#ifdef RISCV_DYNAMIC_TAG_DEFINED
+#undef RISCV_DYNAMIC_TAG
+#undef RISCV_DYNAMIC_TAG_DEFINED
+#endif

diff  --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 540675d6b6efd..df9fd49606378 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -660,6 +660,12 @@ enum {
 #include "ELFRelocs/RISCV.def"
 };
 
+enum {
+  // Symbol may follow 
diff erent calling convention than the standard calling
+  // convention.
+  STO_RISCV_VARIANT_CC = 0x80
+};
+
 // ELF Relocation types for S390/zSeries
 enum {
 #include "ELFRelocs/SystemZ.def"

diff  --git a/llvm/lib/Object/ELF.cpp b/llvm/lib/Object/ELF.cpp
index e9bf482465acd..cd9f8813e74c3 100644
--- a/llvm/lib/Object/ELF.cpp
+++ b/llvm/lib/Object/ELF.cpp
@@ -492,6 +492,14 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
 #undef PPC64_DYNAMIC_TAG
     }
     break;
+
+  case ELF::EM_RISCV:
+    switch (Type) {
+#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_STRINGIFY_ENUM(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef RISCV_DYNAMIC_TAG
+    }
+    break;
   }
 #undef DYNAMIC_TAG
   switch (Type) {
@@ -501,6 +509,7 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
 #define HEXAGON_DYNAMIC_TAG(name, value)
 #define PPC_DYNAMIC_TAG(name, value)
 #define PPC64_DYNAMIC_TAG(name, value)
+#define RISCV_DYNAMIC_TAG(name, value)
 // Also ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc.
 #define DYNAMIC_TAG_MARKER(name, value)
 #define DYNAMIC_TAG(name, value) case value: return #name;
@@ -511,6 +520,7 @@ std::string ELFFile<ELFT>::getDynamicTagAsString(unsigned Arch,
 #undef HEXAGON_DYNAMIC_TAG
 #undef PPC_DYNAMIC_TAG
 #undef PPC64_DYNAMIC_TAG
+#undef RISCV_DYNAMIC_TAG
 #undef DYNAMIC_TAG_MARKER
 #undef DYNAMIC_STRINGIFY_ENUM
   default:

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 3edf500d2cf22..a9e63a68e45e0 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -890,6 +890,13 @@ void ScalarEnumerationTraits<ELFYAML::ELF_DYNTAG>::enumeration(
 #undef PPC64_DYNAMIC_TAG
 #define PPC64_DYNAMIC_TAG(name, value)
     break;
+  case ELF::EM_RISCV:
+#undef RISCV_DYNAMIC_TAG
+#define RISCV_DYNAMIC_TAG(name, value) DYNAMIC_TAG(name, value)
+#include "llvm/BinaryFormat/DynamicTags.def"
+#undef RISCV_DYNAMIC_TAG
+#define RISCV_DYNAMIC_TAG(name, value)
+    break;
   default:
 #include "llvm/BinaryFormat/DynamicTags.def"
     break;
@@ -1168,6 +1175,8 @@ struct NormalizedOther {
 
     if (EMachine == ELF::EM_AARCH64)
       Map["STO_AARCH64_VARIANT_PCS"] = ELF::STO_AARCH64_VARIANT_PCS;
+    if (EMachine == ELF::EM_RISCV)
+      Map["STO_RISCV_VARIANT_CC"] = ELF::STO_RISCV_VARIANT_CC;
     return Map;
   }
 

diff  --git a/llvm/test/tools/llvm-objdump/ELF/dynamic-section-machine-specific.test b/llvm/test/tools/llvm-objdump/ELF/dynamic-section-machine-specific.test
index 2f3b7cb1ce84b..08d7d2e9c7c73 100644
--- a/llvm/test/tools/llvm-objdump/ELF/dynamic-section-machine-specific.test
+++ b/llvm/test/tools/llvm-objdump/ELF/dynamic-section-machine-specific.test
@@ -289,3 +289,32 @@ ProgramHeaders:
   - Type:     PT_DYNAMIC
     FirstSec: .dynamic
     LastSec:  .dynamic
+
+## Case 6: Test that RISC-V machine-specific tags can be dumped.
+# RUN: yaml2obj --docnum=6 %s -o %t.rv
+# RUN: llvm-objdump -p %t.rv | FileCheck %s --check-prefix=RISCV
+
+# RISCV:      Dynamic Section:
+# RISCV-NEXT:  RISCV_VARIANT_CC     0x0000000000000001
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_RISCV
+Sections:
+  - Name: .dynamic
+    Type: SHT_DYNAMIC
+    Entries:
+      - Tag:   DT_RISCV_VARIANT_CC
+        Value: 1
+      - Tag:   DT_NULL
+        Value: 0
+ProgramHeaders:
+  - Type:     PT_LOAD
+    FirstSec: .dynamic
+    LastSec:  .dynamic
+  - Type:     PT_DYNAMIC
+    FirstSec: .dynamic
+    LastSec:  .dynamic

diff  --git a/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test b/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test
new file mode 100644
index 0000000000000..b325aeb9c5b9a
--- /dev/null
+++ b/llvm/test/tools/llvm-readobj/ELF/RISCV/stother.test
@@ -0,0 +1,38 @@
+## Check that we are able to dump RISC-V STO_* flags correctly when dumping symbols.
+
+# RUN: yaml2obj %s -o %t.o
+# RUN: llvm-readobj -s %t.o | FileCheck %s --check-prefix=LLVM
+# RUN: llvm-readelf -s %t.o | FileCheck %s --check-prefix=GNU
+
+# LLVM:      Name: foo1
+# LLVM:      Other [ (0x80)
+# LLVM-NEXT:   STO_RISCV_VARIANT_CC (0x80)
+# LLVM-NEXT: ]
+# LLVM:      Name: foo2
+# LLVM:      Other [ (0xC0)
+# LLVM-NEXT:   STO_RISCV_VARIANT_CC (0x80)
+# LLVM-NEXT: ]
+# LLVM:      Name: foo3
+# LLVM:      Other [ (0x83)
+# LLVM-NEXT:   STO_RISCV_VARIANT_CC (0x80)
+# LLVM-NEXT:   STV_PROTECTED (0x3)
+# LLVM-NEXT: ]
+
+# GNU:      Symbol table '.symtab' contains 4 entries:
+# GNU:      1: 0000000000000000 0 NOTYPE LOCAL DEFAULT   [VARIANT_CC]      UND foo1
+# GNU-NEXT: 2: 0000000000000000 0 NOTYPE LOCAL DEFAULT   [VARIANT_CC | 40] UND foo2
+# GNU-NEXT: 3: 0000000000000000 0 NOTYPE LOCAL PROTECTED [VARIANT_CC]      UND foo3
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_RISCV
+Symbols:
+  - Name: foo1
+    Other: [ STO_RISCV_VARIANT_CC ]
+  - Name: foo2
+    Other: [ STO_RISCV_VARIANT_CC, 0x40 ]
+  - Name: foo3
+    Other: [ STO_RISCV_VARIANT_CC, STV_PROTECTED ]

diff  --git a/llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test
index 02309e51b3429..970edccd7777d 100644
--- a/llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test
+++ b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test
@@ -391,3 +391,41 @@ ProgramHeaders:
   - Type:     PT_DYNAMIC
     FirstSec: .dynamic
     LastSec:  .dynamic
+
+## Case 6: Test that RISC-V machine-specific tags can be dumped.
+# RUN: yaml2obj --docnum=6 %s -o %t.rv
+# RUN: llvm-readobj --dynamic-table %t.rv | FileCheck %s --check-prefix=LLVM-RISCV
+# RUN: llvm-readelf --dynamic-table %t.rv | FileCheck %s --check-prefix=GNU-RISCV
+
+# LLVM-RISCV:      DynamicSection [ (2 entries)
+# LLVM-RISCV-NEXT:   Tag                Type                Name/Value
+# LLVM-RISCV-NEXT:   0x0000000070000001 RISCV_VARIANT_CC    0x1
+# LLVM-RISCV-NEXT:   0x0000000000000000 NULL                0x0
+# LLVM-RISCV-NEXT: ]
+
+# GNU-RISCV:       Dynamic section at offset {{.*}} contains 2 entries:
+# GNU-RISCV-NEXT:   Tag                Type                 Name/Value
+# GNU-RISCV-NEXT:   0x0000000070000001 (RISCV_VARIANT_CC)   0x1
+# GNU-RISCV-NEXT:   0x0000000000000000 (NULL)               0x0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_RISCV
+Sections:
+  - Name: .dynamic
+    Type: SHT_DYNAMIC
+    Entries:
+      - Tag:   DT_RISCV_VARIANT_CC
+        Value: 1
+      - Tag:   DT_NULL
+        Value: 0
+ProgramHeaders:
+  - Type:     PT_LOAD
+    FirstSec: .dynamic
+    LastSec:  .dynamic
+  - Type:     PT_DYNAMIC
+    FirstSec: .dynamic
+    LastSec:  .dynamic

diff  --git a/llvm/test/tools/obj2yaml/ELF/dynamic-section-arch-tags.yaml b/llvm/test/tools/obj2yaml/ELF/dynamic-section-arch-tags.yaml
index cf08db8be6e85..5523b2fee37df 100644
--- a/llvm/test/tools/obj2yaml/ELF/dynamic-section-arch-tags.yaml
+++ b/llvm/test/tools/obj2yaml/ELF/dynamic-section-arch-tags.yaml
@@ -297,12 +297,32 @@ Sections:
       - Tag:             DT_AARCH64_PAC_PLT
         Value:           0x0000000000000000
 
+## Check we can handle RISC-V specific tags.
+# RUN: yaml2obj --docnum=6 %s -o %t6
+# RUN: obj2yaml %t6 | FileCheck %s --check-prefix=RISCV
+
+# RISCV:      - Tag:             DT_RISCV_VARIANT_CC
+# RISCV-NEXT:   Value:           0x0
+
+--- !ELF
+FileHeader:
+  Class:             ELFCLASS64
+  Data:              ELFDATA2LSB
+  Type:              ET_REL
+  Machine:           EM_RISCV
+Sections:
+  - Name:            .dynamic
+    Type:            SHT_DYNAMIC
+    Entries:
+      - Tag:             DT_RISCV_VARIANT_CC
+        Value:           0x0000000000000000
+
 ## Check we can't use a tag from a 
diff erent architecture,
 ## even if it has the same numeric value as a valid tag.
 ## Here for EM_PPC64 we are trying to use DT_HEXAGON_SYMSZ
 ## instead of DT_PPC64_GLINK. They both have value of 0x70000000.
 
-# RUN: not yaml2obj --docnum=6 %s 2>&1 | FileCheck %s --check-prefix=ERR
+# RUN: not yaml2obj --docnum=7 %s 2>&1 | FileCheck %s --check-prefix=ERR
 # ERR:      error: invalid hex64 number
 # ERR-NEXT: - Tag: DT_HEXAGON_SYMSZ
 

diff  --git a/llvm/test/tools/obj2yaml/ELF/riscv-sym-other.yaml b/llvm/test/tools/obj2yaml/ELF/riscv-sym-other.yaml
new file mode 100644
index 0000000000000..0172c3a7bf638
--- /dev/null
+++ b/llvm/test/tools/obj2yaml/ELF/riscv-sym-other.yaml
@@ -0,0 +1,22 @@
+## Check RISC-V st_other extension support.
+
+# RUN: yaml2obj %s -o %t
+# RUN: obj2yaml %t | FileCheck %s
+
+# CHECK: Symbols:
+# CHECK:  - Name:  foo1
+# CHECK:    Other: [ STO_RISCV_VARIANT_CC ]
+# CHECK:  - Name:  foo2
+# CHECK:    Other: [ STO_RISCV_VARIANT_CC, 64 ]
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_RISCV
+Symbols:
+  - Name:  foo1
+    Other: [ STO_RISCV_VARIANT_CC ]
+  - Name:  foo2
+    Other: [ STO_RISCV_VARIANT_CC, 0x40 ]

diff  --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 56fd7c74d5072..ff81768d705ca 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -1616,6 +1616,9 @@ static const EnumEntry<unsigned> ElfMips16SymOtherFlags[] = {
   LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16)
 };
 
+static const EnumEntry<unsigned> ElfRISCVSymOtherFlags[] = {
+    LLVM_READOBJ_ENUM_ENT(ELF, STO_RISCV_VARIANT_CC)};
+
 static const char *getElfMipsOptionsOdkType(unsigned Odk) {
   switch (Odk) {
   LLVM_READOBJ_ENUM_CASE(ELF, ODK_NULL);
@@ -3773,6 +3776,15 @@ void GNUELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
           Fields[5].Str.append(" | " + to_hexString(Other, false));
         Fields[5].Str.append("]");
       }
+    } else if (this->Obj.getHeader().e_machine == ELF::EM_RISCV) {
+      uint8_t Other = Symbol.st_other & ~0x3;
+      if (Other & STO_RISCV_VARIANT_CC) {
+        Other &= ~STO_RISCV_VARIANT_CC;
+        Fields[5].Str += " [VARIANT_CC";
+        if (Other != 0)
+          Fields[5].Str.append(" | " + to_hexString(Other, false));
+        Fields[5].Str.append("]");
+      }
     } else {
       Fields[5].Str +=
           " [<other: " + to_string(format_hex(Symbol.st_other, 2)) + ">]";
@@ -6577,6 +6589,10 @@ void LLVMELFDumper<ELFT>::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex,
       SymOtherFlags.insert(SymOtherFlags.end(),
                            std::begin(ElfAArch64SymOtherFlags),
                            std::end(ElfAArch64SymOtherFlags));
+    } else if (this->Obj.getHeader().e_machine == EM_RISCV) {
+      SymOtherFlags.insert(SymOtherFlags.end(),
+                           std::begin(ElfRISCVSymOtherFlags),
+                           std::end(ElfRISCVSymOtherFlags));
     }
     W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u);
   }


        


More information about the llvm-commits mailing list