Files
clang-p2996/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
Pavel Labath 30e6cbfcfc Revert "Use LLVM for all stat-related functionality."
this reverts r297116 because it breaks the unittests and
TestCompDirSymlink. The ModuleCache unit test is trivially fixable, but
the CompDirSymlink failure is a symptom of a deeper problem: llvm's stat
functionality is not a drop-in replacement for lldb's. The former is
based on stat(2) (which does symlink resolution), while the latter is
based on lstat(2) (which does not).

This also reverts subsequent build fixes (r297128, r297120, 297117) and
r297119 (Remove FileSpec dependency on FileSystem) which builds on top
of this.

llvm-svn: 297139
2017-03-07 13:19:15 +00:00

822 lines
30 KiB
C++

//===-- PlatformRemoteiOS.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "PlatformRemoteiOS.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/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Error.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
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
//------------------------------------------------------------------
static uint32_t g_initialize_count = 0;
//------------------------------------------------------------------
// Static Functions
//------------------------------------------------------------------
void PlatformRemoteiOS::Initialize() {
PlatformDarwin::Initialize();
if (g_initialize_count++ == 0) {
PluginManager::RegisterPlugin(PlatformRemoteiOS::GetPluginNameStatic(),
PlatformRemoteiOS::GetDescriptionStatic(),
PlatformRemoteiOS::CreateInstance);
}
}
void PlatformRemoteiOS::Terminate() {
if (g_initialize_count > 0) {
if (--g_initialize_count == 0) {
PluginManager::UnregisterPlugin(PlatformRemoteiOS::CreateInstance);
}
}
PlatformDarwin::Terminate();
}
PlatformSP PlatformRemoteiOS::CreateInstance(bool force, const ArchSpec *arch) {
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log) {
const char *arch_name;
if (arch && arch->GetArchitectureName())
arch_name = arch->GetArchitectureName();
else
arch_name = "<null>";
const char *triple_cstr =
arch ? arch->GetTriple().getTriple().c_str() : "<null>";
log->Printf("PlatformRemoteiOS::%s(force=%s, arch={%s,%s})", __FUNCTION__,
force ? "true" : "false", arch_name, triple_cstr);
}
bool create = force;
if (create == false && arch && arch->IsValid()) {
switch (arch->GetMachine()) {
case llvm::Triple::arm:
case llvm::Triple::aarch64:
case llvm::Triple::thumb: {
const llvm::Triple &triple = arch->GetTriple();
llvm::Triple::VendorType vendor = triple.getVendor();
switch (vendor) {
case llvm::Triple::Apple:
create = true;
break;
#if defined(__APPLE__)
// Only accept "unknown" for the vendor if the host is Apple and
// it "unknown" wasn't specified (it was just returned because it
// was NOT specified)
case llvm::Triple::UnknownArch:
create = !arch->TripleVendorWasSpecified();
break;
#endif
default:
break;
}
if (create) {
switch (triple.getOS()) {
case llvm::Triple::Darwin: // Deprecated, but still support Darwin for
// historical reasons
case llvm::Triple::IOS: // This is the right triple value for iOS
// debugging
break;
default:
create = false;
break;
}
}
} break;
default:
break;
}
}
if (create) {
if (log)
log->Printf("PlatformRemoteiOS::%s() creating platform", __FUNCTION__);
return lldb::PlatformSP(new PlatformRemoteiOS());
}
if (log)
log->Printf("PlatformRemoteiOS::%s() aborting creation of platform",
__FUNCTION__);
return lldb::PlatformSP();
}
lldb_private::ConstString PlatformRemoteiOS::GetPluginNameStatic() {
static ConstString g_name("remote-ios");
return g_name;
}
const char *PlatformRemoteiOS::GetDescriptionStatic() {
return "Remote iOS platform plug-in.";
}
//------------------------------------------------------------------
/// 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, FileSpec::FileType file_type, 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;
}
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;
}
uint32_t PlatformRemoteiOS::GetSDKIndexBySDKDirectoryInfo(
const SDKDirectoryInfo *sdk_info) {
if (sdk_info == NULL) {
return UINT32_MAX;
}
return sdk_info - &m_sdk_directory_infos[0];
}