Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -229,6 +229,7 @@ bool writeAddends; bool zCombreloc; bool zCopyreloc; + bool zFailIfNoBti; bool zForceBti; bool zForceIbt; bool zGlobal; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -368,6 +368,8 @@ error("-z pac-plt only supported on AArch64"); if (config->zForceBti) error("-z force-bti only supported on AArch64"); + if (config->zFailIfNoBti) + error("-z fail-if-no-bti only supported on AArch64"); } } @@ -441,9 +443,9 @@ static bool isKnownZFlag(StringRef s) { return s == "combreloc" || s == "copyreloc" || s == "defs" || - s == "execstack" || s == "force-bti" || s == "force-ibt" || - s == "global" || s == "hazardplt" || s == "ifunc-noplt" || - s == "initfirst" || s == "interpose" || + s == "execstack" || s == "fail-if-no-bti" || s == "force-bti" || + s == "force-ibt" || s == "global" || s == "hazardplt" || + s == "ifunc-noplt" || s == "initfirst" || s == "interpose" || s == "keep-text-section-prefix" || s == "lazy" || s == "muldefs" || s == "separate-code" || s == "separate-loadable-segments" || s == "start-stop-gc" || s == "nocombreloc" || s == "nocopyreloc" || @@ -1161,6 +1163,7 @@ config->whyExtract = args.getLastArgValue(OPT_why_extract); config->zCombreloc = getZFlag(args, "combreloc", "nocombreloc", true); config->zCopyreloc = getZFlag(args, "copyreloc", "nocopyreloc", true); + config->zFailIfNoBti = hasZOption(args, "fail-if-no-bti"); config->zForceBti = hasZOption(args, "force-bti"); config->zForceIbt = hasZOption(args, "force-ibt"); config->zGlobal = hasZOption(args, "global"); @@ -2134,7 +2137,12 @@ uint32_t ret = -1; for (InputFile *f : objectFiles) { uint32_t features = cast>(f)->andFeatures; - if (config->zForceBti && !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) { + if (config->zFailIfNoBti && + !(features & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) { + error(toString(f) + ": -z fail-if-no-bti: file does not have " + "GNU_PROPERTY_AARCH64_FEATURE_1_BTI property"); + } else 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; Index: lld/docs/ld.lld.1 =================================================================== --- lld/docs/ld.lld.1 +++ lld/docs/ld.lld.1 @@ -689,6 +689,9 @@ .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 +.It Cm fail-if-no-bti +Report an error if Input ELF file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property. +.Pp .It Cm force-ibt Force enable Intel Indirect Branch Tracking in PLT, warn if an input ELF file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property. Index: lld/test/ELF/aarch64-bti-pac-cli-error.s =================================================================== --- lld/test/ELF/aarch64-bti-pac-cli-error.s +++ lld/test/ELF/aarch64-bti-pac-cli-error.s @@ -1,12 +1,13 @@ # 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 fail-if-no-bti %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 fail-if-no-bti 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 fail-if-no-bti only supported on AArch64 .globl start start: ret Index: lld/test/ELF/aarch64-feature-bti.s =================================================================== --- lld/test/ELF/aarch64-feature-bti.s +++ lld/test/ELF/aarch64-feature-bti.s @@ -187,8 +187,10 @@ ## 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 fail-if-no-bti %t.so -o %tfailifnotbti.exe 2>&1 | FileCheck --check-prefix=FAIL-IF-NO-BTI-ERROR %s # FORCE-WARN: aarch64-feature-bti.s.tmp2.o: -z force-bti: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property +# FAIL-IF-NO-BTI-ERROR: aarch64-feature-bti.s.tmp2.o: -z fail-if-no-bti: file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property # RUN: llvm-readelf -n %tforcebti.exe | FileCheck --check-prefix=BTIPROP %s