From c4c22e830251e1961c6ebec78d28d039eb2e6017 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 16 Jul 2020 07:03:27 -0700 Subject: LTO: Add -fcf-protection=check Mixing -fcf-protection and -fcf-protection=none objects are allowed. Linker just merges -fcf-protection values from all input objects. Add -fcf-protection=check for the final link with LTO. An error is issued if LTO object files are compiled with different -fcf-protection values. Otherwise, -fcf-protection=check is ignored at the compile time. Without explicit -fcf-protection at link time, -fcf-protection values from LTO object files are merged at the final link. gcc/ PR bootstrap/96203 * common.opt: Add -fcf-protection=check. * flag-types.h (cf_protection_level): Add CF_CHECK. * lto-wrapper.c (merge_and_complain): Issue an error for mismatching -fcf-protection values with -fcf-protection=check. Otherwise, merge -fcf-protection values. * doc/invoke.texi: Document -fcf-protection=check. gcc/testsuite/ PR bootstrap/96203 * gcc.target/i386/pr96203-1.c: New test. * gcc.target/i386/pr96203-2.c: Likewise. --- gcc/lto-wrapper.c | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) (limited to 'gcc/lto-wrapper.c') diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 5578b6d..e3b5cb2 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -310,20 +310,45 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_fcf_protection_: /* Default to link-time option, else append or check identical. */ - if (!cf_protection_option) + if (!cf_protection_option + || cf_protection_option->value == CF_CHECK) { for (j = 0; j < *decoded_options_count; ++j) if ((*decoded_options)[j].opt_index == foption->opt_index) break; if (j == *decoded_options_count) append_option (decoded_options, decoded_options_count, foption); - else if (strcmp ((*decoded_options)[j].arg, foption->arg)) - fatal_error (input_location, - "option -fcf-protection with mismatching values" - " (%s, %s)", - (*decoded_options)[j].arg, foption->arg); + else if ((*decoded_options)[j].value != foption->value) + { + if (cf_protection_option + && cf_protection_option->value == CF_CHECK) + fatal_error (input_location, + "option -fcf-protection with mismatching values" + " (%s, %s)", + (*decoded_options)[j].arg, foption->arg); + else + { + /* Merge and update the -fcf-protection option. */ + (*decoded_options)[j].value &= (foption->value + & CF_FULL); + switch ((*decoded_options)[j].value) + { + case CF_NONE: + (*decoded_options)[j].arg = "none"; + break; + case CF_BRANCH: + (*decoded_options)[j].arg = "branch"; + break; + case CF_RETURN: + (*decoded_options)[j].arg = "return"; + break; + default: + gcc_unreachable (); + } + } + } } - break; + break; case OPT_O: case OPT_Ofast: -- cgit v1.1