diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 2b72d54ba410d..71c17016d92c0 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -259,8 +259,11 @@ struct Config { ReportPolicy zGcsReportDynamic = ReportPolicy::None; ReportPolicy zExecuteOnlyReport = ReportPolicy::None; ReportPolicy zZicfilpUnlabeledReport = ReportPolicy::None; + ReportPolicy zZicfilpUnlabeledReportDynamic = ReportPolicy::None; ReportPolicy zZicfilpFuncSigReport = ReportPolicy::None; + ReportPolicy zZicfilpFuncSigReportDynamic = ReportPolicy::None; ReportPolicy zZicfissReport = ReportPolicy::None; + ReportPolicy zZicfissReportDynamic = ReportPolicy::None; bool ltoBBAddrMap; llvm::StringRef ltoBasicBlockSections; std::pair thinLTOObjectSuffixReplace; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 7e132a387a04d..65ff789fdf02d 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -65,6 +65,7 @@ #include "llvm/Support/TargetSelect.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/raw_ostream.h" +#include #include #include #include @@ -425,11 +426,20 @@ static void checkOptions(Ctx &ctx) { if (ctx.arg.zZicfilpUnlabeledReport != ReportPolicy::None) ErrAlways(ctx) << "-z zicfilip-unlabeled-report is only supported on " "RISC-V targets"; + if (ctx.arg.zZicfilpUnlabeledReportDynamic != ReportPolicy::None) + ErrAlways(ctx) << "-z zicfilip-unlabeled-report-dynamic is only supported" + " on RISC-V targets"; if (ctx.arg.zZicfilpFuncSigReport != ReportPolicy::None) ErrAlways(ctx) << "-z zicfilip-func-sig-report is only supported on " "RISC-V targets"; + if (ctx.arg.zZicfilpFuncSigReportDynamic != ReportPolicy::None) + ErrAlways(ctx) << "-z zicfilip-func-sig-report-dynamic is only supported " + "on RISC-V targets"; if (ctx.arg.zZicfissReport != ReportPolicy::None) ErrAlways(ctx) << "-z zicfiss-report is only supported on RISC-V targets"; + if (ctx.arg.zZicfissReportDynamic != ReportPolicy::None) + ErrAlways(ctx) << "-z zicfiss-report-dynamic is only supported on RISC-V " + "targets"; if (ctx.arg.zZicfilp != ZicfilpPolicy::Implicit) ErrAlways(ctx) << "-z zicfilp is only supported on RISC-V targets"; if (ctx.arg.zZicfiss != ZicfissPolicy::Implicit) @@ -1686,45 +1696,90 @@ static void readConfigs(Ctx &ctx, opt::InputArgList &args) { ErrAlways(ctx) << errPrefix << pat.takeError() << ": " << kv.first; } - auto reports = { - std::make_pair("bti-report", &ctx.arg.zBtiReport), - std::make_pair("cet-report", &ctx.arg.zCetReport), - std::make_pair("execute-only-report", &ctx.arg.zExecuteOnlyReport), - std::make_pair("gcs-report", &ctx.arg.zGcsReport), - std::make_pair("gcs-report-dynamic", &ctx.arg.zGcsReportDynamic), - std::make_pair("pauth-report", &ctx.arg.zPauthReport), - std::make_pair("zicfilp-unlabeled-report", - &ctx.arg.zZicfilpUnlabeledReport), - std::make_pair("zicfilp-func-sig-report", &ctx.arg.zZicfilpFuncSigReport), - std::make_pair("zicfiss-report", &ctx.arg.zZicfissReport)}; bool hasGcsReportDynamic = false; + bool hasZicfilpUnlabeledReportDynamic = false; + bool hasZicfilpFuncSigReportDynamic = false; + bool hasZicfissReportDynamic = false; + struct ReportOptDesc { + const StringRef name; + ReportPolicy &policy; + bool *const seen; + + ReportOptDesc(const StringRef name, ReportPolicy &policy, bool *seen) + : name(name), policy(policy), seen(seen) {} + }; + // Sort the descriptions by name according to StringRef::compare() so we can + // binary search it + ReportOptDesc reports[] = { + {{"bti-report"}, ctx.arg.zBtiReport, nullptr}, + {{"cet-report"}, ctx.arg.zCetReport, nullptr}, + {{"execute-only-report"}, ctx.arg.zExecuteOnlyReport, nullptr}, + {{"gcs-report"}, ctx.arg.zGcsReport, nullptr}, + {{"gcs-report-dynamic"}, ctx.arg.zGcsReportDynamic, &hasGcsReportDynamic}, + {{"pauth-report"}, ctx.arg.zPauthReport, nullptr}, + {{"zicfilp-func-sig-report"}, ctx.arg.zZicfilpFuncSigReport, nullptr}, + {{"zicfilp-func-sig-report-dynamic"}, + ctx.arg.zZicfilpFuncSigReportDynamic, + &hasZicfilpFuncSigReportDynamic}, + {{"zicfilp-unlabeled-report"}, ctx.arg.zZicfilpUnlabeledReport, nullptr}, + {{"zicfilp-unlabeled-report-dynamic"}, + ctx.arg.zZicfilpUnlabeledReportDynamic, + &hasZicfilpUnlabeledReportDynamic}, + {{"zicfiss-report"}, ctx.arg.zZicfissReport, nullptr}, + {{"zicfiss-report-dynamic"}, + ctx.arg.zZicfissReportDynamic, + &hasZicfissReportDynamic}}; for (opt::Arg *arg : args.filtered(OPT_z)) { std::pair option = StringRef(arg->getValue()).split('='); - for (auto reportArg : reports) { - if (option.first != reportArg.first) - continue; - arg->claim(); - if (option.second == "none") - *reportArg.second = ReportPolicy::None; - else if (option.second == "warning") - *reportArg.second = ReportPolicy::Warning; - else if (option.second == "error") - *reportArg.second = ReportPolicy::Error; - else { - ErrAlways(ctx) << "unknown -z " << reportArg.first - << "= value: " << option.second; - continue; - } - hasGcsReportDynamic |= option.first == "gcs-report-dynamic"; + ReportOptDesc *const desc = std::lower_bound( + std::begin(reports), std::end(reports), option.first, + [](const ReportOptDesc &d, const StringRef &s) { return d.name < s; }); + if (desc == std::end(reports) || desc->name != option.first) + continue; + + arg->claim(); + if (option.second == "none") + desc->policy = ReportPolicy::None; + else if (option.second == "warning") + desc->policy = ReportPolicy::Warning; + else if (option.second == "error") + desc->policy = ReportPolicy::Error; + else { + ErrAlways(ctx) << "unknown -z " << desc->name + << "= value: " << option.second; + continue; } + if (desc->seen) + *desc->seen = true; } - // When -zgcs-report-dynamic is unspecified, it inherits -zgcs-report - // but is capped at warning to avoid needing to rebuild the shared library - // with GCS enabled. - if (!hasGcsReportDynamic && ctx.arg.zGcsReport != ReportPolicy::None) - ctx.arg.zGcsReportDynamic = ReportPolicy::Warning; + struct ReportDynamicOptDesc { + ReportPolicy &dynamicPolicy; + const ReportPolicy objectPolicy; + const bool seenDynamicPolicy; + + ReportDynamicOptDesc(ReportPolicy &dynamicPolicy, + const ReportPolicy objectPolicy, + const bool seenDynamicPolicy) + : dynamicPolicy(dynamicPolicy), objectPolicy(objectPolicy), + seenDynamicPolicy(seenDynamicPolicy) {} + }; + const ReportDynamicOptDesc reportDynamics[] = { + {ctx.arg.zGcsReportDynamic, ctx.arg.zGcsReport, hasGcsReportDynamic}, + {ctx.arg.zZicfilpUnlabeledReportDynamic, ctx.arg.zZicfilpUnlabeledReport, + hasZicfilpUnlabeledReportDynamic}, + {ctx.arg.zZicfilpFuncSigReportDynamic, ctx.arg.zZicfilpFuncSigReport, + hasZicfilpFuncSigReportDynamic}, + {ctx.arg.zZicfissReportDynamic, ctx.arg.zZicfissReport, + hasZicfissReportDynamic}}; + for (const ReportDynamicOptDesc &desc : reportDynamics) { + // When -z xxx-report-dynamic is unspecified, it inherits -z xxx-report + // but is capped at warning to avoid needing to rebuild the shared library + // with XXX enabled. + if (!desc.seenDynamicPolicy && desc.objectPolicy != ReportPolicy::None) + desc.dynamicPolicy = ReportPolicy::Warning; + } for (opt::Arg *arg : args.filtered(OPT_compress_sections)) { SmallVector fields; @@ -3066,13 +3121,15 @@ static void readSecurityNotes(Ctx &ctx) { ctx.arg.andFeatures &= ~GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS; } - // If we are utilising GCS at any stage, the sharedFiles should be checked to - // ensure they also support this feature. The gcs-report-dynamic option is - // used to indicate if the user wants information relating to this, and will - // be set depending on the user's input, or warning if gcs-report is set to - // either `warning` or `error`. - if (ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_GCS) - for (SharedFile *f : ctx.sharedFiles) + // If we are utilising AArch64 GCS/RISC-V ZICFILP-unlabeled/RISC-V + // ZICFILP-func-sig/RISC-V ZICFISS at any stage, the sharedFiles should be + // checked to ensure they also support this feature. The -z xxx-report-dynamic + // option is used to indicate if the user wants information relating to this, + // and will be set depending on the user's input, or warning if -z xxx-report + // is set to either `warning` or `error`. + for (SharedFile *f : ctx.sharedFiles) { + if (ctx.arg.emachine == EM_AARCH64 && + (ctx.arg.andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_GCS)) reportUnless(ctx.arg.zGcsReportDynamic, f->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_GCS) << f @@ -3081,6 +3138,44 @@ static void readSecurityNotes(Ctx &ctx) { << "dynamic loader might not enable GCS or refuse to load the " "program unless all shared library " << "dependencies have the GCS marking."; + + if (ctx.arg.emachine == EM_RISCV) { + if (ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) + reportUnless(ctx.arg.zZicfilpUnlabeledReportDynamic, + f->andFeatures & + GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED) + << f << ": " << "ZICFILP-unlabeled" + << " is enabled, but this shared library lacks the necessary " + "property note. The dynamic loader might not enable " + << "ZICFILP-unlabeled" + << " or refuse to load the program unless all shared library " + "dependencies have the " + << "ZICFILP-unlabeled" << " marking."; + + if (ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG) + reportUnless(ctx.arg.zZicfilpFuncSigReportDynamic, + f->andFeatures & + GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG) + << f << ": " << "ZICFILP-func-sig" + << " is enabled, but this shared library lacks the necessary " + "property note. The dynamic loader might not enable " + << "ZICFILP-func-sig" + << " or refuse to load the program unless all shared library " + "dependencies have the " + << "ZICFILP-func-sig" << " marking."; + + if (ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) + reportUnless(ctx.arg.zZicfissReportDynamic, + f->andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS) + << f << ": " << "ZICFISS" + << " is enabled, but this shared library lacks the necessary " + "property note. The dynamic loader might not enable " + << "ZICFISS" + << " or refuse to load the program unless all shared library " + "dependencies have the " + << "ZICFISS" << " marking."; + } + } } static void initSectionsAndLocalSyms(ELFFileBase *file, bool ignoreComdats) { diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 71e72e7184b9f..08027408e1fd0 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -1450,8 +1450,17 @@ std::vector SharedFile::parseVerneed(const ELFFile &obj, // readGnuProperty, but we don't have the InputSection information. template void SharedFile::parseGnuAndFeatures(const ELFFile &obj) { - if (ctx.arg.emachine != EM_AARCH64) + unsigned featureAndType; + switch (ctx.arg.emachine) { + case EM_AARCH64: + featureAndType = GNU_PROPERTY_AARCH64_FEATURE_1_AND; + break; + case EM_RISCV: + featureAndType = GNU_PROPERTY_RISCV_FEATURE_1_AND; + break; + default: return; + } const uint8_t *base = obj.base(); auto phdrs = CHECK2(obj.program_headers(), this); for (auto phdr : phdrs) { @@ -1463,8 +1472,7 @@ void SharedFile::parseGnuAndFeatures(const ELFFile &obj) { continue; ArrayRef desc = note.getDesc(phdr.p_align); - parseGnuPropertyNote(ctx, *this, GNU_PROPERTY_AARCH64_FEATURE_1_AND, - desc, base); + parseGnuPropertyNote(ctx, *this, featureAndType, desc, base); } } diff --git a/lld/test/ELF/riscv-feature-zicfilp-func-sig.s b/lld/test/ELF/riscv-feature-zicfilp-func-sig.s index c5818dd33978f..c2f3c064b19b5 100644 --- a/lld/test/ELF/riscv-feature-zicfilp-func-sig.s +++ b/lld/test/ELF/riscv-feature-zicfilp-func-sig.s @@ -51,9 +51,24 @@ # REPORT-WARN: warning: f2.o: -z zicfilp-func-sig-report: file does not have GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG property # REPORT-ERROR: error: f3.o: -z zicfilp-func-sig-report: file does not have GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_FUNC_SIG property +## zicfilp-func-sig-report-dynamic should report any dynamic objects that does +## not have the ZICFILP-func-sig property. This also ensures the inhertance from +## zicfilp-func-sig-report is working correctly. +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-func-sig-report=warning -z zicfilp=func-sig 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-func-sig-report=error -z zicfilp=func-sig 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-func-sig-report-dynamic=none -z zicfilp=func-sig 2>&1 | count 0 +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-func-sig-report-dynamic=warning -z zicfilp=func-sig 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: not ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-func-sig-report-dynamic=error -z zicfilp=func-sig 2>&1 | FileCheck --check-prefix=REPORT-ERROR-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.force.so -z zicfilp-func-sig-report-dynamic=error -z zicfilp=func-sig 2>&1 | count 0 +# REPORT-WARN-DYNAMIC: warning: out.no.so: ZICFILP-func-sig is enabled, but this shared library lacks the necessary property note. The dynamic loader might not enable ZICFILP-func-sig or refuse to load the program unless all shared library dependencies have the ZICFILP-func-sig marking. +# REPORT-WARN-DYNAMIC-NOT: {{.}} +# REPORT-ERROR-DYNAMIC: error: out.no.so: ZICFILP-func-sig is enabled, but this shared library lacks the necessary property note. The dynamic loader might not enable ZICFILP-func-sig or refuse to load the program unless all shared library dependencies have the ZICFILP-func-sig marking. +# REPORT-ERROR-DYNAMIC-NOT: error: + ## An invalid -z zicfilp-func-sig-report option should give an error -# RUN: not ld.lld f2-s.o -z zicfilp-func-sig-report=x 2>&1 | FileCheck --check-prefix=INVALID %s +# RUN: not ld.lld f2-s.o -z zicfilp-func-sig-report=x -z zicfilp-func-sig-report-dynamic=x 2>&1 | FileCheck --check-prefix=INVALID %s # INVALID: error: unknown -z zicfilp-func-sig-report= value: x +# INVALID: error: unknown -z zicfilp-func-sig-report-dynamic= value: x ## ZICFILP-unlabeled and ZICFILP-func-sig should conflict with each other. # RUN: ld.lld f3-u.o -o out.override -z zicfilp=func-sig 2>&1 | FileCheck --check-prefix=FORCE-CONFLICT %s diff --git a/lld/test/ELF/riscv-feature-zicfilp-unlabeled.s b/lld/test/ELF/riscv-feature-zicfilp-unlabeled.s index 20491f057c8ed..f06b3db2f6c2b 100644 --- a/lld/test/ELF/riscv-feature-zicfilp-unlabeled.s +++ b/lld/test/ELF/riscv-feature-zicfilp-unlabeled.s @@ -53,10 +53,25 @@ # REPORT-WARN: warning: f2.o: -z zicfilp-unlabeled-report: file does not have GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED property # REPORT-ERROR: error: f3.o: -z zicfilp-unlabeled-report: file does not have GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED property +## zicfilp-unlabeled-report-dynamic should report any dynamic objects that does +## not have the ZICFILP-unlabeled property. This also ensures the inhertance +## from zicfilp-unlabeled-report is working correctly. +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-unlabeled-report=warning -z zicfilp=unlabeled 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-unlabeled-report=error -z zicfilp=unlabeled 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-unlabeled-report-dynamic=none -z zicfilp=unlabeled 2>&1 | count 0 +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-unlabeled-report-dynamic=warning -z zicfilp=unlabeled 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: not ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfilp-unlabeled-report-dynamic=error -z zicfilp=unlabeled 2>&1 | FileCheck --check-prefix=REPORT-ERROR-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.force.so -z zicfilp-unlabeled-report-dynamic=error -z zicfilp=unlabeled 2>&1 | count 0 +# REPORT-WARN-DYNAMIC: warning: out.no.so: ZICFILP-unlabeled is enabled, but this shared library lacks the necessary property note. The dynamic loader might not enable ZICFILP-unlabeled or refuse to load the program unless all shared library dependencies have the ZICFILP-unlabeled marking. +# REPORT-WARN-DYNAMIC-NOT: {{.}} +# REPORT-ERROR-DYNAMIC: error: out.no.so: ZICFILP-unlabeled is enabled, but this shared library lacks the necessary property note. The dynamic loader might not enable ZICFILP-unlabeled or refuse to load the program unless all shared library dependencies have the ZICFILP-unlabeled marking. +# REPORT-ERROR-DYNAMIC-NOT: error: + ## An invalid -z zicfilp-unlabeled-report option should give an error -# RUN: not ld.lld f2-s.o -z zicfilp=x -z zicfilp-unlabeled-report=x 2>&1 | FileCheck --check-prefix=INVALID %s +# RUN: not ld.lld f2-s.o -z zicfilp=x -z zicfilp-unlabeled-report=x -z zicfilp-unlabeled-report-dynamic=x 2>&1 | FileCheck --check-prefix=INVALID %s # INVALID: error: unknown -z zicfilp= value: x # INVALID: error: unknown -z zicfilp-unlabeled-report= value: x +# INVALID: error: unknown -z zicfilp-unlabeled-report-dynamic= value: x ## ZICFILP-unlabeled and ZICFILP-func-sig should conflict with each other # RUN: not ld.lld f1-c.o 2>&1 | FileCheck --check-prefix=CONFLICT %s diff --git a/lld/test/ELF/riscv-feature-zicfiss.s b/lld/test/ELF/riscv-feature-zicfiss.s index 7b208ddd9b8eb..e0b82f19054b8 100644 --- a/lld/test/ELF/riscv-feature-zicfiss.s +++ b/lld/test/ELF/riscv-feature-zicfiss.s @@ -48,10 +48,25 @@ # REPORT-WARN: warning: f2.o: -z zicfiss-report: file does not have GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS property # REPORT-ERROR: error: f3.o: -z zicfiss-report: file does not have GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS property +## zicfiss-report-dynamic should report any dynamic objects that does not have +## the ZICFISS property. This also ensures the inhertance from zicfiss-report +## is working correctly. +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfiss-report=warning -z zicfiss=always 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfiss-report=error -z zicfiss=always 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfiss-report-dynamic=none -z zicfiss=always 2>&1 | count 0 +# RUN: ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfiss-report-dynamic=warning -z zicfiss=always 2>&1 | FileCheck --check-prefix=REPORT-WARN-DYNAMIC %s +# RUN: not ld.lld f1-s.o f3-s.o out.no.so out.force.so -z zicfiss-report-dynamic=error -z zicfiss=always 2>&1 | FileCheck --check-prefix=REPORT-ERROR-DYNAMIC %s +# RUN: ld.lld f1-s.o f3-s.o out.force.so -z zicfiss-report-dynamic=error -z zicfiss=always 2>&1 | count 0 +# REPORT-WARN-DYNAMIC: warning: out.no.so: ZICFISS is enabled, but this shared library lacks the necessary property note. The dynamic loader might not enable ZICFISS or refuse to load the program unless all shared library dependencies have the ZICFISS marking. +# REPORT-WARN-DYNAMIC-NOT: {{.}} +# REPORT-ERROR-DYNAMIC: error: out.no.so: ZICFISS is enabled, but this shared library lacks the necessary property note. The dynamic loader might not enable ZICFISS or refuse to load the program unless all shared library dependencies have the ZICFISS marking. +# REPORT-ERROR-DYNAMIC-NOT: error: + ## An invalid -z zicfiss-report option should give an error -# RUN: not ld.lld f2-s.o f3-s.o -z zicfiss=x -z zicfiss-report=x 2>&1 | FileCheck --check-prefix=INVALID %s +# RUN: not ld.lld f2-s.o f3-s.o -z zicfiss=x -z zicfiss-report=x -z zicfiss-report-dynamic=x 2>&1 | FileCheck --check-prefix=INVALID %s # INVALID: error: unknown -z zicfiss= value: x # INVALID: error: unknown -z zicfiss-report= value: x +# INVALID: error: unknown -z zicfiss-report-dynamic= value: x #--- rv32-f1-s.s .section ".note.gnu.property", "a"