https://github.com/SuHo-llrr updated https://github.com/llvm/llvm-project/pull/77414
>From 13841607619f27dd6dcc2289d0380f5b76d99cbe Mon Sep 17 00:00:00 2001 From: SuHsien Ho <su-hsien...@mediatek.com> Date: Thu, 23 Nov 2023 14:36:43 +0800 Subject: [PATCH 1/5] [RISCV][ELF] Add RISCV GNU property label --- llvm/include/llvm/BinaryFormat/ELF.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h index 8e0356a8efeb61..34c6a2690cbf3f 100644 --- a/llvm/include/llvm/BinaryFormat/ELF.h +++ b/llvm/include/llvm/BinaryFormat/ELF.h @@ -1737,6 +1737,7 @@ enum : unsigned { GNU_PROPERTY_NO_COPY_ON_PROTECTED = 2, GNU_PROPERTY_AARCH64_FEATURE_1_AND = 0xc0000000, GNU_PROPERTY_X86_FEATURE_1_AND = 0xc0000002, + GNU_PROPERTY_RISCV_FEATURE_1_AND = 0xc0000000, GNU_PROPERTY_X86_UINT32_OR_LO = 0xc0008000, GNU_PROPERTY_X86_FEATURE_2_NEEDED = GNU_PROPERTY_X86_UINT32_OR_LO + 1, @@ -1776,6 +1777,12 @@ enum : unsigned { GNU_PROPERTY_X86_ISA_1_V4 = 1 << 3, }; +// riscv processor feature bits. +enum : unsigned { + GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP = 1 << 0, + GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS = 1 << 1, +}; + // FreeBSD note types. enum { NT_FREEBSD_ABI_TAG = 1, >From c45570a62ae59848959bb1e99c8df87771b04fe4 Mon Sep 17 00:00:00 2001 From: SuHsien Ho <su-hsien...@mediatek.com> Date: Thu, 23 Nov 2023 14:38:34 +0800 Subject: [PATCH 2/5] [RISCV][ELF] Emit .gnu.note.property for Zicfiss/Zicfilip(CFI extension) --- .../RISCV/MCTargetDesc/RISCVELFStreamer.cpp | 43 +++++++++++++++++++ .../RISCV/MCTargetDesc/RISCVELFStreamer.h | 1 + 2 files changed, 44 insertions(+) diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp index b375e8bb4b8fac..ef1d86624b771d 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -84,6 +84,35 @@ void RISCVTargetELFStreamer::finishAttributeSection() { ELF::SHT_RISCV_ATTRIBUTES, AttributeSection); } +void RISCVTargetELFStreamer::emitNoteSection(unsigned Flags) { + if (Flags == 0) + return; + + MCStreamer &OutStreamer = getStreamer(); + MCContext &Context = OutStreamer.getContext(); + MCSectionELF *Nt = Context.getELFSection(".note.gnu.property", ELF::SHT_NOTE, + ELF::SHF_ALLOC); + MCSection *Cur = OutStreamer.getCurrentSectionOnly(); + OutStreamer.switchSection(Nt); + + // Emit the note header. + OutStreamer.emitValueToAlignment(Align(8)); + OutStreamer.emitIntValue(4, 4); // data size for note name + OutStreamer.emitIntValue(4 * 4, 4); // data size + OutStreamer.emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4); // note type + OutStreamer.emitBytes(StringRef("GNU", 4)); // note name + + // Emit the CFI(ZICFILP/ZICFISS) properties. + OutStreamer.emitIntValue(ELF::GNU_PROPERTY_RISCV_FEATURE_1_AND, + 4); // and property + OutStreamer.emitIntValue(4, 4); // data size + OutStreamer.emitIntValue(Flags, 4); // data + OutStreamer.emitIntValue(0, 4); // pad + + OutStreamer.endSection(Nt); + OutStreamer.switchSection(Cur); +} + void RISCVTargetELFStreamer::finish() { RISCVTargetStreamer::finish(); MCAssembler &MCA = getStreamer().getAssembler(); @@ -118,6 +147,20 @@ void RISCVTargetELFStreamer::finish() { } MCA.setELFHeaderEFlags(EFlags); + + unsigned GNUNoteFlags = 0; + + // TODO check ZICFILP or ZICFISS with march + // should we check with codegen enable ex. -mllvm + // -riscv-hardware-shadow-stack=true ? + const FeatureBitset &Features = STI.getFeatureBits(); + if (Features[RISCV::FeatureStdExtZicfilp]) + GNUNoteFlags |= ELF::GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP; + + if (Features[RISCV::FeatureStdExtZicfiss]) + GNUNoteFlags |= ELF::GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS; + + emitNoteSection(GNUNoteFlags); } void RISCVTargetELFStreamer::reset() { diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h index a6f54bf67b5d2b..595dc777c30c4a 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -71,6 +71,7 @@ class RISCVTargetELFStreamer : public RISCVTargetStreamer { void emitDirectiveVariantCC(MCSymbol &Symbol) override; void finish() override; + void emitNoteSection(unsigned Flags); }; MCELFStreamer *createRISCVELFStreamer(MCContext &C, >From aaff466a9eda11142f558165ad1d5cb87210dcc4 Mon Sep 17 00:00:00 2001 From: SuHsien Ho <su-hsien...@mediatek.com> Date: Thu, 23 Nov 2023 16:37:08 +0800 Subject: [PATCH 3/5] [LLD] Emit .note.gnu.property in RISCV for Zicfiss/Zicfilip(CFI extension) --- lld/ELF/Driver.cpp | 2 +- lld/ELF/InputFiles.cpp | 15 ++++++++++++--- lld/ELF/SyntheticSections.cpp | 15 ++++++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 4bb9b7a0b2a983..7f97a3be07ab8f 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -2570,7 +2570,7 @@ static void checkAndReportMissingFeature(StringRef config, uint32_t features, // GNU_PROPERTY_AARCH64_FEATURE_1_AND mechanism. static uint32_t getAndFeatures() { if (config->emachine != EM_386 && config->emachine != EM_X86_64 && - config->emachine != EM_AARCH64) + config->emachine != EM_AARCH64 && config->emachine != EM_RISCV) return 0; uint32_t ret = -1; diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 00aebb47640e84..5324c7b95935a8 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -926,9 +926,18 @@ template <class ELFT> static uint32_t readAndFeatures(const InputSection &sec) { continue; } - uint32_t featureAndType = config->emachine == EM_AARCH64 - ? GNU_PROPERTY_AARCH64_FEATURE_1_AND - : GNU_PROPERTY_X86_FEATURE_1_AND; + uint32_t featureAndType = 0; + switch (config->emachine) { + default: + featureAndType = GNU_PROPERTY_X86_FEATURE_1_AND; + break; + case EM_AARCH64: + featureAndType = GNU_PROPERTY_AARCH64_FEATURE_1_AND; + break; + case EM_RISCV: + featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; + break; + } // Read a body of a NOTE record, which consists of type-length-value fields. ArrayRef<uint8_t> desc = note.getDesc(sec.addralign); diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index bada394aa30d7d..1065e5c5be6e14 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -314,9 +314,18 @@ GnuPropertySection::GnuPropertySection() config->wordsize, ".note.gnu.property") {} void GnuPropertySection::writeTo(uint8_t *buf) { - uint32_t featureAndType = config->emachine == EM_AARCH64 - ? GNU_PROPERTY_AARCH64_FEATURE_1_AND - : GNU_PROPERTY_X86_FEATURE_1_AND; + uint32_t featureAndType = 0; + switch (config->emachine) { + default: + featureAndType = GNU_PROPERTY_X86_FEATURE_1_AND; + break; + case EM_AARCH64: + featureAndType = GNU_PROPERTY_AARCH64_FEATURE_1_AND; + break; + case EM_RISCV: + featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; + break; + } write32(buf, 4); // Name size write32(buf + 4, config->is64 ? 16 : 12); // Content size >From 9b394009151b1932f4d54bde78ee67d46c9b4129 Mon Sep 17 00:00:00 2001 From: SuHsien Ho <su-hsien...@mediatek.com> Date: Thu, 23 Nov 2023 18:21:01 +0800 Subject: [PATCH 4/5] [llvm-readobj] Parse .note.gnu.property in RISCV for Zicfiss/Zicfilip(CFI extension) --- clang/test/Driver/riscv-cfi-property.c | 32 ++++++++++ llvm/tools/llvm-readobj/ELFDumper.cpp | 81 +++++++++++++++++++++----- 2 files changed, 98 insertions(+), 15 deletions(-) create mode 100644 clang/test/Driver/riscv-cfi-property.c diff --git a/clang/test/Driver/riscv-cfi-property.c b/clang/test/Driver/riscv-cfi-property.c new file mode 100644 index 00000000000000..f6d97ce52b5506 --- /dev/null +++ b/clang/test/Driver/riscv-cfi-property.c @@ -0,0 +1,32 @@ +// When -march with zicfiss0p4 or zicfilp0p4 add GNU property to file object + +// RUN: %clang -menable-experimental-extensions -march=rv32gc_zicfiss0p4 -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFISS %s +// RUN: %clang -menable-experimental-extensions -march=rv64gc_zicfiss0p4 -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFISS %s +// RUN: %clang -menable-experimental-extensions -march=rv32gc_zicfilp0p4 -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP %s +// RUN: %clang -menable-experimental-extensions -march=rv64gc_zicfilp0p4 -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP %s +// RUN: %clang -menable-experimental-extensions -march=rv32gc_zicfilp0p4_zicfiss0p4 -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP_ZICFISS %s +// RUN: %clang -menable-experimental-extensions -march=rv64gc_zicfilp0p4_zicfiss0p4 -c -o - %s | llvm-readobj -n - | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP_ZICFISS %s + + +// CHECK: Name: .note.gnu.property +// CHECK: Type: NT_GNU_PROPERTY_TYPE_0 +// CHECK: Property [ +// CHECK_ZICFISS: riscv feature: ZICFISS +// CHECK_ZICFILP: riscv feature: ZICFILP +// CHECK_ZICFILP_ZICFISS: riscv feature: ZICFILP, ZICFISS +// CHECK: ] + + + + + +/*.section .note.gnu.property, "a"; +.balign 8; +.long 0x4; +.long 0x10; +.long 0x5 +.asciz "GNU" +.long 0xc0000000 +.long 4 +.long 3 +.long 0*/ diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 50ea63e87a43be..0c058db1ce1e2f 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -5094,7 +5094,7 @@ template <class ELFT> void GNUELFDumper<ELFT>::printAddrsig() { template <typename ELFT> static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, - ArrayRef<uint8_t> Data) { + ArrayRef<uint8_t> Data, uint16_t Target) { std::string str; raw_string_ostream OS(str); uint32_t PrData; @@ -5127,8 +5127,30 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, return OS.str(); case GNU_PROPERTY_AARCH64_FEATURE_1_AND: case GNU_PROPERTY_X86_FEATURE_1_AND: - OS << ((Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) ? "aarch64 feature: " - : "x86 feature: "); + + if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { + if (Target == ELF::EM_RISCV) + OS << "riscv feature: "; + else + OS << "aarch64 feature: "; + } else { + OS << "x86 feature: "; + } + // TODO Should we spilt + // GNU_PROPERTY_AARCH64_FEATURE_1_AND and + // GNU_PROPERTY_RISCV_FEATURE_1_AND to different label ? + /*switch (Type) { + default: + OS << "x86 feature: "; + break; + case GNU_PROPERTY_AARCH64_FEATURE_1_AND: + OS << "aarch64 feature: "; + break; + case GNU_PROPERTY_RISCV_FEATURE_1_AND: + OS << "riscv feature: "; + break; + }*/ + if (DataSize != 4) { OS << format("<corrupt length: 0x%x>", DataSize); return OS.str(); @@ -5138,14 +5160,39 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, OS << "<None>"; return OS.str(); } + if (Type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { - DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"); - DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"); - DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS"); + if (Target == ELF::EM_RISCV) { + DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP, "ZICFILP"); + DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS, "ZICFISS"); + } else { + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"); + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"); + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_GCS, "GCS"); + } } else { DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT"); DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK"); } + + // TODO Should we spilt + // GNU_PROPERTY_AARCH64_FEATURE_1_AND and + // GNU_PROPERTY_RISCV_FEATURE_1_AND to different label ? + /*switch (Type) { + default: + DumpBit(GNU_PROPERTY_X86_FEATURE_1_IBT, "IBT"); + DumpBit(GNU_PROPERTY_X86_FEATURE_1_SHSTK, "SHSTK"); + break; + case GNU_PROPERTY_AARCH64_FEATURE_1_AND: + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_BTI, "BTI"); + DumpBit(GNU_PROPERTY_AARCH64_FEATURE_1_PAC, "PAC"); + break; + case GNU_PROPERTY_RISCV_FEATURE_1_AND: + DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP, "ZICFILP"); + DumpBit(GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS, "ZICFISS"); + break; + }*/ + if (PrData) OS << format("<unknown flags: 0x%x>", PrData); return OS.str(); @@ -5199,7 +5246,8 @@ static std::string getGNUProperty(uint32_t Type, uint32_t DataSize, } template <typename ELFT> -static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr) { +static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr, + uint16_t Target) { using Elf_Word = typename ELFT::Word; SmallVector<std::string, 4> Properties; @@ -5217,8 +5265,8 @@ static SmallVector<std::string, 4> getGNUPropertyList(ArrayRef<uint8_t> Arr) { Properties.push_back(OS.str()); break; } - Properties.push_back( - getGNUProperty<ELFT>(Type, DataSize, Arr.take_front(PaddedSize))); + Properties.push_back(getGNUProperty<ELFT>( + Type, DataSize, Arr.take_front(PaddedSize), Target)); Arr = Arr.drop_front(PaddedSize); } @@ -5270,7 +5318,7 @@ static StringRef getDescAsStringRef(ArrayRef<uint8_t> Desc) { template <typename ELFT> static bool printGNUNote(raw_ostream &OS, uint32_t NoteType, - ArrayRef<uint8_t> Desc) { + ArrayRef<uint8_t> Desc, uint16_t Target) { // Return true if we were able to pretty-print the note, false otherwise. switch (NoteType) { default: @@ -5292,7 +5340,7 @@ static bool printGNUNote(raw_ostream &OS, uint32_t NoteType, break; case ELF::NT_GNU_PROPERTY_TYPE_0: OS << " Properties:"; - for (const std::string &Property : getGNUPropertyList<ELFT>(Desc)) + for (const std::string &Property : getGNUPropertyList<ELFT>(Desc, Target)) OS << " " << Property << "\n"; break; } @@ -6012,10 +6060,12 @@ template <class ELFT> void GNUELFDumper<ELFT>::printNotes() { else OS << "Unknown note type: (" << format_hex(Type, 10) << ")\n"; + uint16_t Target = this->Obj.getHeader().e_machine; + // Print the description, or fallback to printing raw bytes for unknown // owners/if we fail to pretty-print the contents. if (Name == "GNU") { - if (printGNUNote<ELFT>(OS, Type, Descriptor)) + if (printGNUNote<ELFT>(OS, Type, Descriptor, Target)) return Error::success(); } else if (Name == "FreeBSD") { if (std::optional<FreeBSDNote> N = @@ -7642,7 +7692,7 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printAddrsig() { template <typename ELFT> static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc, - ScopedPrinter &W) { + ScopedPrinter &W, uint16_t Target) { // Return true if we were able to pretty-print the note, false otherwise. switch (NoteType) { default: @@ -7667,7 +7717,7 @@ static bool printGNUNoteLLVMStyle(uint32_t NoteType, ArrayRef<uint8_t> Desc, break; case ELF::NT_GNU_PROPERTY_TYPE_0: ListScope D(W, "Property"); - for (const std::string &Property : getGNUPropertyList<ELFT>(Desc)) + for (const std::string &Property : getGNUPropertyList<ELFT>(Desc, Target)) W.printString(Property); break; } @@ -7803,10 +7853,11 @@ template <class ELFT> void LLVMELFDumper<ELFT>::printNotes() { W.printString("Type", "Unknown (" + to_string(format_hex(Type, 10)) + ")"); + uint16_t Target = this->Obj.getHeader().e_machine; // Print the description, or fallback to printing raw bytes for unknown // owners/if we fail to pretty-print the contents. if (Name == "GNU") { - if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W)) + if (printGNUNoteLLVMStyle<ELFT>(Type, Descriptor, W, Target)) return Error::success(); } else if (Name == "FreeBSD") { if (std::optional<FreeBSDNote> N = >From de7f32f29f9b3b1ae9ae9d7b87b146598f9671a8 Mon Sep 17 00:00:00 2001 From: SuHsien Ho <su-hsien...@mediatek.com> Date: Thu, 23 Nov 2023 19:04:26 +0800 Subject: [PATCH 5/5] [LLD] Add force enable Zicfiss/Zicfilip(CFI extension) option --- lld/ELF/Config.h | 4 +++ lld/ELF/Driver.cpp | 40 ++++++++++++++++++++++++- lld/test/ELF/riscv-force-cfi-property.s | 35 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/riscv-force-cfi-property.s diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index fcca8c42b29b71..552a5060452729 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -187,6 +187,8 @@ struct Config { llvm::StringRef cmseOutputLib; StringRef zBtiReport = "none"; StringRef zCetReport = "none"; + llvm::StringRef zZicfilpReport = "none"; + llvm::StringRef zZicfissReport = "none"; bool ltoBBAddrMap; llvm::StringRef ltoBasicBlockSections; std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace; @@ -324,6 +326,8 @@ struct Config { bool zText; bool zRetpolineplt; bool zWxneeded; + bool zForceZicfilp; + bool zForceZicfiss; DiscardPolicy discard; GnuStackKind zGnustack; ICFLevel icf; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 7f97a3be07ab8f..1791d275a4d00c 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -463,6 +463,13 @@ static void checkOptions() { error("-z bti-report only supported on AArch64"); } + if (config->emachine != EM_RISCV) { + if (config->zZicfilpReport != "none") + error("-z zicfilip-report only support on RISCV32/RISCV64"); + if (config->zZicfissReport != "none") + error("-z zicfiss-report only support on RISCV32/RISCV64"); + } + if (config->emachine != EM_386 && config->emachine != EM_X86_64 && config->zCetReport != "none") error("-z cet-report only supported on X86 and X86_64"); @@ -1455,6 +1462,8 @@ static void readConfigs(opt::InputArgList &args) { config->zWxneeded = hasZOption(args, "wxneeded"); setUnresolvedSymbolPolicy(args); config->power10Stubs = args.getLastArgValue(OPT_power10_stubs_eq) != "no"; + config->zForceZicfilp = hasZOption(args, "force-zicfilp"); + config->zForceZicfiss = hasZOption(args, "force-zicfiss"); if (opt::Arg *arg = args.getLastArg(OPT_eb, OPT_el)) { if (arg->getOption().matches(OPT_eb)) @@ -1497,7 +1506,9 @@ static void readConfigs(opt::InputArgList &args) { } auto reports = {std::make_pair("bti-report", &config->zBtiReport), - std::make_pair("cet-report", &config->zCetReport)}; + std::make_pair("cet-report", &config->zCetReport), + std::make_pair("zicfilp-report", &config->zZicfilpReport), + std::make_pair("zicfiss-report", &config->zZicfissReport)}; for (opt::Arg *arg : args.filtered(OPT_z)) { std::pair<StringRef, StringRef> option = StringRef(arg->getValue()).split('='); @@ -2592,6 +2603,16 @@ static uint32_t getAndFeatures() { toString(f) + ": -z cet-report: file does not have " "GNU_PROPERTY_X86_FEATURE_1_SHSTK property"); + checkAndReportMissingFeature( + config->zZicfilpReport, features, GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP, + toString(f) + ": -z zicfilp-report: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP property"); + + checkAndReportMissingFeature( + config->zZicfissReport, features, GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS, + toString(f) + ": -z zicfiss-report: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS property"); + if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) { features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI; if (config->zBtiReport == "none") @@ -2604,6 +2625,23 @@ static uint32_t getAndFeatures() { "GNU_PROPERTY_X86_FEATURE_1_IBT property"); features |= GNU_PROPERTY_X86_FEATURE_1_IBT; } + + if (config->zForceZicfilp && + !(features & GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP)) { + features |= GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP; + if (config->zZicfilpReport == "none") + warn(toString(f) + ": -z force-zicfilp: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_ZICFILP property"); + } + + if (config->zForceZicfiss && + !(features & GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS)) { + features |= GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS; + if (config->zZicfissReport == "none") + warn(toString(f) + ": -z force-zicfiss: file does not have " + "GNU_PROPERTY_RISCV_FEATURE_1_ZICFISS property"); + } + if (config->zPacPlt && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) { warn(toString(f) + ": -z pac-plt: file does not have " "GNU_PROPERTY_AARCH64_FEATURE_1_PAC property"); diff --git a/lld/test/ELF/riscv-force-cfi-property.s b/lld/test/ELF/riscv-force-cfi-property.s new file mode 100644 index 00000000000000..65043d1e71261e --- /dev/null +++ b/lld/test/ELF/riscv-force-cfi-property.s @@ -0,0 +1,35 @@ +# REQUIRES: riscv + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf %s -o %t.rv32_lp.o +# RUN: ld.lld %t.rv32_lp.o -zforce-zicfilp -o %t.rv32_lp | count 0 +# RUN: llvm-readobj -n %t.rv32_lp | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf %s -o %t.rv64_lp.o +# RUN: ld.lld %t.rv64_lp.o -zforce-zicfilp -o %t.rv64_lp | count 0 +# RUN: llvm-readobj -n %t.rv64_lp | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP %s + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf %s -o %t.rv32_ss.o +# RUN: ld.lld %t.rv32_ss.o -zforce-zicfiss -o %t.rv32_ss | count 0 +# RUN: llvm-readobj -n %t.rv32_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFISS %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf %s -o %t.rv64_ss.o +# RUN: ld.lld %t.rv64_ss.o -zforce-zicfiss -o %t.rv64_ss | count 0 +# RUN: llvm-readobj -n %t.rv64_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFISS %s + +# RUN: llvm-mc -filetype=obj -triple=riscv32-unknown-elf %s -o %t.rv32_lp_ss.o +# RUN: ld.lld %t.rv32_lp_ss.o -zforce-zicfilp -zforce-zicfiss -o %t.rv32_lp_ss | count 0 +# RUN: llvm-readobj -n %t.rv32_lp_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP_ZICFISS %s + +# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf %s -o %t.rv64_lp_ss.o +# RUN: ld.lld %t.rv64_lp_ss.o -zforce-zicfilp -zforce-zicfiss -o %t.rv64_lp_ss | count 0 +# RUN: llvm-readobj -n %t.rv64_lp_ss | FileCheck -check-prefix=CHECK -check-prefix=CHECK_ZICFILP_ZICFISS %s + + + +// CHECK: Name: .note.gnu.property +// CHECK: Type: NT_GNU_PROPERTY_TYPE_0 +// CHECK: Property [ +// CHECK_ZICFISS: riscv feature: ZICFISS +// CHECK_ZICFILP: riscv feature: ZICFILP +// CHECK_ZICFILP_ZICFISS: riscv feature: ZICFILP, ZICFISS +// CHECK: ] _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits