JDevlieghere created this revision.
JDevlieghere added reviewers: friss, jasonmolenda.
JDevlieghere requested review of this revision.

Honor the CPU type (and subtype) when launching the inferior on macOS. Part of 
this functionality was thought to be no longer needed and removed in 
`85bd4369610fe60397455c8e0914a09288285e84`, however it's still needed, for 
example to launch binaries under Rosetta 2 on Apple Silicon. This patch will 
use `posix_spawnattr_setarchpref_np` if available and fallback to 
`posix_spawnattr_setbinpref_np` if not.


https://reviews.llvm.org/D95922

Files:
  lldb/source/Host/macosx/objcxx/Host.mm


Index: lldb/source/Host/macosx/objcxx/Host.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/Host.mm
+++ lldb/source/Host/macosx/objcxx/Host.mm
@@ -38,6 +38,7 @@
 
 #include <asl.h>
 #include <crt_externs.h>
+#include <dlfcn.h>
 #include <grp.h>
 #include <libproc.h>
 #include <pwd.h>
@@ -1108,6 +1109,49 @@
     }
   }
 
+  // Don't set the binpref if a shell was provided. After all, that's only
+  // going to affect what version of the shell is launched, not what fork of
+  // the binary is launched.  We insert "arch --arch <ARCH> as part of the
+  // shell invocation to do that job on OSX.
+  if (launch_info.GetShell() == FileSpec()) {
+    const ArchSpec &arch_spec = launch_info.GetArchitecture();
+    cpu_type_t cpu_type = arch_spec.GetMachOCPUType();
+    cpu_type_t cpu_subtype = arch_spec.GetMachOCPUSubType();
+    if (cpu_type != 0 && cpu_type != static_cast<cpu_type_t>(UINT32_MAX) &&
+        cpu_type != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE)) {
+      size_t ocount = 0;
+      typedef int (*posix_spawnattr_setarchpref_np_t)(
+          posix_spawnattr_t *, size_t, cpu_type_t *, cpu_subtype_t *, size_t 
*);
+      posix_spawnattr_setarchpref_np_t posix_spawnattr_setarchpref_np_fn =
+          (posix_spawnattr_setarchpref_np_t)dlsym(
+              RTLD_DEFAULT, "posix_spawnattr_setarchpref_np");
+      if (posix_spawnattr_setarchpref_np_fn) {
+        error.SetError((*posix_spawnattr_setarchpref_np_fn)(
+                           &attr, 1, &cpu_type, &cpu_subtype, &ocount),
+                       eErrorTypePOSIX);
+        if (error.Fail())
+          LLDB_LOG(log,
+                   "error: {0}, ::posix_spawnattr_setarchpref_np ( &attr, 1, "
+                   "cpu_type = {1:x}, cpu_subtype = {1:x}, count => {2} )",
+                   error, cpu_type, cpu_subtype, ocount);
+
+        if (error.Fail() || ocount != 1)
+          return error;
+      } else {
+        error.SetError(
+            ::posix_spawnattr_setbinpref_np(&attr, 1, &cpu_type, &ocount),
+            eErrorTypePOSIX);
+        if (error.Fail())
+          LLDB_LOG(log,
+                   "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, "
+                   "cpu_type = {1:x}, count => {2} )",
+                   error, cpu_type, ocount);
+        if (error.Fail() || ocount != 1)
+          return error;
+      }
+    }
+  }
+
   const char *tmp_argv[2];
   char *const *argv = const_cast<char *const *>(
       launch_info.GetArguments().GetConstArgumentVector());


Index: lldb/source/Host/macosx/objcxx/Host.mm
===================================================================
--- lldb/source/Host/macosx/objcxx/Host.mm
+++ lldb/source/Host/macosx/objcxx/Host.mm
@@ -38,6 +38,7 @@
 
 #include <asl.h>
 #include <crt_externs.h>
+#include <dlfcn.h>
 #include <grp.h>
 #include <libproc.h>
 #include <pwd.h>
@@ -1108,6 +1109,49 @@
     }
   }
 
+  // Don't set the binpref if a shell was provided. After all, that's only
+  // going to affect what version of the shell is launched, not what fork of
+  // the binary is launched.  We insert "arch --arch <ARCH> as part of the
+  // shell invocation to do that job on OSX.
+  if (launch_info.GetShell() == FileSpec()) {
+    const ArchSpec &arch_spec = launch_info.GetArchitecture();
+    cpu_type_t cpu_type = arch_spec.GetMachOCPUType();
+    cpu_type_t cpu_subtype = arch_spec.GetMachOCPUSubType();
+    if (cpu_type != 0 && cpu_type != static_cast<cpu_type_t>(UINT32_MAX) &&
+        cpu_type != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE)) {
+      size_t ocount = 0;
+      typedef int (*posix_spawnattr_setarchpref_np_t)(
+          posix_spawnattr_t *, size_t, cpu_type_t *, cpu_subtype_t *, size_t *);
+      posix_spawnattr_setarchpref_np_t posix_spawnattr_setarchpref_np_fn =
+          (posix_spawnattr_setarchpref_np_t)dlsym(
+              RTLD_DEFAULT, "posix_spawnattr_setarchpref_np");
+      if (posix_spawnattr_setarchpref_np_fn) {
+        error.SetError((*posix_spawnattr_setarchpref_np_fn)(
+                           &attr, 1, &cpu_type, &cpu_subtype, &ocount),
+                       eErrorTypePOSIX);
+        if (error.Fail())
+          LLDB_LOG(log,
+                   "error: {0}, ::posix_spawnattr_setarchpref_np ( &attr, 1, "
+                   "cpu_type = {1:x}, cpu_subtype = {1:x}, count => {2} )",
+                   error, cpu_type, cpu_subtype, ocount);
+
+        if (error.Fail() || ocount != 1)
+          return error;
+      } else {
+        error.SetError(
+            ::posix_spawnattr_setbinpref_np(&attr, 1, &cpu_type, &ocount),
+            eErrorTypePOSIX);
+        if (error.Fail())
+          LLDB_LOG(log,
+                   "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, "
+                   "cpu_type = {1:x}, count => {2} )",
+                   error, cpu_type, ocount);
+        if (error.Fail() || ocount != 1)
+          return error;
+      }
+    }
+  }
+
   const char *tmp_argv[2];
   char *const *argv = const_cast<char *const *>(
       launch_info.GetArguments().GetConstArgumentVector());
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to