The following patch fixes both PR56010 and PR83743.  PR56010 is fixed by
adding an extra altname field to the RS6000_CPU table which matches the
cases where the Linux kernel's AT_PLATFORM name differs from the name GCC
expects.  If we match on the altname, then we return the canonical name.

PR83743 is fixed by catching the case where we do not recognize at all
the AT_PLATFORM value returned by the kernel.  In that case, we emit an
error message and request the user use an explicit cpu name rather than
using "native".

I have tested this by forcing use of non-existant names and kernel alternate
names and verifying we call cc1/cc1plus with the either the correct canonical
cpu names or we emit an error message and quit.

This has bootstrapped and regtested with no errors.  Ok for mainline?

This patch applies fairly easy to the release branches, do we want this
fix there as well?

Peter

        PR target/56010
        PR target/83743
        * config/rs6000/rs6000-cpus.def (RS6000_CPU table): Add alternate cpu
        names.
        * config/rs6000/driver-rs6000.c: #include "diagnostic.h".
        (struct rs6000_ptt): Define new structure.
        (rs6000_supported_cpu_names): New static variable.
        (elf_platform) <cpu>: Define new static variable and use it.
        Translate kernel AT_PLATFORM name to canonical name if needed.
        Error if platform name is unknown.
        * config/rs6000/rs6000.c: Handle extra field in RS6000_CPU table.
        * config/rs6000/default64.h: Likewise.

Index: gcc/config/rs6000/rs6000-cpus.def
===================================================================
--- gcc/config/rs6000/rs6000-cpus.def   (revision 256364)
+++ gcc/config/rs6000/rs6000-cpus.def   (working copy)
@@ -150,82 +150,82 @@
 
    Before including this file, define a macro:
 
-   RS6000_CPU (NAME, CPU, FLAGS)
+   RS6000_CPU (NAME, ALTNAME, CPU, FLAGS)
 
    where the arguments are the fields of struct rs6000_ptt.  */
 
-RS6000_CPU ("401", PROCESSOR_PPC403, MASK_SOFT_FLOAT)
-RS6000_CPU ("403", PROCESSOR_PPC403, MASK_SOFT_FLOAT | MASK_STRICT_ALIGN)
-RS6000_CPU ("405", PROCESSOR_PPC405, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("405fp", PROCESSOR_PPC405, MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("440", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("440fp", PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("464", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("464fp", PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("476", PROCESSOR_PPC476,
+RS6000_CPU ("401", NULL, PROCESSOR_PPC403, MASK_SOFT_FLOAT)
+RS6000_CPU ("403", "ppc403", PROCESSOR_PPC403, MASK_SOFT_FLOAT | 
MASK_STRICT_ALIGN)
+RS6000_CPU ("405", "ppc405", PROCESSOR_PPC405, MASK_SOFT_FLOAT | MASK_MULHW | 
MASK_DLMZB)
+RS6000_CPU ("405fp", NULL, PROCESSOR_PPC405, MASK_MULHW | MASK_DLMZB)
+RS6000_CPU ("440", "ppc440", PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | 
MASK_DLMZB)
+RS6000_CPU ("440fp", NULL, PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB)
+RS6000_CPU ("464", NULL, PROCESSOR_PPC440, MASK_SOFT_FLOAT | MASK_MULHW | 
MASK_DLMZB)
+RS6000_CPU ("464fp", NULL, PROCESSOR_PPC440, MASK_MULHW | MASK_DLMZB)
+RS6000_CPU ("476", "ppc470", PROCESSOR_PPC476,
            MASK_SOFT_FLOAT | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB
            | MASK_FPRND | MASK_CMPB | MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("476fp", PROCESSOR_PPC476,
+RS6000_CPU ("476fp", NULL, PROCESSOR_PPC476,
            MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
            | MASK_CMPB | MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("505", PROCESSOR_MPCCORE, 0)
-RS6000_CPU ("601", PROCESSOR_PPC601, MASK_MULTIPLE | MASK_STRING)
-RS6000_CPU ("602", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
-RS6000_CPU ("603", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
-RS6000_CPU ("603e", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
-RS6000_CPU ("604", PROCESSOR_PPC604, MASK_PPC_GFXOPT)
-RS6000_CPU ("604e", PROCESSOR_PPC604e, MASK_PPC_GFXOPT)
-RS6000_CPU ("620", PROCESSOR_PPC620, MASK_PPC_GFXOPT | MASK_POWERPC64)
-RS6000_CPU ("630", PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64)
-RS6000_CPU ("740", PROCESSOR_PPC750, MASK_PPC_GFXOPT)
-RS6000_CPU ("7400", PROCESSOR_PPC7400, POWERPC_7400_MASK)
-RS6000_CPU ("7450", PROCESSOR_PPC7450, POWERPC_7400_MASK)
-RS6000_CPU ("750", PROCESSOR_PPC750, MASK_PPC_GFXOPT)
-RS6000_CPU ("801", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
-RS6000_CPU ("821", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
-RS6000_CPU ("823", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
-RS6000_CPU ("8540", PROCESSOR_PPC8540, MASK_STRICT_ALIGN | MASK_ISEL)
-RS6000_CPU ("8548", PROCESSOR_PPC8548, MASK_STRICT_ALIGN | MASK_ISEL)
-RS6000_CPU ("a2", PROCESSOR_PPCA2,
+RS6000_CPU ("505", NULL, PROCESSOR_MPCCORE, 0)
+RS6000_CPU ("601", "ppc601", PROCESSOR_PPC601, MASK_MULTIPLE |MASK_STRING)
+RS6000_CPU ("602", NULL, PROCESSOR_PPC603, MASK_PPC_GFXOPT)
+RS6000_CPU ("603", "ppc603", PROCESSOR_PPC603, MASK_PPC_GFXOPT)
+RS6000_CPU ("603e", NULL, PROCESSOR_PPC603, MASK_PPC_GFXOPT)
+RS6000_CPU ("604", "ppc604", PROCESSOR_PPC604, MASK_PPC_GFXOPT)
+RS6000_CPU ("604e", NULL, PROCESSOR_PPC604e, MASK_PPC_GFXOPT)
+RS6000_CPU ("620", NULL, PROCESSOR_PPC620, MASK_PPC_GFXOPT | MASK_POWERPC64)
+RS6000_CPU ("630", NULL, PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64)
+RS6000_CPU ("740", NULL, PROCESSOR_PPC750, MASK_PPC_GFXOPT)
+RS6000_CPU ("7400", "ppc7400", PROCESSOR_PPC7400, POWERPC_7400_MASK)
+RS6000_CPU ("7450", "ppc7450", PROCESSOR_PPC7450, POWERPC_7400_MASK)
+RS6000_CPU ("750", "ppc750", PROCESSOR_PPC750, MASK_PPC_GFXOPT)
+RS6000_CPU ("801", NULL, PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
+RS6000_CPU ("821", NULL, PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
+RS6000_CPU ("823", "ppc823", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
+RS6000_CPU ("8540", "ppc8540", PROCESSOR_PPC8540, MASK_STRICT_ALIGN | 
MASK_ISEL)
+RS6000_CPU ("8548", "ppc8548", PROCESSOR_PPC8548, MASK_STRICT_ALIGN | 
MASK_ISEL)
+RS6000_CPU ("a2", NULL, PROCESSOR_PPCA2,
            MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_POPCNTB | MASK_CMPB
            | MASK_NO_UPDATE)
-RS6000_CPU ("e300c2", PROCESSOR_PPCE300C2, MASK_SOFT_FLOAT)
-RS6000_CPU ("e300c3", PROCESSOR_PPCE300C3, 0)
-RS6000_CPU ("e500mc", PROCESSOR_PPCE500MC, MASK_PPC_GFXOPT | MASK_ISEL)
-RS6000_CPU ("e500mc64", PROCESSOR_PPCE500MC64,
+RS6000_CPU ("e300c2", NULL, PROCESSOR_PPCE300C2, MASK_SOFT_FLOAT)
+RS6000_CPU ("e300c3", NULL, PROCESSOR_PPCE300C3, 0)
+RS6000_CPU ("e500mc", "ppce500mc", PROCESSOR_PPCE500MC, MASK_PPC_GFXOPT | 
MASK_ISEL)
+RS6000_CPU ("e500mc64", NULL, PROCESSOR_PPCE500MC64,
            MASK_POWERPC64 | MASK_PPC_GFXOPT | MASK_ISEL)
-RS6000_CPU ("e5500", PROCESSOR_PPCE5500,
+RS6000_CPU ("e5500", "ppce5500", PROCESSOR_PPCE5500,
            MASK_POWERPC64 | MASK_PPC_GFXOPT | MASK_ISEL)
-RS6000_CPU ("e6500", PROCESSOR_PPCE6500, POWERPC_7400_MASK | MASK_POWERPC64
+RS6000_CPU ("e6500", "ppce6500", PROCESSOR_PPCE6500, POWERPC_7400_MASK | 
MASK_POWERPC64
            | MASK_MFCRF | MASK_ISEL)
-RS6000_CPU ("860", PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
-RS6000_CPU ("970", PROCESSOR_POWER4,
+RS6000_CPU ("860", NULL, PROCESSOR_MPCCORE, MASK_SOFT_FLOAT)
+RS6000_CPU ("970", "ppc970", PROCESSOR_POWER4,
            POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64)
-RS6000_CPU ("cell", PROCESSOR_CELL,
+RS6000_CPU ("cell", "ppc-cell-be", PROCESSOR_CELL,
            POWERPC_7400_MASK  | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64)
-RS6000_CPU ("ec603e", PROCESSOR_PPC603, MASK_SOFT_FLOAT)
-RS6000_CPU ("G3", PROCESSOR_PPC750, MASK_PPC_GFXOPT)
-RS6000_CPU ("G4",  PROCESSOR_PPC7450, POWERPC_7400_MASK)
-RS6000_CPU ("G5", PROCESSOR_POWER4,
+RS6000_CPU ("ec603e", NULL, PROCESSOR_PPC603, MASK_SOFT_FLOAT)
+RS6000_CPU ("G3", NULL, PROCESSOR_PPC750, MASK_PPC_GFXOPT)
+RS6000_CPU ("G4", NULL, PROCESSOR_PPC7450, POWERPC_7400_MASK)
+RS6000_CPU ("G5", NULL, PROCESSOR_POWER4,
            POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64)
-RS6000_CPU ("titan", PROCESSOR_TITAN, MASK_MULHW | MASK_DLMZB)
-RS6000_CPU ("power3", PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64)
-RS6000_CPU ("power4", PROCESSOR_POWER4, MASK_POWERPC64 | MASK_PPC_GPOPT
+RS6000_CPU ("titan", NULL, PROCESSOR_TITAN, MASK_MULHW | MASK_DLMZB)
+RS6000_CPU ("power3", NULL, PROCESSOR_PPC630, MASK_PPC_GFXOPT | MASK_POWERPC64)
+RS6000_CPU ("power4", NULL, PROCESSOR_POWER4, MASK_POWERPC64 | MASK_PPC_GPOPT
            | MASK_PPC_GFXOPT | MASK_MFCRF)
-RS6000_CPU ("power5", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT
+RS6000_CPU ("power5", NULL, PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT
            | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB)
-RS6000_CPU ("power5+", PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT
+RS6000_CPU ("power5+", NULL, PROCESSOR_POWER5, MASK_POWERPC64 | MASK_PPC_GPOPT
            | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND)
-RS6000_CPU ("power6", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
+RS6000_CPU ("power6", NULL, PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
            | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
            | MASK_CMPB | MASK_DFP | MASK_RECIP_PRECISION)
-RS6000_CPU ("power6x", PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
+RS6000_CPU ("power6x", NULL, PROCESSOR_POWER6, MASK_POWERPC64 | MASK_PPC_GPOPT
            | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND
            | MASK_CMPB | MASK_DFP | MASK_MFPGPR | MASK_RECIP_PRECISION)
-RS6000_CPU ("power7", PROCESSOR_POWER7, MASK_POWERPC64 | ISA_2_6_MASKS_SERVER)
-RS6000_CPU ("power8", PROCESSOR_POWER8, MASK_POWERPC64 | ISA_2_7_MASKS_SERVER)
-RS6000_CPU ("power9", PROCESSOR_POWER9, MASK_POWERPC64 | ISA_3_0_MASKS_SERVER)
-RS6000_CPU ("powerpc", PROCESSOR_POWERPC, 0)
-RS6000_CPU ("powerpc64", PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | MASK_POWERPC64)
-RS6000_CPU ("powerpc64le", PROCESSOR_POWER8, MASK_POWERPC64 | 
ISA_2_7_MASKS_SERVER)
-RS6000_CPU ("rs64", PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64)
+RS6000_CPU ("power7", "power7+", PROCESSOR_POWER7, MASK_POWERPC64 | 
ISA_2_6_MASKS_SERVER)
+RS6000_CPU ("power8", NULL, PROCESSOR_POWER8, MASK_POWERPC64 | 
ISA_2_7_MASKS_SERVER)
+RS6000_CPU ("power9", NULL, PROCESSOR_POWER9, MASK_POWERPC64 | 
ISA_3_0_MASKS_SERVER)
+RS6000_CPU ("powerpc", NULL, PROCESSOR_POWERPC, 0)
+RS6000_CPU ("powerpc64", NULL, PROCESSOR_POWERPC64, MASK_PPC_GFXOPT | 
MASK_POWERPC64)
+RS6000_CPU ("powerpc64le", NULL, PROCESSOR_POWER8, MASK_POWERPC64 | 
ISA_2_7_MASKS_SERVER)
+RS6000_CPU ("rs64", NULL, PROCESSOR_RS64A, MASK_PPC_GFXOPT | MASK_POWERPC64)
Index: gcc/config/rs6000/driver-rs6000.c
===================================================================
--- gcc/config/rs6000/driver-rs6000.c   (revision 256364)
+++ gcc/config/rs6000/driver-rs6000.c   (working copy)
@@ -23,6 +23,7 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "diagnostic.h"
 #include <stdlib.h>
 
 #ifdef _AIX
@@ -38,6 +39,20 @@
 # include <sys/sysctl.h>
 #endif
 
+/* Processor table.  */
+struct rs6000_ptt
+{
+  const char *const name;     /* Canonical cpu name.  */
+  const char *const altname;  /* Kernel AT_PLATFORM cpu name.  */
+};
+
+static struct rs6000_ptt const rs6000_supported_cpu_names[] =
+{
+#define RS6000_CPU(NAME, ALTNAME, CPU, FLAGS) { NAME, ALTNAME },
+#include "rs6000-cpus.def"
+#undef RS6000_CPU
+};
+
 const char *host_detect_local_cpu (int argc, const char **argv);
 
 #if GCC_VERSION >= 0
@@ -158,15 +173,19 @@
 
 #ifdef __linux__
 
-/* Returns AT_PLATFORM if present, otherwise generic PowerPC.  */
+/* Returns the canonical AT_PLATFORM if present, otherwise NULL.  */
 
 static const char *
 elf_platform (void)
 {
-  int fd;
+  static const char *cpu = NULL;
 
-  fd = open ("/proc/self/auxv", O_RDONLY);
+  /* Use the cached AT_PLATFORM cpu name if we've already determined it.  */
+  if (cpu != NULL)
+    return cpu;
 
+  int fd = open ("/proc/self/auxv", O_RDONLY);
+
   if (fd != -1)
     {
       char buf[1024];
@@ -179,15 +198,53 @@
       if (n > 0)
        {
          for (av = (ElfW(auxv_t) *) buf; av->a_type != AT_NULL; ++av)
-           switch (av->a_type)
+           if (av->a_type == AT_PLATFORM)
              {
-             case AT_PLATFORM:
-               return (const char *) av->a_un.a_val;
-
-             default:
+               cpu = (const char *) av->a_un.a_val;
                break;
              }
        }
+
+      /* Verify that CPU is either a valid -mcpu=<cpu> option name, or is a
+        valid alternative name.  If it is a valid alternative name, then use
+        the canonical name.  */
+      if (cpu != NULL)
+       {
+         size_t i, len = 0;
+         char *s, *p;
+
+         for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
+           {
+             if (!strcmp (cpu, rs6000_supported_cpu_names[i].name))
+               return cpu;
+             if (rs6000_supported_cpu_names[i].altname != NULL
+                 && !strcmp (cpu, rs6000_supported_cpu_names[i].altname))
+               {
+                 cpu = rs6000_supported_cpu_names[i].name;
+                 return cpu;
+               }
+             len += strlen (rs6000_supported_cpu_names[i].name) + 1;
+           }
+
+         /* The kernel returned an AT_PLATFORM cpu name we do not support.  */
+         s = XALLOCAVEC (char, len);
+         p = s;
+         for (i = 0; i < ARRAY_SIZE (rs6000_supported_cpu_names); i++)
+           {
+             size_t arglen = strlen (rs6000_supported_cpu_names[i].name);
+             memcpy (p, rs6000_supported_cpu_names[i].name, arglen);
+             p[arglen] = ' ';
+             p += arglen + 1;
+           }
+         p[-1] = 0;
+
+         fatal_error (
+           input_location,
+           "Unsupported cpu name returned from kernel for -mcpu=native: %s\n"
+           "Please use an explicit cpu name.  Valid cpu names are: %s",
+           cpu, s);
+       }
+
     }
   return NULL;
 }
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c  (revision 256364)
+++ gcc/config/rs6000/rs6000.c  (working copy)
@@ -1990,7 +1990,7 @@
 
 static struct rs6000_ptt const processor_target_table[] =
 {
-#define RS6000_CPU(NAME, CPU, FLAGS) { NAME, CPU, FLAGS },
+#define RS6000_CPU(NAME, ALTNAME, CPU, FLAGS) { NAME, CPU, FLAGS },
 #include "rs6000-cpus.def"
 #undef RS6000_CPU
 };
Index: gcc/config/rs6000/default64.h
===================================================================
--- gcc/config/rs6000/default64.h       (revision 256364)
+++ gcc/config/rs6000/default64.h       (working copy)
@@ -18,7 +18,7 @@
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#define RS6000_CPU(NAME, CPU, FLAGS)
+#define RS6000_CPU(NAME, ALTNAME, CPU, FLAGS)
 #include "rs6000-cpus.def"
 #undef RS6000_CPU
 

Reply via email to