diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2020-07-16 07:03:27 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2020-07-27 04:40:13 -0700 |
commit | c4c22e830251e1961c6ebec78d28d039eb2e6017 (patch) | |
tree | c8ca64121d22d1d3222b58e85fc477bd68166c6a /gcc/lto-wrapper.c | |
parent | fd5966e8e044785f51cd7373b59ad9575a5ac96c (diff) | |
download | gcc-c4c22e830251e1961c6ebec78d28d039eb2e6017.zip gcc-c4c22e830251e1961c6ebec78d28d039eb2e6017.tar.gz gcc-c4c22e830251e1961c6ebec78d28d039eb2e6017.tar.bz2 |
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.
Diffstat (limited to 'gcc/lto-wrapper.c')
-rw-r--r-- | gcc/lto-wrapper.c | 39 |
1 files changed, 32 insertions, 7 deletions
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: |