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 table entries. +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 @@ -642,6 +642,13 @@ #include "ELFRelocs/Lanai.def" }; +// Special values for the st_other field in the symbol table entry for RISC-V. +enum { + // Symbol may follow different calling convention than standard calling + // conventions. + STO_RISCV_VARIANT_CC = 0x80 +}; + // RISCV Specific e_flags enum : unsigned { EF_RISCV_RVC = 0x0001, 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 @@ -481,6 +481,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) { @@ -489,6 +497,7 @@ #define MIPS_DYNAMIC_TAG(name, value) #define HEXAGON_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; @@ -498,6 +507,7 @@ #undef MIPS_DYNAMIC_TAG #undef HEXAGON_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 @@ -843,6 +843,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) // Ignore marker tags such as DT_HIOS (maps to DT_VERNEEDNUM), etc. #define DYNAMIC_TAG_MARKER(name, value) @@ -884,6 +885,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; @@ -893,6 +901,7 @@ #undef HEXAGON_DYNAMIC_TAG #undef PPC_DYNAMIC_TAG #undef PPC64_DYNAMIC_TAG +#undef RISCV_DYNAMIC_TAG #undef DYNAMIC_TAG_MARKER #undef STRINGIFY #undef DYNAMIC_TAG @@ -1161,6 +1170,10 @@ 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/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -169,6 +169,7 @@ bool parseDirectiveOption(); bool parseDirectiveAttribute(); + bool parseDirectiveVariantCC(); void setFeatureBits(uint64_t Feature, StringRef FeatureString) { if (!(getSTI().getFeatureBits()[Feature])) { @@ -1837,6 +1838,8 @@ return parseDirectiveOption(); else if (IDVal == ".attribute") return parseDirectiveAttribute(); + else if (IDVal == ".variant_cc") + return parseDirectiveVariantCC(); return true; } @@ -2200,6 +2203,32 @@ return false; } +/// parseDirectiveVariantCC +/// ::= .variant_cc symbol +bool RISCVAsmParser::parseDirectiveVariantCC() { + MCAsmParser &Parser = getParser(); + + const AsmToken &Tok = Parser.getTok(); + if (Tok.isNot(AsmToken::Identifier)) + return TokError("expected symbol name"); + + StringRef SymbolName = Tok.getIdentifier(); + + MCSymbol *Sym = getContext().lookupSymbol(SymbolName); + if (!Sym) + return TokError("unknown symbol in '.variant_cc' directive"); + + Parser.Lex(); // Eat the symbol + + // Shouldn't be any more tokens + if (parseToken(AsmToken::EndOfStatement)) + return addErrorSuffix(" in '.variant_cc' directive"); + + getTargetStreamer().emitDirectiveVariantCC(Sym); + + return false; +} + void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { MCInst CInst; bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -103,6 +103,7 @@ void emitDirectiveOptionNoRVC() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; + void emitDirectiveVariantCC(MCSymbol *Symbol) override; }; } #endif diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -167,3 +167,7 @@ } return Result; } + +void RISCVTargetELFStreamer::emitDirectiveVariantCC(MCSymbol *Symbol) { + cast(Symbol)->setOther(ELF::STO_RISCV_VARIANT_CC); +} diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -36,6 +36,8 @@ StringRef StringValue); void emitTargetAttributes(const MCSubtargetInfo &STI); + /// Callback used to implement the .variant_cc directive. + virtual void emitDirectiveVariantCC(MCSymbol *Symbol); }; // This part is for ascii assembly output @@ -59,6 +61,7 @@ void emitDirectiveOptionNoRVC() override; void emitDirectiveOptionRelax() override; void emitDirectiveOptionNoRelax() override; + void emitDirectiveVariantCC(MCSymbol *Symbol) override; }; } diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -96,6 +96,8 @@ emitTextAttribute(RISCVAttrs::ARCH, Arch); } +void RISCVTargetStreamer::emitDirectiveVariantCC(MCSymbol *Symbol) {} + // This part is for ascii assembly output RISCVTargetAsmStreamer::RISCVTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS) @@ -147,3 +149,7 @@ StringRef StringValue) {} void RISCVTargetAsmStreamer::finishAttributeSection() {} + +void RISCVTargetAsmStreamer::emitDirectiveVariantCC(MCSymbol *Symbol) { + OS << "\t.variant_cc\t" << Symbol->getName() << "\n"; +} diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp --- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp +++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp @@ -68,6 +68,8 @@ void emitStartOfAsmFile(Module &M) override; void emitEndOfAsmFile(Module &M) override; + void emitFunctionEntryLabel() override; + private: void emitAttributes(); }; @@ -196,6 +198,17 @@ RTS.emitTargetAttributes(*STI); } +void RISCVAsmPrinter::emitFunctionEntryLabel() { + const RISCVSubtarget &ST = MF->getSubtarget(); + if (ST.getRegisterInfo()->hasRVVArgsOrReturn(MF)) { + auto *TS = + static_cast(OutStreamer->getTargetStreamer()); + TS->emitDirectiveVariantCC(CurrentFnSym); + } + + return AsmPrinter::emitFunctionEntryLabel(); +} + // Force static initialization. extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmPrinter() { RegisterAsmPrinter X(getTheRISCV32Target()); diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.h +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.h @@ -63,6 +63,8 @@ const TargetRegisterClass * getLargestLegalSuperClass(const TargetRegisterClass *RC, const MachineFunction &) const override; + + bool hasRVVArgsOrReturn(const MachineFunction *MF) const; }; } diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp @@ -350,3 +350,18 @@ return &RISCV::VRRegClass; return RC; } + +bool RISCVRegisterInfo::hasRVVArgsOrReturn(const MachineFunction *MF) const { + const Function &F = MF->getFunction(); + auto &Subtarget = MF->getSubtarget(); + if (Subtarget.useRVVForFixedLengthVectors()) { + return isa(F.getReturnType()) || + any_of(F.args(), [](const Argument &Arg) { + return isa(Arg.getType()); + }); + } + return isa(F.getReturnType()) || + any_of(F.args(), [](const Argument &Arg) { + return isa(Arg.getType()); + }); +} diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-variant-cc.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-variant-cc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-variant-cc.ll @@ -0,0 +1,44 @@ +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -riscv-v-vector-bits-min=128 -o - %s \ +; RUN: | FileCheck %s --check-prefix=CHECK-ASM +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -riscv-v-vector-bits-min=128 -filetype=obj -o - %s \ +; RUN: | llvm-readobj --symbols - | FileCheck %s --check-prefix=CHECK-OBJ + +define i32 @base_cc() { +; CHECK-ASM-LABEL: base_cc: +; CHECK-ASM-NOT: .variant_cc +; CHECK-OBJ-LABEL: Name: base_cc +; CHECK-OBJ: Other: 0 + ret i32 42 +} + +define <4 x i32> @fixed_vector_vector_cc_1() { +; CHECK-ASM: .variant_cc fixed_vector_vector_cc_1 +; CHECK-ASM-NEXT: fixed_vector_vector_cc_1: +; CHECK-OBJ-LABEL: Name: fixed_vector_vector_cc_1 +; CHECK-OBJ: Other [ (0x80) + ret <4 x i32> undef +} + +define <4 x i1> @fixed_vector_vector_cc_2() { +; CHECK-ASM: .variant_cc fixed_vector_vector_cc_2 +; CHECK-ASM-NEXT: fixed_vector_vector_cc_2: +; CHECK-OBJ-LABEL: Name: fixed_vector_vector_cc_2 +; CHECK-OBJ: Other [ (0x80) + ret <4 x i1> undef +} + +define void @fixed_vector_vector_cc_3(<4 x i32> %arg) { +; CHECK-ASM: .variant_cc fixed_vector_vector_cc_3 +; CHECK-ASM-NEXT: fixed_vector_vector_cc_3: +; CHECK-OBJ-LABEL: Name: fixed_vector_vector_cc_3 +; CHECK-OBJ: Other [ (0x80) + ret void +} + +define void @fixed_vector_vector_cc_4(<4 x i1> %arg) { +; CHECK-ASM: .variant_cc fixed_vector_vector_cc_4 +; CHECK-ASM-NEXT: fixed_vector_vector_cc_4: +; CHECK-OBJ-LABEL: Name: fixed_vector_vector_cc_4 +; CHECK-OBJ: Other [ (0x80) + ret void +} diff --git a/llvm/test/CodeGen/RISCV/rvv/variant-cc.ll b/llvm/test/CodeGen/RISCV/rvv/variant-cc.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/variant-cc.ll @@ -0,0 +1,51 @@ +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -o - %s | FileCheck %s --check-prefix=CHECK-ASM +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -filetype=obj -o - %s \ +; RUN: | llvm-readobj --symbols - | FileCheck %s --check-prefix=CHECK-OBJ + +define i32 @base_cc() { +; CHECK-ASM-LABEL: base_cc: +; CHECK-ASM-NOT: .variant_cc +; CHECK-OBJ-LABEL: Name: base_cc +; CHECK-OBJ: Other: 0 + ret i32 42 +} + +define <4 x i32> @fixed_vector_cc_1(<4 x i32> %arg) { +; CHECK-ASM-LABEL: fixed_vector_cc_1: +; CHECK-ASM-NOT: .variant_cc +; CHECK-OBJ-LABEL: Name: fixed_vector_cc_1 +; CHECK-OBJ: Other: 0 + ret <4 x i32> %arg +} + +define @rvv_vector_cc_1() { +; CHECK-ASM: .variant_cc rvv_vector_cc_1 +; CHECK-ASM-NEXT: rvv_vector_cc_1: +; CHECK-OBJ-LABEL: Name: rvv_vector_cc_1 +; CHECK-OBJ: Other [ (0x80) + ret undef +} + +define @rvv_vector_cc_2() { +; CHECK-ASM: .variant_cc rvv_vector_cc_2 +; CHECK-ASM-NEXT: rvv_vector_cc_2: +; CHECK-OBJ-LABEL: Name: rvv_vector_cc_2 +; CHECK-OBJ: Other [ (0x80) + ret undef +} + +define void @rvv_vector_cc_3( %arg) { +; CHECK-ASM: .variant_cc rvv_vector_cc_3 +; CHECK-ASM-NEXT: rvv_vector_cc_3: +; CHECK-OBJ-LABEL: Name: rvv_vector_cc_3 +; CHECK-OBJ: Other [ (0x80) + ret void +} + +define void @rvv_vector_cc_4( %arg) { +; CHECK-ASM: .variant_cc rvv_vector_cc_4 +; CHECK-ASM-NEXT: rvv_vector_cc_4: +; CHECK-OBJ-LABEL: Name: rvv_vector_cc_4 +; CHECK-OBJ: Other [ (0x80) + ret void +} diff --git a/llvm/test/MC/RISCV/directive-variant_cc-err.s b/llvm/test/MC/RISCV/directive-variant_cc-err.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/directive-variant_cc-err.s @@ -0,0 +1,17 @@ +// RUN: not llvm-mc -triple riscv64 -filetype asm -o - %s 2>&1 | FileCheck %s + +.variant_cc +// CHECK: error: expected symbol name +// CHECK-NEXT: .variant_cc +// CHECK-NEXT: ^ + +.variant_cc foo +// CHECK: error: unknown symbol in '.variant_cc' directive +// CHECK-NEXT: .variant_cc foo +// CHECK-NEXT: ^ + +.global foo +.variant_cc foo bar +// CHECK: error: unexpected token in '.variant_cc' directive +// CHECK-NEXT: .variant_cc foo bar +// CHECK-NEXT: ^ diff --git a/llvm/test/MC/RISCV/directive-variant_cc.s b/llvm/test/MC/RISCV/directive-variant_cc.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/RISCV/directive-variant_cc.s @@ -0,0 +1,11 @@ +// RUN: llvm-mc -triple riscv64 -filetype asm -o - %s | FileCheck %s +// RUN: llvm-mc -triple riscv64 -filetype obj -o - %s \ +// RUN: | llvm-readobj --symbols - | FileCheck %s --check-prefix=CHECK-ST_OTHER + +.text +.global foo +.variant_cc foo +// CHECK: .variant_cc foo + +// CHECK-ST_OTHER: Name: foo +// CHECK-ST_OTHER: Other [ (0x80) 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.riscv +# RUN: llvm-readobj --dynamic-table %t.riscv | FileCheck %s --check-prefix=LLVM-RISCV +# RUN: llvm-readelf --dynamic-table %t.riscv | 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 1 +# 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) 1 +# 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/llvm-readobj/ELF/riscv-symbols-stother.test b/llvm/test/tools/llvm-readobj/ELF/riscv-symbols-stother.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-readobj/ELF/riscv-symbols-stother.test @@ -0,0 +1,23 @@ +## Check that we are able to dump RISC-V STO_* flags correctly when dumping symbols. + +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-readobj --symbols %t.o | FileCheck %s --check-prefix=LLVM +# RUN: llvm-readelf --symbols %t.o | FileCheck %s --check-prefix=GNU + +# LLVM: Name: foo1 +# LLVM: Other [ (0x80) +# LLVM-NEXT: STO_RISCV_VARIANT_CC (0x80) +# LLVM-NEXT: ] + +# GNU: Symbol table '.symtab' contains 2 entries: +# GNU: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT [VARIANT_CC] UND foo1 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_RISCV +Symbols: + - Name: foo1 + Other: [ STO_RISCV_VARIANT_CC ] 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,18 @@ +## 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 ] + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_RISCV +Symbols: + - Name: foo1 + Other: [ STO_RISCV_VARIANT_CC ] 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 @@ -1601,6 +1601,10 @@ LLVM_READOBJ_ENUM_ENT(ELF, STO_MIPS_MIPS16) }; +static const EnumEntry 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); @@ -2239,6 +2243,14 @@ break; } break; + case EM_RISCV: + switch (Type) { + case DT_RISCV_VARIANT_CC: + return std::to_string(Value); + default: + break; + } + break; default: break; } @@ -3754,6 +3766,15 @@ 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 += " []"; @@ -6514,6 +6535,10 @@ 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); }