//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#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;
}
