summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2014-08-20 18:13:03 +0000
committerGreg Clayton <gclayton@apple.com>2014-08-20 18:13:03 +0000
commitb0cc53cf971c3fe7f44ae7fc88167e04412c7d3a (patch)
tree60b1c7676787c265fafcdf508e261573a9013930 /lldb/source/Target
parentf3cfeef2e9f13c15af1d02b97c25fde6ef971372 (diff)
downloadbcm5719-llvm-b0cc53cf971c3fe7f44ae7fc88167e04412c7d3a.tar.gz
bcm5719-llvm-b0cc53cf971c3fe7f44ae7fc88167e04412c7d3a.zip
If an executable file is specified with no architecture and it contains more than one architecture select a compatible platform if all architectures match the same platform.
This helps us "do the right thing" when loading a file without having to specify an architecture. <rdar://problem/18021558> llvm-svn: 216115
Diffstat (limited to 'lldb/source/Target')
-rw-r--r--lldb/source/Target/TargetList.cpp124
1 files changed, 98 insertions, 26 deletions
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index d1775213d60..5ee75ff7444 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -89,6 +89,19 @@ TargetList::CreateTarget (Debugger &debugger,
bool prefer_platform_arch = false;
+ CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
+ if (platform_options && platform_options->PlatformWasSpecified ())
+ {
+ const bool select_platform = true;
+ platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
+ arch,
+ select_platform,
+ error,
+ platform_arch);
+ if (!platform_sp)
+ return error;
+ }
+
if (user_exe_path && user_exe_path[0])
{
ModuleSpecList module_specs;
@@ -150,26 +163,92 @@ TargetList::CreateTarget (Debugger &debugger,
platform_arch = matching_module_spec.GetArchitecture();
}
}
+ else
+ {
+ // No architecture specified, check if there is only one platform for
+ // all of the architectures.
+
+ typedef std::vector<PlatformSP> PlatformList;
+ PlatformList platforms;
+ PlatformSP host_platform_sp = Platform::GetDefaultPlatform();
+ for (size_t i=0; i<num_specs; ++i)
+ {
+ ModuleSpec module_spec;
+ if (module_specs.GetModuleSpecAtIndex(i, module_spec))
+ {
+ // See if there was a selected platform and check that first
+ // since the user may have specified it.
+ if (platform_sp)
+ {
+ if (platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL))
+ {
+ platforms.push_back(platform_sp);
+ continue;
+ }
+ }
+
+ // Next check the host platform it if wasn't already checked above
+ if (host_platform_sp && (!platform_sp || host_platform_sp->GetName() != platform_sp->GetName()))
+ {
+ if (host_platform_sp->IsCompatibleArchitecture(module_spec.GetArchitecture(), false, NULL))
+ {
+ platforms.push_back(host_platform_sp);
+ continue;
+ }
+ }
+
+ // Just find a platform that matches the architecture in the executable file
+ platforms.push_back(Platform::GetPlatformForArchitecture(module_spec.GetArchitecture(), nullptr));
+ }
+ }
+
+ Platform *platform_ptr = NULL;
+ for (const auto &the_platform_sp : platforms)
+ {
+ if (platform_ptr)
+ {
+ if (platform_ptr->GetName() != the_platform_sp->GetName())
+ {
+ platform_ptr = NULL;
+ break;
+ }
+ }
+ else
+ {
+ platform_ptr = the_platform_sp.get();
+ }
+ }
+
+ if (platform_ptr)
+ {
+ // All platforms for all modules in the exectuable match, so we can select this platform
+ platform_sp = platforms.front();
+ }
+ else
+ {
+ // More than one platform claims to support this file, so the --platform option must be specified
+ StreamString error_strm;
+ std::set<Platform *> platform_set;
+ error_strm.Printf ("more than one platform supports this executable (");
+ for (const auto &the_platform_sp : platforms)
+ {
+ if (platform_set.find(the_platform_sp.get()) == platform_set.end())
+ {
+ if (!platform_set.empty())
+ error_strm.PutCString(", ");
+ error_strm.PutCString(the_platform_sp->GetName().GetCString());
+ platform_set.insert(the_platform_sp.get());
+ }
+ }
+ error_strm.Printf("), use the --platform option to specify a platform");
+ error.SetErrorString(error_strm.GetString().c_str());
+ return error;
+ }
+ }
}
}
}
- CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
- if (platform_options)
- {
- if (platform_options->PlatformWasSpecified ())
- {
- const bool select_platform = true;
- platform_sp = platform_options->CreatePlatformWithOptions (interpreter,
- arch,
- select_platform,
- error,
- platform_arch);
- if (!platform_sp)
- return error;
- }
- }
-
if (!platform_sp)
{
// Get the current platform and make sure it is compatible with the
@@ -219,17 +298,10 @@ TargetList::CreateTarget (Debugger &debugger,
ArchSpec arch(specified_arch);
- if (platform_sp)
- {
- if (arch.IsValid())
- {
- if (!platform_sp->IsCompatibleArchitecture(arch, false, NULL))
- platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
- }
- }
- else if (arch.IsValid())
+ if (arch.IsValid())
{
- platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
+ if (!platform_sp || !platform_sp->IsCompatibleArchitecture(arch, false, NULL))
+ platform_sp = Platform::GetPlatformForArchitecture(specified_arch, &arch);
}
if (!platform_sp)
OpenPOWER on IntegriCloud