diff --git a/llvm/include/llvm/BinaryFormat/DynamicTags.def b/llvm/include/llvm/BinaryFormat/DynamicTags.def --- 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 @@ 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 @@ #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 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -660,6 +660,12 @@ #include "ELFRelocs/RISCV.def" }; +enum { + // Symbol may follow different 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 --- a/llvm/lib/Object/ELF.cpp +++ b/llvm/lib/Object/ELF.cpp @@ -489,6 +489,14 @@ #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) { @@ -498,6 +506,7 @@ #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; @@ -508,6 +517,7 @@ #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 --- a/llvm/lib/ObjectYAML/ELFYAML.cpp +++ b/llvm/lib/ObjectYAML/ELFYAML.cpp @@ -887,6 +887,13 @@ #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; @@ -1165,6 +1172,8 @@ 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 --- 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 @@ - 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/dynamic-tags-machine-specific.test b/llvm/test/tools/llvm-readobj/ELF/dynamic-tags-machine-specific.test --- 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 @@ - 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 --- 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 @@ - 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 different 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 --- /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 ]