[lld] 2b4e605 - [lld] Add cet-report and bti-report flags
Daniel Kiss via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 16 07:26:31 PST 2021
Author: Daniel Kiss
Date: 2021-12-16T16:26:26+01:00
New Revision: 2b4e6052b3bfff7177d81a747e9f48b44da9eb1c
URL: https://github.com/llvm/llvm-project/commit/2b4e6052b3bfff7177d81a747e9f48b44da9eb1c
DIFF: https://github.com/llvm/llvm-project/commit/2b4e6052b3bfff7177d81a747e9f48b44da9eb1c.diff
LOG: [lld] Add cet-report and bti-report flags
Implement cet-report as supported in binutils.
bti-report has the same behaviour for AArch64-BTI.
Fixes https://github.com/llvm/llvm-project/issues/44828
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D113901
Added:
Modified:
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/docs/ld.lld.1
lld/test/ELF/aarch64-bti-pac-cli-error.s
lld/test/ELF/aarch64-feature-bti.s
lld/test/ELF/i386-feature-cet.s
lld/test/ELF/x86-64-feature-cet.s
Removed:
################################################################################
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index f0f8eb86f44c4..0c8ce62c566a1 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -128,6 +128,8 @@ struct Configuration {
llvm::StringRef thinLTOCacheDir;
llvm::StringRef thinLTOIndexOnlyArg;
llvm::StringRef whyExtract;
+ StringRef zBtiReport = "none";
+ StringRef zCetReport = "none";
llvm::StringRef ltoBasicBlockSections;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOObjectSuffixReplace;
std::pair<llvm::StringRef, llvm::StringRef> thinLTOPrefixReplace;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 4d6fec26bd3a8..d0007449a2b14 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -368,7 +368,13 @@ static void checkOptions() {
error("-z pac-plt only supported on AArch64");
if (config->zForceBti)
error("-z force-bti only supported on AArch64");
+ if (config->zBtiReport != "none")
+ error("-z bti-report only supported on AArch64");
}
+
+ if (config->emachine != EM_386 && config->emachine != EM_X86_64 &&
+ config->zCetReport != "none")
+ error("-z cet-report only supported on X86 and X86_64");
}
static const char *getReproduceOption(opt::InputArgList &args) {
@@ -455,6 +461,7 @@ static bool isKnownZFlag(StringRef s) {
s == "rela" || s == "relro" || s == "retpolineplt" ||
s == "rodynamic" || s == "shstk" || s == "text" || s == "undefs" ||
s == "wxneeded" || s.startswith("common-page-size=") ||
+ s.startswith("bti-report=") || s.startswith("cet-report=") ||
s.startswith("dead-reloc-in-nonalloc=") ||
s.startswith("max-page-size=") || s.startswith("stack-size=") ||
s.startswith("start-stop-visibility=");
@@ -970,6 +977,11 @@ static void parseClangOption(StringRef opt, const Twine &msg) {
error(msg + ": " + StringRef(err).trim());
}
+// Checks the parameter of the bti-report and cet-report options.
+static bool isValidReportString(StringRef arg) {
+ return arg == "none" || arg == "warning" || arg == "error";
+}
+
// Initializes Config members by the command line options.
static void readConfigs(opt::InputArgList &args) {
errorHandler().verbose = args.hasArg(OPT_verbose);
@@ -1203,6 +1215,23 @@ static void readConfigs(opt::InputArgList &args) {
error(errPrefix + toString(pat.takeError()));
}
+ auto reports = {std::make_pair("bti-report", &config->zBtiReport),
+ std::make_pair("cet-report", &config->zCetReport)};
+ for (opt::Arg *arg : args.filtered(OPT_z)) {
+ std::pair<StringRef, StringRef> option =
+ StringRef(arg->getValue()).split('=');
+ for (auto reportArg : reports) {
+ if (option.first != reportArg.first)
+ continue;
+ if (!isValidReportString(option.second)) {
+ error(Twine("-z ") + reportArg.first + "= parameter " + option.second +
+ " is not recognized");
+ continue;
+ }
+ *reportArg.second = option.second;
+ }
+ }
+
for (opt::Arg *arg : args.filtered(OPT_z)) {
std::pair<StringRef, StringRef> option =
StringRef(arg->getValue()).split('=');
@@ -2103,6 +2132,16 @@ static void redirectSymbols(ArrayRef<WrappedSymbol> wrapped) {
symtab->wrap(w.sym, w.real, w.wrap);
}
+static void checkAndReportMissingFeature(StringRef config, uint32_t features,
+ uint32_t mask, const Twine &report) {
+ if (!(features & mask)) {
+ if (config == "error")
+ error(report);
+ else if (config == "warning")
+ warn(report);
+ }
+}
+
// To enable CET (x86's hardware-assited control flow enforcement), each
// source file must be compiled with -fcf-protection. Object files compiled
// with the flag contain feature flags indicating that they are compatible
@@ -2119,14 +2158,32 @@ template <class ELFT> static uint32_t getAndFeatures() {
uint32_t ret = -1;
for (InputFile *f : objectFiles) {
uint32_t features = cast<ObjFile<ELFT>>(f)->andFeatures;
+
+ checkAndReportMissingFeature(
+ config->zBtiReport, features, GNU_PROPERTY_AARCH64_FEATURE_1_BTI,
+ toString(f) + ": -z bti-report: file does not have "
+ "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
+
+ checkAndReportMissingFeature(
+ config->zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_IBT,
+ toString(f) + ": -z cet-report: file does not have "
+ "GNU_PROPERTY_X86_FEATURE_1_IBT property");
+
+ checkAndReportMissingFeature(
+ config->zCetReport, features, GNU_PROPERTY_X86_FEATURE_1_SHSTK,
+ toString(f) + ": -z cet-report: file does not have "
+ "GNU_PROPERTY_X86_FEATURE_1_SHSTK property");
+
if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
- warn(toString(f) + ": -z force-bti: file does not have "
- "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
features |= GNU_PROPERTY_AARCH64_FEATURE_1_BTI;
+ if (config->zBtiReport == "none")
+ warn(toString(f) + ": -z force-bti: file does not have "
+ "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property");
} else if (config->zForceIbt &&
!(features & GNU_PROPERTY_X86_FEATURE_1_IBT)) {
- warn(toString(f) + ": -z force-ibt: file does not have "
- "GNU_PROPERTY_X86_FEATURE_1_IBT property");
+ if (config->zCetReport == "none")
+ warn(toString(f) + ": -z force-ibt: file does not have "
+ "GNU_PROPERTY_X86_FEATURE_1_IBT property");
features |= GNU_PROPERTY_X86_FEATURE_1_IBT;
}
if (config->zPacPlt && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 0422231d78b51..04f0982b4ced4 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -702,6 +702,16 @@ Stack permissions are recorded in the
.Dv PT_GNU_STACK
segment.
.Pp
+.It Cm bti-report Ns = Ns Ar [none|warning|error]
+Specify how to report the missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI property.
+.Cm none
+is the default, linker will not report the missing property otherwise will be reported as a warning or an error.
+.Pp
+.It Cm cet-report Ns = Ns Ar [none|warning|error]
+Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_IBT or GNU_PROPERTY_X86_FEATURE_1_SHSTK properties.
+.Cm none
+is the default, linker will not report the missing property otherwise will be reported as a warning or an error.
+.Pp
.It Cm force-bti
Force enable AArch64 BTI instruction in PLT, warn if Input ELF file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property.
.Pp
diff --git a/lld/test/ELF/aarch64-bti-pac-cli-error.s b/lld/test/ELF/aarch64-bti-pac-cli-error.s
index 8155097674e76..b8ab1a28fa5a8 100644
--- a/lld/test/ELF/aarch64-bti-pac-cli-error.s
+++ b/lld/test/ELF/aarch64-bti-pac-cli-error.s
@@ -1,12 +1,18 @@
# REQUIRES: x86
# RUN: llvm-mc --triple=x86_64-pc-linux --filetype=obj -o %t.o %s
-# RUN: not ld.lld -z pac-plt -z force-bti %t.o -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld -z pac-plt -z force-bti -z bti-report=error %t.o -o /dev/null 2>&1 | FileCheck %s
#
-## Check that we error if -z pac-plt and -z force-bti are used when target is not
+## Check that we error if -z pac-plt, -z force-bti and -z bti-report=error are used when target is not
## aarch64
# CHECK: error: -z pac-plt only supported on AArch64
# CHECK-NEXT: error: -z force-bti only supported on AArch64
+# CHECK-NEXT: error: -z bti-report only supported on AArch64
+
+# RUN: not ld.lld -z bti-report=something %t.o -o /dev/null 2>&1 | \
+# RUN: FileCheck --check-prefix=REPORT_INVALID %s
+# REPORT_INVALID: error: -z bti-report= parameter something is not recognized
+# REPORT_INVALID-EMPTY:
.globl start
start: ret
diff --git a/lld/test/ELF/aarch64-feature-bti.s b/lld/test/ELF/aarch64-feature-bti.s
index e9bbd9eaa38bc..7035c9e714a35 100644
--- a/lld/test/ELF/aarch64-feature-bti.s
+++ b/lld/test/ELF/aarch64-feature-bti.s
@@ -187,9 +187,11 @@
## from the file without the .note.gnu.property.
# RUN: ld.lld %t.o %t2.o -z force-bti %t.so -o %tforcebti.exe 2>&1 | FileCheck --check-prefix=FORCE-WARN %s
+# RUN: not ld.lld %t.o %t2.o -z force-bti -z bti-report=error %t.so -o %tfailifnotbti.exe 2>&1 | FileCheck --check-prefix=BTI_REPORT-ERROR %s
# FORCE-WARN: aarch64-feature-bti.s.tmp2.o: -z force-bti: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property
-
+# BTI_REPORT-ERROR: aarch64-feature-bti.s.tmp2.o: -z bti-report: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property
+# BTI_REPORT-ERROR-EMPTY:
# RUN: llvm-readelf -n %tforcebti.exe | FileCheck --check-prefix=BTIPROP %s
# RUN: llvm-readelf --dynamic-table %tforcebti.exe | FileCheck --check-prefix BTIDYN %s
diff --git a/lld/test/ELF/i386-feature-cet.s b/lld/test/ELF/i386-feature-cet.s
index 25a44ee6e52da..d748a98e997c7 100644
--- a/lld/test/ELF/i386-feature-cet.s
+++ b/lld/test/ELF/i386-feature-cet.s
@@ -23,6 +23,23 @@
# RUN: | FileCheck --check-prefix=WARN %s
# WARN: {{.*}}.o: -z force-ibt: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# RUN: not ld.lld -e func1 %t.o %t3.o -o /dev/null -z cet-report=something 2>&1 \
+# RUN: | FileCheck --check-prefix=REPORT_INVALID %s
+# REPORT_INVALID: error: -z cet-report= parameter something is not recognized
+# REPORT_INVALID-EMPTY:
+
+# RUN: ld.lld -e func1 %t.o %t3.o -o /dev/null -z cet-report=warning 2>&1 \
+# RUN: | FileCheck --check-prefix=CET_REPORT_WARN %s
+# CET_REPORT_WARN: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# CET_REPORT_WARN: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_SHSTK property
+# CET_REPORT_WARN-EMPTY:
+
+# RUN: not ld.lld -e func1 %t.o %t3.o -o /dev/null -z cet-report=error 2>&1 \
+# RUN: | FileCheck --check-prefix=CET_REPORT_ERROR %s
+# CET_REPORT_ERROR: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# CET_REPORT_ERROR: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_SHSTK property
+# CET_REPORT_ERROR-EMPTY:
+
# RUN: ld.lld -e func1 %t.o %t4.o -o %t
# RUN: llvm-readelf -n %t | FileCheck --check-prefix=NOSHSTK %s
diff --git a/lld/test/ELF/x86-64-feature-cet.s b/lld/test/ELF/x86-64-feature-cet.s
index 7cd26696dc5ae..5322bbdf3f383 100644
--- a/lld/test/ELF/x86-64-feature-cet.s
+++ b/lld/test/ELF/x86-64-feature-cet.s
@@ -23,6 +23,29 @@
# RUN: | FileCheck --check-prefix=WARN %s
# WARN: {{.*}}.o: -z force-ibt: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# RUN:not ld.lld -e func1 %t.o %t3.o -o /dev/null -z cet-report=something 2>&1 \
+# RUN: | FileCheck --check-prefix=REPORT_INVALID %s
+# REPORT_INVALID: error: -z cet-report= parameter something is not recognized
+# REPORT_INVALID-EMPTY:
+
+# RUN: ld.lld -e func1 %t.o %t3.o -o /dev/null -z force-ibt -z cet-report=warning 2>&1 \
+# RUN: | FileCheck --check-prefix=REPORT_FORCE %s
+# REPORT_FORCE: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# REPORT_FORCE: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_SHSTK property
+# REPORT_FORCE-EMPTY:
+
+# RUN: ld.lld -e func1 %t.o %t3.o -o /dev/null -z cet-report=warning 2>&1 \
+# RUN: | FileCheck --check-prefix=CET_REPORT_WARN %s
+# CET_REPORT_WARN: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# CET_REPORT_WARN: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_SHSTK property
+# CET_REPORT_WARN-EMPTY:
+
+# RUN: not ld.lld -e func1 %t.o %t3.o -o /dev/null -z cet-report=error 2>&1 \
+# RUN: | FileCheck --check-prefix=CET_REPORT_ERROR %s
+# CET_REPORT_ERROR: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property
+# CET_REPORT_ERROR: {{.*}}.o: -z cet-report: file does not have GNU_PROPERTY_X86_FEATURE_1_SHSTK property
+# CET_REPORT_ERROR-EMPTY:
+
# RUN: ld.lld -e func1 %t.o %t4.o -o %t
# RUN: llvm-readelf -n %t | FileCheck --check-prefix=NOSHSTK %s
More information about the llvm-commits
mailing list