x86: Add -mneeded for GNU_PROPERTY_X86_ISA_1_V[234] marker
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 9 Nov 2020 17:29:23 +0000 (09:29 -0800)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 2 Dec 2020 00:33:10 +0000 (16:33 -0800)
GCC 11 supports -march=x86-64-v[234] to enable x86 micro-architecture ISA
levels:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97250

Binutils has been updated to support GNU_PROPERTY_X86_ISA_1_V[234] marker:

https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13

with

commit b0ab06937385e0ae25cebf1991787d64f439bf12
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Oct 30 06:49:57 2020 -0700

    x86: Support GNU_PROPERTY_X86_ISA_1_BASELINE marker

and

commit 32930e4edbc06bc6f10c435dbcc63131715df678
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Fri Oct 9 05:05:57 2020 -0700

    x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker

in x86 ELF binaries.

Add -mneeded to emit GNU_PROPERTY_X86_ISA_1_NEEDED property to indicate
the micro-architecture ISA level required to execute the binary.

gcc/

* config.gcc: Replace cet.o with gnu-property.o.  Replace
i386/t-cet with i386/t-gnu-property.
* config/i386/cet.c: Renamed to ...
* config/i386/gnu-property.c: This.
(emit_gnu_property): New function.
(file_end_indicate_exec_stack_and_cet): Renamed to ...
(file_end_indicate_exec_stack_and_gnu_property): This.  Call
emit_gnu_property to generate GNU_PROPERTY_X86_FEATURE_1_AND and
GNU_PROPERTY_X86_ISA_1_NEEDED properties.
* config/i386/i386.opt (mneeded): New.
* config/i386/linux-common.h (file_end_indicate_exec_stack_and_cet):
Renamed to ...
(file_end_indicate_exec_stack_and_gnu_property): This.
(TARGET_ASM_FILE_END): Updated.
* config/i386/t-cet: Renamed to ...
* config/i386/t-gnu-property: This.
(cet.o): Renamed to ...
(gnu-property.o): This.
* doc/invoke.texi: Document -mneeded.

gcc/testsuite/

* gcc.target/i386/x86-needed-1.c: New test.
* gcc.target/i386/x86-needed-2.c: Likewise.
* gcc.target/i386/x86-needed-3.c: Likewise.

gcc/config.gcc
gcc/config/i386/cet.c [deleted file]
gcc/config/i386/gnu-property.c [new file with mode: 0644]
gcc/config/i386/i386.opt
gcc/config/i386/linux-common.h
gcc/config/i386/t-gnu-property [moved from gcc/config/i386/t-cet with 93% similarity]
gcc/doc/invoke.texi
gcc/testsuite/gcc.target/i386/x86-needed-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/x86-needed-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/x86-needed-3.c [new file with mode: 0644]

index 4808b69..b8d2686 100644 (file)
@@ -5231,8 +5231,8 @@ case ${target} in
        i[34567]86-*-darwin* | x86_64-*-darwin*)
                ;;
        i[34567]86-*-linux* | x86_64-*-linux*)
-               extra_objs="${extra_objs} cet.o"
-               tmake_file="$tmake_file i386/t-linux i386/t-cet"
+               extra_objs="${extra_objs} gnu-property.o"
+               tmake_file="$tmake_file i386/t-linux i386/t-gnu-property"
                ;;
        i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
                tmake_file="$tmake_file i386/t-kfreebsd"
diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c
deleted file mode 100644 (file)
index 5450ac3..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Functions for CET/x86.
-   Copyright (C) 2017-2020 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
-
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "output.h"
-#include "linux-common.h"
-
-void
-file_end_indicate_exec_stack_and_cet (void)
-{
-  file_end_indicate_exec_stack ();
-
-  if (flag_cf_protection == CF_NONE)
-    return;
-
-  unsigned int feature_1 = 0;
-
-  if (flag_cf_protection & CF_BRANCH)
-    /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
-    feature_1 |= 0x1;
-
-  if (flag_cf_protection & CF_RETURN)
-    /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
-    feature_1 |= 0x2;
-
-  if (feature_1)
-    {
-      int p2align = ptr_mode == SImode ? 2 : 3;
-
-      /* Generate GNU_PROPERTY_X86_FEATURE_1_XXX.  */
-      switch_to_section (get_section (".note.gnu.property",
-                                     SECTION_NOTYPE, NULL));
-
-      ASM_OUTPUT_ALIGN (asm_out_file, p2align);
-      /* name length.  */
-      fprintf (asm_out_file, ASM_LONG " 1f - 0f\n");
-      /* data length.  */
-      fprintf (asm_out_file, ASM_LONG " 4f - 1f\n");
-      /* note type: NT_GNU_PROPERTY_TYPE_0.  */
-      fprintf (asm_out_file, ASM_LONG " 5\n");
-      fprintf (asm_out_file, "0:\n");
-      /* vendor name: "GNU".  */
-      fprintf (asm_out_file, STRING_ASM_OP " \"GNU\"\n");
-      fprintf (asm_out_file, "1:\n");
-      ASM_OUTPUT_ALIGN (asm_out_file, p2align);
-      /* pr_type: GNU_PROPERTY_X86_FEATURE_1_AND.  */
-      fprintf (asm_out_file, ASM_LONG " 0xc0000002\n");
-      /* pr_datasz.  */\
-      fprintf (asm_out_file, ASM_LONG " 3f - 2f\n");
-      fprintf (asm_out_file, "2:\n");
-      /* GNU_PROPERTY_X86_FEATURE_1_XXX.  */
-      fprintf (asm_out_file, ASM_LONG " 0x%x\n", feature_1);
-      fprintf (asm_out_file, "3:\n");
-      ASM_OUTPUT_ALIGN (asm_out_file, p2align);
-      fprintf (asm_out_file, "4:\n");
-    }
-}
diff --git a/gcc/config/i386/gnu-property.c b/gcc/config/i386/gnu-property.c
new file mode 100644 (file)
index 0000000..1288325
--- /dev/null
@@ -0,0 +1,124 @@
+/* Functions for x86 GNU property.
+   Copyright (C) 2017-2020 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "output.h"
+#include "linux-common.h"
+
+static void
+emit_gnu_property (unsigned int type, unsigned int data)
+{
+  int p2align = ptr_mode == SImode ? 2 : 3;
+
+  switch_to_section (get_section (".note.gnu.property",
+                                 SECTION_NOTYPE, NULL));
+
+  ASM_OUTPUT_ALIGN (asm_out_file, p2align);
+  /* name length.  */
+  fprintf (asm_out_file, ASM_LONG "1f - 0f\n");
+  /* data length.  */
+  fprintf (asm_out_file, ASM_LONG "4f - 1f\n");
+  /* note type: NT_GNU_PROPERTY_TYPE_0.  */
+  fprintf (asm_out_file, ASM_LONG "5\n");
+  fprintf (asm_out_file, "0:\n");
+  /* vendor name: "GNU".  */
+  fprintf (asm_out_file, STRING_ASM_OP "\"GNU\"\n");
+  fprintf (asm_out_file, "1:\n");
+  ASM_OUTPUT_ALIGN (asm_out_file, p2align);
+  /* pr_type.  */
+  fprintf (asm_out_file, ASM_LONG "0x%x\n", type);
+  /* pr_datasz.  */
+  fprintf (asm_out_file, ASM_LONG "3f - 2f\n");
+  fprintf (asm_out_file, "2:\n");
+  fprintf (asm_out_file, ASM_LONG "0x%x\n", data);
+  fprintf (asm_out_file, "3:\n");
+  ASM_OUTPUT_ALIGN (asm_out_file, p2align);
+  fprintf (asm_out_file, "4:\n");
+}
+
+void
+file_end_indicate_exec_stack_and_gnu_property (void)
+{
+  file_end_indicate_exec_stack ();
+
+  if (flag_cf_protection == CF_NONE && !ix86_needed)
+    return;
+
+  unsigned int feature_1 = 0;
+
+  if (flag_cf_protection & CF_BRANCH)
+    /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
+    feature_1 |= 0x1;
+
+  if (flag_cf_protection & CF_RETURN)
+    /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
+    feature_1 |= 0x2;
+
+  /* Generate GNU_PROPERTY_X86_FEATURE_1_AND.  */
+  if (feature_1)
+    emit_gnu_property (0xc0000002, feature_1);
+
+  unsigned int isa_1 = 0;
+  if (ix86_needed)
+    {
+      /* GNU_PROPERTY_X86_ISA_1_BASELINE.  */
+      if (TARGET_64BIT
+         || TARGET_FXSR
+         || TARGET_80387
+         || TARGET_MMX
+         || TARGET_SSE
+         || TARGET_SSE2)
+       isa_1 |= 1 << 0;
+
+      /* GNU_PROPERTY_X86_ISA_1_V2.  */
+      if (TARGET_CMPXCHG16B
+         || (TARGET_64BIT && TARGET_SAHF)
+         || TARGET_POPCNT
+         || TARGET_SSE3
+         || TARGET_SSSE3
+         || TARGET_SSE4_1
+         || TARGET_SSE4_2)
+       isa_1 |= 1 << 1;
+
+      /* GNU_PROPERTY_X86_ISA_1_V3.  */
+      if (TARGET_AVX
+         || TARGET_AVX2
+         || TARGET_F16C
+         || TARGET_FMA
+         || TARGET_LZCNT
+         || TARGET_MOVBE
+         || TARGET_XSAVE)
+       isa_1 |= 1 << 2;
+
+      /* GNU_PROPERTY_X86_ISA_1_V4.  */
+      if (TARGET_AVX512F
+         || TARGET_AVX512BW
+         || TARGET_AVX512CD
+         || TARGET_AVX512DQ
+         || TARGET_AVX512VL)
+       isa_1 |= 1 << 3;
+    }
+
+  /* Generate GNU_PROPERTY_X86_ISA_1_NEEDED.  */
+  if (isa_1)
+    emit_gnu_property (0xc0008002, isa_1);
+}
index fac76e4..d7e4f44 100644 (file)
@@ -1148,3 +1148,7 @@ mavxvnni
 Target Report Mask(ISA2_AVXVNNI) Var(ix86_isa_flags2) Save
 Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, and
 AVXVNNI built-in functions and code generation.
+
+mneeded
+Target Report Var(ix86_needed) Save
+Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property
index 982390d..da0fabb 100644 (file)
@@ -65,7 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #define MPX_LD_AS_NEEDED_GUARD_POP ""
 #endif
 
-extern void file_end_indicate_exec_stack_and_cet (void);
+extern void file_end_indicate_exec_stack_and_gnu_property (void);
 
 #undef TARGET_ASM_FILE_END
-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack_and_cet
+#define TARGET_ASM_FILE_END file_end_indicate_exec_stack_and_gnu_property
similarity index 93%
rename from gcc/config/i386/t-cet
rename to gcc/config/i386/t-gnu-property
index d685d31..fd8bbce 100644 (file)
@@ -16,6 +16,6 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-cet.o: $(srcdir)/config/i386/cet.c
+gnu-property.o: $(srcdir)/config/i386/gnu-property.c
          $(COMPILE) $<
          $(POSTCOMPILE)
index 5547d79..0844408 100644 (file)
@@ -1392,7 +1392,7 @@ See RS/6000 and PowerPC Options.
 -mstack-protector-guard-symbol=@var{symbol} @gol
 -mgeneral-regs-only  -mcall-ms2sysv-xlogues @gol
 -mindirect-branch=@var{choice}  -mfunction-return=@var{choice} @gol
--mindirect-branch-register}
+-mindirect-branch-register -mneeded}
 
 @emph{x86 Windows Options}
 @gccoptlist{-mconsole  -mcygwin  -mno-cygwin  -mdll @gol
@@ -31377,6 +31377,12 @@ environments.
 Generate code for short address mode.  This is only supported for 32-bit
 and x32 environments.  It is the default address mode for 32-bit and
 x32 environments.
+
+@item -mneeded
+@itemx -mno-needed
+@opindex mneeded
+Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property for Linux target to
+indicate the micro-architecture ISA level required to execute the binary.
 @end table
 
 @node x86 Windows Options
diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-1.c b/gcc/testsuite/gcc.target/i386/x86-needed-1.c
new file mode 100644 (file)
index 0000000..b4584df
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection -march=x86-64 -mneeded" } */
+/* { dg-final { scan-assembler-times ".note.gnu.property" 1 } } */
+/* { dg-final { scan-assembler-times ".long    0xc0000002" 1 } } */
+/* { dg-final { scan-assembler-times ".long    0xc0008002" 1 } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-2.c b/gcc/testsuite/gcc.target/i386/x86-needed-2.c
new file mode 100644 (file)
index 0000000..2d91656
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fcf-protection=none -march=x86-64 -mno-needed" } */
+/* { dg-final { scan-assembler-not ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-3.c b/gcc/testsuite/gcc.target/i386/x86-needed-3.c
new file mode 100644 (file)
index 0000000..1d93726
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-fcf-protection=none -march=i686 -msoft-float -mneeded" } */
+/* { dg-final { scan-assembler-not ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}