This revision was automatically updated to reflect the committed changes.
Closed by commit rLLDB355032: Move Host/Symbols.cpp to 
Symbols/LocateSymbolFile.cpp (authored by zturner, committed by ).
Herald added subscribers: abidh, krytarowski.
Herald added a project: LLDB.

Changed prior to commit:
  https://reviews.llvm.org/D58730?vs=188587&id=188613#toc

Repository:
  rLLDB LLDB

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

https://reviews.llvm.org/D58730

Files:
  include/lldb/Host/Symbols.h
  include/lldb/Symbol/LocateSymbolFile.h
  include/lldb/module.modulemap
  source/Commands/CommandObjectTarget.cpp
  source/Core/ModuleList.cpp
  source/Host/CMakeLists.txt
  source/Host/common/Symbols.cpp
  source/Host/macosx/Symbols.cpp
  source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
  source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
  source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
  source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
  source/Symbol/CMakeLists.txt
  source/Symbol/LocateSymbolFile.cpp
  source/Symbol/LocateSymbolFileMacOSX.cpp
  unittests/Host/CMakeLists.txt
  unittests/Host/SymbolsTest.cpp
  unittests/Symbol/CMakeLists.txt
  unittests/Symbol/LocateSymbolFileTest.cpp

Index: include/lldb/module.modulemap
===================================================================
--- include/lldb/module.modulemap
+++ include/lldb/module.modulemap
@@ -48,7 +48,6 @@
   module SocketAddress { header "Host/SocketAddress.h" export * }
   module Socket { header "Host/Socket.h" export * }
   module StringConvert { textual header "Host/StringConvert.h" export * }
-  module Symbols { header "Host/Symbols.h" export * }
   module TaskPool { header "Host/TaskPool.h" export * }
   module Terminal { header "Host/Terminal.h" export * }
   module ThreadLauncher { header "Host/ThreadLauncher.h" export * }
Index: include/lldb/Symbol/LocateSymbolFile.h
===================================================================
--- include/lldb/Symbol/LocateSymbolFile.h
+++ include/lldb/Symbol/LocateSymbolFile.h
@@ -0,0 +1,61 @@
+//===-- Symbols.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Symbols_h_
+#define liblldb_Symbols_h_
+
+#include <stdint.h>
+
+#include "lldb/Utility/FileSpec.h"
+
+namespace lldb_private {
+
+class ArchSpec;
+class ModuleSpec;
+class UUID;
+
+class Symbols {
+public:
+  //----------------------------------------------------------------------
+  // Locate the executable file given a module specification.
+  //
+  // Locating the file should happen only on the local computer or using the
+  // current computers global settings.
+  //----------------------------------------------------------------------
+  static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec);
+
+  //----------------------------------------------------------------------
+  // Locate the symbol file given a module specification.
+  //
+  // Locating the file should happen only on the local computer or using the
+  // current computers global settings.
+  //----------------------------------------------------------------------
+  static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec);
+
+  static FileSpec FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
+                                         const lldb_private::UUID *uuid,
+                                         const ArchSpec *arch);
+
+  //----------------------------------------------------------------------
+  // Locate the object and symbol file given a module specification.
+  //
+  // Locating the file can try to download the file from a corporate build
+  // repository, or using any other means necessary to locate both the
+  // unstripped object file and the debug symbols. The force_lookup argument
+  // controls whether the external program is called unconditionally to find
+  // the symbol file, or if the user's settings are checked to see if they've
+  // enabled the external program before calling.
+  //
+  //----------------------------------------------------------------------
+  static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+                                          bool force_lookup = true);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Symbols_h_
Index: unittests/Host/CMakeLists.txt
===================================================================
--- unittests/Host/CMakeLists.txt
+++ unittests/Host/CMakeLists.txt
@@ -9,7 +9,6 @@
   ProcessLaunchInfoTest.cpp
   SocketAddressTest.cpp
   SocketTest.cpp
-  SymbolsTest.cpp
   TaskPoolTest.cpp
 )
 
Index: unittests/Symbol/LocateSymbolFileTest.cpp
===================================================================
--- unittests/Symbol/LocateSymbolFileTest.cpp
+++ unittests/Symbol/LocateSymbolFileTest.cpp
@@ -0,0 +1,48 @@
+//===-- SymbolsTest.cpp -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
+
+using namespace lldb_private;
+
+namespace {
+class SymbolsTest : public ::testing::Test {
+public:
+  void SetUp() override {
+    FileSystem::Initialize();
+    HostInfo::Initialize();
+  }
+  void TearDown() override {
+    HostInfo::Terminate();
+    FileSystem::Terminate();
+  }
+};
+} // namespace
+
+TEST_F(
+    SymbolsTest,
+    TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
+  ModuleSpec module_spec;
+  FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
+  EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
+}
+
+TEST_F(SymbolsTest,
+       LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
+  ModuleSpec module_spec;
+  // using a GUID here because the symbol file shouldn't actually exist on disk
+  module_spec.GetSymbolFileSpec().SetFile(
+      "4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native);
+  FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
+  EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
+}
Index: unittests/Symbol/CMakeLists.txt
===================================================================
--- unittests/Symbol/CMakeLists.txt
+++ unittests/Symbol/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_lldb_unittest(SymbolTests
+  LocateSymbolFileTest.cpp
   TestClangASTContext.cpp
   TestDWARFCallFrameInfo.cpp
   TestType.cpp
Index: source/Core/ModuleList.cpp
===================================================================
--- source/Core/ModuleList.cpp
+++ source/Core/ModuleList.cpp
@@ -11,10 +11,10 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Interpreter/OptionValueFileSpec.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/VariableList.h"
Index: source/Symbol/LocateSymbolFile.cpp
===================================================================
--- source/Symbol/LocateSymbolFile.cpp
+++ source/Symbol/LocateSymbolFile.cpp
@@ -0,0 +1,388 @@
+//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/LocateSymbolFile.h"
+
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+#include "lldb/Utility/UUID.h"
+
+#include "llvm/Support/FileSystem.h"
+
+// From MacOSX system header "mach/machine.h"
+typedef int cpu_type_t;
+typedef int cpu_subtype_t;
+
+using namespace lldb;
+using namespace lldb_private;
+
+#if defined(__APPLE__)
+
+// Forward declaration of method defined in source/Host/macosx/Symbols.cpp
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+                                       ModuleSpec &return_module_spec);
+
+#else
+
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+                                       ModuleSpec &return_module_spec) {
+  // Cannot find MacOSX files using debug symbols on non MacOSX.
+  return 0;
+}
+
+#endif
+
+static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
+                                          const ArchSpec *arch,
+                                          const lldb_private::UUID *uuid) {
+  ModuleSpecList module_specs;
+  if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
+    ModuleSpec spec;
+    for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+      bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+      UNUSED_IF_ASSERT_DISABLED(got_spec);
+      assert(got_spec);
+      if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+          (arch == NULL || (spec.GetArchitecturePtr() &&
+                            spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
+// return true if there is a matching dSYM bundle next to the exec_fspec,
+// and return that value in dsym_fspec.
+// If there is a .dSYM.yaa compressed archive next to the exec_fspec,
+// call through Symbols::DownloadObjectAndSymbolFile to download the
+// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
+
+static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
+                                            const FileSpec &exec_fspec,
+                                            FileSpec &dsym_fspec) {
+  ConstString filename = exec_fspec.GetFilename();
+  FileSpec dsym_directory = exec_fspec;
+  dsym_directory.RemoveLastPathComponent();
+
+  std::string dsym_filename = filename.AsCString();
+  dsym_filename += ".dSYM";
+  dsym_directory.AppendPathComponent(dsym_filename);
+  dsym_directory.AppendPathComponent("Contents");
+  dsym_directory.AppendPathComponent("Resources");
+  dsym_directory.AppendPathComponent("DWARF");
+
+  if (FileSystem::Instance().Exists(dsym_directory)) {
+
+    // See if the binary name exists in the dSYM DWARF
+    // subdir.
+    dsym_fspec = dsym_directory;
+    dsym_fspec.AppendPathComponent(filename.AsCString());
+    if (FileSystem::Instance().Exists(dsym_fspec) &&
+        FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
+                                      mod_spec.GetUUIDPtr())) {
+      return true;
+    }
+
+    // See if we have "../CF.framework" - so we'll look for
+    // CF.framework.dSYM/Contents/Resources/DWARF/CF
+    // We need to drop the last suffix after '.' to match
+    // 'CF' in the DWARF subdir.
+    std::string binary_name(filename.AsCString());
+    auto last_dot = binary_name.find_last_of('.');
+    if (last_dot != std::string::npos) {
+      binary_name.erase(last_dot);
+      dsym_fspec = dsym_directory;
+      dsym_fspec.AppendPathComponent(binary_name);
+      if (FileSystem::Instance().Exists(dsym_fspec) &&
+          FileAtPathContainsArchAndUUID(dsym_fspec,
+                                        mod_spec.GetArchitecturePtr(),
+                                        mod_spec.GetUUIDPtr())) {
+        return true;
+      }
+    }
+  }
+
+  // See if we have a .dSYM.yaa next to this executable path.
+  FileSpec dsym_yaa_fspec = exec_fspec;
+  dsym_yaa_fspec.RemoveLastPathComponent();
+  std::string dsym_yaa_filename = filename.AsCString();
+  dsym_yaa_filename += ".dSYM.yaa";
+  dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
+
+  if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
+    ModuleSpec mutable_mod_spec = mod_spec;
+    if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) &&
+        FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
+      dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
+      return true;
+    }
+  }
+
+  return false;
+}
+
+// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
+// filled in, look for a .dSYM bundle next to that binary.  Returns true
+// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
+// FileSpec.
+//
+// This routine looks a few directory layers above the given exec_path -
+// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
+// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
+//
+// If there is a .dSYM.yaa compressed archive found next to the binary,
+// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
+
+static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
+                                              FileSpec &dsym_fspec) {
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+  const FileSpec &exec_fspec = module_spec.GetFileSpec();
+  if (exec_fspec) {
+    if (::LookForDsymNextToExecutablePath(module_spec, exec_fspec,
+                                          dsym_fspec)) {
+      if (log) {
+        log->Printf("dSYM with matching UUID & arch found at %s",
+                    dsym_fspec.GetPath().c_str());
+      }
+      return true;
+    } else {
+      FileSpec parent_dirs = exec_fspec;
+
+      // Remove the binary name from the FileSpec
+      parent_dirs.RemoveLastPathComponent();
+
+      // Add a ".dSYM" name to each directory component of the path,
+      // stripping off components.  e.g. we may have a binary like
+      // /S/L/F/Foundation.framework/Versions/A/Foundation and
+      // /S/L/F/Foundation.framework.dSYM
+      //
+      // so we'll need to start with
+      // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
+      // "A", and if that doesn't exist, strip off the "A" and try it again
+      // with "Versions", etc., until we find a dSYM bundle or we've
+      // stripped off enough path components that there's no need to
+      // continue.
+
+      for (int i = 0; i < 4; i++) {
+        // Does this part of the path have a "." character - could it be a
+        // bundle's top level directory?
+        const char *fn = parent_dirs.GetFilename().AsCString();
+        if (fn == nullptr)
+          break;
+        if (::strchr(fn, '.') != nullptr) {
+          if (::LookForDsymNextToExecutablePath(module_spec, parent_dirs,
+                                                dsym_fspec)) {
+            if (log) {
+              log->Printf("dSYM with matching UUID & arch found at %s",
+                          dsym_fspec.GetPath().c_str());
+            }
+            return true;
+          }
+        }
+        parent_dirs.RemoveLastPathComponent();
+      }
+    }
+  }
+  dsym_fspec.Clear();
+  return false;
+}
+
+static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
+  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+  const ArchSpec *arch = module_spec.GetArchitecturePtr();
+  const UUID *uuid = module_spec.GetUUIDPtr();
+
+  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+  Timer scoped_timer(
+      func_cat,
+      "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
+      exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
+      arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
+
+  FileSpec symbol_fspec;
+  ModuleSpec dsym_module_spec;
+  // First try and find the dSYM in the same directory as the executable or in
+  // an appropriate parent directory
+  if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
+    // We failed to easily find the dSYM above, so use DebugSymbols
+    LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
+  } else {
+    dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
+  }
+  return dsym_module_spec.GetSymbolFileSpec();
+}
+
+ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
+  ModuleSpec result;
+  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+  const ArchSpec *arch = module_spec.GetArchitecturePtr();
+  const UUID *uuid = module_spec.GetUUIDPtr();
+  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+  Timer scoped_timer(
+      func_cat, "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
+      exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
+      arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
+
+  ModuleSpecList module_specs;
+  ModuleSpec matched_module_spec;
+  if (exec_fspec &&
+      ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) &&
+      module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) {
+    result.GetFileSpec() = exec_fspec;
+  } else {
+    LocateMacOSXFilesUsingDebugSymbols(module_spec, result);
+  }
+  return result;
+}
+
+// Keep "symbols.enable-external-lookup" description in sync with this function.
+
+FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
+  FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
+  if (symbol_file_spec.IsAbsolute() &&
+      FileSystem::Instance().Exists(symbol_file_spec))
+    return symbol_file_spec;
+
+  const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
+  if (symbol_filename && symbol_filename[0]) {
+    FileSpecList debug_file_search_paths(
+        Target::GetDefaultDebugFileSearchPaths());
+
+    // Add module directory.
+    FileSpec module_file_spec = module_spec.GetFileSpec();
+    // We keep the unresolved pathname if it fails.
+    FileSystem::Instance().ResolveSymbolicLink(module_file_spec,
+                                               module_file_spec);
+
+    const ConstString &file_dir = module_file_spec.GetDirectory();
+    {
+      FileSpec file_spec(file_dir.AsCString("."));
+      FileSystem::Instance().Resolve(file_spec);
+      debug_file_search_paths.AppendIfUnique(file_spec);
+    }
+
+    if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+
+      // Add current working directory.
+      {
+        FileSpec file_spec(".");
+        FileSystem::Instance().Resolve(file_spec);
+        debug_file_search_paths.AppendIfUnique(file_spec);
+      }
+
+#ifndef _WIN32
+#if defined(__NetBSD__)
+      // Add /usr/libdata/debug directory.
+      {
+        FileSpec file_spec("/usr/libdata/debug");
+        FileSystem::Instance().Resolve(file_spec);
+        debug_file_search_paths.AppendIfUnique(file_spec);
+      }
+#else
+      // Add /usr/lib/debug directory.
+      {
+        FileSpec file_spec("/usr/lib/debug");
+        FileSystem::Instance().Resolve(file_spec);
+        debug_file_search_paths.AppendIfUnique(file_spec);
+      }
+#endif
+#endif // _WIN32
+    }
+
+    std::string uuid_str;
+    const UUID &module_uuid = module_spec.GetUUID();
+    if (module_uuid.IsValid()) {
+      // Some debug files are stored in the .build-id directory like this:
+      //   /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
+      uuid_str = module_uuid.GetAsString("");
+      std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
+                     ::tolower);
+      uuid_str.insert(2, 1, '/');
+      uuid_str = uuid_str + ".debug";
+    }
+
+    size_t num_directories = debug_file_search_paths.GetSize();
+    for (size_t idx = 0; idx < num_directories; ++idx) {
+      FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+      FileSystem::Instance().Resolve(dirspec);
+      if (!FileSystem::Instance().IsDirectory(dirspec))
+        continue;
+
+      std::vector<std::string> files;
+      std::string dirname = dirspec.GetPath();
+
+      files.push_back(dirname + "/" + symbol_filename);
+      files.push_back(dirname + "/.debug/" + symbol_filename);
+      files.push_back(dirname + "/.build-id/" + uuid_str);
+
+      // Some debug files may stored in the module directory like this:
+      //   /usr/lib/debug/usr/lib/library.so.debug
+      if (!file_dir.IsEmpty())
+        files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename);
+
+      const uint32_t num_files = files.size();
+      for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
+        const std::string &filename = files[idx_file];
+        FileSpec file_spec(filename);
+        FileSystem::Instance().Resolve(file_spec);
+
+        if (llvm::sys::fs::equivalent(file_spec.GetPath(),
+                                      module_file_spec.GetPath()))
+          continue;
+
+        if (FileSystem::Instance().Exists(file_spec)) {
+          lldb_private::ModuleSpecList specs;
+          const size_t num_specs =
+              ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
+          assert(num_specs <= 1 &&
+                 "Symbol Vendor supports only a single architecture");
+          if (num_specs == 1) {
+            ModuleSpec mspec;
+            if (specs.GetModuleSpecAtIndex(0, mspec)) {
+              // Skip the uuids check if module_uuid is invalid. For example,
+              // this happens for *.dwp files since at the moment llvm-dwp
+              // doesn't output build ids, nor does binutils dwp.
+              if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
+                return file_spec;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return LocateExecutableSymbolFileDsym(module_spec);
+}
+
+#if !defined(__APPLE__)
+
+FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
+                                         const lldb_private::UUID *uuid,
+                                         const ArchSpec *arch) {
+  // FIXME
+  return FileSpec();
+}
+
+bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+                                          bool force_lookup) {
+  // Fill in the module_spec.GetFileSpec() for the object file and/or the
+  // module_spec.GetSymbolFileSpec() for the debug symbols file.
+  return false;
+}
+
+#endif
Index: source/Symbol/LocateSymbolFileMacOSX.cpp
===================================================================
--- source/Symbol/LocateSymbolFileMacOSX.cpp
+++ source/Symbol/LocateSymbolFileMacOSX.cpp
@@ -0,0 +1,653 @@
+//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Symbol/LocateSymbolFile.h"
+
+#include <dirent.h>
+#include <pwd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include "Host/macosx/cfcpp/CFCBundle.h"
+#include "Host/macosx/cfcpp/CFCData.h"
+#include "Host/macosx/cfcpp/CFCReleaser.h"
+#include "Host/macosx/cfcpp/CFCString.h"
+#include "lldb/Core/ModuleList.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/Timer.h"
+#include "lldb/Utility/UUID.h"
+#include "mach/machine.h"
+
+#include "llvm/Support/FileSystem.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+#if !defined(__arm__) && !defined(__arm64__) &&                                \
+    !defined(__aarch64__) // No DebugSymbols on the iOS devices
+extern "C" {
+
+CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url);
+CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
+}
+#endif
+
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+                                       ModuleSpec &return_module_spec) {
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+  if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
+    if (log)
+      log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
+    return 0;
+  }
+
+  return_module_spec = module_spec;
+  return_module_spec.GetFileSpec().Clear();
+  return_module_spec.GetSymbolFileSpec().Clear();
+
+  int items_found = 0;
+
+#if !defined(__arm__) && !defined(__arm64__) &&                                \
+    !defined(__aarch64__) // No DebugSymbols on the iOS devices
+
+  const UUID *uuid = module_spec.GetUUIDPtr();
+  const ArchSpec *arch = module_spec.GetArchitecturePtr();
+
+  if (uuid && uuid->IsValid()) {
+    // Try and locate the dSYM file using DebugSymbols first
+    llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
+    if (module_uuid.size() == 16) {
+      CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
+          NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
+          module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
+          module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
+          module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));
+
+      if (module_uuid_ref.get()) {
+        CFCReleaser<CFURLRef> exec_url;
+        const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+        if (exec_fspec) {
+          char exec_cf_path[PATH_MAX];
+          if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
+            exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
+                NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
+                FALSE));
+        }
+
+        CFCReleaser<CFURLRef> dsym_url(
+            ::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
+        char path[PATH_MAX];
+
+        if (dsym_url.get()) {
+          if (::CFURLGetFileSystemRepresentation(
+                  dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+            if (log) {
+              log->Printf("DebugSymbols framework returned dSYM path of %s for "
+                          "UUID %s -- looking for the dSYM",
+                          path, uuid->GetAsString().c_str());
+            }
+            FileSpec dsym_filespec(path);
+            if (path[0] == '~')
+              FileSystem::Instance().Resolve(dsym_filespec);
+
+            if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
+              dsym_filespec =
+                  Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
+              ++items_found;
+            } else {
+              ++items_found;
+            }
+            return_module_spec.GetSymbolFileSpec() = dsym_filespec;
+          }
+
+          bool success = false;
+          if (log) {
+            if (::CFURLGetFileSystemRepresentation(
+                    dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+              log->Printf("DebugSymbols framework returned dSYM path of %s for "
+                          "UUID %s -- looking for an exec file",
+                          path, uuid->GetAsString().c_str());
+            }
+          }
+
+          CFCReleaser<CFDictionaryRef> dict(
+              ::DBGCopyDSYMPropertyLists(dsym_url.get()));
+          CFDictionaryRef uuid_dict = NULL;
+          if (dict.get()) {
+            CFCString uuid_cfstr(uuid->GetAsString().c_str());
+            uuid_dict = static_cast<CFDictionaryRef>(
+                ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
+          }
+          if (uuid_dict) {
+            CFStringRef exec_cf_path =
+                static_cast<CFStringRef>(::CFDictionaryGetValue(
+                    uuid_dict, CFSTR("DBGSymbolRichExecutable")));
+            if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
+                                    exec_cf_path, path, sizeof(path))) {
+              if (log) {
+                log->Printf("plist bundle has exec path of %s for UUID %s",
+                            path, uuid->GetAsString().c_str());
+              }
+              ++items_found;
+              FileSpec exec_filespec(path);
+              if (path[0] == '~')
+                FileSystem::Instance().Resolve(exec_filespec);
+              if (FileSystem::Instance().Exists(exec_filespec)) {
+                success = true;
+                return_module_spec.GetFileSpec() = exec_filespec;
+              }
+            }
+          }
+
+          if (!success) {
+            // No dictionary, check near the dSYM bundle for an executable that
+            // matches...
+            if (::CFURLGetFileSystemRepresentation(
+                    dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
+              char *dsym_extension_pos = ::strstr(path, ".dSYM");
+              if (dsym_extension_pos) {
+                *dsym_extension_pos = '\0';
+                if (log) {
+                  log->Printf("Looking for executable binary next to dSYM "
+                              "bundle with name with name %s",
+                              path);
+                }
+                FileSpec file_spec(path);
+                FileSystem::Instance().Resolve(file_spec);
+                ModuleSpecList module_specs;
+                ModuleSpec matched_module_spec;
+                using namespace llvm::sys::fs;
+                switch (get_file_type(file_spec.GetPath())) {
+
+                case file_type::directory_file: // Bundle directory?
+                {
+                  CFCBundle bundle(path);
+                  CFCReleaser<CFURLRef> bundle_exe_url(
+                      bundle.CopyExecutableURL());
+                  if (bundle_exe_url.get()) {
+                    if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
+                                                           true, (UInt8 *)path,
+                                                           sizeof(path) - 1)) {
+                      FileSpec bundle_exe_file_spec(path);
+                      FileSystem::Instance().Resolve(bundle_exe_file_spec);
+                      if (ObjectFile::GetModuleSpecifications(
+                              bundle_exe_file_spec, 0, 0, module_specs) &&
+                          module_specs.FindMatchingModuleSpec(
+                              module_spec, matched_module_spec))
+
+                      {
+                        ++items_found;
+                        return_module_spec.GetFileSpec() = bundle_exe_file_spec;
+                        if (log) {
+                          log->Printf("Executable binary %s next to dSYM is "
+                                      "compatible; using",
+                                      path);
+                        }
+                      }
+                    }
+                  }
+                } break;
+
+                case file_type::fifo_file:      // Forget pipes
+                case file_type::socket_file:    // We can't process socket files
+                case file_type::file_not_found: // File doesn't exist...
+                case file_type::status_error:
+                  break;
+
+                case file_type::type_unknown:
+                case file_type::regular_file:
+                case file_type::symlink_file:
+                case file_type::block_file:
+                case file_type::character_file:
+                  if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
+                                                          module_specs) &&
+                      module_specs.FindMatchingModuleSpec(module_spec,
+                                                          matched_module_spec))
+
+                  {
+                    ++items_found;
+                    return_module_spec.GetFileSpec() = file_spec;
+                    if (log) {
+                      log->Printf("Executable binary %s next to dSYM is "
+                                  "compatible; using",
+                                  path);
+                    }
+                  }
+                  break;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
+       // (__aarch64__)
+
+  return items_found;
+}
+
+FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
+                                         const lldb_private::UUID *uuid,
+                                         const ArchSpec *arch) {
+  char path[PATH_MAX];
+  if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
+    return {};
+
+  ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
+
+  DIR *dirp = opendir(path);
+  if (!dirp)
+    return {};
+
+  // Make sure we close the directory before exiting this scope.
+  CleanUp cleanup_dir(closedir, dirp);
+
+  FileSpec dsym_fspec;
+  dsym_fspec.GetDirectory().SetCString(path);
+  struct dirent *dp;
+  while ((dp = readdir(dirp)) != NULL) {
+    // Only search directories
+    if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
+      if (dp->d_namlen == 1 && dp->d_name[0] == '.')
+        continue;
+
+      if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
+        continue;
+    }
+
+    if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
+      dsym_fspec.GetFilename().SetCString(dp->d_name);
+      ModuleSpecList module_specs;
+      if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
+        ModuleSpec spec;
+        for (size_t i = 0; i < module_specs.GetSize(); ++i) {
+          bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+          UNUSED_IF_ASSERT_DISABLED(got_spec);
+          assert(got_spec);
+          if ((uuid == NULL ||
+               (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+              (arch == NULL ||
+               (spec.GetArchitecturePtr() &&
+                spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+            return dsym_fspec;
+          }
+        }
+      }
+    }
+  }
+
+  return {};
+}
+
+static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
+                                                ModuleSpec &module_spec) {
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+  bool success = false;
+  if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
+    std::string str;
+    CFStringRef cf_str;
+    CFDictionaryRef cf_dict;
+
+    cf_str = (CFStringRef)CFDictionaryGetValue(
+        (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
+    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+      if (CFCString::FileSystemRepresentation(cf_str, str)) {
+        module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
+        FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+        if (log) {
+          log->Printf(
+              "From dsymForUUID plist: Symbol rich executable is at '%s'",
+              str.c_str());
+        }
+      }
+    }
+
+    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+                                               CFSTR("DBGDSYMPath"));
+    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+      if (CFCString::FileSystemRepresentation(cf_str, str)) {
+        module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
+                                                FileSpec::Style::native);
+        FileSystem::Instance().Resolve(module_spec.GetFileSpec());
+        success = true;
+        if (log) {
+          log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
+        }
+      }
+    }
+
+    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+                                               CFSTR("DBGArchitecture"));
+    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+      if (CFCString::FileSystemRepresentation(cf_str, str))
+        module_spec.GetArchitecture().SetTriple(str.c_str());
+    }
+
+    std::string DBGBuildSourcePath;
+    std::string DBGSourcePath;
+
+    // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
+    // If DBGVersion 2, strip last two components of path remappings from
+    //                  entries to fix an issue with a specific set of
+    //                  DBGSourcePathRemapping entries that lldb worked
+    //                  with.
+    // If DBGVersion 3, trust & use the source path remappings as-is.
+    //
+    cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
+        (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
+    if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
+      // If we see DBGVersion with a value of 2 or higher, this is a new style
+      // DBGSourcePathRemapping dictionary
+      bool new_style_source_remapping_dictionary = false;
+      bool do_truncate_remapping_names = false;
+      std::string original_DBGSourcePath_value = DBGSourcePath;
+      cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+                                                 CFSTR("DBGVersion"));
+      if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+        std::string version;
+        CFCString::FileSystemRepresentation(cf_str, version);
+        if (!version.empty() && isdigit(version[0])) {
+          int version_number = atoi(version.c_str());
+          if (version_number > 1) {
+            new_style_source_remapping_dictionary = true;
+          }
+          if (version_number == 2) {
+            do_truncate_remapping_names = true;
+          }
+        }
+      }
+
+      CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
+      if (kv_pair_count > 0) {
+        CFStringRef *keys =
+            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
+        CFStringRef *values =
+            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
+        if (keys != nullptr && values != nullptr) {
+          CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
+                                       (const void **)keys,
+                                       (const void **)values);
+        }
+        for (CFIndex i = 0; i < kv_pair_count; i++) {
+          DBGBuildSourcePath.clear();
+          DBGSourcePath.clear();
+          if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
+            CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
+          }
+          if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
+            CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
+          }
+          if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+            // In the "old style" DBGSourcePathRemapping dictionary, the
+            // DBGSourcePath values (the "values" half of key-value path pairs)
+            // were wrong.  Ignore them and use the universal DBGSourcePath
+            // string from earlier.
+            if (new_style_source_remapping_dictionary &&
+                !original_DBGSourcePath_value.empty()) {
+              DBGSourcePath = original_DBGSourcePath_value;
+            }
+            if (DBGSourcePath[0] == '~') {
+              FileSpec resolved_source_path(DBGSourcePath.c_str());
+              FileSystem::Instance().Resolve(resolved_source_path);
+              DBGSourcePath = resolved_source_path.GetPath();
+            }
+            // With version 2 of DBGSourcePathRemapping, we can chop off the
+            // last two filename parts from the source remapping and get a more
+            // general source remapping that still works. Add this as another
+            // option in addition to the full source path remap.
+            module_spec.GetSourceMappingList().Append(
+                ConstString(DBGBuildSourcePath.c_str()),
+                ConstString(DBGSourcePath.c_str()), true);
+            if (do_truncate_remapping_names) {
+              FileSpec build_path(DBGBuildSourcePath.c_str());
+              FileSpec source_path(DBGSourcePath.c_str());
+              build_path.RemoveLastPathComponent();
+              build_path.RemoveLastPathComponent();
+              source_path.RemoveLastPathComponent();
+              source_path.RemoveLastPathComponent();
+              module_spec.GetSourceMappingList().Append(
+                  ConstString(build_path.GetPath().c_str()),
+                  ConstString(source_path.GetPath().c_str()), true);
+            }
+          }
+        }
+        if (keys)
+          free(keys);
+        if (values)
+          free(values);
+      }
+    }
+
+    // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
+    // source remappings list.
+
+    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+                                               CFSTR("DBGBuildSourcePath"));
+    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+      CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
+    }
+
+    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+                                               CFSTR("DBGSourcePath"));
+    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+      CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+    }
+
+    if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+      if (DBGSourcePath[0] == '~') {
+        FileSpec resolved_source_path(DBGSourcePath.c_str());
+        FileSystem::Instance().Resolve(resolved_source_path);
+        DBGSourcePath = resolved_source_path.GetPath();
+      }
+      module_spec.GetSourceMappingList().Append(
+          ConstString(DBGBuildSourcePath.c_str()),
+          ConstString(DBGSourcePath.c_str()), true);
+    }
+  }
+  return success;
+}
+
+bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
+                                          bool force_lookup) {
+  bool success = false;
+  const UUID *uuid_ptr = module_spec.GetUUIDPtr();
+  const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
+
+  // It's expensive to check for the DBGShellCommands defaults setting, only do
+  // it once per lldb run and cache the result.
+  static bool g_have_checked_for_dbgshell_command = false;
+  static const char *g_dbgshell_command = NULL;
+  if (!g_have_checked_for_dbgshell_command) {
+    g_have_checked_for_dbgshell_command = true;
+    CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
+        CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
+    if (defaults_setting &&
+        CFGetTypeID(defaults_setting) == CFStringGetTypeID()) {
+      char cstr_buf[PATH_MAX];
+      if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf,
+                             sizeof(cstr_buf), kCFStringEncodingUTF8)) {
+        g_dbgshell_command =
+            strdup(cstr_buf); // this malloc'ed memory will never be freed
+      }
+    }
+    if (defaults_setting) {
+      CFRelease(defaults_setting);
+    }
+  }
+
+  // When g_dbgshell_command is NULL, the user has not enabled the use of an
+  // external program to find the symbols, don't run it for them.
+  if (!force_lookup && g_dbgshell_command == NULL) {
+    return false;
+  }
+
+  if (uuid_ptr ||
+      (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) {
+    static bool g_located_dsym_for_uuid_exe = false;
+    static bool g_dsym_for_uuid_exe_exists = false;
+    static char g_dsym_for_uuid_exe_path[PATH_MAX];
+    if (!g_located_dsym_for_uuid_exe) {
+      g_located_dsym_for_uuid_exe = true;
+      const char *dsym_for_uuid_exe_path_cstr =
+          getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
+      FileSpec dsym_for_uuid_exe_spec;
+      if (dsym_for_uuid_exe_path_cstr) {
+        dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr,
+                                       FileSpec::Style::native);
+        FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
+        g_dsym_for_uuid_exe_exists =
+            FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+      }
+
+      if (!g_dsym_for_uuid_exe_exists) {
+        dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID",
+                                       FileSpec::Style::native);
+        g_dsym_for_uuid_exe_exists =
+            FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+        if (!g_dsym_for_uuid_exe_exists) {
+          long bufsize;
+          if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) {
+            char buffer[bufsize];
+            struct passwd pwd;
+            struct passwd *tilde_rc = NULL;
+            // we are a library so we need to use the reentrant version of
+            // getpwnam()
+            if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 &&
+                tilde_rc && tilde_rc->pw_dir) {
+              std::string dsymforuuid_path(tilde_rc->pw_dir);
+              dsymforuuid_path += "/bin/dsymForUUID";
+              dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(),
+                                             FileSpec::Style::native);
+              g_dsym_for_uuid_exe_exists =
+                  FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+            }
+          }
+        }
+      }
+      if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
+        dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command,
+                                       FileSpec::Style::native);
+        FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
+        g_dsym_for_uuid_exe_exists =
+            FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
+      }
+
+      if (g_dsym_for_uuid_exe_exists)
+        dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path,
+                                       sizeof(g_dsym_for_uuid_exe_path));
+    }
+    if (g_dsym_for_uuid_exe_exists) {
+      std::string uuid_str;
+      char file_path[PATH_MAX];
+      file_path[0] = '\0';
+
+      if (uuid_ptr)
+        uuid_str = uuid_ptr->GetAsString();
+
+      if (file_spec_ptr)
+        file_spec_ptr->GetPath(file_path, sizeof(file_path));
+
+      StreamString command;
+      if (!uuid_str.empty())
+        command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
+                       g_dsym_for_uuid_exe_path, uuid_str.c_str());
+      else if (file_path[0] != '\0')
+        command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
+                       g_dsym_for_uuid_exe_path, file_path);
+
+      if (!command.GetString().empty()) {
+        Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+        int exit_status = -1;
+        int signo = -1;
+        std::string command_output;
+        if (log) {
+          if (!uuid_str.empty())
+            log->Printf("Calling %s with UUID %s to find dSYM",
+                        g_dsym_for_uuid_exe_path, uuid_str.c_str());
+          else if (file_path[0] != '\0')
+            log->Printf("Calling %s with file %s to find dSYM",
+                        g_dsym_for_uuid_exe_path, file_path);
+        }
+        Status error = Host::RunShellCommand(
+            command.GetData(),
+            NULL,            // current working directory
+            &exit_status,    // Exit status
+            &signo,          // Signal int *
+            &command_output, // Command output
+            std::chrono::seconds(
+                30), // Large timeout to allow for long dsym download times
+            false);  // Don't run in a shell (we don't need shell expansion)
+        if (error.Success() && exit_status == 0 && !command_output.empty()) {
+          CFCData data(CFDataCreateWithBytesNoCopy(
+              NULL, (const UInt8 *)command_output.data(), command_output.size(),
+              kCFAllocatorNull));
+
+          CFCReleaser<CFDictionaryRef> plist(
+              (CFDictionaryRef)::CFPropertyListCreateFromXMLData(
+                  NULL, data.get(), kCFPropertyListImmutable, NULL));
+
+          if (plist.get() &&
+              CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) {
+            if (!uuid_str.empty()) {
+              CFCString uuid_cfstr(uuid_str.c_str());
+              CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue(
+                  plist.get(), uuid_cfstr.get());
+              success =
+                  GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec);
+            } else {
+              const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
+              if (num_values > 0) {
+                std::vector<CFStringRef> keys(num_values, NULL);
+                std::vector<CFDictionaryRef> values(num_values, NULL);
+                ::CFDictionaryGetKeysAndValues(plist.get(), NULL,
+                                               (const void **)&values[0]);
+                if (num_values == 1) {
+                  return GetModuleSpecInfoFromUUIDDictionary(values[0],
+                                                             module_spec);
+                } else {
+                  for (CFIndex i = 0; i < num_values; ++i) {
+                    ModuleSpec curr_module_spec;
+                    if (GetModuleSpecInfoFromUUIDDictionary(values[i],
+                                                            curr_module_spec)) {
+                      if (module_spec.GetArchitecture().IsCompatibleMatch(
+                              curr_module_spec.GetArchitecture())) {
+                        module_spec = curr_module_spec;
+                        return true;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        } else {
+          if (log) {
+            if (!uuid_str.empty())
+              log->Printf("Called %s on %s, no matches",
+                          g_dsym_for_uuid_exe_path, uuid_str.c_str());
+            else if (file_path[0] != '\0')
+              log->Printf("Called %s on %s, no matches",
+                          g_dsym_for_uuid_exe_path, file_path);
+          }
+        }
+      }
+    }
+  }
+  return success;
+}
Index: source/Symbol/CMakeLists.txt
===================================================================
--- source/Symbol/CMakeLists.txt
+++ source/Symbol/CMakeLists.txt
@@ -1,3 +1,9 @@
+set(LLVM_OPTIONAL_SOURCES LocateSymbolFileMacOSX.cpp)
+
+if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
+  set(PLATFORM_SOURCES LocateSymbolFileMacOSX.cpp)
+endif()
+
 add_lldb_library(lldbSymbol
   ArmUnwindInfo.cpp
   Block.cpp
@@ -18,6 +24,7 @@
   FuncUnwinders.cpp
   LineEntry.cpp
   LineTable.cpp
+  LocateSymbolFile.cpp
   ObjectFile.cpp
   Symbol.cpp
   SymbolContext.cpp
@@ -34,6 +41,8 @@
   VariableList.cpp
   VerifyDecl.cpp
 
+  ${PLATFORM_SOURCES}
+
   LINK_LIBS
     clangAST
     clangBasic
Index: source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
===================================================================
--- source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -21,9 +21,9 @@
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Host/XML.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
Index: source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
===================================================================
--- source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
+++ source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
@@ -15,8 +15,8 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Host/XML.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/Timer.h"
Index: source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
===================================================================
--- source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
+++ source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp
@@ -15,7 +15,7 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/StreamString.h"
 #include "lldb/Utility/Timer.h"
Index: source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
===================================================================
--- source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -18,7 +18,6 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/common/TCPSocket.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
@@ -28,6 +27,7 @@
 #include "lldb/Interpreter/OptionGroupString.h"
 #include "lldb/Interpreter/OptionGroupUInt64.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/Target.h"
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -41,7 +41,6 @@
 #include "lldb/Host/PosixApi.h"
 #include "lldb/Host/PseudoTerminal.h"
 #include "lldb/Host/StringConvert.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/XML.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
@@ -54,6 +53,7 @@
 #include "lldb/Interpreter/OptionValueProperties.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/Property.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/ABI.h"
 #include "lldb/Target/DynamicLoader.h"
Index: source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
===================================================================
--- source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -15,8 +15,8 @@
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamFile.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Target/OperatingSystem.h"
 #include "lldb/Target/RegisterContext.h"
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -29,7 +29,6 @@
 
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/Host.h"
-#include "lldb/Host/Symbols.h"
 
 #include "lldb/Interpreter/OptionValueFileSpecList.h"
 #include "lldb/Interpreter/OptionValueProperties.h"
@@ -42,6 +41,7 @@
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Symbol/DebugMacros.h"
 #include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
 #include "lldb/Symbol/TypeMap.h"
Index: source/Commands/CommandObjectTarget.cpp
===================================================================
--- source/Commands/CommandObjectTarget.cpp
+++ source/Commands/CommandObjectTarget.cpp
@@ -17,7 +17,6 @@
 #include "lldb/DataFormatters/ValueObjectPrinter.h"
 #include "lldb/Host/OptionParser.h"
 #include "lldb/Host/StringConvert.h"
-#include "lldb/Host/Symbols.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/OptionArgParser.h"
@@ -35,6 +34,7 @@
 #include "lldb/Symbol/CompileUnit.h"
 #include "lldb/Symbol/FuncUnwinders.h"
 #include "lldb/Symbol/LineTable.h"
+#include "lldb/Symbol/LocateSymbolFile.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/SymbolVendor.h"
Index: source/Host/CMakeLists.txt
===================================================================
--- source/Host/CMakeLists.txt
+++ source/Host/CMakeLists.txt
@@ -44,7 +44,6 @@
   common/SocketAddress.cpp
   common/Socket.cpp
   common/StringConvert.cpp
-  common/Symbols.cpp
   common/TaskPool.cpp
   common/TCPSocket.cpp
   common/Terminal.cpp
@@ -95,7 +94,6 @@
     add_subdirectory(macosx/objcxx)
     set(LLDBObjCLibs lldbHostMacOSXObjCXX)
     add_host_subdirectory(macosx
-      macosx/Symbols.cpp
       macosx/cfcpp/CFCBundle.cpp
       macosx/cfcpp/CFCData.cpp
       macosx/cfcpp/CFCMutableArray.cpp
@@ -166,7 +164,6 @@
 
   LINK_LIBS
     lldbCore
-    lldbSymbol
     lldbTarget
     lldbUtility
     ${EXTRA_LIBS}
Index: include/lldb/Host/Symbols.h
===================================================================
--- include/lldb/Host/Symbols.h
+++ include/lldb/Host/Symbols.h
@@ -1,61 +0,0 @@
-//===-- Symbols.h -----------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef liblldb_Symbols_h_
-#define liblldb_Symbols_h_
-
-#include <stdint.h>
-
-#include "lldb/Utility/FileSpec.h"
-
-namespace lldb_private {
-
-class ArchSpec;
-class ModuleSpec;
-class UUID;
-
-class Symbols {
-public:
-  //----------------------------------------------------------------------
-  // Locate the executable file given a module specification.
-  //
-  // Locating the file should happen only on the local computer or using the
-  // current computers global settings.
-  //----------------------------------------------------------------------
-  static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec);
-
-  //----------------------------------------------------------------------
-  // Locate the symbol file given a module specification.
-  //
-  // Locating the file should happen only on the local computer or using the
-  // current computers global settings.
-  //----------------------------------------------------------------------
-  static FileSpec LocateExecutableSymbolFile(const ModuleSpec &module_spec);
-
-  static FileSpec FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
-                                         const lldb_private::UUID *uuid,
-                                         const ArchSpec *arch);
-
-  //----------------------------------------------------------------------
-  // Locate the object and symbol file given a module specification.
-  //
-  // Locating the file can try to download the file from a corporate build
-  // repository, or using any other means necessary to locate both the
-  // unstripped object file and the debug symbols. The force_lookup argument
-  // controls whether the external program is called unconditionally to find
-  // the symbol file, or if the user's settings are checked to see if they've
-  // enabled the external program before calling.
-  //
-  //----------------------------------------------------------------------
-  static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
-                                          bool force_lookup = true);
-};
-
-} // namespace lldb_private
-
-#endif // liblldb_Symbols_h_
Index: unittests/Host/SymbolsTest.cpp
===================================================================
--- unittests/Host/SymbolsTest.cpp
+++ unittests/Host/SymbolsTest.cpp
@@ -1,48 +0,0 @@
-//===-- SymbolsTest.cpp -----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "gtest/gtest.h"
-
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/Symbols.h"
-
-using namespace lldb_private;
-
-namespace {
-class SymbolsTest : public ::testing::Test {
-public:
-  void SetUp() override {
-    FileSystem::Initialize();
-    HostInfo::Initialize();
-  }
-  void TearDown() override {
-    HostInfo::Terminate();
-    FileSystem::Terminate();
-  }
-};
-} // namespace
-
-TEST_F(
-    SymbolsTest,
-    TerminateLocateExecutableSymbolFileForUnknownExecutableAndUnknownSymbolFile) {
-  ModuleSpec module_spec;
-  FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
-  EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
-}
-
-TEST_F(SymbolsTest,
-       LocateExecutableSymbolFileForUnknownExecutableAndMissingSymbolFile) {
-  ModuleSpec module_spec;
-  // using a GUID here because the symbol file shouldn't actually exist on disk
-  module_spec.GetSymbolFileSpec().SetFile(
-      "4A524676-B24B-4F4E-968A-551D465EBAF1.so", FileSpec::Style::native);
-  FileSpec symbol_file_spec = Symbols::LocateExecutableSymbolFile(module_spec);
-  EXPECT_TRUE(symbol_file_spec.GetFilename().IsEmpty());
-}
Index: source/Host/macosx/Symbols.cpp
===================================================================
--- source/Host/macosx/Symbols.cpp
+++ source/Host/macosx/Symbols.cpp
@@ -1,654 +0,0 @@
-//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/Symbols.h"
-
-#include <dirent.h>
-#include <pwd.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "Host/macosx/cfcpp/CFCBundle.h"
-#include "Host/macosx/cfcpp/CFCData.h"
-#include "Host/macosx/cfcpp/CFCReleaser.h"
-#include "Host/macosx/cfcpp/CFCString.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/CleanUp.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/Endian.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-#include "lldb/Utility/UUID.h"
-#include "mach/machine.h"
-
-#include "llvm/Support/FileSystem.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#if !defined(__arm__) && !defined(__arm64__) &&                                \
-    !defined(__aarch64__) // No DebugSymbols on the iOS devices
-extern "C" {
-
-CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url);
-CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
-}
-#endif
-
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
-                                       ModuleSpec &return_module_spec) {
-  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-  if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
-    if (log)
-      log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
-    return 0;
-  }
-  
-  return_module_spec = module_spec;
-  return_module_spec.GetFileSpec().Clear();
-  return_module_spec.GetSymbolFileSpec().Clear();
-
-  int items_found = 0;
-
-#if !defined(__arm__) && !defined(__arm64__) &&                                \
-    !defined(__aarch64__) // No DebugSymbols on the iOS devices
-
-  const UUID *uuid = module_spec.GetUUIDPtr();
-  const ArchSpec *arch = module_spec.GetArchitecturePtr();
-
-  if (uuid && uuid->IsValid()) {
-    // Try and locate the dSYM file using DebugSymbols first
-    llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
-    if (module_uuid.size() == 16) {
-      CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
-          NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
-          module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
-          module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
-          module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));
-
-      if (module_uuid_ref.get()) {
-        CFCReleaser<CFURLRef> exec_url;
-        const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
-        if (exec_fspec) {
-          char exec_cf_path[PATH_MAX];
-          if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
-            exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
-                NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
-                FALSE));
-        }
-
-        CFCReleaser<CFURLRef> dsym_url(
-            ::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
-        char path[PATH_MAX];
-
-        if (dsym_url.get()) {
-          if (::CFURLGetFileSystemRepresentation(
-                  dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
-            if (log) {
-              log->Printf("DebugSymbols framework returned dSYM path of %s for "
-                          "UUID %s -- looking for the dSYM",
-                          path, uuid->GetAsString().c_str());
-            }
-            FileSpec dsym_filespec(path);
-            if (path[0] == '~')
-              FileSystem::Instance().Resolve(dsym_filespec);
-
-            if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
-              dsym_filespec =
-                  Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
-              ++items_found;
-            } else {
-              ++items_found;
-            }
-            return_module_spec.GetSymbolFileSpec() = dsym_filespec;
-          }
-
-          bool success = false;
-          if (log) {
-            if (::CFURLGetFileSystemRepresentation(
-                    dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
-              log->Printf("DebugSymbols framework returned dSYM path of %s for "
-                          "UUID %s -- looking for an exec file",
-                          path, uuid->GetAsString().c_str());
-            }
-          }
-
-          CFCReleaser<CFDictionaryRef> dict(
-              ::DBGCopyDSYMPropertyLists(dsym_url.get()));
-          CFDictionaryRef uuid_dict = NULL;
-          if (dict.get()) {
-            CFCString uuid_cfstr(uuid->GetAsString().c_str());
-            uuid_dict = static_cast<CFDictionaryRef>(
-                ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
-          }
-          if (uuid_dict) {
-            CFStringRef exec_cf_path =
-                static_cast<CFStringRef>(::CFDictionaryGetValue(
-                    uuid_dict, CFSTR("DBGSymbolRichExecutable")));
-            if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
-                                    exec_cf_path, path, sizeof(path))) {
-              if (log) {
-                log->Printf("plist bundle has exec path of %s for UUID %s",
-                            path, uuid->GetAsString().c_str());
-              }
-              ++items_found;
-              FileSpec exec_filespec(path);
-              if (path[0] == '~')
-                FileSystem::Instance().Resolve(exec_filespec);
-              if (FileSystem::Instance().Exists(exec_filespec)) {
-                success = true;
-                return_module_spec.GetFileSpec() = exec_filespec;
-              }
-            }
-          }
-
-          if (!success) {
-            // No dictionary, check near the dSYM bundle for an executable that
-            // matches...
-            if (::CFURLGetFileSystemRepresentation(
-                    dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
-              char *dsym_extension_pos = ::strstr(path, ".dSYM");
-              if (dsym_extension_pos) {
-                *dsym_extension_pos = '\0';
-                if (log) {
-                  log->Printf("Looking for executable binary next to dSYM "
-                              "bundle with name with name %s",
-                              path);
-                }
-                FileSpec file_spec(path);
-                FileSystem::Instance().Resolve(file_spec);
-                ModuleSpecList module_specs;
-                ModuleSpec matched_module_spec;
-                using namespace llvm::sys::fs;
-                switch (get_file_type(file_spec.GetPath())) {
-
-                case file_type::directory_file: // Bundle directory?
-                {
-                  CFCBundle bundle(path);
-                  CFCReleaser<CFURLRef> bundle_exe_url(
-                      bundle.CopyExecutableURL());
-                  if (bundle_exe_url.get()) {
-                    if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
-                                                           true, (UInt8 *)path,
-                                                           sizeof(path) - 1)) {
-                      FileSpec bundle_exe_file_spec(path);
-                      FileSystem::Instance().Resolve(bundle_exe_file_spec);
-                      if (ObjectFile::GetModuleSpecifications(
-                              bundle_exe_file_spec, 0, 0, module_specs) &&
-                          module_specs.FindMatchingModuleSpec(
-                              module_spec, matched_module_spec))
-
-                      {
-                        ++items_found;
-                        return_module_spec.GetFileSpec() = bundle_exe_file_spec;
-                        if (log) {
-                          log->Printf("Executable binary %s next to dSYM is "
-                                      "compatible; using",
-                                      path);
-                        }
-                      }
-                    }
-                  }
-                } break;
-
-                case file_type::fifo_file:      // Forget pipes
-                case file_type::socket_file:    // We can't process socket files
-                case file_type::file_not_found: // File doesn't exist...
-                case file_type::status_error:
-                  break;
-
-                case file_type::type_unknown:
-                case file_type::regular_file:
-                case file_type::symlink_file:
-                case file_type::block_file:
-                case file_type::character_file:
-                  if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
-                                                          module_specs) &&
-                      module_specs.FindMatchingModuleSpec(module_spec,
-                                                          matched_module_spec))
-
-                  {
-                    ++items_found;
-                    return_module_spec.GetFileSpec() = file_spec;
-                    if (log) {
-                      log->Printf("Executable binary %s next to dSYM is "
-                                  "compatible; using",
-                                  path);
-                    }
-                  }
-                  break;
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
-       // (__aarch64__)
-
-  return items_found;
-}
-
-FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
-                                         const lldb_private::UUID *uuid,
-                                         const ArchSpec *arch) {
-  char path[PATH_MAX];
-  if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
-    return {};
-
-  ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
-
-  DIR *dirp = opendir(path);
-  if (!dirp)
-    return {};
-
-  // Make sure we close the directory before exiting this scope.
-  CleanUp cleanup_dir(closedir, dirp);
-
-  FileSpec dsym_fspec;
-  dsym_fspec.GetDirectory().SetCString(path);
-  struct dirent *dp;
-  while ((dp = readdir(dirp)) != NULL) {
-    // Only search directories
-    if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
-      if (dp->d_namlen == 1 && dp->d_name[0] == '.')
-        continue;
-
-      if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
-        continue;
-    }
-
-    if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
-      dsym_fspec.GetFilename().SetCString(dp->d_name);
-      ModuleSpecList module_specs;
-      if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
-        ModuleSpec spec;
-        for (size_t i = 0; i < module_specs.GetSize(); ++i) {
-          bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
-          UNUSED_IF_ASSERT_DISABLED(got_spec);
-          assert(got_spec);
-          if ((uuid == NULL ||
-               (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
-              (arch == NULL ||
-               (spec.GetArchitecturePtr() &&
-                spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
-            return dsym_fspec;
-          }
-        }
-      }
-    }
-  }
-
-  return {};
-}
-
-static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
-                                                ModuleSpec &module_spec) {
-  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-  bool success = false;
-  if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
-    std::string str;
-    CFStringRef cf_str;
-    CFDictionaryRef cf_dict;
-
-    cf_str = (CFStringRef)CFDictionaryGetValue(
-        (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
-    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
-      if (CFCString::FileSystemRepresentation(cf_str, str)) {
-        module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
-        FileSystem::Instance().Resolve(module_spec.GetFileSpec());
-        if (log) {
-          log->Printf(
-              "From dsymForUUID plist: Symbol rich executable is at '%s'",
-              str.c_str());
-        }
-      }
-    }
-
-    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
-                                               CFSTR("DBGDSYMPath"));
-    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
-      if (CFCString::FileSystemRepresentation(cf_str, str)) {
-        module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
-                                                FileSpec::Style::native);
-        FileSystem::Instance().Resolve(module_spec.GetFileSpec());
-        success = true;
-        if (log) {
-          log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
-        }
-      }
-    }
-
-    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
-                                               CFSTR("DBGArchitecture"));
-    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
-      if (CFCString::FileSystemRepresentation(cf_str, str))
-        module_spec.GetArchitecture().SetTriple(str.c_str());
-    }
-
-    std::string DBGBuildSourcePath;
-    std::string DBGSourcePath;
-
-    // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
-    // If DBGVersion 2, strip last two components of path remappings from
-    //                  entries to fix an issue with a specific set of
-    //                  DBGSourcePathRemapping entries that lldb worked
-    //                  with.
-    // If DBGVersion 3, trust & use the source path remappings as-is.
-    //
-    cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
-        (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
-    if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
-      // If we see DBGVersion with a value of 2 or higher, this is a new style
-      // DBGSourcePathRemapping dictionary
-      bool new_style_source_remapping_dictionary = false;
-      bool do_truncate_remapping_names = false;
-      std::string original_DBGSourcePath_value = DBGSourcePath;
-      cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
-                                                 CFSTR("DBGVersion"));
-      if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
-        std::string version;
-        CFCString::FileSystemRepresentation(cf_str, version);
-        if (!version.empty() && isdigit(version[0])) {
-          int version_number = atoi(version.c_str());
-          if (version_number > 1) {
-            new_style_source_remapping_dictionary = true;
-          }
-          if (version_number == 2) {
-            do_truncate_remapping_names = true;
-          }
-        }
-      }
-
-      CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
-      if (kv_pair_count > 0) {
-        CFStringRef *keys =
-            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
-        CFStringRef *values =
-            (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
-        if (keys != nullptr && values != nullptr) {
-          CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
-                                       (const void **)keys,
-                                       (const void **)values);
-        }
-        for (CFIndex i = 0; i < kv_pair_count; i++) {
-          DBGBuildSourcePath.clear();
-          DBGSourcePath.clear();
-          if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
-            CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
-          }
-          if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
-            CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
-          }
-          if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
-            // In the "old style" DBGSourcePathRemapping dictionary, the
-            // DBGSourcePath values (the "values" half of key-value path pairs)
-            // were wrong.  Ignore them and use the universal DBGSourcePath
-            // string from earlier.
-            if (new_style_source_remapping_dictionary &&
-                !original_DBGSourcePath_value.empty()) {
-              DBGSourcePath = original_DBGSourcePath_value;
-            }
-            if (DBGSourcePath[0] == '~') {
-              FileSpec resolved_source_path(DBGSourcePath.c_str());
-              FileSystem::Instance().Resolve(resolved_source_path);
-              DBGSourcePath = resolved_source_path.GetPath();
-            }
-            // With version 2 of DBGSourcePathRemapping, we can chop off the
-            // last two filename parts from the source remapping and get a more
-            // general source remapping that still works. Add this as another
-            // option in addition to the full source path remap.
-            module_spec.GetSourceMappingList().Append(
-                ConstString(DBGBuildSourcePath.c_str()),
-                ConstString(DBGSourcePath.c_str()), true);
-            if (do_truncate_remapping_names) {
-              FileSpec build_path(DBGBuildSourcePath.c_str());
-              FileSpec source_path(DBGSourcePath.c_str());
-              build_path.RemoveLastPathComponent();
-              build_path.RemoveLastPathComponent();
-              source_path.RemoveLastPathComponent();
-              source_path.RemoveLastPathComponent();
-              module_spec.GetSourceMappingList().Append(
-                ConstString(build_path.GetPath().c_str()),
-                ConstString(source_path.GetPath().c_str()), true);
-            }
-          }
-        }
-        if (keys)
-          free(keys);
-        if (values)
-          free(values);
-      }
-    }
-
-
-    // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
-    // source remappings list.
-
-    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
-                                               CFSTR("DBGBuildSourcePath"));
-    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
-      CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
-    }
-
-    cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
-                                               CFSTR("DBGSourcePath"));
-    if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
-      CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
-    }
-
-    if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
-      if (DBGSourcePath[0] == '~') {
-        FileSpec resolved_source_path(DBGSourcePath.c_str());
-        FileSystem::Instance().Resolve(resolved_source_path);
-        DBGSourcePath = resolved_source_path.GetPath();
-      }
-      module_spec.GetSourceMappingList().Append(
-          ConstString(DBGBuildSourcePath.c_str()),
-          ConstString(DBGSourcePath.c_str()), true);
-    }
-  }
-  return success;
-}
-
-bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
-                                          bool force_lookup) {
-  bool success = false;
-  const UUID *uuid_ptr = module_spec.GetUUIDPtr();
-  const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
-
-  // It's expensive to check for the DBGShellCommands defaults setting, only do
-  // it once per lldb run and cache the result.
-  static bool g_have_checked_for_dbgshell_command = false;
-  static const char *g_dbgshell_command = NULL;
-  if (!g_have_checked_for_dbgshell_command) {
-    g_have_checked_for_dbgshell_command = true;
-    CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
-        CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
-    if (defaults_setting &&
-        CFGetTypeID(defaults_setting) == CFStringGetTypeID()) {
-      char cstr_buf[PATH_MAX];
-      if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf,
-                             sizeof(cstr_buf), kCFStringEncodingUTF8)) {
-        g_dbgshell_command =
-            strdup(cstr_buf); // this malloc'ed memory will never be freed
-      }
-    }
-    if (defaults_setting) {
-      CFRelease(defaults_setting);
-    }
-  }
-
-  // When g_dbgshell_command is NULL, the user has not enabled the use of an
-  // external program to find the symbols, don't run it for them.
-  if (!force_lookup && g_dbgshell_command == NULL) {
-    return false;
-  }
-
-  if (uuid_ptr ||
-      (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) {
-    static bool g_located_dsym_for_uuid_exe = false;
-    static bool g_dsym_for_uuid_exe_exists = false;
-    static char g_dsym_for_uuid_exe_path[PATH_MAX];
-    if (!g_located_dsym_for_uuid_exe) {
-      g_located_dsym_for_uuid_exe = true;
-      const char *dsym_for_uuid_exe_path_cstr =
-          getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
-      FileSpec dsym_for_uuid_exe_spec;
-      if (dsym_for_uuid_exe_path_cstr) {
-        dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr,
-                                       FileSpec::Style::native);
-        FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
-        g_dsym_for_uuid_exe_exists =
-            FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
-      }
-
-      if (!g_dsym_for_uuid_exe_exists) {
-        dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID",
-                                       FileSpec::Style::native);
-        g_dsym_for_uuid_exe_exists =
-            FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
-        if (!g_dsym_for_uuid_exe_exists) {
-          long bufsize;
-          if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) {
-            char buffer[bufsize];
-            struct passwd pwd;
-            struct passwd *tilde_rc = NULL;
-            // we are a library so we need to use the reentrant version of
-            // getpwnam()
-            if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 &&
-                tilde_rc && tilde_rc->pw_dir) {
-              std::string dsymforuuid_path(tilde_rc->pw_dir);
-              dsymforuuid_path += "/bin/dsymForUUID";
-              dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(),
-                                             FileSpec::Style::native);
-              g_dsym_for_uuid_exe_exists =
-                  FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
-            }
-          }
-        }
-      }
-      if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
-        dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command,
-                                       FileSpec::Style::native);
-        FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
-        g_dsym_for_uuid_exe_exists =
-            FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
-      }
-
-      if (g_dsym_for_uuid_exe_exists)
-        dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path,
-                                       sizeof(g_dsym_for_uuid_exe_path));
-    }
-    if (g_dsym_for_uuid_exe_exists) {
-      std::string uuid_str;
-      char file_path[PATH_MAX];
-      file_path[0] = '\0';
-
-      if (uuid_ptr)
-        uuid_str = uuid_ptr->GetAsString();
-
-      if (file_spec_ptr)
-        file_spec_ptr->GetPath(file_path, sizeof(file_path));
-
-      StreamString command;
-      if (!uuid_str.empty())
-        command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
-                       g_dsym_for_uuid_exe_path, uuid_str.c_str());
-      else if (file_path[0] != '\0')
-        command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
-                       g_dsym_for_uuid_exe_path, file_path);
-
-      if (!command.GetString().empty()) {
-        Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-        int exit_status = -1;
-        int signo = -1;
-        std::string command_output;
-        if (log) {
-          if (!uuid_str.empty())
-            log->Printf("Calling %s with UUID %s to find dSYM",
-                        g_dsym_for_uuid_exe_path, uuid_str.c_str());
-          else if (file_path[0] != '\0')
-            log->Printf("Calling %s with file %s to find dSYM",
-                        g_dsym_for_uuid_exe_path, file_path);
-        }
-        Status error = Host::RunShellCommand(
-            command.GetData(),
-            NULL,            // current working directory
-            &exit_status,    // Exit status
-            &signo,          // Signal int *
-            &command_output, // Command output
-            std::chrono::seconds(
-                30), // Large timeout to allow for long dsym download times
-            false);  // Don't run in a shell (we don't need shell expansion)
-        if (error.Success() && exit_status == 0 && !command_output.empty()) {
-          CFCData data(CFDataCreateWithBytesNoCopy(
-              NULL, (const UInt8 *)command_output.data(), command_output.size(),
-              kCFAllocatorNull));
-
-          CFCReleaser<CFDictionaryRef> plist(
-              (CFDictionaryRef)::CFPropertyListCreateFromXMLData(
-                  NULL, data.get(), kCFPropertyListImmutable, NULL));
-
-          if (plist.get() &&
-              CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) {
-            if (!uuid_str.empty()) {
-              CFCString uuid_cfstr(uuid_str.c_str());
-              CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue(
-                  plist.get(), uuid_cfstr.get());
-              success =
-                  GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec);
-            } else {
-              const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
-              if (num_values > 0) {
-                std::vector<CFStringRef> keys(num_values, NULL);
-                std::vector<CFDictionaryRef> values(num_values, NULL);
-                ::CFDictionaryGetKeysAndValues(plist.get(), NULL,
-                                               (const void **)&values[0]);
-                if (num_values == 1) {
-                  return GetModuleSpecInfoFromUUIDDictionary(values[0],
-                                                             module_spec);
-                } else {
-                  for (CFIndex i = 0; i < num_values; ++i) {
-                    ModuleSpec curr_module_spec;
-                    if (GetModuleSpecInfoFromUUIDDictionary(values[i],
-                                                            curr_module_spec)) {
-                      if (module_spec.GetArchitecture().IsCompatibleMatch(
-                              curr_module_spec.GetArchitecture())) {
-                        module_spec = curr_module_spec;
-                        return true;
-                      }
-                    }
-                  }
-                }
-              }
-            }
-          }
-        } else {
-          if (log) {
-            if (!uuid_str.empty())
-              log->Printf("Called %s on %s, no matches",
-                          g_dsym_for_uuid_exe_path, uuid_str.c_str());
-            else if (file_path[0] != '\0')
-              log->Printf("Called %s on %s, no matches",
-                          g_dsym_for_uuid_exe_path, file_path);
-          }
-        }
-      }
-    }
-  }
-  return success;
-}
Index: source/Host/common/Symbols.cpp
===================================================================
--- source/Host/common/Symbols.cpp
+++ source/Host/common/Symbols.cpp
@@ -1,383 +0,0 @@
-//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/Symbols.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Utility/ArchSpec.h"
-#include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamString.h"
-#include "lldb/Utility/Timer.h"
-#include "lldb/Utility/UUID.h"
-
-#include "llvm/Support/FileSystem.h"
-
-// From MacOSX system header "mach/machine.h"
-typedef int cpu_type_t;
-typedef int cpu_subtype_t;
-
-using namespace lldb;
-using namespace lldb_private;
-
-#if defined(__APPLE__)
-
-// Forward declaration of method defined in source/Host/macosx/Symbols.cpp
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
-                                       ModuleSpec &return_module_spec);
-
-#else
-
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
-                                       ModuleSpec &return_module_spec) {
-  // Cannot find MacOSX files using debug symbols on non MacOSX.
-  return 0;
-}
-
-#endif
-
-static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
-                                          const ArchSpec *arch,
-                                          const lldb_private::UUID *uuid) {
-  ModuleSpecList module_specs;
-  if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
-    ModuleSpec spec;
-    for (size_t i = 0; i < module_specs.GetSize(); ++i) {
-      bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
-      UNUSED_IF_ASSERT_DISABLED(got_spec);
-      assert(got_spec);
-      if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
-          (arch == NULL || (spec.GetArchitecturePtr() &&
-                            spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
-// return true if there is a matching dSYM bundle next to the exec_fspec,
-// and return that value in dsym_fspec.  
-// If there is a .dSYM.yaa compressed archive next to the exec_fspec, 
-// call through Symbols::DownloadObjectAndSymbolFile to download the
-// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
-
-static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
-                                            const FileSpec &exec_fspec,
-                                            FileSpec &dsym_fspec) {
-  ConstString filename = exec_fspec.GetFilename();
-  FileSpec dsym_directory = exec_fspec;
-  dsym_directory.RemoveLastPathComponent();
-
-  std::string dsym_filename = filename.AsCString();
-  dsym_filename += ".dSYM";
-  dsym_directory.AppendPathComponent(dsym_filename);
-  dsym_directory.AppendPathComponent("Contents");
-  dsym_directory.AppendPathComponent("Resources");
-  dsym_directory.AppendPathComponent("DWARF");
-
-  if (FileSystem::Instance().Exists(dsym_directory)) {
-
-    // See if the binary name exists in the dSYM DWARF
-    // subdir.
-    dsym_fspec = dsym_directory;
-    dsym_fspec.AppendPathComponent(filename.AsCString());
-    if (FileSystem::Instance().Exists(dsym_fspec) &&
-        FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
-                                      mod_spec.GetUUIDPtr())) {
-      return true;
-    }
-
-    // See if we have "../CF.framework" - so we'll look for
-    // CF.framework.dSYM/Contents/Resources/DWARF/CF
-    // We need to drop the last suffix after '.' to match 
-    // 'CF' in the DWARF subdir.
-    std::string binary_name (filename.AsCString());
-    auto last_dot = binary_name.find_last_of('.');
-    if (last_dot != std::string::npos) {
-      binary_name.erase(last_dot);
-      dsym_fspec = dsym_directory;
-      dsym_fspec.AppendPathComponent(binary_name);
-      if (FileSystem::Instance().Exists(dsym_fspec) &&
-          FileAtPathContainsArchAndUUID(dsym_fspec,
-                                        mod_spec.GetArchitecturePtr(),
-                                        mod_spec.GetUUIDPtr())) {
-        return true;
-      }
-    }
-  }
-
-  // See if we have a .dSYM.yaa next to this executable path.
-  FileSpec dsym_yaa_fspec = exec_fspec;
-  dsym_yaa_fspec.RemoveLastPathComponent();
-  std::string dsym_yaa_filename = filename.AsCString();
-  dsym_yaa_filename += ".dSYM.yaa";
-  dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
-
-  if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
-    ModuleSpec mutable_mod_spec = mod_spec;
-    if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) &&
-        FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
-      dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
-      return true;
-    }
-  }
-
-  return false;
-}
-
-// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
-// filled in, look for a .dSYM bundle next to that binary.  Returns true
-// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
-// FileSpec.
-//
-// This routine looks a few directory layers above the given exec_path -
-// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
-// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
-//
-// If there is a .dSYM.yaa compressed archive found next to the binary,
-// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
-
-static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
-                                              FileSpec &dsym_fspec) {
-  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-  const FileSpec &exec_fspec = module_spec.GetFileSpec();
-  if (exec_fspec) {
-    if (::LookForDsymNextToExecutablePath (module_spec, exec_fspec, dsym_fspec)) {
-        if (log) {
-          log->Printf("dSYM with matching UUID & arch found at %s", dsym_fspec.GetPath().c_str());
-        }
-        return true;
-    } else {
-      FileSpec parent_dirs = exec_fspec;
-
-      // Remove the binary name from the FileSpec
-      parent_dirs.RemoveLastPathComponent();
-
-      // Add a ".dSYM" name to each directory component of the path,
-      // stripping off components.  e.g. we may have a binary like
-      // /S/L/F/Foundation.framework/Versions/A/Foundation and
-      // /S/L/F/Foundation.framework.dSYM
-      //
-      // so we'll need to start with
-      // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
-      // "A", and if that doesn't exist, strip off the "A" and try it again
-      // with "Versions", etc., until we find a dSYM bundle or we've
-      // stripped off enough path components that there's no need to
-      // continue.
-
-      for (int i = 0; i < 4; i++) {
-        // Does this part of the path have a "." character - could it be a
-        // bundle's top level directory?
-        const char *fn = parent_dirs.GetFilename().AsCString();
-        if (fn == nullptr)
-          break;
-        if (::strchr(fn, '.') != nullptr) {
-          if (::LookForDsymNextToExecutablePath (module_spec, parent_dirs, dsym_fspec)) {
-            if (log) {
-              log->Printf("dSYM with matching UUID & arch found at %s",
-                          dsym_fspec.GetPath().c_str());
-            }
-            return true;
-          }
-        }
-        parent_dirs.RemoveLastPathComponent();
-      }
-    }
-  }
-  dsym_fspec.Clear();
-  return false;
-}
-
-static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
-  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
-  const ArchSpec *arch = module_spec.GetArchitecturePtr();
-  const UUID *uuid = module_spec.GetUUIDPtr();
-
-  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
-  Timer scoped_timer(
-      func_cat,
-      "LocateExecutableSymbolFileDsym (file = %s, arch = %s, uuid = %p)",
-      exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
-      arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
-
-  FileSpec symbol_fspec;
-  ModuleSpec dsym_module_spec;
-  // First try and find the dSYM in the same directory as the executable or in
-  // an appropriate parent directory
-  if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
-    // We failed to easily find the dSYM above, so use DebugSymbols
-    LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
-  } else {
-    dsym_module_spec.GetSymbolFileSpec() = symbol_fspec;
-  }
-  return dsym_module_spec.GetSymbolFileSpec();
-}
-
-ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
-  ModuleSpec result;
-  const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
-  const ArchSpec *arch = module_spec.GetArchitecturePtr();
-  const UUID *uuid = module_spec.GetUUIDPtr();
-  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
-  Timer scoped_timer(
-      func_cat, "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)",
-      exec_fspec ? exec_fspec->GetFilename().AsCString("<NULL>") : "<NULL>",
-      arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid);
-
-  ModuleSpecList module_specs;
-  ModuleSpec matched_module_spec;
-  if (exec_fspec &&
-      ObjectFile::GetModuleSpecifications(*exec_fspec, 0, 0, module_specs) &&
-      module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) {
-    result.GetFileSpec() = exec_fspec;
-  } else {
-    LocateMacOSXFilesUsingDebugSymbols(module_spec, result);
-  }
-  return result;
-}
-
-// Keep "symbols.enable-external-lookup" description in sync with this function.
-
-FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
-  FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
-  if (symbol_file_spec.IsAbsolute() &&
-      FileSystem::Instance().Exists(symbol_file_spec))
-    return symbol_file_spec;
-
-  const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
-  if (symbol_filename && symbol_filename[0]) {
-    FileSpecList debug_file_search_paths(
-        Target::GetDefaultDebugFileSearchPaths());
-
-    // Add module directory.
-    FileSpec module_file_spec = module_spec.GetFileSpec();
-    // We keep the unresolved pathname if it fails.
-    FileSystem::Instance().ResolveSymbolicLink(module_file_spec, module_file_spec);
-
-    const ConstString &file_dir = module_file_spec.GetDirectory();
-    {
-      FileSpec file_spec(file_dir.AsCString("."));
-      FileSystem::Instance().Resolve(file_spec);
-      debug_file_search_paths.AppendIfUnique(file_spec);
-    }
-
-    if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
-
-      // Add current working directory.
-      {
-        FileSpec file_spec(".");
-        FileSystem::Instance().Resolve(file_spec);
-        debug_file_search_paths.AppendIfUnique(file_spec);
-      }
-
-#ifndef _WIN32
-#if defined(__NetBSD__)
-      // Add /usr/libdata/debug directory.
-      {
-        FileSpec file_spec("/usr/libdata/debug");
-        FileSystem::Instance().Resolve(file_spec);
-        debug_file_search_paths.AppendIfUnique(file_spec);
-      }
-#else
-      // Add /usr/lib/debug directory.
-      {
-        FileSpec file_spec("/usr/lib/debug");
-        FileSystem::Instance().Resolve(file_spec);
-        debug_file_search_paths.AppendIfUnique(file_spec);
-      }
-#endif
-#endif // _WIN32
-    }
-
-    std::string uuid_str;
-    const UUID &module_uuid = module_spec.GetUUID();
-    if (module_uuid.IsValid()) {
-      // Some debug files are stored in the .build-id directory like this:
-      //   /usr/lib/debug/.build-id/ff/e7fe727889ad82bb153de2ad065b2189693315.debug
-      uuid_str = module_uuid.GetAsString("");
-      std::transform(uuid_str.begin(), uuid_str.end(), uuid_str.begin(),
-          ::tolower);
-      uuid_str.insert(2, 1, '/');
-      uuid_str = uuid_str + ".debug";
-    }
-
-    size_t num_directories = debug_file_search_paths.GetSize();
-    for (size_t idx = 0; idx < num_directories; ++idx) {
-      FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
-      FileSystem::Instance().Resolve(dirspec);
-      if (!FileSystem::Instance().IsDirectory(dirspec))
-        continue;
-
-      std::vector<std::string> files;
-      std::string dirname = dirspec.GetPath();
-
-      files.push_back(dirname + "/" + symbol_filename);
-      files.push_back(dirname + "/.debug/" + symbol_filename);
-      files.push_back(dirname + "/.build-id/" + uuid_str);
-
-      // Some debug files may stored in the module directory like this:
-      //   /usr/lib/debug/usr/lib/library.so.debug
-      if (!file_dir.IsEmpty())
-        files.push_back(dirname + file_dir.AsCString() + "/" + symbol_filename);
-
-      const uint32_t num_files = files.size();
-      for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
-        const std::string &filename = files[idx_file];
-        FileSpec file_spec(filename);
-        FileSystem::Instance().Resolve(file_spec);
-
-        if (llvm::sys::fs::equivalent(file_spec.GetPath(),
-                                      module_file_spec.GetPath()))
-          continue;
-
-        if (FileSystem::Instance().Exists(file_spec)) {
-          lldb_private::ModuleSpecList specs;
-          const size_t num_specs =
-              ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
-          assert(num_specs <= 1 &&
-                 "Symbol Vendor supports only a single architecture");
-          if (num_specs == 1) {
-            ModuleSpec mspec;
-            if (specs.GetModuleSpecAtIndex(0, mspec)) {
-              // Skip the uuids check if module_uuid is invalid. For example,
-              // this happens for *.dwp files since at the moment llvm-dwp
-              // doesn't output build ids, nor does binutils dwp.
-              if (!module_uuid.IsValid() || module_uuid == mspec.GetUUID())
-                return file_spec;
-            }
-          }
-        }
-      }
-    }
-  }
-
-  return LocateExecutableSymbolFileDsym(module_spec);
-}
-
-#if !defined(__APPLE__)
-
-FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &symfile_bundle,
-                                         const lldb_private::UUID *uuid,
-                                         const ArchSpec *arch) {
-  // FIXME
-  return FileSpec();
-}
-
-bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
-                                          bool force_lookup) {
-  // Fill in the module_spec.GetFileSpec() for the object file and/or the
-  // module_spec.GetSymbolFileSpec() for the debug symbols file.
-  return false;
-}
-
-#endif
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to