Subject: bug#52330: Different processor architecture on Apple M1 CPU

From: Paul Eggert <[email-masked]>
Date: Mon, 6 Dec 2021 14:41:28 -0800

On 12/6/21 06:53, Jakub Sokołowski via GNU coreutils Bug Reports wrote:
> I've identified an issue with GNU Coreutils uname utility. Specifically
> with the value it returns for the processor type/architecture(-p). When
> used on a MacOS with M1 arm64 processor the returned value is amr64, but
> the default uname utility on MacOS returns arm.

Does the attached patch fix things for you? Unfortunately I don't have 
access to macOS to test it.

From 202befd373ea4c851e4c3be85c52eeb108c6c7be Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Mon, 6 Dec 2021 14:39:22 -0800
Subject: [PATCH] uname: port to recent macOS
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Problem reported by Jakub Sokołowski (bug #52330).
* src/uname.c [__APPLE__]: Don’t include sys/syctl.h,
mach/machine.h, mach-o/arch.h.
(print_element_env): New function.
(main): Use it.  For -p with __APPLE__, rely on predefined macros
and omit any 64-bit indication, for compatibility with macOS uname.
---
 src/uname.c | 75 ++++++++++++++++++++++++++++-------------------------
 1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/src/uname.c b/src/uname.c
index ae9b8e29d..e84fc477a 100644
--- a/src/uname.c
+++ b/src/uname.c
@@ -27,7 +27,7 @@
 # include <sys/systeminfo.h>
 #endif
 
-#if HAVE_SYS_SYSCTL_H && ! defined __GLIBC__
+#if HAVE_SYS_SYSCTL_H && ! defined __GLIBC__ && ! defined __APPLE__
 # if HAVE_SYS_PARAM_H
 #  include <sys/param.h> /* needed for OpenBSD 3.0 */
 # endif
@@ -44,11 +44,6 @@
 # endif
 #endif
 
-#ifdef __APPLE__
-# include <mach/machine.h>
-# include <mach-o/arch.h>
-#endif
-
 #include "system.h"
 #include "die.h"
 #include "error.h"
@@ -167,6 +162,24 @@ print_element (char const *element)
   fputs (element, stdout);
 }
 
+/* Print ELEMENT, preceded by a space if something has already been
+   printed.  But if the environment variable ENVVAR is set, print its
+   value instead of ELEMENT.  */
+
+static void
+print_element_env (char const *element, MAYBE_UNUSED char const *envvar)
+{
+#ifdef __APPLE__
+  if (envvar)
+    {
+      char const *val = getenv (envvar);
+      if (val)
+        element = val;
+    }
+#endif
+  print_element (element);
+}
+
 
 /* Set all the option flags according to the switches specified.
    Return the mask indicating which elements to print.  */
@@ -287,26 +300,36 @@ main (int argc, char **argv)
         die (EXIT_FAILURE, errno, _("cannot get system name"));
 
       if (toprint & PRINT_KERNEL_NAME)
-        print_element (name.sysname);
+        print_element_env (name.sysname, "UNAME_SYSNAME");
       if (toprint & PRINT_NODENAME)
-        print_element (name.nodename);
+        print_element_env (name.nodename, "UNAME_NODENAME");
       if (toprint & PRINT_KERNEL_RELEASE)
-        print_element (name.release);
+        print_element_env (name.release, "UNAME_RELEASE");
       if (toprint & PRINT_KERNEL_VERSION)
-        print_element (name.version);
+        print_element_env (name.version, "UNAME_VERSION");
       if (toprint & PRINT_MACHINE)
-        print_element (name.machine);
+        print_element_env (name.machine, "UNAME_MACHINE");
     }
 
   if (toprint & PRINT_PROCESSOR)
     {
       char const *element = unknown;
+#ifdef __APPLE__
+# if defined __arm__ || defined __arm64__
+      element = "arm";
+# elif defined __i386__ || defined __x86_64__
+      element = "i386";
+# elif defined __ppc__ || defined __ppc64__
+      element = "powerpc";
+# endif
+#endif
 #if HAVE_SYSINFO && defined SI_ARCHITECTURE
-      {
-        static char processor[257];
-        if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
-          element = processor;
-      }
+      if (element == unknown)
+        {
+          static char processor[257];
+          if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor))
+            element = processor;
+        }
 #endif
 #ifdef UNAME_PROCESSOR
       if (element == unknown)
@@ -316,26 +339,6 @@ main (int argc, char **argv)
           static int mib[] = { CTL_HW, UNAME_PROCESSOR };
           if (sysctl (mib, 2, processor, &s, 0, 0) >= 0)
             element = processor;
-
-# ifdef __APPLE__
-          /* This kludge works around a bug in Mac OS X.  */
-          if (element == unknown)
-            {
-              cpu_type_t cputype;
-              size_t cs = sizeof cputype;
-              NXArchInfo const *ai;
-              if (sysctlbyname ("hw.cputype", &cputype, &cs, NULL, 0) == 0
-                  && (ai = NXGetArchInfoFromCpuType (cputype,
-                                                     CPU_SUBTYPE_MULTIPLE))
-                  != NULL)
-                element = ai->name;
-
-              /* Hack "safely" around the ppc vs. powerpc return value. */
-              if (cputype == CPU_TYPE_POWERPC
-                  && STRNCMP_LIT (element, "ppc") == 0)
-                element = "powerpc";
-            }
-# endif
         }
 #endif
       if (! (toprint == UINT_MAX && element == unknown))
-- 
2.33.1