forked from OSchip/llvm-project
Unify the common code in the ios, tvos, watchos platforms into a single
PlatformRemoveDarwinDevice class, subclassed to those three so they can provide their specific information. <rdar://problem/30159764> llvm-svn: 300512
This commit is contained in:
parent
47ee0f4d31
commit
1781d6f732
|
@ -923,6 +923,8 @@
|
|||
AF33B4BE1C1FA441001B28D9 /* NetBSDSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */; };
|
||||
AF33B4BF1C1FA441001B28D9 /* NetBSDSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = AF33B4BD1C1FA441001B28D9 /* NetBSDSignals.h */; };
|
||||
AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF37E10917C861F20061E18E /* ProcessRunLock.cpp */; };
|
||||
AF3A4AD21EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */; };
|
||||
AF3A4AD31EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */; };
|
||||
AF415AE71D949E4400FCE0D4 /* x86AssemblyInspectionEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF415AE51D949E4400FCE0D4 /* x86AssemblyInspectionEngine.cpp */; };
|
||||
AF415AE81D949E4400FCE0D4 /* x86AssemblyInspectionEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = AF415AE61D949E4400FCE0D4 /* x86AssemblyInspectionEngine.h */; };
|
||||
AF45FDE518A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF45FDE318A1F3AC0007051C /* AppleGetThreadItemInfoHandler.cpp */; };
|
||||
|
@ -2937,6 +2939,8 @@
|
|||
AF33B4BC1C1FA441001B28D9 /* NetBSDSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NetBSDSignals.cpp; path = Utility/NetBSDSignals.cpp; sourceTree = "<group>"; };
|
||||
AF33B4BD1C1FA441001B28D9 /* NetBSDSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetBSDSignals.h; path = Utility/NetBSDSignals.h; sourceTree = "<group>"; };
|
||||
AF37E10917C861F20061E18E /* ProcessRunLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessRunLock.cpp; sourceTree = "<group>"; };
|
||||
AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteDarwinDevice.cpp; sourceTree = "<group>"; };
|
||||
AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteDarwinDevice.h; sourceTree = "<group>"; };
|
||||
AF3F54AE1B3BA59C00186E73 /* CrashReason.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CrashReason.cpp; sourceTree = "<group>"; };
|
||||
AF3F54AF1B3BA59C00186E73 /* CrashReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CrashReason.h; sourceTree = "<group>"; };
|
||||
AF3F54B21B3BA5D500186E73 /* POSIXStopInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = POSIXStopInfo.cpp; sourceTree = "<group>"; };
|
||||
|
@ -5426,6 +5430,8 @@
|
|||
9455630D1BEAD0570073F75F /* PlatformiOSSimulatorCoreSimulatorSupport.mm */,
|
||||
26C5577B132575AD008FD8FE /* PlatformMacOSX.cpp */,
|
||||
26C5577C132575AD008FD8FE /* PlatformMacOSX.h */,
|
||||
AF3A4AD01EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp */,
|
||||
AF3A4AD11EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h */,
|
||||
AF8AD6331BEC28C400150209 /* PlatformRemoteAppleTV.cpp */,
|
||||
AF8AD6341BEC28C400150209 /* PlatformRemoteAppleTV.h */,
|
||||
AF8AD6351BEC28C400150209 /* PlatformRemoteAppleWatch.cpp */,
|
||||
|
@ -6469,6 +6475,7 @@
|
|||
files = (
|
||||
AF8AD6381BEC28C400150209 /* PlatformRemoteAppleTV.h in Headers */,
|
||||
26EFB61C1BFE8D3E00544801 /* PlatformNetBSD.h in Headers */,
|
||||
AF3A4AD31EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.h in Headers */,
|
||||
AF33B4BF1C1FA441001B28D9 /* NetBSDSignals.h in Headers */,
|
||||
AF6335E31C87B21E00F7D554 /* SymbolFilePDB.h in Headers */,
|
||||
267F685A1CC02EBE0086832B /* RegisterInfos_s390x.h in Headers */,
|
||||
|
@ -7284,6 +7291,7 @@
|
|||
AE6897281B94F6DE0018845D /* DWARFASTParserGo.cpp in Sources */,
|
||||
945261C41B9A11FC00BF138D /* LibCxxUnorderedMap.cpp in Sources */,
|
||||
26CEB5F218762056008F575A /* CommandObjectGUI.cpp in Sources */,
|
||||
AF3A4AD21EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp in Sources */,
|
||||
2689008013353E2200698AC0 /* CommandInterpreter.cpp in Sources */,
|
||||
AF77E0A41A033D360096C0EA /* RegisterContextPOSIX_powerpc.cpp in Sources */,
|
||||
4CDB8D6D1DBA91B6006C5B13 /* LibStdcppUniquePointer.cpp in Sources */,
|
||||
|
|
|
@ -5,6 +5,7 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES
|
|||
PlatformRemoteiOS.cpp
|
||||
PlatformRemoteAppleTV.cpp
|
||||
PlatformRemoteAppleWatch.cpp
|
||||
PlatformRemoteDarwinDevice.cpp
|
||||
)
|
||||
|
||||
list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES
|
||||
|
|
|
@ -569,6 +569,8 @@ bool PlatformDarwin::ARMGetSupportedArchitectureAtIndex(uint32_t idx,
|
|||
#define OSNAME "tvos"
|
||||
#elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
|
||||
#define OSNAME "watchos"
|
||||
#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
|
||||
#define OSNAME "bridgeos"
|
||||
#else
|
||||
#define OSNAME "ios"
|
||||
#endif
|
||||
|
|
|
@ -37,22 +37,7 @@ using namespace lldb_private;
|
|||
/// Default Constructor
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteAppleTV::PlatformRemoteAppleTV()
|
||||
: PlatformDarwin(false), // This is a remote platform
|
||||
m_sdk_directory_infos(), m_device_support_directory(),
|
||||
m_device_support_directory_for_os_version(), m_build_update(),
|
||||
m_last_module_sdk_idx(UINT32_MAX),
|
||||
m_connected_module_sdk_idx(UINT32_MAX) {}
|
||||
|
||||
PlatformRemoteAppleTV::SDKDirectoryInfo::SDKDirectoryInfo(
|
||||
const lldb_private::FileSpec &sdk_dir)
|
||||
: directory(sdk_dir), build(), version_major(0), version_minor(0),
|
||||
version_update(0), user_cached(false) {
|
||||
llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
|
||||
llvm::StringRef build_str;
|
||||
std::tie(version_major, version_minor, version_update, build_str) =
|
||||
ParseVersionBuildDir(dirname_str);
|
||||
build.SetString(build_str);
|
||||
}
|
||||
: PlatformRemoteDarwinDevice () {}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Static Variables
|
||||
|
@ -165,615 +150,6 @@ const char *PlatformRemoteAppleTV::GetDescriptionStatic() {
|
|||
return "Remote Apple TV platform plug-in.";
|
||||
}
|
||||
|
||||
void PlatformRemoteAppleTV::GetStatus(Stream &strm) {
|
||||
Platform::GetStatus(strm);
|
||||
const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (sdk_directory)
|
||||
strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
|
||||
else
|
||||
strm.PutCString(" SDK Path: error: unable to locate SDK\n");
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
|
||||
sdk_dir_info.directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Error PlatformRemoteAppleTV::ResolveExecutable(
|
||||
const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
|
||||
const FileSpecList *module_search_paths_ptr) {
|
||||
Error error;
|
||||
// Nothing special to do here, just use the actual file and architecture
|
||||
|
||||
ModuleSpec resolved_module_spec(ms);
|
||||
|
||||
// Resolve any executable within a bundle on MacOSX
|
||||
// TODO: verify that this handles shallow bundles, if not then implement one
|
||||
// ourselves
|
||||
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
|
||||
|
||||
if (resolved_module_spec.GetFileSpec().Exists()) {
|
||||
if (resolved_module_spec.GetArchitecture().IsValid() ||
|
||||
resolved_module_spec.GetUUID().IsValid()) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
return error;
|
||||
exe_module_sp.reset();
|
||||
}
|
||||
// No valid architecture was specified or the exact ARM slice wasn't
|
||||
// found so ask the platform for the architectures that we should be
|
||||
// using (in the correct order) and see if we can find a match that way
|
||||
StreamString arch_names;
|
||||
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
|
||||
idx, resolved_module_spec.GetArchitecture());
|
||||
++idx) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
nullptr, nullptr, nullptr);
|
||||
// Did we find an executable using one of the
|
||||
if (error.Success()) {
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
break;
|
||||
else
|
||||
error.SetErrorToGenericError();
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
arch_names.PutCString(", ");
|
||||
arch_names.PutCString(
|
||||
resolved_module_spec.GetArchitecture().GetArchitectureName());
|
||||
}
|
||||
|
||||
if (error.Fail() || !exe_module_sp) {
|
||||
if (resolved_module_spec.GetFileSpec().Readable()) {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' doesn't contain any '%s' platform architectures: %s",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str(),
|
||||
GetPluginName().GetCString(), arch_names.GetData());
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' is not readable",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' does not exist",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FileSpec::EnumerateDirectoryResult
|
||||
PlatformRemoteAppleTV::GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
|
||||
((PlatformRemoteAppleTV::SDKDirectoryInfoCollection *)baton)
|
||||
->push_back(PlatformRemoteAppleTV::SDKDirectoryInfo(file_spec));
|
||||
return FileSpec::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
|
||||
bool PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded() {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
|
||||
if (m_sdk_directory_infos.empty()) {
|
||||
const char *device_support_dir = GetDeviceSupportDirectory();
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded Got "
|
||||
"DeviceSupport directory %s",
|
||||
device_support_dir);
|
||||
}
|
||||
if (device_support_dir) {
|
||||
const bool find_directories = true;
|
||||
const bool find_files = false;
|
||||
const bool find_other = false;
|
||||
|
||||
SDKDirectoryInfoCollection builtin_sdk_directory_infos;
|
||||
FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
|
||||
find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&builtin_sdk_directory_infos);
|
||||
|
||||
// Only add SDK directories that have symbols in them, some SDKs only
|
||||
// contain
|
||||
// developer disk images and no symbols, so they aren't useful to us.
|
||||
FileSpec sdk_symbols_symlink_fspec;
|
||||
for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
|
||||
sdk_symbols_symlink_fspec = sdk_directory_info.directory;
|
||||
sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
|
||||
if (sdk_symbols_symlink_fspec.Exists()) {
|
||||
m_sdk_directory_infos.push_back(sdk_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleTV::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
|
||||
"directory %s",
|
||||
sdk_symbols_symlink_fspec.GetPath().c_str());
|
||||
}
|
||||
} else {
|
||||
sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
|
||||
if (sdk_symbols_symlink_fspec.Exists())
|
||||
m_sdk_directory_infos.push_back(sdk_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleTV::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
|
||||
"directory %s",
|
||||
sdk_symbols_symlink_fspec.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t num_installed = m_sdk_directory_infos.size();
|
||||
FileSpec local_sdk_cache("~/Library/Developer/Xcode/tvOS DeviceSupport",
|
||||
true);
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
// Try looking for another possible name
|
||||
local_sdk_cache = FileSpec(
|
||||
"~/Library/Developer/Xcode/Apple TVOS DeviceSupport", true);
|
||||
}
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
// Try looking for another possible name
|
||||
local_sdk_cache =
|
||||
FileSpec("~/Library/Developer/Xcode/AppleTVOS DeviceSupport", true);
|
||||
}
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
// Try looking for another possible name
|
||||
local_sdk_cache = FileSpec(
|
||||
"~/Library/Developer/Xcode/AppleTV OS DeviceSupport", true);
|
||||
}
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
// Try looking for another possible name
|
||||
local_sdk_cache = FileSpec(
|
||||
"~/Library/Developer/Xcode/Apple TV OS DeviceSupport", true);
|
||||
}
|
||||
if (local_sdk_cache.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleTV::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"searching %s for additional SDKs",
|
||||
local_sdk_cache.GetPath().c_str());
|
||||
}
|
||||
char path[PATH_MAX];
|
||||
if (local_sdk_cache.GetPath(path, sizeof(path))) {
|
||||
FileSpec::EnumerateDirectory(
|
||||
path, find_directories, find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&m_sdk_directory_infos);
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
|
||||
m_sdk_directory_infos[i].user_cached = true;
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleTV::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded user SDK directory "
|
||||
"%s",
|
||||
m_sdk_directory_infos[i].directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !m_sdk_directory_infos.empty();
|
||||
}
|
||||
|
||||
const PlatformRemoteAppleTV::SDKDirectoryInfo *
|
||||
PlatformRemoteAppleTV::GetSDKDirectoryForCurrentOSVersion() {
|
||||
uint32_t i;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// Check to see if the user specified a build string. If they did, then
|
||||
// be sure to match it.
|
||||
std::vector<bool> check_sdk_info(num_sdk_infos, true);
|
||||
ConstString build(m_sdk_build);
|
||||
if (build) {
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
|
||||
}
|
||||
|
||||
// If we are connected we can find the version of the OS the platform
|
||||
// us running on and select the right SDK
|
||||
uint32_t major, minor, update;
|
||||
if (GetOSVersion(major, minor, update)) {
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
// First try for an exact match of major, minor and update
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor &&
|
||||
m_sdk_directory_infos[i].version_update == update) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// First try for an exact match of major and minor
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Lastly try to match of major version only..
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (build) {
|
||||
// No version, just a build number, search for the first one that matches
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
if (check_sdk_info[i])
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const PlatformRemoteAppleTV::SDKDirectoryInfo *
|
||||
PlatformRemoteAppleTV::GetSDKDirectoryForLatestOSVersion() {
|
||||
const PlatformRemoteAppleTV::SDKDirectoryInfo *result = nullptr;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (sdk_dir_info.version_major != UINT32_MAX) {
|
||||
if (result == nullptr ||
|
||||
sdk_dir_info.version_major > result->version_major) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_major == result->version_major) {
|
||||
if (sdk_dir_info.version_minor > result->version_minor) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_minor == result->version_minor) {
|
||||
if (sdk_dir_info.version_update > result->version_update) {
|
||||
result = &sdk_dir_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteAppleTV::GetDeviceSupportDirectory() {
|
||||
if (m_device_support_directory.empty()) {
|
||||
const char *device_support_dir = GetDeveloperDirectory();
|
||||
if (device_support_dir) {
|
||||
m_device_support_directory.assign(device_support_dir);
|
||||
m_device_support_directory.append(
|
||||
"/Platforms/AppleTVOS.platform/DeviceSupport");
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into m_device_support_directory
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory.empty() == false);
|
||||
if (m_device_support_directory[0])
|
||||
return m_device_support_directory.c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteAppleTV::GetDeviceSupportDirectoryForOSVersion() {
|
||||
if (m_sdk_sysroot)
|
||||
return m_sdk_sysroot.GetCString();
|
||||
|
||||
if (m_device_support_directory_for_os_version.empty()) {
|
||||
const PlatformRemoteAppleTV::SDKDirectoryInfo *sdk_dir_info =
|
||||
GetSDKDirectoryForCurrentOSVersion();
|
||||
if (sdk_dir_info == nullptr)
|
||||
sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
|
||||
if (sdk_dir_info) {
|
||||
char path[PATH_MAX];
|
||||
if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
|
||||
m_device_support_directory_for_os_version = path;
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
}
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory_for_os_version.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into
|
||||
// m_device_support_directory_for_os_version
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory_for_os_version.empty() == false);
|
||||
if (m_device_support_directory_for_os_version[0])
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PlatformRemoteAppleTV::FindFileInAllSDKs(const char *platform_file_path,
|
||||
FileSpecList &file_list) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (platform_file_path && platform_file_path[0] &&
|
||||
UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
lldb_private::FileSpec local_file;
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
|
||||
file_list.Append(local_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_list.GetSize();
|
||||
}
|
||||
|
||||
bool PlatformRemoteAppleTV::GetFileInSDK(const char *platform_file_path,
|
||||
uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (sdk_idx < m_sdk_directory_infos.size()) {
|
||||
std::string sdkroot_path =
|
||||
m_sdk_directory_infos[sdk_idx].directory.GetPath();
|
||||
if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
|
||||
// We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
|
||||
// the
|
||||
// SDK root directory and the file path.
|
||||
|
||||
const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
|
||||
for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
|
||||
local_file.SetFile(sdkroot_path, false);
|
||||
if (paths_to_try[i][0] != '\0')
|
||||
local_file.AppendPathComponent(paths_to_try[i]);
|
||||
local_file.AppendPathComponent(platform_file_path);
|
||||
local_file.ResolvePath();
|
||||
if (local_file.Exists()) {
|
||||
if (log)
|
||||
log->Printf("Found a copy of %s in the SDK dir %s/%s",
|
||||
platform_file_path, sdkroot_path.c_str(),
|
||||
paths_to_try[i]);
|
||||
return true;
|
||||
}
|
||||
local_file.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Error PlatformRemoteAppleTV::GetSymbolFile(const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
char resolved_path[PATH_MAX];
|
||||
|
||||
const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (os_version_dir) {
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
|
||||
platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf(
|
||||
"Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
local_file = platform_file;
|
||||
if (local_file.Exists())
|
||||
return error;
|
||||
|
||||
error.SetErrorStringWithFormat(
|
||||
"unable to locate a platform file for '%s' in platform '%s'",
|
||||
platform_file_path, GetPluginName().GetCString());
|
||||
} else {
|
||||
error.SetErrorString("invalid platform file argument");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Error PlatformRemoteAppleTV::GetSharedModule(
|
||||
const ModuleSpec &module_spec, lldb_private::Process *process,
|
||||
ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
|
||||
ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
|
||||
// For Apple TV, the SDK files are all cached locally on the host
|
||||
// system. So first we ask for the file in the cached SDK,
|
||||
// then we attempt to get a shared module for the right architecture
|
||||
// with the right UUID.
|
||||
const FileSpec &platform_file = module_spec.GetFileSpec();
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
ModuleSpec platform_module_spec(module_spec);
|
||||
|
||||
UpdateSDKDirectoryInfosIfNeeded();
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// If we are connected we migth be able to correctly deduce the SDK
|
||||
// directory
|
||||
// using the OS build.
|
||||
const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
|
||||
if (connected_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[connected_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, connected_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
|
||||
if (module_sp) {
|
||||
m_last_module_sdk_idx = connected_sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try the last SDK index if it is set as most files from an SDK
|
||||
// will tend to be valid in that same SDK.
|
||||
if (m_last_module_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
|
||||
m_sdk_directory_infos[m_last_module_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
|
||||
if (module_sp) {
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
if (m_last_module_sdk_idx == sdk_idx) {
|
||||
// Skip the last module SDK index if we already searched
|
||||
// it above
|
||||
continue;
|
||||
}
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
// printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
|
||||
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
|
||||
if (module_sp) {
|
||||
// Remember the index of the last SDK that we found a file
|
||||
// in in case the wrong SDK was selected.
|
||||
m_last_module_sdk_idx = sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Not the module we are looking for... Nothing to see here...
|
||||
module_sp.reset();
|
||||
|
||||
// This may not be an SDK-related module. Try whether we can bring in the
|
||||
// thing to our local cache.
|
||||
error = GetSharedModuleWithLocalCache(module_spec, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success())
|
||||
return error;
|
||||
|
||||
// See if the file is present in any of the module_search_paths_ptr
|
||||
// directories.
|
||||
if (!module_sp && module_search_paths_ptr && platform_file) {
|
||||
// create a vector of all the file / directory names in platform_file
|
||||
// e.g. this might be
|
||||
// /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
//
|
||||
// We'll need to look in the module_search_paths_ptr directories for
|
||||
// both "UIFoundation" and "UIFoundation.framework" -- most likely the
|
||||
// latter will be the one we find there.
|
||||
|
||||
FileSpec platform_pull_apart(platform_file);
|
||||
std::vector<std::string> path_parts;
|
||||
ConstString unix_root_dir("/");
|
||||
while (true) {
|
||||
ConstString part = platform_pull_apart.GetLastPathComponent();
|
||||
platform_pull_apart.RemoveLastPathComponent();
|
||||
if (part.IsEmpty() || part == unix_root_dir)
|
||||
break;
|
||||
path_parts.push_back(part.AsCString());
|
||||
}
|
||||
const size_t path_parts_size = path_parts.size();
|
||||
|
||||
size_t num_module_search_paths = module_search_paths_ptr->GetSize();
|
||||
for (size_t i = 0; i < num_module_search_paths; ++i) {
|
||||
// Create a new FileSpec with this module_search_paths_ptr
|
||||
// plus just the filename ("UIFoundation"), then the parent
|
||||
// dir plus filename ("UIFoundation.framework/UIFoundation")
|
||||
// etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
|
||||
|
||||
for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
|
||||
FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
|
||||
|
||||
// Add the components backwards. For
|
||||
// .../PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
// path_parts is
|
||||
// [0] UIFoundation
|
||||
// [1] UIFoundation.framework
|
||||
// [2] PrivateFrameworks
|
||||
//
|
||||
// and if 'j' is 2, we want to append path_parts[1] and then
|
||||
// path_parts[0], aka
|
||||
// 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
|
||||
// path.
|
||||
|
||||
for (int k = j; k >= 0; --k) {
|
||||
path_to_try.AppendPathComponent(path_parts[k]);
|
||||
}
|
||||
|
||||
if (path_to_try.Exists()) {
|
||||
ModuleSpec new_module_spec(module_spec);
|
||||
new_module_spec.GetFileSpec() = path_to_try;
|
||||
Error new_error(Platform::GetSharedModule(
|
||||
new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
|
||||
did_create_ptr));
|
||||
|
||||
if (module_sp) {
|
||||
module_sp->SetPlatformFileSpec(path_to_try);
|
||||
return new_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool always_create = false;
|
||||
error = ModuleList::GetSharedModule(
|
||||
module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
|
||||
did_create_ptr, always_create);
|
||||
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
bool PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex(uint32_t idx,
|
||||
ArchSpec &arch) {
|
||||
ArchSpec system_arch(GetSystemArchitecture());
|
||||
|
@ -860,23 +236,15 @@ bool PlatformRemoteAppleTV::GetSupportedArchitectureAtIndex(uint32_t idx,
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteAppleTV::GetConnectedSDKIndex() {
|
||||
if (IsConnected()) {
|
||||
if (m_connected_module_sdk_idx == UINT32_MAX) {
|
||||
std::string build;
|
||||
if (GetRemoteOSBuildString(build)) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
|
||||
build.c_str())) {
|
||||
m_connected_module_sdk_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_connected_module_sdk_idx = UINT32_MAX;
|
||||
}
|
||||
return m_connected_module_sdk_idx;
|
||||
|
||||
void PlatformRemoteAppleTV::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
|
||||
{
|
||||
dirnames.clear();
|
||||
dirnames.push_back("tvOS DeviceSupport");
|
||||
}
|
||||
|
||||
std::string PlatformRemoteAppleTV::GetPlatformName ()
|
||||
{
|
||||
return "AppleTVOS.platform";
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
||||
#include "PlatformDarwin.h"
|
||||
#include "PlatformRemoteDarwinDevice.h"
|
||||
|
||||
class PlatformRemoteAppleTV : public PlatformDarwin {
|
||||
class PlatformRemoteAppleTV : public PlatformRemoteDarwinDevice {
|
||||
public:
|
||||
PlatformRemoteAppleTV();
|
||||
|
||||
|
@ -42,9 +42,6 @@ public:
|
|||
|
||||
static const char *GetDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Methods
|
||||
//------------------------------------------------------------
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
|
@ -57,80 +54,21 @@ public:
|
|||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
lldb_private::Error ResolveExecutable(
|
||||
const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr) override;
|
||||
|
||||
const char *GetDescription() override { return GetDescriptionStatic(); }
|
||||
|
||||
void GetStatus(lldb_private::Stream &strm) override;
|
||||
|
||||
virtual lldb_private::Error
|
||||
GetSymbolFile(const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
lldb_private::Error
|
||||
GetSharedModule(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb_private::Process *process, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) override;
|
||||
|
||||
bool GetSupportedArchitectureAtIndex(uint32_t idx,
|
||||
lldb_private::ArchSpec &arch) override;
|
||||
|
||||
void
|
||||
AddClangModuleCompilationOptions(lldb_private::Target *target,
|
||||
std::vector<std::string> &options) override {
|
||||
return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
|
||||
target, options, PlatformDarwin::SDKType::iPhoneOS);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct SDKDirectoryInfo {
|
||||
SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
|
||||
lldb_private::FileSpec directory;
|
||||
lldb_private::ConstString build;
|
||||
uint32_t version_major;
|
||||
uint32_t version_minor;
|
||||
uint32_t version_update;
|
||||
bool user_cached;
|
||||
};
|
||||
typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
|
||||
std::mutex m_sdk_dir_mutex;
|
||||
SDKDirectoryInfoCollection m_sdk_directory_infos;
|
||||
std::string m_device_support_directory;
|
||||
std::string m_device_support_directory_for_os_version;
|
||||
std::string m_build_update;
|
||||
uint32_t m_last_module_sdk_idx;
|
||||
uint32_t m_connected_module_sdk_idx;
|
||||
|
||||
bool UpdateSDKDirectoryInfosIfNeeded();
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PlatformRemoteDarwinDevice functions
|
||||
//------------------------------------------------------------
|
||||
|
||||
const char *GetDeviceSupportDirectory();
|
||||
void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
|
||||
|
||||
const char *GetDeviceSupportDirectoryForOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
|
||||
|
||||
static lldb_private::FileSpec::EnumerateDirectoryResult
|
||||
GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft,
|
||||
const lldb_private::FileSpec &file_spec);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const char *platform_file_path,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
uint32_t GetConnectedSDKIndex();
|
||||
std::string GetPlatformName () override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleTV);
|
||||
|
|
|
@ -33,27 +33,6 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default Constructor
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
|
||||
: PlatformDarwin(false), // This is a remote platform
|
||||
m_sdk_directory_infos(), m_device_support_directory(),
|
||||
m_device_support_directory_for_os_version(), m_build_update(),
|
||||
m_last_module_sdk_idx(UINT32_MAX),
|
||||
m_connected_module_sdk_idx(UINT32_MAX) {}
|
||||
|
||||
PlatformRemoteAppleWatch::SDKDirectoryInfo::SDKDirectoryInfo(
|
||||
const lldb_private::FileSpec &sdk_dir)
|
||||
: directory(sdk_dir), build(), version_major(0), version_minor(0),
|
||||
version_update(0), user_cached(false) {
|
||||
llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
|
||||
llvm::StringRef build_str;
|
||||
std::tie(version_major, version_minor, version_update, build_str) =
|
||||
ParseVersionBuildDir(dirname_str);
|
||||
build.SetString(build_str);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Static Variables
|
||||
//------------------------------------------------------------------
|
||||
|
@ -175,618 +154,11 @@ const char *PlatformRemoteAppleWatch::GetDescriptionStatic() {
|
|||
return "Remote Apple Watch platform plug-in.";
|
||||
}
|
||||
|
||||
void PlatformRemoteAppleWatch::GetStatus(Stream &strm) {
|
||||
Platform::GetStatus(strm);
|
||||
const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (sdk_directory)
|
||||
strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
|
||||
else
|
||||
strm.PutCString(" SDK Path: error: unable to locate SDK\n");
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
|
||||
sdk_dir_info.directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Error PlatformRemoteAppleWatch::ResolveExecutable(
|
||||
const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
|
||||
const FileSpecList *module_search_paths_ptr) {
|
||||
Error error;
|
||||
// Nothing special to do here, just use the actual file and architecture
|
||||
|
||||
ModuleSpec resolved_module_spec(ms);
|
||||
|
||||
// Resolve any executable within a bundle on MacOSX
|
||||
// TODO: verify that this handles shallow bundles, if not then implement one
|
||||
// ourselves
|
||||
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
|
||||
|
||||
if (resolved_module_spec.GetFileSpec().Exists()) {
|
||||
if (resolved_module_spec.GetArchitecture().IsValid() ||
|
||||
resolved_module_spec.GetUUID().IsValid()) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
nullptr, nullptr, nullptr);
|
||||
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
return error;
|
||||
exe_module_sp.reset();
|
||||
}
|
||||
// No valid architecture was specified or the exact ARM slice wasn't
|
||||
// found so ask the platform for the architectures that we should be
|
||||
// using (in the correct order) and see if we can find a match that way
|
||||
StreamString arch_names;
|
||||
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
|
||||
idx, resolved_module_spec.GetArchitecture());
|
||||
++idx) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
nullptr, nullptr, nullptr);
|
||||
// Did we find an executable using one of the
|
||||
if (error.Success()) {
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
break;
|
||||
else
|
||||
error.SetErrorToGenericError();
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
arch_names.PutCString(", ");
|
||||
arch_names.PutCString(
|
||||
resolved_module_spec.GetArchitecture().GetArchitectureName());
|
||||
}
|
||||
|
||||
if (error.Fail() || !exe_module_sp) {
|
||||
if (resolved_module_spec.GetFileSpec().Readable()) {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' doesn't contain any '%s' platform architectures: %s",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str(),
|
||||
GetPluginName().GetCString(), arch_names.GetData());
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' is not readable",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' does not exist",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FileSpec::EnumerateDirectoryResult
|
||||
PlatformRemoteAppleWatch::GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
|
||||
((PlatformRemoteAppleWatch::SDKDirectoryInfoCollection *)baton)
|
||||
->push_back(PlatformRemoteAppleWatch::SDKDirectoryInfo(file_spec));
|
||||
return FileSpec::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
|
||||
bool PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded() {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
|
||||
if (m_sdk_directory_infos.empty()) {
|
||||
const char *device_support_dir = GetDeviceSupportDirectory();
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleWatch::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"Got DeviceSupport directory %s",
|
||||
device_support_dir);
|
||||
}
|
||||
if (device_support_dir) {
|
||||
const bool find_directories = true;
|
||||
const bool find_files = false;
|
||||
const bool find_other = false;
|
||||
|
||||
SDKDirectoryInfoCollection builtin_sdk_directory_infos;
|
||||
FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
|
||||
find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&builtin_sdk_directory_infos);
|
||||
|
||||
// Only add SDK directories that have symbols in them, some SDKs only
|
||||
// contain
|
||||
// developer disk images and no symbols, so they aren't useful to us.
|
||||
FileSpec sdk_symbols_symlink_fspec;
|
||||
for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
|
||||
sdk_symbols_symlink_fspec = sdk_directory_info.directory;
|
||||
sdk_symbols_symlink_fspec.AppendPathComponent("Symbols.Internal");
|
||||
if (sdk_symbols_symlink_fspec.Exists()) {
|
||||
m_sdk_directory_infos.push_back(sdk_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleWatch::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
|
||||
"directory %s",
|
||||
sdk_symbols_symlink_fspec.GetPath().c_str());
|
||||
}
|
||||
} else {
|
||||
sdk_symbols_symlink_fspec.GetFilename().SetCString("Symbols");
|
||||
if (sdk_symbols_symlink_fspec.Exists())
|
||||
m_sdk_directory_infos.push_back(sdk_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleWatch::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded added builtin SDK "
|
||||
"directory %s",
|
||||
sdk_symbols_symlink_fspec.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t num_installed = m_sdk_directory_infos.size();
|
||||
FileSpec local_sdk_cache(
|
||||
"~/Library/Developer/Xcode/watchOS DeviceSupport", true);
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
local_sdk_cache =
|
||||
FileSpec("~/Library/Developer/Xcode/watch OS DeviceSupport", true);
|
||||
}
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
local_sdk_cache =
|
||||
FileSpec("~/Library/Developer/Xcode/WatchOS DeviceSupport", true);
|
||||
}
|
||||
if (!local_sdk_cache.Exists()) {
|
||||
local_sdk_cache =
|
||||
FileSpec("~/Library/Developer/Xcode/Watch OS DeviceSupport", true);
|
||||
}
|
||||
if (local_sdk_cache.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleWatch::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded searching %s for "
|
||||
"additional SDKs",
|
||||
local_sdk_cache.GetPath().c_str());
|
||||
}
|
||||
char path[PATH_MAX];
|
||||
if (local_sdk_cache.GetPath(path, sizeof(path))) {
|
||||
FileSpec::EnumerateDirectory(
|
||||
path, find_directories, find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&m_sdk_directory_infos);
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
|
||||
m_sdk_directory_infos[i].user_cached = true;
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteAppleWatch::"
|
||||
"UpdateSDKDirectoryInfosIfNeeded user SDK directory "
|
||||
"%s",
|
||||
m_sdk_directory_infos[i].directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !m_sdk_directory_infos.empty();
|
||||
}
|
||||
|
||||
const PlatformRemoteAppleWatch::SDKDirectoryInfo *
|
||||
PlatformRemoteAppleWatch::GetSDKDirectoryForCurrentOSVersion() {
|
||||
uint32_t i;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// Check to see if the user specified a build string. If they did, then
|
||||
// be sure to match it.
|
||||
std::vector<bool> check_sdk_info(num_sdk_infos, true);
|
||||
ConstString build(m_sdk_build);
|
||||
if (build) {
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
|
||||
}
|
||||
|
||||
// If we are connected we can find the version of the OS the platform
|
||||
// us running on and select the right SDK
|
||||
uint32_t major, minor, update;
|
||||
if (GetOSVersion(major, minor, update)) {
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
// First try for an exact match of major, minor and update
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor &&
|
||||
m_sdk_directory_infos[i].version_update == update) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// First try for an exact match of major and minor
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Lastly try to match of major version only..
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (build) {
|
||||
// No version, just a build number, search for the first one that matches
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
if (check_sdk_info[i])
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const PlatformRemoteAppleWatch::SDKDirectoryInfo *
|
||||
PlatformRemoteAppleWatch::GetSDKDirectoryForLatestOSVersion() {
|
||||
const PlatformRemoteAppleWatch::SDKDirectoryInfo *result = nullptr;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (sdk_dir_info.version_major != UINT32_MAX) {
|
||||
if (result == nullptr ||
|
||||
sdk_dir_info.version_major > result->version_major) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_major == result->version_major) {
|
||||
if (sdk_dir_info.version_minor > result->version_minor) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_minor == result->version_minor) {
|
||||
if (sdk_dir_info.version_update > result->version_update) {
|
||||
result = &sdk_dir_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteAppleWatch::GetDeviceSupportDirectory() {
|
||||
if (m_device_support_directory.empty()) {
|
||||
const char *device_support_dir = GetDeveloperDirectory();
|
||||
if (device_support_dir) {
|
||||
m_device_support_directory.assign(device_support_dir);
|
||||
m_device_support_directory.append(
|
||||
"/Platforms/watchOS.platform/DeviceSupport");
|
||||
FileSpec platform_device_support_dir(m_device_support_directory, true);
|
||||
if (!platform_device_support_dir.Exists()) {
|
||||
std::string alt_platform_dirname = device_support_dir;
|
||||
alt_platform_dirname.append(
|
||||
"/Platforms/WatchOS.platform/DeviceSupport");
|
||||
FileSpec alt_platform_device_support_dir(m_device_support_directory,
|
||||
true);
|
||||
if (alt_platform_device_support_dir.Exists()) {
|
||||
m_device_support_directory = alt_platform_dirname;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into m_device_support_directory
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory.empty() == false);
|
||||
if (m_device_support_directory[0])
|
||||
return m_device_support_directory.c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteAppleWatch::GetDeviceSupportDirectoryForOSVersion() {
|
||||
if (m_sdk_sysroot)
|
||||
return m_sdk_sysroot.GetCString();
|
||||
|
||||
if (m_device_support_directory_for_os_version.empty()) {
|
||||
const PlatformRemoteAppleWatch::SDKDirectoryInfo *sdk_dir_info =
|
||||
GetSDKDirectoryForCurrentOSVersion();
|
||||
if (sdk_dir_info == nullptr)
|
||||
sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
|
||||
if (sdk_dir_info) {
|
||||
char path[PATH_MAX];
|
||||
if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
|
||||
m_device_support_directory_for_os_version = path;
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
}
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory_for_os_version.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into
|
||||
// m_device_support_directory_for_os_version
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory_for_os_version.empty() == false);
|
||||
if (m_device_support_directory_for_os_version[0])
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PlatformRemoteAppleWatch::FindFileInAllSDKs(const char *platform_file_path,
|
||||
FileSpecList &file_list) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (platform_file_path && platform_file_path[0] &&
|
||||
UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
lldb_private::FileSpec local_file;
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
|
||||
file_list.Append(local_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_list.GetSize();
|
||||
}
|
||||
|
||||
bool PlatformRemoteAppleWatch::GetFileInSDK(
|
||||
const char *platform_file_path, uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (sdk_idx < m_sdk_directory_infos.size()) {
|
||||
std::string sdkroot_path =
|
||||
m_sdk_directory_infos[sdk_idx].directory.GetPath();
|
||||
if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
|
||||
// We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
|
||||
// the
|
||||
// SDK root directory and the file path.
|
||||
|
||||
const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
|
||||
for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
|
||||
local_file.SetFile(sdkroot_path, false);
|
||||
if (paths_to_try[i][0] != '\0')
|
||||
local_file.AppendPathComponent(paths_to_try[i]);
|
||||
local_file.AppendPathComponent(platform_file_path);
|
||||
local_file.ResolvePath();
|
||||
if (local_file.Exists()) {
|
||||
if (log)
|
||||
log->Printf("Found a copy of %s in the SDK dir %s/%s",
|
||||
platform_file_path, sdkroot_path.c_str(),
|
||||
paths_to_try[i]);
|
||||
return true;
|
||||
}
|
||||
local_file.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Error PlatformRemoteAppleWatch::GetSymbolFile(const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
char resolved_path[PATH_MAX];
|
||||
|
||||
const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (os_version_dir) {
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
|
||||
platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf(
|
||||
"Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
local_file = platform_file;
|
||||
if (local_file.Exists())
|
||||
return error;
|
||||
|
||||
error.SetErrorStringWithFormat(
|
||||
"unable to locate a platform file for '%s' in platform '%s'",
|
||||
platform_file_path, GetPluginName().GetCString());
|
||||
} else {
|
||||
error.SetErrorString("invalid platform file argument");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Error PlatformRemoteAppleWatch::GetSharedModule(
|
||||
const ModuleSpec &module_spec, lldb_private::Process *process,
|
||||
ModuleSP &module_sp, const FileSpecList *module_search_paths_ptr,
|
||||
ModuleSP *old_module_sp_ptr, bool *did_create_ptr) {
|
||||
// For Apple Watch, the SDK files are all cached locally on the host
|
||||
// system. So first we ask for the file in the cached SDK,
|
||||
// then we attempt to get a shared module for the right architecture
|
||||
// with the right UUID.
|
||||
const FileSpec &platform_file = module_spec.GetFileSpec();
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
ModuleSpec platform_module_spec(module_spec);
|
||||
|
||||
UpdateSDKDirectoryInfosIfNeeded();
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// If we are connected we migth be able to correctly deduce the SDK
|
||||
// directory
|
||||
// using the OS build.
|
||||
const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
|
||||
if (connected_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[connected_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, connected_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
|
||||
if (module_sp) {
|
||||
m_last_module_sdk_idx = connected_sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try the last SDK index if it is set as most files from an SDK
|
||||
// will tend to be valid in that same SDK.
|
||||
if (m_last_module_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[m_last_module_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
|
||||
if (module_sp) {
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
if (m_last_module_sdk_idx == sdk_idx) {
|
||||
// Skip the last module SDK index if we already searched
|
||||
// it above
|
||||
continue;
|
||||
}
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
// printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
|
||||
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, nullptr);
|
||||
if (module_sp) {
|
||||
// Remember the index of the last SDK that we found a file
|
||||
// in in case the wrong SDK was selected.
|
||||
m_last_module_sdk_idx = sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Not the module we are looking for... Nothing to see here...
|
||||
module_sp.reset();
|
||||
|
||||
// This may not be an SDK-related module. Try whether we can bring in the
|
||||
// thing to our local cache.
|
||||
error = GetSharedModuleWithLocalCache(module_spec, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success())
|
||||
return error;
|
||||
|
||||
// See if the file is present in any of the module_search_paths_ptr
|
||||
// directories.
|
||||
if (!module_sp && module_search_paths_ptr && platform_file) {
|
||||
// create a vector of all the file / directory names in platform_file
|
||||
// e.g. this might be
|
||||
// /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
//
|
||||
// We'll need to look in the module_search_paths_ptr directories for
|
||||
// both "UIFoundation" and "UIFoundation.framework" -- most likely the
|
||||
// latter will be the one we find there.
|
||||
|
||||
FileSpec platform_pull_apart(platform_file);
|
||||
std::vector<std::string> path_parts;
|
||||
ConstString unix_root_dir("/");
|
||||
while (true) {
|
||||
ConstString part = platform_pull_apart.GetLastPathComponent();
|
||||
platform_pull_apart.RemoveLastPathComponent();
|
||||
if (part.IsEmpty() || part == unix_root_dir)
|
||||
break;
|
||||
path_parts.push_back(part.AsCString());
|
||||
}
|
||||
const size_t path_parts_size = path_parts.size();
|
||||
|
||||
size_t num_module_search_paths = module_search_paths_ptr->GetSize();
|
||||
for (size_t i = 0; i < num_module_search_paths; ++i) {
|
||||
// Create a new FileSpec with this module_search_paths_ptr
|
||||
// plus just the filename ("UIFoundation"), then the parent
|
||||
// dir plus filename ("UIFoundation.framework/UIFoundation")
|
||||
// etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
|
||||
|
||||
for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
|
||||
FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
|
||||
|
||||
// Add the components backwards. For
|
||||
// .../PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
// path_parts is
|
||||
// [0] UIFoundation
|
||||
// [1] UIFoundation.framework
|
||||
// [2] PrivateFrameworks
|
||||
//
|
||||
// and if 'j' is 2, we want to append path_parts[1] and then
|
||||
// path_parts[0], aka
|
||||
// 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
|
||||
// path.
|
||||
|
||||
for (int k = j; k >= 0; --k) {
|
||||
path_to_try.AppendPathComponent(path_parts[k]);
|
||||
}
|
||||
|
||||
if (path_to_try.Exists()) {
|
||||
ModuleSpec new_module_spec(module_spec);
|
||||
new_module_spec.GetFileSpec() = path_to_try;
|
||||
Error new_error(Platform::GetSharedModule(
|
||||
new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
|
||||
did_create_ptr));
|
||||
|
||||
if (module_sp) {
|
||||
module_sp->SetPlatformFileSpec(path_to_try);
|
||||
return new_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool always_create = false;
|
||||
error = ModuleList::GetSharedModule(
|
||||
module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
|
||||
did_create_ptr, always_create);
|
||||
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
|
||||
return error;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
/// Default Constructor
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteAppleWatch::PlatformRemoteAppleWatch()
|
||||
: PlatformRemoteDarwinDevice() {}
|
||||
|
||||
bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
|
||||
ArchSpec &arch) {
|
||||
|
@ -923,23 +295,13 @@ bool PlatformRemoteAppleWatch::GetSupportedArchitectureAtIndex(uint32_t idx,
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteAppleWatch::GetConnectedSDKIndex() {
|
||||
if (IsConnected()) {
|
||||
if (m_connected_module_sdk_idx == UINT32_MAX) {
|
||||
std::string build;
|
||||
if (GetRemoteOSBuildString(build)) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
|
||||
build.c_str())) {
|
||||
m_connected_module_sdk_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_connected_module_sdk_idx = UINT32_MAX;
|
||||
}
|
||||
return m_connected_module_sdk_idx;
|
||||
void PlatformRemoteAppleWatch::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
|
||||
{
|
||||
dirnames.clear();
|
||||
dirnames.push_back("watchOS DeviceSupport");
|
||||
}
|
||||
|
||||
std::string PlatformRemoteAppleWatch::GetPlatformName ()
|
||||
{
|
||||
return "WatchOS.platform";
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
// Project includes
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
|
||||
#include "PlatformDarwin.h"
|
||||
#include "PlatformRemoteDarwinDevice.h"
|
||||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
||||
class PlatformRemoteAppleWatch : public PlatformDarwin {
|
||||
class PlatformRemoteAppleWatch : public PlatformRemoteDarwinDevice {
|
||||
public:
|
||||
PlatformRemoteAppleWatch();
|
||||
|
||||
|
@ -44,9 +44,11 @@ public:
|
|||
static const char *GetDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Methods
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
|
||||
const char *GetDescription() override { return GetDescriptionStatic(); }
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
|
@ -59,80 +61,19 @@ public:
|
|||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
lldb_private::Error ResolveExecutable(
|
||||
const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr) override;
|
||||
|
||||
const char *GetDescription() override { return GetDescriptionStatic(); }
|
||||
|
||||
void GetStatus(lldb_private::Stream &strm) override;
|
||||
|
||||
virtual lldb_private::Error
|
||||
GetSymbolFile(const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
lldb_private::Error
|
||||
GetSharedModule(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb_private::Process *process, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) override;
|
||||
|
||||
bool GetSupportedArchitectureAtIndex(uint32_t idx,
|
||||
lldb_private::ArchSpec &arch) override;
|
||||
|
||||
void
|
||||
AddClangModuleCompilationOptions(lldb_private::Target *target,
|
||||
std::vector<std::string> &options) override {
|
||||
return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
|
||||
target, options, PlatformDarwin::SDKType::iPhoneOS);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct SDKDirectoryInfo {
|
||||
SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
|
||||
lldb_private::FileSpec directory;
|
||||
lldb_private::ConstString build;
|
||||
uint32_t version_major;
|
||||
uint32_t version_minor;
|
||||
uint32_t version_update;
|
||||
bool user_cached;
|
||||
};
|
||||
typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
|
||||
std::mutex m_sdk_dir_mutex;
|
||||
SDKDirectoryInfoCollection m_sdk_directory_infos;
|
||||
std::string m_device_support_directory;
|
||||
std::string m_device_support_directory_for_os_version;
|
||||
std::string m_build_update;
|
||||
uint32_t m_last_module_sdk_idx;
|
||||
uint32_t m_connected_module_sdk_idx;
|
||||
|
||||
bool UpdateSDKDirectoryInfosIfNeeded();
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PlatformRemoteDarwinDevice functions
|
||||
//------------------------------------------------------------
|
||||
|
||||
const char *GetDeviceSupportDirectory();
|
||||
void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
|
||||
|
||||
const char *GetDeviceSupportDirectoryForOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
|
||||
|
||||
static lldb_private::FileSpec::EnumerateDirectoryResult
|
||||
GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft,
|
||||
const lldb_private::FileSpec &file_spec);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const char *platform_file_path,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
uint32_t GetConnectedSDKIndex();
|
||||
std::string GetPlatformName () override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteAppleWatch);
|
||||
|
|
|
@ -0,0 +1,712 @@
|
|||
//===-- PlatformRemoteDarwinDevice.cpp -----------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PlatformRemoteDarwinDevice.h"
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Breakpoint/BreakpointLocation.h"
|
||||
#include "lldb/Core/ArchSpec.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/Target/Process.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Utility/Error.h"
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/StreamString.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
PlatformRemoteDarwinDevice::SDKDirectoryInfo::SDKDirectoryInfo(
|
||||
const lldb_private::FileSpec &sdk_dir)
|
||||
: directory(sdk_dir), build(), version_major(0), version_minor(0),
|
||||
version_update(0), user_cached(false) {
|
||||
llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
|
||||
llvm::StringRef build_str;
|
||||
std::tie(version_major, version_minor, version_update, build_str) =
|
||||
ParseVersionBuildDir(dirname_str);
|
||||
build.SetString(build_str);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Default Constructor
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteDarwinDevice::PlatformRemoteDarwinDevice()
|
||||
: PlatformDarwin(false), // This is a remote platform
|
||||
m_sdk_directory_infos(), m_device_support_directory(),
|
||||
m_device_support_directory_for_os_version(), m_build_update(),
|
||||
m_last_module_sdk_idx(UINT32_MAX),
|
||||
m_connected_module_sdk_idx(UINT32_MAX) {}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
///
|
||||
/// The destructor is virtual since this class is designed to be
|
||||
/// inherited from by the plug-in instance.
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteDarwinDevice::~PlatformRemoteDarwinDevice() {}
|
||||
|
||||
void PlatformRemoteDarwinDevice::GetStatus(Stream &strm) {
|
||||
Platform::GetStatus(strm);
|
||||
const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (sdk_directory)
|
||||
strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
|
||||
else
|
||||
strm.PutCString(" SDK Path: error: unable to locate SDK\n");
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
|
||||
sdk_dir_info.directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Error PlatformRemoteDarwinDevice::ResolveExecutable(
|
||||
const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
|
||||
const FileSpecList *module_search_paths_ptr) {
|
||||
Error error;
|
||||
// Nothing special to do here, just use the actual file and architecture
|
||||
|
||||
ModuleSpec resolved_module_spec(ms);
|
||||
|
||||
// Resolve any executable within a bundle on MacOSX
|
||||
// TODO: verify that this handles shallow bundles, if not then implement one
|
||||
// ourselves
|
||||
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
|
||||
|
||||
if (resolved_module_spec.GetFileSpec().Exists()) {
|
||||
if (resolved_module_spec.GetArchitecture().IsValid() ||
|
||||
resolved_module_spec.GetUUID().IsValid()) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
return error;
|
||||
exe_module_sp.reset();
|
||||
}
|
||||
// No valid architecture was specified or the exact ARM slice wasn't
|
||||
// found so ask the platform for the architectures that we should be
|
||||
// using (in the correct order) and see if we can find a match that way
|
||||
StreamString arch_names;
|
||||
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
|
||||
idx, resolved_module_spec.GetArchitecture());
|
||||
++idx) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
NULL, NULL, NULL);
|
||||
// Did we find an executable using one of the
|
||||
if (error.Success()) {
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
break;
|
||||
else
|
||||
error.SetErrorToGenericError();
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
arch_names.PutCString(", ");
|
||||
arch_names.PutCString(
|
||||
resolved_module_spec.GetArchitecture().GetArchitectureName());
|
||||
}
|
||||
|
||||
if (error.Fail() || !exe_module_sp) {
|
||||
if (resolved_module_spec.GetFileSpec().Readable()) {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' doesn't contain any '%s' platform architectures: %s",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str(),
|
||||
GetPluginName().GetCString(), arch_names.GetData());
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' is not readable",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' does not exist",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FileSpec::EnumerateDirectoryResult
|
||||
PlatformRemoteDarwinDevice::GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
|
||||
((PlatformRemoteDarwinDevice::SDKDirectoryInfoCollection *)baton)
|
||||
->push_back(PlatformRemoteDarwinDevice::SDKDirectoryInfo(file_spec));
|
||||
return FileSpec::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
|
||||
bool PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded() {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
|
||||
if (m_sdk_directory_infos.empty()) {
|
||||
// A --sysroot option was supplied - add it to our list of SDKs to check
|
||||
if (m_sdk_sysroot) {
|
||||
FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
|
||||
const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
|
||||
m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded added "
|
||||
"--sysroot SDK directory %s",
|
||||
m_sdk_sysroot.GetCString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const char *device_support_dir = GetDeviceSupportDirectory();
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded Got "
|
||||
"DeviceSupport directory %s",
|
||||
device_support_dir);
|
||||
}
|
||||
if (device_support_dir) {
|
||||
const bool find_directories = true;
|
||||
const bool find_files = false;
|
||||
const bool find_other = false;
|
||||
|
||||
SDKDirectoryInfoCollection builtin_sdk_directory_infos;
|
||||
FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
|
||||
find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&builtin_sdk_directory_infos);
|
||||
|
||||
// Only add SDK directories that have symbols in them, some SDKs only
|
||||
// contain
|
||||
// developer disk images and no symbols, so they aren't useful to us.
|
||||
FileSpec sdk_symbols_symlink_fspec;
|
||||
for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
|
||||
sdk_symbols_symlink_fspec = sdk_directory_info.directory;
|
||||
sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
|
||||
if (sdk_symbols_symlink_fspec.Exists()) {
|
||||
m_sdk_directory_infos.push_back(sdk_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"added builtin SDK directory %s",
|
||||
sdk_symbols_symlink_fspec.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> device_support_dirnames;
|
||||
GetDeviceSupportDirectoryNames (device_support_dirnames);
|
||||
|
||||
for (std::string &dirname : device_support_dirnames)
|
||||
{
|
||||
const uint32_t num_installed = m_sdk_directory_infos.size();
|
||||
std::string local_sdk_cache_str = "~/Library/Developer/Xcode/";
|
||||
local_sdk_cache_str += dirname;
|
||||
FileSpec local_sdk_cache(local_sdk_cache_str.c_str(), true);
|
||||
if (local_sdk_cache.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"searching %s for additional SDKs",
|
||||
local_sdk_cache.GetPath().c_str());
|
||||
}
|
||||
char path[PATH_MAX];
|
||||
if (local_sdk_cache.GetPath(path, sizeof(path))) {
|
||||
FileSpec::EnumerateDirectory(
|
||||
path, find_directories, find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&m_sdk_directory_infos);
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
|
||||
m_sdk_directory_infos[i].user_cached = true;
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteDarwinDevice::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"user SDK directory %s",
|
||||
m_sdk_directory_infos[i].directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !m_sdk_directory_infos.empty();
|
||||
}
|
||||
|
||||
const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
|
||||
PlatformRemoteDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
|
||||
uint32_t i;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// Check to see if the user specified a build string. If they did, then
|
||||
// be sure to match it.
|
||||
std::vector<bool> check_sdk_info(num_sdk_infos, true);
|
||||
ConstString build(m_sdk_build);
|
||||
if (build) {
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
|
||||
}
|
||||
|
||||
// If we are connected we can find the version of the OS the platform
|
||||
// us running on and select the right SDK
|
||||
uint32_t major, minor, update;
|
||||
if (GetOSVersion(major, minor, update)) {
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
// First try for an exact match of major, minor and update
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor &&
|
||||
m_sdk_directory_infos[i].version_update == update) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// First try for an exact match of major and minor
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Lastly try to match of major version only..
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (build) {
|
||||
// No version, just a build number, search for the first one that matches
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
if (check_sdk_info[i])
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const PlatformRemoteDarwinDevice::SDKDirectoryInfo *
|
||||
PlatformRemoteDarwinDevice::GetSDKDirectoryForLatestOSVersion() {
|
||||
const PlatformRemoteDarwinDevice::SDKDirectoryInfo *result = NULL;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (sdk_dir_info.version_major != UINT32_MAX) {
|
||||
if (result == NULL ||
|
||||
sdk_dir_info.version_major > result->version_major) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_major == result->version_major) {
|
||||
if (sdk_dir_info.version_minor > result->version_minor) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_minor == result->version_minor) {
|
||||
if (sdk_dir_info.version_update > result->version_update) {
|
||||
result = &sdk_dir_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectory() {
|
||||
std::string platform_dir = "/Platforms/" + GetPlatformName() + "/DeviceSupport";
|
||||
if (m_device_support_directory.empty()) {
|
||||
const char *device_support_dir = GetDeveloperDirectory();
|
||||
if (device_support_dir) {
|
||||
m_device_support_directory.assign(device_support_dir);
|
||||
m_device_support_directory.append(platform_dir.c_str());
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into m_device_support_directory
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory.empty() == false);
|
||||
if (m_device_support_directory[0])
|
||||
return m_device_support_directory.c_str();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteDarwinDevice::GetDeviceSupportDirectoryForOSVersion() {
|
||||
if (m_sdk_sysroot)
|
||||
return m_sdk_sysroot.GetCString();
|
||||
|
||||
if (m_device_support_directory_for_os_version.empty()) {
|
||||
const PlatformRemoteDarwinDevice::SDKDirectoryInfo *sdk_dir_info =
|
||||
GetSDKDirectoryForCurrentOSVersion();
|
||||
if (sdk_dir_info == NULL)
|
||||
sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
|
||||
if (sdk_dir_info) {
|
||||
char path[PATH_MAX];
|
||||
if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
|
||||
m_device_support_directory_for_os_version = path;
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
}
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory_for_os_version.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into
|
||||
// m_device_support_directory_for_os_version
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory_for_os_version.empty() == false);
|
||||
if (m_device_support_directory_for_os_version[0])
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteDarwinDevice::FindFileInAllSDKs(const char *platform_file_path,
|
||||
FileSpecList &file_list) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (platform_file_path && platform_file_path[0] &&
|
||||
UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
lldb_private::FileSpec local_file;
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
|
||||
file_list.Append(local_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_list.GetSize();
|
||||
}
|
||||
|
||||
bool PlatformRemoteDarwinDevice::GetFileInSDK(const char *platform_file_path,
|
||||
uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (sdk_idx < m_sdk_directory_infos.size()) {
|
||||
std::string sdkroot_path =
|
||||
m_sdk_directory_infos[sdk_idx].directory.GetPath();
|
||||
local_file.Clear();
|
||||
|
||||
if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
|
||||
// We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
|
||||
// the
|
||||
// SDK root directory and the file path.
|
||||
|
||||
const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
|
||||
for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
|
||||
local_file.SetFile(sdkroot_path, false);
|
||||
if (paths_to_try[i][0] != '\0')
|
||||
local_file.AppendPathComponent(paths_to_try[i]);
|
||||
local_file.AppendPathComponent(platform_file_path);
|
||||
local_file.ResolvePath();
|
||||
if (local_file.Exists()) {
|
||||
if (log)
|
||||
log->Printf("Found a copy of %s in the SDK dir %s/%s",
|
||||
platform_file_path, sdkroot_path.c_str(),
|
||||
paths_to_try[i]);
|
||||
return true;
|
||||
}
|
||||
local_file.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Error PlatformRemoteDarwinDevice::GetSymbolFile(const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
char resolved_path[PATH_MAX];
|
||||
|
||||
const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (os_version_dir) {
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
|
||||
platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf(
|
||||
"Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
local_file = platform_file;
|
||||
if (local_file.Exists())
|
||||
return error;
|
||||
|
||||
error.SetErrorStringWithFormat(
|
||||
"unable to locate a platform file for '%s' in platform '%s'",
|
||||
platform_file_path, GetPluginName().GetCString());
|
||||
} else {
|
||||
error.SetErrorString("invalid platform file argument");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Error PlatformRemoteDarwinDevice::GetSharedModule(
|
||||
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
|
||||
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) {
|
||||
// For iOS, the SDK files are all cached locally on the host
|
||||
// system. So first we ask for the file in the cached SDK,
|
||||
// then we attempt to get a shared module for the right architecture
|
||||
// with the right UUID.
|
||||
const FileSpec &platform_file = module_spec.GetFileSpec();
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
ModuleSpec platform_module_spec(module_spec);
|
||||
|
||||
UpdateSDKDirectoryInfosIfNeeded();
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// If we are connected we migth be able to correctly deduce the SDK
|
||||
// directory
|
||||
// using the OS build.
|
||||
const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
|
||||
if (connected_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[connected_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, connected_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
m_last_module_sdk_idx = connected_sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try the last SDK index if it is set as most files from an SDK
|
||||
// will tend to be valid in that same SDK.
|
||||
if (m_last_module_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[m_last_module_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First try for an exact match of major, minor and update:
|
||||
// If a particalar SDK version was specified via --version or --build, look
|
||||
// for a match on disk.
|
||||
const SDKDirectoryInfo *current_sdk_info =
|
||||
GetSDKDirectoryForCurrentOSVersion();
|
||||
const uint32_t current_sdk_idx =
|
||||
GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
|
||||
if (current_sdk_idx < num_sdk_infos &&
|
||||
current_sdk_idx != m_last_module_sdk_idx) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[current_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, current_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
m_last_module_sdk_idx = current_sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second try all SDKs that were found.
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
if (m_last_module_sdk_idx == sdk_idx) {
|
||||
// Skip the last module SDK index if we already searched
|
||||
// it above
|
||||
continue;
|
||||
}
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
// printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
|
||||
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
// Remember the index of the last SDK that we found a file
|
||||
// in in case the wrong SDK was selected.
|
||||
m_last_module_sdk_idx = sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Not the module we are looking for... Nothing to see here...
|
||||
module_sp.reset();
|
||||
|
||||
// This may not be an SDK-related module. Try whether we can bring in the
|
||||
// thing to our local cache.
|
||||
error = GetSharedModuleWithLocalCache(module_spec, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success())
|
||||
return error;
|
||||
|
||||
// See if the file is present in any of the module_search_paths_ptr
|
||||
// directories.
|
||||
if (!module_sp && module_search_paths_ptr && platform_file) {
|
||||
// create a vector of all the file / directory names in platform_file
|
||||
// e.g. this might be
|
||||
// /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
//
|
||||
// We'll need to look in the module_search_paths_ptr directories for
|
||||
// both "UIFoundation" and "UIFoundation.framework" -- most likely the
|
||||
// latter will be the one we find there.
|
||||
|
||||
FileSpec platform_pull_apart(platform_file);
|
||||
std::vector<std::string> path_parts;
|
||||
ConstString unix_root_dir("/");
|
||||
while (true) {
|
||||
ConstString part = platform_pull_apart.GetLastPathComponent();
|
||||
platform_pull_apart.RemoveLastPathComponent();
|
||||
if (part.IsEmpty() || part == unix_root_dir)
|
||||
break;
|
||||
path_parts.push_back(part.AsCString());
|
||||
}
|
||||
const size_t path_parts_size = path_parts.size();
|
||||
|
||||
size_t num_module_search_paths = module_search_paths_ptr->GetSize();
|
||||
for (size_t i = 0; i < num_module_search_paths; ++i) {
|
||||
LLDB_LOGV(log, "searching for binary in search-path {0}",
|
||||
module_search_paths_ptr->GetFileSpecAtIndex(i));
|
||||
// Create a new FileSpec with this module_search_paths_ptr
|
||||
// plus just the filename ("UIFoundation"), then the parent
|
||||
// dir plus filename ("UIFoundation.framework/UIFoundation")
|
||||
// etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
|
||||
|
||||
for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
|
||||
FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
|
||||
|
||||
// Add the components backwards. For
|
||||
// .../PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
// path_parts is
|
||||
// [0] UIFoundation
|
||||
// [1] UIFoundation.framework
|
||||
// [2] PrivateFrameworks
|
||||
//
|
||||
// and if 'j' is 2, we want to append path_parts[1] and then
|
||||
// path_parts[0], aka
|
||||
// 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
|
||||
// path.
|
||||
|
||||
for (int k = j; k >= 0; --k) {
|
||||
path_to_try.AppendPathComponent(path_parts[k]);
|
||||
}
|
||||
|
||||
if (path_to_try.Exists()) {
|
||||
ModuleSpec new_module_spec(module_spec);
|
||||
new_module_spec.GetFileSpec() = path_to_try;
|
||||
Error new_error(Platform::GetSharedModule(
|
||||
new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
|
||||
did_create_ptr));
|
||||
|
||||
if (module_sp) {
|
||||
module_sp->SetPlatformFileSpec(path_to_try);
|
||||
return new_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool always_create = false;
|
||||
error = ModuleList::GetSharedModule(
|
||||
module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
|
||||
did_create_ptr, always_create);
|
||||
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteDarwinDevice::GetConnectedSDKIndex() {
|
||||
if (IsConnected()) {
|
||||
if (m_connected_module_sdk_idx == UINT32_MAX) {
|
||||
std::string build;
|
||||
if (GetRemoteOSBuildString(build)) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
|
||||
build.c_str())) {
|
||||
m_connected_module_sdk_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_connected_module_sdk_idx = UINT32_MAX;
|
||||
}
|
||||
return m_connected_module_sdk_idx;
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteDarwinDevice::GetSDKIndexBySDKDirectoryInfo(
|
||||
const SDKDirectoryInfo *sdk_info) {
|
||||
if (sdk_info == NULL) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
return sdk_info - &m_sdk_directory_infos[0];
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
//===-- PlatformRemoteDarwinDevice.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_PlatformRemoteDarwinDevice_h_
|
||||
#define liblldb_PlatformRemoteDarwinDevice_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <string>
|
||||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "PlatformDarwin.h"
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
||||
class PlatformRemoteDarwinDevice : public PlatformDarwin {
|
||||
public:
|
||||
PlatformRemoteDarwinDevice();
|
||||
|
||||
~PlatformRemoteDarwinDevice() override;
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
lldb_private::Error ResolveExecutable(
|
||||
const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr) override;
|
||||
|
||||
void GetStatus(lldb_private::Stream &strm) override;
|
||||
|
||||
virtual lldb_private::Error
|
||||
GetSymbolFile(const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
lldb_private::Error
|
||||
GetSharedModule(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb_private::Process *process, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) override;
|
||||
|
||||
void
|
||||
AddClangModuleCompilationOptions(lldb_private::Target *target,
|
||||
std::vector<std::string> &options) override {
|
||||
return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
|
||||
target, options, PlatformDarwin::SDKType::iPhoneOS);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct SDKDirectoryInfo {
|
||||
SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
|
||||
lldb_private::FileSpec directory;
|
||||
lldb_private::ConstString build;
|
||||
uint32_t version_major;
|
||||
uint32_t version_minor;
|
||||
uint32_t version_update;
|
||||
bool user_cached;
|
||||
};
|
||||
|
||||
typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
|
||||
|
||||
std::mutex m_sdk_dir_mutex;
|
||||
SDKDirectoryInfoCollection m_sdk_directory_infos;
|
||||
std::string m_device_support_directory;
|
||||
std::string m_device_support_directory_for_os_version;
|
||||
std::string m_build_update;
|
||||
uint32_t m_last_module_sdk_idx;
|
||||
uint32_t m_connected_module_sdk_idx;
|
||||
|
||||
bool UpdateSDKDirectoryInfosIfNeeded();
|
||||
|
||||
const char *GetDeviceSupportDirectory();
|
||||
|
||||
const char *GetDeviceSupportDirectoryForOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
|
||||
|
||||
static lldb_private::FileSpec::EnumerateDirectoryResult
|
||||
GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft,
|
||||
const lldb_private::FileSpec &file_spec);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const char *platform_file_path,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
uint32_t GetConnectedSDKIndex();
|
||||
|
||||
// Get index of SDK in SDKDirectoryInfoCollection by its pointer and return
|
||||
// UINT32_MAX if that SDK not found.
|
||||
uint32_t GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo *sdk_info);
|
||||
|
||||
|
||||
virtual void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) = 0;
|
||||
|
||||
virtual std::string GetPlatformName () = 0;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteDarwinDevice);
|
||||
};
|
||||
|
||||
#endif // liblldb_PlatformRemoteDarwinDevice_h_
|
|
@ -30,17 +30,6 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
PlatformRemoteiOS::SDKDirectoryInfo::SDKDirectoryInfo(
|
||||
const lldb_private::FileSpec &sdk_dir)
|
||||
: directory(sdk_dir), build(), version_major(0), version_minor(0),
|
||||
version_update(0), user_cached(false) {
|
||||
llvm::StringRef dirname_str = sdk_dir.GetFilename().GetStringRef();
|
||||
llvm::StringRef build_str;
|
||||
std::tie(version_major, version_minor, version_update, build_str) =
|
||||
ParseVersionBuildDir(dirname_str);
|
||||
build.SetString(build_str);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Static Variables
|
||||
//------------------------------------------------------------------
|
||||
|
@ -156,666 +145,21 @@ const char *PlatformRemoteiOS::GetDescriptionStatic() {
|
|||
/// Default Constructor
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteiOS::PlatformRemoteiOS()
|
||||
: PlatformDarwin(false), // This is a remote platform
|
||||
m_sdk_directory_infos(), m_device_support_directory(),
|
||||
m_device_support_directory_for_os_version(), m_build_update(),
|
||||
m_last_module_sdk_idx(UINT32_MAX),
|
||||
m_connected_module_sdk_idx(UINT32_MAX) {}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Destructor.
|
||||
///
|
||||
/// The destructor is virtual since this class is designed to be
|
||||
/// inherited from by the plug-in instance.
|
||||
//------------------------------------------------------------------
|
||||
PlatformRemoteiOS::~PlatformRemoteiOS() {}
|
||||
|
||||
void PlatformRemoteiOS::GetStatus(Stream &strm) {
|
||||
Platform::GetStatus(strm);
|
||||
const char *sdk_directory = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (sdk_directory)
|
||||
strm.Printf(" SDK Path: \"%s\"\n", sdk_directory);
|
||||
else
|
||||
strm.PutCString(" SDK Path: error: unable to locate SDK\n");
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
strm.Printf(" SDK Roots: [%2u] \"%s\"\n", i,
|
||||
sdk_dir_info.directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
Error PlatformRemoteiOS::ResolveExecutable(
|
||||
const ModuleSpec &ms, lldb::ModuleSP &exe_module_sp,
|
||||
const FileSpecList *module_search_paths_ptr) {
|
||||
Error error;
|
||||
// Nothing special to do here, just use the actual file and architecture
|
||||
|
||||
ModuleSpec resolved_module_spec(ms);
|
||||
|
||||
// Resolve any executable within a bundle on MacOSX
|
||||
// TODO: verify that this handles shallow bundles, if not then implement one
|
||||
// ourselves
|
||||
Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec());
|
||||
|
||||
if (resolved_module_spec.GetFileSpec().Exists()) {
|
||||
if (resolved_module_spec.GetArchitecture().IsValid() ||
|
||||
resolved_module_spec.GetUUID().IsValid()) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
return error;
|
||||
exe_module_sp.reset();
|
||||
}
|
||||
// No valid architecture was specified or the exact ARM slice wasn't
|
||||
// found so ask the platform for the architectures that we should be
|
||||
// using (in the correct order) and see if we can find a match that way
|
||||
StreamString arch_names;
|
||||
for (uint32_t idx = 0; GetSupportedArchitectureAtIndex(
|
||||
idx, resolved_module_spec.GetArchitecture());
|
||||
++idx) {
|
||||
error = ModuleList::GetSharedModule(resolved_module_spec, exe_module_sp,
|
||||
NULL, NULL, NULL);
|
||||
// Did we find an executable using one of the
|
||||
if (error.Success()) {
|
||||
if (exe_module_sp && exe_module_sp->GetObjectFile())
|
||||
break;
|
||||
else
|
||||
error.SetErrorToGenericError();
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
arch_names.PutCString(", ");
|
||||
arch_names.PutCString(
|
||||
resolved_module_spec.GetArchitecture().GetArchitectureName());
|
||||
}
|
||||
|
||||
if (error.Fail() || !exe_module_sp) {
|
||||
if (resolved_module_spec.GetFileSpec().Readable()) {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' doesn't contain any '%s' platform architectures: %s",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str(),
|
||||
GetPluginName().GetCString(), arch_names.GetData());
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' is not readable",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error.SetErrorStringWithFormat(
|
||||
"'%s' does not exist",
|
||||
resolved_module_spec.GetFileSpec().GetPath().c_str());
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
FileSpec::EnumerateDirectoryResult
|
||||
PlatformRemoteiOS::GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft, const FileSpec &file_spec) {
|
||||
((PlatformRemoteiOS::SDKDirectoryInfoCollection *)baton)
|
||||
->push_back(PlatformRemoteiOS::SDKDirectoryInfo(file_spec));
|
||||
return FileSpec::eEnumerateDirectoryResultNext;
|
||||
}
|
||||
|
||||
bool PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded() {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
std::lock_guard<std::mutex> guard(m_sdk_dir_mutex);
|
||||
if (m_sdk_directory_infos.empty()) {
|
||||
// A --sysroot option was supplied - add it to our list of SDKs to check
|
||||
if (m_sdk_sysroot) {
|
||||
FileSpec sdk_sysroot_fspec(m_sdk_sysroot.GetCString(), true);
|
||||
const SDKDirectoryInfo sdk_sysroot_directory_info(sdk_sysroot_fspec);
|
||||
m_sdk_directory_infos.push_back(sdk_sysroot_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded added "
|
||||
"--sysroot SDK directory %s",
|
||||
m_sdk_sysroot.GetCString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const char *device_support_dir = GetDeviceSupportDirectory();
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded Got "
|
||||
"DeviceSupport directory %s",
|
||||
device_support_dir);
|
||||
}
|
||||
if (device_support_dir) {
|
||||
const bool find_directories = true;
|
||||
const bool find_files = false;
|
||||
const bool find_other = false;
|
||||
|
||||
SDKDirectoryInfoCollection builtin_sdk_directory_infos;
|
||||
FileSpec::EnumerateDirectory(m_device_support_directory, find_directories,
|
||||
find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&builtin_sdk_directory_infos);
|
||||
|
||||
// Only add SDK directories that have symbols in them, some SDKs only
|
||||
// contain
|
||||
// developer disk images and no symbols, so they aren't useful to us.
|
||||
FileSpec sdk_symbols_symlink_fspec;
|
||||
for (const auto &sdk_directory_info : builtin_sdk_directory_infos) {
|
||||
sdk_symbols_symlink_fspec = sdk_directory_info.directory;
|
||||
sdk_symbols_symlink_fspec.AppendPathComponent("Symbols");
|
||||
if (sdk_symbols_symlink_fspec.Exists()) {
|
||||
m_sdk_directory_infos.push_back(sdk_directory_info);
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"added builtin SDK directory %s",
|
||||
sdk_symbols_symlink_fspec.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t num_installed = m_sdk_directory_infos.size();
|
||||
FileSpec local_sdk_cache("~/Library/Developer/Xcode/iOS DeviceSupport",
|
||||
true);
|
||||
if (local_sdk_cache.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"searching %s for additional SDKs",
|
||||
local_sdk_cache.GetPath().c_str());
|
||||
}
|
||||
char path[PATH_MAX];
|
||||
if (local_sdk_cache.GetPath(path, sizeof(path))) {
|
||||
FileSpec::EnumerateDirectory(
|
||||
path, find_directories, find_files, find_other,
|
||||
GetContainedFilesIntoVectorOfStringsCallback,
|
||||
&m_sdk_directory_infos);
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = num_installed; i < num_sdk_infos; ++i) {
|
||||
m_sdk_directory_infos[i].user_cached = true;
|
||||
if (log) {
|
||||
log->Printf("PlatformRemoteiOS::UpdateSDKDirectoryInfosIfNeeded "
|
||||
"user SDK directory %s",
|
||||
m_sdk_directory_infos[i].directory.GetPath().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !m_sdk_directory_infos.empty();
|
||||
}
|
||||
|
||||
const PlatformRemoteiOS::SDKDirectoryInfo *
|
||||
PlatformRemoteiOS::GetSDKDirectoryForCurrentOSVersion() {
|
||||
uint32_t i;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// Check to see if the user specified a build string. If they did, then
|
||||
// be sure to match it.
|
||||
std::vector<bool> check_sdk_info(num_sdk_infos, true);
|
||||
ConstString build(m_sdk_build);
|
||||
if (build) {
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
|
||||
}
|
||||
|
||||
// If we are connected we can find the version of the OS the platform
|
||||
// us running on and select the right SDK
|
||||
uint32_t major, minor, update;
|
||||
if (GetOSVersion(major, minor, update)) {
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
// First try for an exact match of major, minor and update
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor &&
|
||||
m_sdk_directory_infos[i].version_update == update) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// First try for an exact match of major and minor
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major &&
|
||||
m_sdk_directory_infos[i].version_minor == minor) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Lastly try to match of major version only..
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version_major == major) {
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (build) {
|
||||
// No version, just a build number, search for the first one that matches
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
if (check_sdk_info[i])
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const PlatformRemoteiOS::SDKDirectoryInfo *
|
||||
PlatformRemoteiOS::GetSDKDirectoryForLatestOSVersion() {
|
||||
const PlatformRemoteiOS::SDKDirectoryInfo *result = NULL;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (sdk_dir_info.version_major != UINT32_MAX) {
|
||||
if (result == NULL ||
|
||||
sdk_dir_info.version_major > result->version_major) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_major == result->version_major) {
|
||||
if (sdk_dir_info.version_minor > result->version_minor) {
|
||||
result = &sdk_dir_info;
|
||||
} else if (sdk_dir_info.version_minor == result->version_minor) {
|
||||
if (sdk_dir_info.version_update > result->version_update) {
|
||||
result = &sdk_dir_info;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteiOS::GetDeviceSupportDirectory() {
|
||||
if (m_device_support_directory.empty()) {
|
||||
const char *device_support_dir = GetDeveloperDirectory();
|
||||
if (device_support_dir) {
|
||||
m_device_support_directory.assign(device_support_dir);
|
||||
m_device_support_directory.append(
|
||||
"/Platforms/iPhoneOS.platform/DeviceSupport");
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into m_device_support_directory
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory.empty() == false);
|
||||
if (m_device_support_directory[0])
|
||||
return m_device_support_directory.c_str();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *PlatformRemoteiOS::GetDeviceSupportDirectoryForOSVersion() {
|
||||
if (m_sdk_sysroot)
|
||||
return m_sdk_sysroot.GetCString();
|
||||
|
||||
if (m_device_support_directory_for_os_version.empty()) {
|
||||
const PlatformRemoteiOS::SDKDirectoryInfo *sdk_dir_info =
|
||||
GetSDKDirectoryForCurrentOSVersion();
|
||||
if (sdk_dir_info == NULL)
|
||||
sdk_dir_info = GetSDKDirectoryForLatestOSVersion();
|
||||
if (sdk_dir_info) {
|
||||
char path[PATH_MAX];
|
||||
if (sdk_dir_info->directory.GetPath(path, sizeof(path))) {
|
||||
m_device_support_directory_for_os_version = path;
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
}
|
||||
} else {
|
||||
// Assign a single NULL character so we know we tried to find the device
|
||||
// support directory and we don't keep trying to find it over and over.
|
||||
m_device_support_directory_for_os_version.assign(1, '\0');
|
||||
}
|
||||
}
|
||||
// We should have put a single NULL character into
|
||||
// m_device_support_directory_for_os_version
|
||||
// or it should have a valid path if the code gets here
|
||||
assert(m_device_support_directory_for_os_version.empty() == false);
|
||||
if (m_device_support_directory_for_os_version[0])
|
||||
return m_device_support_directory_for_os_version.c_str();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteiOS::FindFileInAllSDKs(const char *platform_file_path,
|
||||
FileSpecList &file_list) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (platform_file_path && platform_file_path[0] &&
|
||||
UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
lldb_private::FileSpec local_file;
|
||||
// First try for an exact match of major, minor and update
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file_path,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx, local_file)) {
|
||||
file_list.Append(local_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_list.GetSize();
|
||||
}
|
||||
|
||||
bool PlatformRemoteiOS::GetFileInSDK(const char *platform_file_path,
|
||||
uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
if (sdk_idx < m_sdk_directory_infos.size()) {
|
||||
std::string sdkroot_path =
|
||||
m_sdk_directory_infos[sdk_idx].directory.GetPath();
|
||||
local_file.Clear();
|
||||
|
||||
if (!sdkroot_path.empty() && platform_file_path && platform_file_path[0]) {
|
||||
// We may need to interpose "/Symbols/" or "/Symbols.Internal/" between
|
||||
// the
|
||||
// SDK root directory and the file path.
|
||||
|
||||
const char *paths_to_try[] = {"Symbols", "", "Symbols.Internal", nullptr};
|
||||
for (size_t i = 0; paths_to_try[i] != nullptr; i++) {
|
||||
local_file.SetFile(sdkroot_path, false);
|
||||
if (paths_to_try[i][0] != '\0')
|
||||
local_file.AppendPathComponent(paths_to_try[i]);
|
||||
local_file.AppendPathComponent(platform_file_path);
|
||||
local_file.ResolvePath();
|
||||
if (local_file.Exists()) {
|
||||
if (log)
|
||||
log->Printf("Found a copy of %s in the SDK dir %s/%s",
|
||||
platform_file_path, sdkroot_path.c_str(),
|
||||
paths_to_try[i]);
|
||||
return true;
|
||||
}
|
||||
local_file.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Error PlatformRemoteiOS::GetSymbolFile(const FileSpec &platform_file,
|
||||
const UUID *uuid_ptr,
|
||||
FileSpec &local_file) {
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
char resolved_path[PATH_MAX];
|
||||
|
||||
const char *os_version_dir = GetDeviceSupportDirectoryForOSVersion();
|
||||
if (os_version_dir) {
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/%s", os_version_dir,
|
||||
platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols.Internal/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf(
|
||||
"Found a copy of %s in the DeviceSupport dir %s/Symbols.Internal",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
::snprintf(resolved_path, sizeof(resolved_path), "%s/Symbols/%s",
|
||||
os_version_dir, platform_file_path);
|
||||
|
||||
local_file.SetFile(resolved_path, true);
|
||||
if (local_file.Exists()) {
|
||||
if (log) {
|
||||
log->Printf("Found a copy of %s in the DeviceSupport dir %s/Symbols",
|
||||
platform_file_path, os_version_dir);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
}
|
||||
local_file = platform_file;
|
||||
if (local_file.Exists())
|
||||
return error;
|
||||
|
||||
error.SetErrorStringWithFormat(
|
||||
"unable to locate a platform file for '%s' in platform '%s'",
|
||||
platform_file_path, GetPluginName().GetCString());
|
||||
} else {
|
||||
error.SetErrorString("invalid platform file argument");
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
Error PlatformRemoteiOS::GetSharedModule(
|
||||
const ModuleSpec &module_spec, Process *process, ModuleSP &module_sp,
|
||||
const FileSpecList *module_search_paths_ptr, ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) {
|
||||
// For iOS, the SDK files are all cached locally on the host
|
||||
// system. So first we ask for the file in the cached SDK,
|
||||
// then we attempt to get a shared module for the right architecture
|
||||
// with the right UUID.
|
||||
const FileSpec &platform_file = module_spec.GetFileSpec();
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
|
||||
|
||||
Error error;
|
||||
char platform_file_path[PATH_MAX];
|
||||
|
||||
if (platform_file.GetPath(platform_file_path, sizeof(platform_file_path))) {
|
||||
ModuleSpec platform_module_spec(module_spec);
|
||||
|
||||
UpdateSDKDirectoryInfosIfNeeded();
|
||||
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// If we are connected we migth be able to correctly deduce the SDK
|
||||
// directory
|
||||
// using the OS build.
|
||||
const uint32_t connected_sdk_idx = GetConnectedSDKIndex();
|
||||
if (connected_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[connected_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, connected_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
m_last_module_sdk_idx = connected_sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try the last SDK index if it is set as most files from an SDK
|
||||
// will tend to be valid in that same SDK.
|
||||
if (m_last_module_sdk_idx < num_sdk_infos) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[m_last_module_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, m_last_module_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First try for an exact match of major, minor and update:
|
||||
// If a particalar SDK version was specified via --version or --build, look
|
||||
// for a match on disk.
|
||||
const SDKDirectoryInfo *current_sdk_info =
|
||||
GetSDKDirectoryForCurrentOSVersion();
|
||||
const uint32_t current_sdk_idx =
|
||||
GetSDKIndexBySDKDirectoryInfo(current_sdk_info);
|
||||
if (current_sdk_idx < num_sdk_infos &&
|
||||
current_sdk_idx != m_last_module_sdk_idx) {
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[current_sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, current_sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
module_sp.reset();
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
m_last_module_sdk_idx = current_sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Second try all SDKs that were found.
|
||||
for (uint32_t sdk_idx = 0; sdk_idx < num_sdk_infos; ++sdk_idx) {
|
||||
if (m_last_module_sdk_idx == sdk_idx) {
|
||||
// Skip the last module SDK index if we already searched
|
||||
// it above
|
||||
continue;
|
||||
}
|
||||
LLDB_LOGV(log, "Searching for {0} in sdk path {1}", platform_file,
|
||||
m_sdk_directory_infos[sdk_idx].directory);
|
||||
if (GetFileInSDK(platform_file_path, sdk_idx,
|
||||
platform_module_spec.GetFileSpec())) {
|
||||
// printf ("sdk[%u]: '%s'\n", sdk_idx, local_file.GetPath().c_str());
|
||||
|
||||
error = ResolveExecutable(platform_module_spec, module_sp, NULL);
|
||||
if (module_sp) {
|
||||
// Remember the index of the last SDK that we found a file
|
||||
// in in case the wrong SDK was selected.
|
||||
m_last_module_sdk_idx = sdk_idx;
|
||||
error.Clear();
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Not the module we are looking for... Nothing to see here...
|
||||
module_sp.reset();
|
||||
|
||||
// This may not be an SDK-related module. Try whether we can bring in the
|
||||
// thing to our local cache.
|
||||
error = GetSharedModuleWithLocalCache(module_spec, module_sp,
|
||||
module_search_paths_ptr,
|
||||
old_module_sp_ptr, did_create_ptr);
|
||||
if (error.Success())
|
||||
return error;
|
||||
|
||||
// See if the file is present in any of the module_search_paths_ptr
|
||||
// directories.
|
||||
if (!module_sp && module_search_paths_ptr && platform_file) {
|
||||
// create a vector of all the file / directory names in platform_file
|
||||
// e.g. this might be
|
||||
// /System/Library/PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
//
|
||||
// We'll need to look in the module_search_paths_ptr directories for
|
||||
// both "UIFoundation" and "UIFoundation.framework" -- most likely the
|
||||
// latter will be the one we find there.
|
||||
|
||||
FileSpec platform_pull_apart(platform_file);
|
||||
std::vector<std::string> path_parts;
|
||||
ConstString unix_root_dir("/");
|
||||
while (true) {
|
||||
ConstString part = platform_pull_apart.GetLastPathComponent();
|
||||
platform_pull_apart.RemoveLastPathComponent();
|
||||
if (part.IsEmpty() || part == unix_root_dir)
|
||||
break;
|
||||
path_parts.push_back(part.AsCString());
|
||||
}
|
||||
const size_t path_parts_size = path_parts.size();
|
||||
|
||||
size_t num_module_search_paths = module_search_paths_ptr->GetSize();
|
||||
for (size_t i = 0; i < num_module_search_paths; ++i) {
|
||||
LLDB_LOGV(log, "searching for binary in search-path {0}",
|
||||
module_search_paths_ptr->GetFileSpecAtIndex(i));
|
||||
// Create a new FileSpec with this module_search_paths_ptr
|
||||
// plus just the filename ("UIFoundation"), then the parent
|
||||
// dir plus filename ("UIFoundation.framework/UIFoundation")
|
||||
// etc - up to four names (to handle "Foo.framework/Contents/MacOS/Foo")
|
||||
|
||||
for (size_t j = 0; j < 4 && j < path_parts_size - 1; ++j) {
|
||||
FileSpec path_to_try(module_search_paths_ptr->GetFileSpecAtIndex(i));
|
||||
|
||||
// Add the components backwards. For
|
||||
// .../PrivateFrameworks/UIFoundation.framework/UIFoundation
|
||||
// path_parts is
|
||||
// [0] UIFoundation
|
||||
// [1] UIFoundation.framework
|
||||
// [2] PrivateFrameworks
|
||||
//
|
||||
// and if 'j' is 2, we want to append path_parts[1] and then
|
||||
// path_parts[0], aka
|
||||
// 'UIFoundation.framework/UIFoundation', to the module_search_paths_ptr
|
||||
// path.
|
||||
|
||||
for (int k = j; k >= 0; --k) {
|
||||
path_to_try.AppendPathComponent(path_parts[k]);
|
||||
}
|
||||
|
||||
if (path_to_try.Exists()) {
|
||||
ModuleSpec new_module_spec(module_spec);
|
||||
new_module_spec.GetFileSpec() = path_to_try;
|
||||
Error new_error(Platform::GetSharedModule(
|
||||
new_module_spec, process, module_sp, NULL, old_module_sp_ptr,
|
||||
did_create_ptr));
|
||||
|
||||
if (module_sp) {
|
||||
module_sp->SetPlatformFileSpec(path_to_try);
|
||||
return new_error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bool always_create = false;
|
||||
error = ModuleList::GetSharedModule(
|
||||
module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr,
|
||||
did_create_ptr, always_create);
|
||||
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
|
||||
return error;
|
||||
}
|
||||
: PlatformRemoteDarwinDevice() {}
|
||||
|
||||
bool PlatformRemoteiOS::GetSupportedArchitectureAtIndex(uint32_t idx,
|
||||
ArchSpec &arch) {
|
||||
return ARMGetSupportedArchitectureAtIndex(idx, arch);
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteiOS::GetConnectedSDKIndex() {
|
||||
if (IsConnected()) {
|
||||
if (m_connected_module_sdk_idx == UINT32_MAX) {
|
||||
std::string build;
|
||||
if (GetRemoteOSBuildString(build)) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
for (uint32_t i = 0; i < num_sdk_infos; ++i) {
|
||||
const SDKDirectoryInfo &sdk_dir_info = m_sdk_directory_infos[i];
|
||||
if (strstr(sdk_dir_info.directory.GetFilename().AsCString(""),
|
||||
build.c_str())) {
|
||||
m_connected_module_sdk_idx = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_connected_module_sdk_idx = UINT32_MAX;
|
||||
}
|
||||
return m_connected_module_sdk_idx;
|
||||
|
||||
void PlatformRemoteiOS::GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames)
|
||||
{
|
||||
dirnames.clear();
|
||||
dirnames.push_back("iOS DeviceSupport");
|
||||
}
|
||||
|
||||
uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo(
|
||||
const SDKDirectoryInfo *sdk_info) {
|
||||
if (sdk_info == NULL) {
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
return sdk_info - &m_sdk_directory_infos[0];
|
||||
std::string PlatformRemoteiOS::GetPlatformName ()
|
||||
{
|
||||
return "iPhoneOS.platform";
|
||||
}
|
||||
|
|
|
@ -16,16 +16,16 @@
|
|||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "PlatformDarwin.h"
|
||||
#include "PlatformRemoteDarwinDevice.h"
|
||||
#include "lldb/Utility/FileSpec.h"
|
||||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
||||
class PlatformRemoteiOS : public PlatformDarwin {
|
||||
class PlatformRemoteiOS : public PlatformRemoteDarwinDevice {
|
||||
public:
|
||||
PlatformRemoteiOS();
|
||||
|
||||
~PlatformRemoteiOS() override;
|
||||
~PlatformRemoteiOS() override = default;
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Class Functions
|
||||
|
@ -41,6 +41,12 @@ public:
|
|||
|
||||
static const char *GetDescriptionStatic();
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
|
||||
const char *GetDescription() override { return GetDescriptionStatic(); }
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PluginInterface functions
|
||||
//------------------------------------------------------------
|
||||
|
@ -50,89 +56,18 @@ public:
|
|||
|
||||
uint32_t GetPluginVersion() override { return 1; }
|
||||
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::Platform functions
|
||||
//------------------------------------------------------------
|
||||
lldb_private::Error ResolveExecutable(
|
||||
const lldb_private::ModuleSpec &module_spec, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr) override;
|
||||
|
||||
const char *GetDescription() override { return GetDescriptionStatic(); }
|
||||
|
||||
void GetStatus(lldb_private::Stream &strm) override;
|
||||
|
||||
virtual lldb_private::Error
|
||||
GetSymbolFile(const lldb_private::FileSpec &platform_file,
|
||||
const lldb_private::UUID *uuid_ptr,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
lldb_private::Error
|
||||
GetSharedModule(const lldb_private::ModuleSpec &module_spec,
|
||||
lldb_private::Process *process, lldb::ModuleSP &module_sp,
|
||||
const lldb_private::FileSpecList *module_search_paths_ptr,
|
||||
lldb::ModuleSP *old_module_sp_ptr,
|
||||
bool *did_create_ptr) override;
|
||||
|
||||
bool GetSupportedArchitectureAtIndex(uint32_t idx,
|
||||
lldb_private::ArchSpec &arch) override;
|
||||
|
||||
void
|
||||
AddClangModuleCompilationOptions(lldb_private::Target *target,
|
||||
std::vector<std::string> &options) override {
|
||||
return PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
|
||||
target, options, PlatformDarwin::SDKType::iPhoneOS);
|
||||
}
|
||||
|
||||
protected:
|
||||
struct SDKDirectoryInfo {
|
||||
SDKDirectoryInfo(const lldb_private::FileSpec &sdk_dir_spec);
|
||||
lldb_private::FileSpec directory;
|
||||
lldb_private::ConstString build;
|
||||
uint32_t version_major;
|
||||
uint32_t version_minor;
|
||||
uint32_t version_update;
|
||||
bool user_cached;
|
||||
};
|
||||
|
||||
typedef std::vector<SDKDirectoryInfo> SDKDirectoryInfoCollection;
|
||||
//------------------------------------------------------------
|
||||
// lldb_private::PlatformRemoteDarwinDevice functions
|
||||
//------------------------------------------------------------
|
||||
|
||||
std::mutex m_sdk_dir_mutex;
|
||||
SDKDirectoryInfoCollection m_sdk_directory_infos;
|
||||
std::string m_device_support_directory;
|
||||
std::string m_device_support_directory_for_os_version;
|
||||
std::string m_build_update;
|
||||
uint32_t m_last_module_sdk_idx;
|
||||
uint32_t m_connected_module_sdk_idx;
|
||||
void GetDeviceSupportDirectoryNames (std::vector<std::string> &dirnames) override;
|
||||
|
||||
bool UpdateSDKDirectoryInfosIfNeeded();
|
||||
|
||||
const char *GetDeviceSupportDirectory();
|
||||
|
||||
const char *GetDeviceSupportDirectoryForOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForLatestOSVersion();
|
||||
|
||||
const SDKDirectoryInfo *GetSDKDirectoryForCurrentOSVersion();
|
||||
|
||||
static lldb_private::FileSpec::EnumerateDirectoryResult
|
||||
GetContainedFilesIntoVectorOfStringsCallback(
|
||||
void *baton, llvm::sys::fs::file_type ft,
|
||||
const lldb_private::FileSpec &file_spec);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const char *platform_file_path,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
bool GetFileInSDK(const char *platform_file_path, uint32_t sdk_idx,
|
||||
lldb_private::FileSpec &local_file);
|
||||
|
||||
uint32_t FindFileInAllSDKs(const lldb_private::FileSpec &platform_file,
|
||||
lldb_private::FileSpecList &file_list);
|
||||
|
||||
uint32_t GetConnectedSDKIndex();
|
||||
|
||||
// Get index of SDK in SDKDirectoryInfoCollection by its pointer and return
|
||||
// UINT32_MAX if that SDK not found.
|
||||
uint32_t GetSDKIndexBySDKDirectoryInfo(const SDKDirectoryInfo *sdk_info);
|
||||
std::string GetPlatformName () override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(PlatformRemoteiOS);
|
||||
|
|
Loading…
Reference in New Issue