JDevlieghere updated this revision to Diff 250810.
JDevlieghere added a comment.

New approach. Test is coming but upload the patch so Adrian can take a look.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76261/new/

https://reviews.llvm.org/D76261

Files:
  lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
  lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
  lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp

Index: lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -185,73 +185,35 @@
 
 ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
   ModuleSP exe_module_sp(target.GetExecutableModule());
-  if (exe_module_sp) {
-    ObjectFile *objfile = exe_module_sp->GetObjectFile();
-    if (objfile) {
-      std::string xcode_contents_path;
-      std::string default_xcode_sdk;
-      FileSpec fspec;
-      llvm::VersionTuple version = objfile->GetSDKVersion();
-      if (!version.empty()) {
-        fspec = HostInfo::GetShlibDir();
-        if (fspec) {
-          std::string path;
-          xcode_contents_path = fspec.GetPath();
-          size_t pos = xcode_contents_path.find("/Xcode.app/Contents/");
-          if (pos != std::string::npos) {
-            // LLDB.framework is inside an Xcode app bundle, we can locate the
-            // SDK from here
-            xcode_contents_path.erase(pos + strlen("/Xcode.app/Contents/"));
-          } else {
-            xcode_contents_path.clear();
-            // Use the selected Xcode
-            int status = 0;
-            int signo = 0;
-            std::string output;
-            const char *command = "xcrun -sdk macosx --show-sdk-path";
-            lldb_private::Status error = RunShellCommand(
-                command,    // shell command to run
-                FileSpec(), // current working directory
-                &status,    // Put the exit status of the process in here
-                &signo,     // Put the signal that caused the process to exit in
-                            // here
-                &output, // Get the output from the command and place it in this
-                         // string
-                std::chrono::seconds(3));
-            if (status == 0 && !output.empty()) {
-              size_t first_non_newline = output.find_last_not_of("\r\n");
-              if (first_non_newline != std::string::npos)
-                output.erase(first_non_newline + 1);
-              default_xcode_sdk = output;
-
-              pos = default_xcode_sdk.find("/Xcode.app/Contents/");
-              if (pos != std::string::npos)
-                xcode_contents_path = default_xcode_sdk.substr(
-                    0, pos + strlen("/Xcode.app/Contents/"));
-            }
-          }
-        }
-
-        if (!xcode_contents_path.empty()) {
-          StreamString sdk_path;
-          sdk_path.Printf("%sDeveloper/Platforms/MacOSX.platform/Developer/"
-                          "SDKs/MacOSX%u.%u.sdk",
-                          xcode_contents_path.c_str(), version.getMajor(),
-                          version.getMinor().getValue());
-          fspec.SetFile(sdk_path.GetString(), FileSpec::Style::native);
-          if (FileSystem::Instance().Exists(fspec))
-            return ConstString(sdk_path.GetString());
-        }
+  if (!exe_module_sp)
+    return {};
+
+  ObjectFile *objfile = exe_module_sp->GetObjectFile();
+  if (!objfile)
+    return {};
+
+  llvm::VersionTuple version = objfile->GetSDKVersion();
+  if (version.empty())
+    return {};
+
+  // First try to find an SDK that matches the given SDK version.
+  if (FileSpec fspec = GetXcodeContentsDirectory()) {
+    StreamString sdk_path;
+    sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/"
+                    "SDKs/MacOSX%u.%u.sdk",
+                    fspec.GetPath().c_str(), version.getMajor(),
+                    version.getMinor().getValue());
+    if (FileSystem::Instance().Exists(fspec))
+      return ConstString(sdk_path.GetString());
+  }
 
-        if (!default_xcode_sdk.empty()) {
-          fspec.SetFile(default_xcode_sdk, FileSpec::Style::native);
-          if (FileSystem::Instance().Exists(fspec))
-            return ConstString(default_xcode_sdk);
-        }
-      }
-    }
+  // Use the default SDK as a fallback.
+  if (FileSpec fspec = GetXcodeSDK(SDKType::MacOSX)) {
+    if (FileSystem::Instance().Exists(fspec))
+      return ConstString(fspec.GetPath());
   }
-  return ConstString();
+
+  return {};
 }
 
 Status PlatformMacOSX::GetSymbolFile(const FileSpec &platform_file,
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -79,10 +79,17 @@
   static std::tuple<llvm::VersionTuple, llvm::StringRef>
   ParseVersionBuildDir(llvm::StringRef str);
 
-  enum SDKType : unsigned {
+  enum SDKType : int {
     MacOSX = 0,
     iPhoneSimulator,
     iPhoneOS,
+    AppleTVSimulator,
+    AppleTVOS,
+    WatchSimulator,
+    watchOS,
+    Linux,
+    numSDKTypes,
+    unknown = -1
   };
 
   llvm::Expected<lldb_private::StructuredData::DictionarySP>
@@ -160,7 +167,13 @@
       const lldb_private::FileSpecList *module_search_paths_ptr,
       lldb::ModuleSP *old_module_sp_ptr, bool *did_create_ptr);
 
+  static llvm::StringRef GetSDKNameForType(SDKType type);
+  static lldb_private::FileSpec GetXcodeSDK(SDKType type);
+  static lldb_private::FileSpec GetXcodeContentsDirectory();
+
 protected:
+  static std::string FindXcodeContentsDirectoryInPath(llvm::StringRef path);
+
   std::string m_developer_directory;
 
 private:
Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -1268,9 +1268,9 @@
   m_trap_handlers.push_back(ConstString("_sigtramp"));
 }
 
-static const char *const sdk_strings[] = {
-    "MacOSX", "iPhoneSimulator", "iPhoneOS",
-};
+const char *const sdk_strings[] = {
+    "macosx",    "iphonesimulator", "iphoneos", "appletvsimulator",
+    "appletvos", "watchsimulator",  "watchos",  "linux"};
 
 static FileSpec CheckPathForXcode(const FileSpec &fspec) {
   if (FileSystem::Instance().Exists(fspec)) {
@@ -1360,6 +1360,8 @@
   case SDKType::iPhoneOS:
   case SDKType::iPhoneSimulator:
     return version >= llvm::VersionTuple(8);
+  default:
+    return false;
   }
 
   return false;
@@ -1370,7 +1372,7 @@
   ConstString last_path_component = sdk_path.GetLastPathComponent();
 
   if (last_path_component) {
-    const llvm::StringRef sdk_name = last_path_component.GetStringRef();
+    const llvm::StringRef sdk_name = last_path_component.GetStringRef().lower();
 
     if (!sdk_name.startswith(sdk_strings[desired_type]))
       return false;
@@ -1427,13 +1429,6 @@
 }
 
 FileSpec PlatformDarwin::GetSDKDirectoryForModules(SDKType sdk_type) {
-  switch (sdk_type) {
-  case SDKType::MacOSX:
-  case SDKType::iPhoneSimulator:
-  case SDKType::iPhoneOS:
-    break;
-  }
-
   FileSpec sdks_spec = GetXcodeContentsPath();
   sdks_spec.AppendPathComponent("Developer");
   sdks_spec.AppendPathComponent("Platforms");
@@ -1448,6 +1443,8 @@
   case SDKType::iPhoneOS:
     sdks_spec.AppendPathComponent("iPhoneOS.platform");
     break;
+  default:
+    llvm_unreachable("unsupported sdk");
   }
 
   sdks_spec.AppendPathComponent("Developer");
@@ -1656,6 +1653,8 @@
     use_current_os_version = false;
 #endif
     break;
+  default:
+    break;
   }
 
   llvm::VersionTuple version;
@@ -1685,6 +1684,9 @@
     case SDKType::MacOSX:
       minimum_version_option.PutCString("-mmacosx-version-min=");
       minimum_version_option.PutCString(version.getAsString());
+      break;
+    default:
+      llvm_unreachable("unsupported sdk");
     }
     options.push_back(std::string(minimum_version_option.GetString()));
   }
@@ -1816,12 +1818,10 @@
   return PlatformPOSIX::LaunchProcess(launch_info);
 }
 
-lldb_private::Status
-PlatformDarwin::FindBundleBinaryInExecSearchPaths (const ModuleSpec &module_spec, Process *process, 
-                                                   ModuleSP &module_sp, 
-                                                   const FileSpecList *module_search_paths_ptr, 
-                                                   ModuleSP *old_module_sp_ptr, bool *did_create_ptr)
-{
+lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths(
+    const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
+    const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
+    bool *did_create_ptr) {
   const FileSpec &platform_file = module_spec.GetFileSpec();
   // See if the file is present in any of the module_search_paths_ptr
   // directories.
@@ -1892,3 +1892,100 @@
   }
   return Status();
 }
+
+std::string
+PlatformDarwin::FindXcodeContentsDirectoryInPath(llvm::StringRef path) {
+  auto begin = llvm::sys::path::begin(path);
+  auto end = llvm::sys::path::end(path);
+
+  // Iterate over the path components until we find something that ends with
+  // .app. If the next component is Contents then we've found the Contents
+  // directory.
+  for (auto it = begin; it != end; ++it) {
+    if (it->endswith(".app")) {
+      auto next = it;
+      if (++next != end && *next == "Contents") {
+        llvm::SmallString<128> buffer;
+        llvm::sys::path::append(buffer, begin, ++next);
+        return buffer.str().str();
+      }
+    }
+  }
+
+  return {};
+}
+
+llvm::StringRef PlatformDarwin::GetSDKNameForType(SDKType type) {
+  if (type != SDKType::unknown)
+    return sdk_strings[type];
+  return "unknown";
+}
+
+FileSpec PlatformDarwin::GetXcodeSDK(SDKType type) {
+  std::string xcrun_cmd =
+      "xcrun --show-sdk-path -sdk " + GetSDKNameForType(type).str();
+
+  int status = 0;
+  int signo = 0;
+  std::string output_str;
+  lldb_private::Status error =
+      Host::RunShellCommand(xcrun_cmd.c_str(), FileSpec(), &status, &signo,
+                            &output_str, std::chrono::seconds(15));
+
+  // Check that xcrun return something useful.
+  if (status != 0 || output_str.empty())
+    return {};
+
+  // Convert to a StringRef so we can manipulate the string without modifying
+  // the underlying data.
+  llvm::StringRef output(output_str);
+
+  // Remove any trailing newline characters.
+  output = output.rtrim();
+
+  // Strip any leading newline characters and everything before them.
+  const size_t last_newline = output.rfind('\n');
+  if (last_newline != llvm::StringRef::npos)
+    output = output.substr(last_newline + 1);
+
+  // Whatever is left in output should be a valid path.
+  if (!FileSystem::Instance().Exists(output))
+    return {};
+
+  // Find the contents dir in the xcrun provided path.
+  std::string xcode_contents_dir = FindXcodeContentsDirectoryInPath(output);
+  if (xcode_contents_dir.empty())
+    return {};
+
+  return FileSpec(xcode_contents_dir);
+}
+
+FileSpec PlatformDarwin::GetXcodeContentsDirectory() {
+  static FileSpec g_xcode_contents_path;
+  static std::once_flag g_once_flag;
+  std::call_once(g_once_flag, [&]() {
+    // Try the shlib dir first.
+    if (FileSpec fspec = HostInfo::GetShlibDir()) {
+      if (FileSystem::Instance().Exists(fspec)) {
+        std::string xcode_contents_dir =
+            FindXcodeContentsDirectoryInPath(fspec.GetPath());
+        if (!xcode_contents_dir.empty()) {
+          g_xcode_contents_path = FileSpec(xcode_contents_dir);
+          return;
+        }
+      }
+    }
+
+    if (FileSpec fspec = GetXcodeSDK(SDKType::MacOSX)) {
+      if (FileSystem::Instance().Exists(fspec)) {
+        std::string xcode_contents_dir =
+            FindXcodeContentsDirectoryInPath(fspec.GetPath());
+        if (!xcode_contents_dir.empty()) {
+          g_xcode_contents_path = FileSpec(xcode_contents_dir);
+          return;
+        }
+      }
+    }
+  });
+  return g_xcode_contents_path;
+}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to