Extract remote debugging logic from PlatformMacOSX and move it into PlatformRemoteMacOSX so it can benefit from all the logic necessary for remote debugging. Until now, remote macOS debugging was treated almost identical to local macOS debugging. By moving in into its own class, we can have it inherit from PlatformRemoteDarwinDevice and all the functionality it provides, such as looking at the correct DeviceSupport directory. rdar://68167374 Differential revision: https://reviews.llvm.org/D92452
220 lines
6.7 KiB
C++
220 lines
6.7 KiB
C++
//===-- PlatformRemoteMacOSX.cpp -------------------------------------===//
|
|
//
|
|
// 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 <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "PlatformRemoteMacOSX.h"
|
|
|
|
#include "lldb/Breakpoint/BreakpointLocation.h"
|
|
#include "lldb/Core/Module.h"
|
|
#include "lldb/Core/ModuleList.h"
|
|
#include "lldb/Core/ModuleSpec.h"
|
|
#include "lldb/Core/PluginManager.h"
|
|
#include "lldb/Host/Host.h"
|
|
#include "lldb/Host/HostInfo.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Target/Target.h"
|
|
#include "lldb/Utility/ArchSpec.h"
|
|
#include "lldb/Utility/FileSpec.h"
|
|
#include "lldb/Utility/Log.h"
|
|
#include "lldb/Utility/StreamString.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
/// Default Constructor
|
|
PlatformRemoteMacOSX::PlatformRemoteMacOSX() : PlatformRemoteDarwinDevice() {}
|
|
|
|
// Static Variables
|
|
static uint32_t g_initialize_count = 0;
|
|
|
|
// Static Functions
|
|
void PlatformRemoteMacOSX::Initialize() {
|
|
PlatformDarwin::Initialize();
|
|
|
|
if (g_initialize_count++ == 0) {
|
|
PluginManager::RegisterPlugin(PlatformRemoteMacOSX::GetPluginNameStatic(),
|
|
PlatformRemoteMacOSX::GetDescriptionStatic(),
|
|
PlatformRemoteMacOSX::CreateInstance);
|
|
}
|
|
}
|
|
|
|
void PlatformRemoteMacOSX::Terminate() {
|
|
if (g_initialize_count > 0) {
|
|
if (--g_initialize_count == 0) {
|
|
PluginManager::UnregisterPlugin(PlatformRemoteMacOSX::CreateInstance);
|
|
}
|
|
}
|
|
|
|
PlatformDarwin::Terminate();
|
|
}
|
|
|
|
PlatformSP PlatformRemoteMacOSX::CreateInstance(bool force,
|
|
const ArchSpec *arch) {
|
|
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
|
|
if (log) {
|
|
const char *arch_name;
|
|
if (arch && arch->GetArchitectureName())
|
|
arch_name = arch->GetArchitectureName();
|
|
else
|
|
arch_name = "<null>";
|
|
|
|
const char *triple_cstr =
|
|
arch ? arch->GetTriple().getTriple().c_str() : "<null>";
|
|
|
|
LLDB_LOGF(log, "PlatformMacOSX::%s(force=%s, arch={%s,%s})", __FUNCTION__,
|
|
force ? "true" : "false", arch_name, triple_cstr);
|
|
}
|
|
|
|
bool create = force;
|
|
if (!create && arch && arch->IsValid()) {
|
|
const llvm::Triple &triple = arch->GetTriple();
|
|
switch (triple.getVendor()) {
|
|
case llvm::Triple::Apple:
|
|
create = true;
|
|
break;
|
|
|
|
#if defined(__APPLE__)
|
|
// Only accept "unknown" for vendor if the host is Apple and it "unknown"
|
|
// wasn't specified (it was just returned because it was NOT specified)
|
|
case llvm::Triple::UnknownVendor:
|
|
create = !arch->TripleVendorWasSpecified();
|
|
break;
|
|
#endif
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (create) {
|
|
switch (triple.getOS()) {
|
|
case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
|
|
// historical reasons
|
|
case llvm::Triple::MacOSX:
|
|
break;
|
|
#if defined(__APPLE__)
|
|
// Only accept "vendor" for vendor if the host is Apple and it "unknown"
|
|
// wasn't specified (it was just returned because it was NOT specified)
|
|
case llvm::Triple::UnknownOS:
|
|
create = !arch->TripleOSWasSpecified();
|
|
break;
|
|
#endif
|
|
default:
|
|
create = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (create) {
|
|
LLDB_LOGF(log, "PlatformRemoteMacOSX::%s() creating platform",
|
|
__FUNCTION__);
|
|
return std::make_shared<PlatformRemoteMacOSX>();
|
|
}
|
|
|
|
LLDB_LOGF(log, "PlatformRemoteMacOSX::%s() aborting creation of platform",
|
|
__FUNCTION__);
|
|
|
|
return PlatformSP();
|
|
}
|
|
|
|
bool PlatformRemoteMacOSX::GetSupportedArchitectureAtIndex(uint32_t idx,
|
|
ArchSpec &arch) {
|
|
// macOS for ARM64 support both native and translated x86_64 processes
|
|
if (!m_num_arm_arches || idx < m_num_arm_arches) {
|
|
bool res = ARMGetSupportedArchitectureAtIndex(idx, arch);
|
|
if (res)
|
|
return true;
|
|
if (!m_num_arm_arches)
|
|
m_num_arm_arches = idx;
|
|
}
|
|
|
|
// We can't use x86GetSupportedArchitectureAtIndex() because it uses
|
|
// the system architecture for some of its return values and also
|
|
// has a 32bits variant.
|
|
if (idx == m_num_arm_arches) {
|
|
arch.SetTriple("x86_64-apple-macosx");
|
|
return true;
|
|
} else if (idx == m_num_arm_arches + 1) {
|
|
arch.SetTriple("x86_64-apple-ios-macabi");
|
|
return true;
|
|
} else if (idx == m_num_arm_arches + 2) {
|
|
arch.SetTriple("arm64-apple-ios");
|
|
return true;
|
|
} else if (idx == m_num_arm_arches + 3) {
|
|
arch.SetTriple("arm64e-apple-ios");
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
lldb_private::Status PlatformRemoteMacOSX::GetFileWithUUID(
|
|
const lldb_private::FileSpec &platform_file,
|
|
const lldb_private::UUID *uuid_ptr, lldb_private::FileSpec &local_file) {
|
|
if (m_remote_platform_sp) {
|
|
std::string local_os_build;
|
|
#if !defined(__linux__)
|
|
HostInfo::GetOSBuildString(local_os_build);
|
|
#endif
|
|
std::string remote_os_build;
|
|
m_remote_platform_sp->GetOSBuildString(remote_os_build);
|
|
if (local_os_build == remote_os_build) {
|
|
// same OS version: the local file is good enough
|
|
local_file = platform_file;
|
|
return Status();
|
|
} else {
|
|
// try to find the file in the cache
|
|
std::string cache_path(GetLocalCacheDirectory());
|
|
std::string module_path(platform_file.GetPath());
|
|
cache_path.append(module_path);
|
|
FileSpec module_cache_spec(cache_path);
|
|
if (FileSystem::Instance().Exists(module_cache_spec)) {
|
|
local_file = module_cache_spec;
|
|
return Status();
|
|
}
|
|
// bring in the remote module file
|
|
FileSpec module_cache_folder =
|
|
module_cache_spec.CopyByRemovingLastPathComponent();
|
|
// try to make the local directory first
|
|
Status err(
|
|
llvm::sys::fs::create_directory(module_cache_folder.GetPath()));
|
|
if (err.Fail())
|
|
return err;
|
|
err = GetFile(platform_file, module_cache_spec);
|
|
if (err.Fail())
|
|
return err;
|
|
if (FileSystem::Instance().Exists(module_cache_spec)) {
|
|
local_file = module_cache_spec;
|
|
return Status();
|
|
} else
|
|
return Status("unable to obtain valid module file");
|
|
}
|
|
}
|
|
local_file = platform_file;
|
|
return Status();
|
|
}
|
|
|
|
lldb_private::ConstString PlatformRemoteMacOSX::GetPluginNameStatic() {
|
|
static ConstString g_name("remote-macosx");
|
|
return g_name;
|
|
}
|
|
|
|
const char *PlatformRemoteMacOSX::GetDescriptionStatic() {
|
|
return "Remote Mac OS X user platform plug-in.";
|
|
}
|
|
|
|
llvm::StringRef PlatformRemoteMacOSX::GetDeviceSupportDirectoryName() {
|
|
return "macOS DeviceSupport";
|
|
}
|
|
|
|
llvm::StringRef PlatformRemoteMacOSX::GetPlatformName() {
|
|
return "MacOSX.platform";
|
|
}
|