[clang] [libcxx] [libcxxabi] [lld] [llvm] Support .note.gnu.property for enable Zicfiss and Zicfilp extension (PR #77414)

via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 15 00:33:20 PST 2024


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.ho at mediatek.com>
Date: Thu, 23 Nov 2023 14:36:43 +0800
Subject: [PATCH 1/6] [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.ho at mediatek.com>
Date: Thu, 23 Nov 2023 14:38:34 +0800
Subject: [PATCH 2/6] [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.ho at mediatek.com>
Date: Thu, 23 Nov 2023 16:37:08 +0800
Subject: [PATCH 3/6] [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 5a3db4fdb2c95b597b3d2f7e734b72c2955f371c Mon Sep 17 00:00:00 2001
From: SuHsien Ho <su-hsien.ho at mediatek.com>
Date: Thu, 23 Nov 2023 18:21:01 +0800
Subject: [PATCH 4/6] [llvm-readobj] Parse .note.gnu.property in RISCV for
 Zicfiss/Zicfilip(CFI extension)

---
 clang/test/Driver/riscv-cfi-property.c | 30 ++++++++++++++++
 llvm/tools/llvm-readobj/ELFDumper.cpp  | 49 ++++++++++++++++++--------
 2 files changed, 64 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..6afd31dca02d86
--- /dev/null
+++ b/clang/test/Driver/riscv-cfi-property.c
@@ -0,0 +1,30 @@
+// REQUIRES: riscv-registered-target
+// 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: ]
+
+// GNU Note Section Example
+/*.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..a6840b6370ed5b 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,16 @@ 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: ";
+    }
+
     if (DataSize != 4) {
       OS << format("<corrupt length: 0x%x>", DataSize);
       return OS.str();
@@ -5138,14 +5146,21 @@ 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");
     }
+
     if (PrData)
       OS << format("<unknown flags: 0x%x>", PrData);
     return OS.str();
@@ -5199,7 +5214,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 +5233,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 +5286,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 +5308,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 +6028,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 +7660,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 +7685,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 +7821,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 319c5476c7d585037cbc9c097be0621cae8475ab Mon Sep 17 00:00:00 2001
From: SuHsien Ho <su-hsien.ho at mediatek.com>
Date: Thu, 23 Nov 2023 19:04:26 +0800
Subject: [PATCH 5/6] [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: ]

>From 6c7684eaee8d8ee27d20f7213f7c99b6d76b9b08 Mon Sep 17 00:00:00 2001
From: SuHsien Ho <su-hsien.ho at mediatek.com>
Date: Thu, 15 Feb 2024 16:31:47 +0800
Subject: [PATCH 6/6] temp

---
 libcxx/CMakeLists.txt    | 6 +++---
 libcxxabi/CMakeLists.txt | 4 ++--
 llvm/CMakeLists.txt      | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
index d392e95077ac57..b6a3f9ab0f183c 100644
--- a/libcxx/CMakeLists.txt
+++ b/libcxx/CMakeLists.txt
@@ -52,14 +52,14 @@ option(LIBCXX_ENABLE_ASSERTIONS
   "Enable assertions inside the compiled library, and at the same time make it the
    default when compiling user code. Note that assertions can be enabled or disabled
    by users in their own code regardless of this option." OFF)
-option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON)
+option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." OFF)
 option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON)
 option(LIBCXX_ENABLE_FILESYSTEM
   "Whether to include support for parts of the library that rely on a filesystem being
    available on the platform. This includes things like most parts of <filesystem> and
    others like <fstream>" ON)
 option(LIBCXX_INCLUDE_TESTS "Build the libc++ tests." ${LLVM_INCLUDE_TESTS})
-set(LIBCXX_SUPPORTED_HARDENING_MODES none fast extensive debug)
+set(LIBCXX_SUPPORTED_HARDENING_MODES none fast extensive debug unchecked)
 set(LIBCXX_HARDENING_MODE "none" CACHE STRING
   "Specify the default hardening mode to use. This mode will be used inside the
    compiled library and will be the default when compiling user code. Note that
@@ -291,7 +291,7 @@ option(LIBCXX_ENABLE_EXCEPTIONS "Use exceptions." ON)
 option(LIBCXX_ENABLE_RTTI
   "Use runtime type information.
    This option may only be set to OFF when LIBCXX_ENABLE_EXCEPTIONS=OFF." ON)
-option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." ON)
+option(LIBCXX_ENABLE_THREADS "Build libc++ with support for threads." OFF)
 option(LIBCXX_ENABLE_MONOTONIC_CLOCK
   "Build libc++ with support for a monotonic clock.
    This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON)
diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt
index da998d2221dc4f..8c4313717223eb 100644
--- a/libcxxabi/CMakeLists.txt
+++ b/libcxxabi/CMakeLists.txt
@@ -52,7 +52,7 @@ if (LIBCXXABI_USE_LLVM_UNWINDER AND NOT "libunwind" IN_LIST LLVM_ENABLE_RUNTIMES
 endif()
 option(LIBCXXABI_ENABLE_STATIC_UNWINDER "Statically link the LLVM unwinder." OFF)
 option(LIBCXXABI_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)
-option(LIBCXXABI_ENABLE_THREADS "Build with threads enabled" ON)
+option(LIBCXXABI_ENABLE_THREADS "Build with threads enabled" OFF)
 option(LIBCXXABI_HAS_PTHREAD_API "Ignore auto-detection and force use of pthread API" OFF)
 option(LIBCXXABI_HAS_WIN32_THREAD_API "Ignore auto-detection and force use of win32 thread API" OFF)
 option(LIBCXXABI_HAS_EXTERNAL_THREAD_API
@@ -102,7 +102,7 @@ usual symlinks pointing to that.")
 # the libc++abi that is being built. The problem with testing a static libc++abi
 # is that libc++ will prefer a dynamic libc++abi from the system over a static
 # libc++abi from the output directory.
-option(LIBCXXABI_ENABLE_SHARED "Build libc++abi as a shared library." ON)
+option(LIBCXXABI_ENABLE_SHARED "Build libc++abi as a shared library." OFF)
 option(LIBCXXABI_ENABLE_STATIC "Build libc++abi as a static library." ON)
 
 cmake_dependent_option(LIBCXXABI_INSTALL_STATIC_LIBRARY
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index a760a19efcb6b1..f43fe582c67805 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -155,7 +155,7 @@ endif()
 #
 # As we migrate runtimes to using the bootstrapping build, the set of default runtimes
 # should grow as we remove those runtimes from LLVM_ENABLE_PROJECTS above.
-set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind")
+#set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind")
 set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc")
 set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
   "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")



More information about the cfe-commits mailing list