When generating the separate file with LTO debug sections, we should also copy .note.gnu.property section.
OK for master if there is no regression? Thanks. H.J. --- libiberty/ PR lto/93966 * simple-object.c (handle_lto_debug_sections): Also copy .note.gnu.property section. gcc/ PR lto/93966 * configure.ac (HAVE_LD_CET_REPORT_SUPPORT): New. Set to 1 if linker supports -z cet-report=. * config.in: Regenerated. * configure: Likewise. gcc/testsuite/ PR lto/93966 * gcc.target/i386/pr93966.c: New file. * lib/target-supports.exp (check_effective_target_cet_report): New. --- gcc/config.in | 6 ++++ gcc/configure | 24 +++++++++++++ gcc/configure.ac | 20 +++++++++++ gcc/testsuite/gcc.target/i386/pr93966.c | 10 ++++++ gcc/testsuite/lib/target-supports.exp | 47 +++++++++++++++++++++++++ libiberty/simple-object.c | 3 ++ 6 files changed, 110 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr93966.c diff --git a/gcc/config.in b/gcc/config.in index 01fb18dbbb5..288f4ad509d 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -1500,6 +1500,12 @@ #endif +/* Define if your linker supports -z cet-report=. */ +#ifndef USED_FOR_TARGET +#undef HAVE_LD_CET_REPORT_SUPPORT +#endif + + /* Define if the linker supports clearing hardware capabilities via mapfile. */ #ifndef USED_FOR_TARGET diff --git a/gcc/configure b/gcc/configure index f55cdb8c77f..c132887083e 100755 --- a/gcc/configure +++ b/gcc/configure @@ -30714,6 +30714,30 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_bndplt_support" >&5 $as_echo "$ld_bndplt_support" >&6; } +# Check linker supports '-z cet-report='. +ld_cet_report_support=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z cet-report= option" >&5 +$as_echo_n "checking linker -z cet-report= option... " >&6; } +if test x"$ld_is_gold" = xno; then + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 33 -o "$gcc_cv_gld_major_version" -gt 2; then + ld_cet_report_support=yes + fi + elif test x$gcc_cv_ld != x; then + # Check if linker supports -a cet-report= option + if $gcc_cv_ld --help 2>&1 | grep -- '-z cet-report=' > /dev/null; then + ld_cet_report_support=yes + fi + fi +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_LD_CET_REPORT_SUPPORT `if test x"$ld_cet_report_support" = xyes; then echo 1; else echo 0; fi` +_ACEOF + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_cet_report_support" >&5 +$as_echo "$ld_cet_report_support" >&6; } + # Check linker supports '--push-state'/'--pop-state' ld_pushpopstate_support=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker --push-state/--pop-state options" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index 0e6e475950d..b1bff5064ca 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -6838,6 +6838,26 @@ if test x"$ld_bndplt_support" = xyes; then fi AC_MSG_RESULT($ld_bndplt_support) +# Check linker supports '-z cet-report='. +ld_cet_report_support=no +AC_MSG_CHECKING(linker -z cet-report= option) +if test x"$ld_is_gold" = xno; then + if test $in_tree_ld = yes ; then + if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 33 -o "$gcc_cv_gld_major_version" -gt 2; then + ld_cet_report_support=yes + fi + elif test x$gcc_cv_ld != x; then + # Check if linker supports -a cet-report= option + if $gcc_cv_ld --help 2>&1 | grep -- '-z cet-report=' > /dev/null; then + ld_cet_report_support=yes + fi + fi +fi +AC_DEFINE_UNQUOTED(HAVE_LD_CET_REPORT_SUPPORT, + [`if test x"$ld_cet_report_support" = xyes; then echo 1; else echo 0; fi`], + [Define if your linker supports -z cet-report=.]) +AC_MSG_RESULT($ld_cet_report_support) + # Check linker supports '--push-state'/'--pop-state' ld_pushpopstate_support=no AC_MSG_CHECKING(linker --push-state/--pop-state options) diff --git a/gcc/testsuite/gcc.target/i386/pr93966.c b/gcc/testsuite/gcc.target/i386/pr93966.c new file mode 100644 index 00000000000..05ac88acf8a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93966.c @@ -0,0 +1,10 @@ +/* { dg-do run { target cet } } */ +/* { dg-require-effective-target lto } */ +/* { dg-require-effective-target cet_report } */ +/* { dg-options "-flto -fcf-protection -g -Wl,-z,cet-report=error" } */ + +int +main () +{ + return 0; +} diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index ca3895c2269..9847e224ed6 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -9477,6 +9477,53 @@ proc check_effective_target_tls_get_addr_via_got { } { }] } +# Return 1 if the x86 linker supports -z cet-report=, 0 otherwise. +# Cache the result. + +proc check_effective_target_cet_report { } { + global tool + global GCC_UNDER_TEST + + if { !([istarget i?86-*-*] || [istarget x86_64-*-*]) } { + return 0 + } + + # Need auto-host.h to check linker support. + if { ![file exists ../../auto-host.h ] } { + return 0 + } + + return [check_cached_effective_target cet_report { + # Set up and compile to see if linker supports -z cet-report=. + # reloc. Include the current process ID in the file names to + # prevent conflicts with invocations for multiple testsuites. + + set src cet[pid].c + set obj cet[pid].o + + set f [open $src "w"] + puts $f "#include \"../../auto-host.h\"" + puts $f "#if HAVE_LD_CET_REPORT_SUPPORT == 0" + puts $f "# error Linker does not support -z cet-report=." + puts $f "#endif" + close $f + + verbose "check_effective_target_cet_report compiling testfile $src" 2 + set lines [${tool}_target_compile $src $obj object ""] + + file delete $src + file delete $obj + + if [string match "" $lines] then { + verbose "check_effective_target_cet_report testfile compilation passed" 2 + return 1 + } else { + verbose "check_effective_target_cet_report testfile compilation failed" 2 + return 0 + } + }] +} + # Return 1 if the target uses comdat groups. proc check_effective_target_comdat_group {} { diff --git a/libiberty/simple-object.c b/libiberty/simple-object.c index d9c648af717..e6c466ab767 100644 --- a/libiberty/simple-object.c +++ b/libiberty/simple-object.c @@ -293,6 +293,9 @@ handle_lto_debug_sections (const char *name, int rename) /* Copy over .note.GNU-stack section under the same name if present. */ else if (strcmp (name, ".note.GNU-stack") == 0) return strcpy (newname, name); + /* Copy over .note.gnu.property section under the same name if present. */ + else if (strcmp (name, ".note.gnu.property") == 0) + return strcpy (newname, name); /* Copy over .comment section under the same name if present. Solaris ld uses them to relax its checking of ELF gABI access rules for COMDAT sections in objects produced by GCC. */ -- 2.24.1