Files
clang-p2996/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
Adrian Prantl 33cbda4cac Improve error logging when xcrun fails to execute successfully
Because Host::RunShellCommand runs commands through $SHELL there is an
opportunity for this to fail spectacularly on systems that use custom
shells with odd behaviors. This patch makes these situations easier to
debug by at least logging the result of the failed xcrun invocation.

It also doesn't run xcrun through a shell any more.

rdar://102389438

Differential Revision: https://reviews.llvm.org/D138060
2022-12-01 16:22:14 -08:00

227 lines
7.9 KiB
C++

//===-- PlatformMacOSX.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 "PlatformMacOSX.h"
#include "PlatformRemoteMacOSX.h"
#include "PlatformRemoteiOS.h"
#if defined(__APPLE__)
#include "PlatformAppleSimulator.h"
#include "PlatformDarwinKernel.h"
#include "PlatformRemoteAppleBridge.h"
#include "PlatformRemoteAppleTV.h"
#include "PlatformRemoteAppleWatch.h"
#endif
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/StreamString.h"
#include <sstream>
using namespace lldb;
using namespace lldb_private;
LLDB_PLUGIN_DEFINE(PlatformMacOSX)
static uint32_t g_initialize_count = 0;
void PlatformMacOSX::Initialize() {
PlatformDarwin::Initialize();
PlatformRemoteiOS::Initialize();
PlatformRemoteMacOSX::Initialize();
#if defined(__APPLE__)
PlatformAppleSimulator::Initialize();
PlatformDarwinKernel::Initialize();
PlatformRemoteAppleTV::Initialize();
PlatformRemoteAppleWatch::Initialize();
PlatformRemoteAppleBridge::Initialize();
#endif
if (g_initialize_count++ == 0) {
#if defined(__APPLE__)
PlatformSP default_platform_sp(new PlatformMacOSX());
default_platform_sp->SetSystemArchitecture(HostInfo::GetArchitecture());
Platform::SetHostPlatform(default_platform_sp);
#endif
PluginManager::RegisterPlugin(PlatformMacOSX::GetPluginNameStatic(),
PlatformMacOSX::GetDescriptionStatic(),
PlatformMacOSX::CreateInstance);
}
}
void PlatformMacOSX::Terminate() {
if (g_initialize_count > 0) {
if (--g_initialize_count == 0) {
PluginManager::UnregisterPlugin(PlatformMacOSX::CreateInstance);
}
}
#if defined(__APPLE__)
PlatformRemoteAppleBridge::Terminate();
PlatformRemoteAppleWatch::Terminate();
PlatformRemoteAppleTV::Terminate();
PlatformDarwinKernel::Terminate();
PlatformAppleSimulator::Terminate();
#endif
PlatformRemoteMacOSX::Initialize();
PlatformRemoteiOS::Terminate();
PlatformDarwin::Terminate();
}
llvm::StringRef PlatformMacOSX::GetDescriptionStatic() {
return "Local Mac OS X user platform plug-in.";
}
PlatformSP PlatformMacOSX::CreateInstance(bool force, const ArchSpec *arch) {
// The only time we create an instance is when we are creating a remote
// macosx platform which is handled by PlatformRemoteMacOSX.
return PlatformSP();
}
/// Default Constructor
PlatformMacOSX::PlatformMacOSX() : PlatformDarwinDevice(true) {}
ConstString PlatformMacOSX::GetSDKDirectory(lldb_private::Target &target) {
ModuleSP exe_module_sp(target.GetExecutableModule());
if (!exe_module_sp)
return {};
ObjectFile *objfile = exe_module_sp->GetObjectFile();
if (!objfile)
return {};
llvm::VersionTuple version = objfile->GetSDKVersion();
if (version.empty())
return {};
// First try to find an SDK that matches the given SDK version.
if (FileSpec fspec = HostInfo::GetXcodeContentsDirectory()) {
StreamString sdk_path;
sdk_path.Printf("%s/Developer/Platforms/MacOSX.platform/Developer/"
"SDKs/MacOSX%u.%u.sdk",
fspec.GetPath().c_str(), version.getMajor(),
*version.getMinor());
if (FileSystem::Instance().Exists(fspec))
return ConstString(sdk_path.GetString());
}
// Use the default SDK as a fallback.
auto sdk_path_or_err = HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS());
if (!sdk_path_or_err) {
Debugger::ReportError("Error while searching for Xcode SDK: " +
toString(sdk_path_or_err.takeError()));
return {};
}
FileSpec fspec(*sdk_path_or_err);
if (fspec) {
if (FileSystem::Instance().Exists(fspec))
return ConstString(fspec.GetPath());
}
return {};
}
std::vector<ArchSpec>
PlatformMacOSX::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
std::vector<ArchSpec> result;
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
// When cmdline lldb is run on iOS, watchOS, etc, it is still
// using "PlatformMacOSX".
llvm::Triple::OSType host_os = GetHostOSType();
ARMGetSupportedArchitectures(result, host_os);
if (host_os == llvm::Triple::MacOSX) {
// We can't use x86GetSupportedArchitectures() because it uses
// the system architecture for some of its return values and also
// has a 32bits variant.
result.push_back(ArchSpec("x86_64-apple-macosx"));
result.push_back(ArchSpec("x86_64-apple-ios-macabi"));
result.push_back(ArchSpec("arm64-apple-ios-macabi"));
result.push_back(ArchSpec("arm64e-apple-ios-macabi"));
// On Apple Silicon, the host platform is compatible with iOS triples to
// support unmodified "iPhone and iPad Apps on Apple Silicon Macs". Because
// the binaries are identical, we must rely on the host architecture to
// tell them apart and mark the host platform as compatible or not.
if (!process_host_arch ||
process_host_arch.GetTriple().getOS() == llvm::Triple::MacOSX) {
result.push_back(ArchSpec("arm64-apple-ios"));
result.push_back(ArchSpec("arm64e-apple-ios"));
}
}
#else
x86GetSupportedArchitectures(result);
result.push_back(ArchSpec("x86_64-apple-ios-macabi"));
#endif
return result;
}
lldb_private::Status PlatformMacOSX::GetSharedModule(
const lldb_private::ModuleSpec &module_spec, Process *process,
lldb::ModuleSP &module_sp,
const lldb_private::FileSpecList *module_search_paths_ptr,
llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr) {
Status error = GetSharedModuleWithLocalCache(module_spec, module_sp,
module_search_paths_ptr,
old_modules, did_create_ptr);
if (module_sp) {
if (module_spec.GetArchitecture().GetCore() ==
ArchSpec::eCore_x86_64_x86_64h) {
ObjectFile *objfile = module_sp->GetObjectFile();
if (objfile == nullptr) {
// We didn't find an x86_64h slice, fall back to a x86_64 slice
ModuleSpec module_spec_x86_64(module_spec);
module_spec_x86_64.GetArchitecture() = ArchSpec("x86_64-apple-macosx");
lldb::ModuleSP x86_64_module_sp;
llvm::SmallVector<lldb::ModuleSP, 1> old_x86_64_modules;
bool did_create = false;
Status x86_64_error = GetSharedModuleWithLocalCache(
module_spec_x86_64, x86_64_module_sp, module_search_paths_ptr,
&old_x86_64_modules, &did_create);
if (x86_64_module_sp && x86_64_module_sp->GetObjectFile()) {
module_sp = x86_64_module_sp;
if (old_modules)
old_modules->append(old_x86_64_modules.begin(),
old_x86_64_modules.end());
if (did_create_ptr)
*did_create_ptr = did_create;
return x86_64_error;
}
}
}
}
if (!module_sp) {
error = FindBundleBinaryInExecSearchPaths(module_spec, process, module_sp,
module_search_paths_ptr,
old_modules, did_create_ptr);
}
return error;
}
llvm::StringRef PlatformMacOSX::GetDeviceSupportDirectoryName() {
return "macOS DeviceSupport";
}
llvm::StringRef PlatformMacOSX::GetPlatformName() { return "MacOSX.platform"; }