[Lldb-commits] [lldb] r216115 - 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.

Greg Clayton gclayton at apple.com
Wed Aug 20 11:13:03 PDT 2014


Author: gclayton
Date: Wed Aug 20 13:13:03 2014
New Revision: 216115

URL: http://llvm.org/viewvc/llvm-project?rev=216115&view=rev
Log:
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>

Modified:
    lldb/trunk/source/Target/TargetList.cpp

Modified: lldb/trunk/source/Target/TargetList.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/TargetList.cpp?rev=216115&r1=216114&r2=216115&view=diff
==============================================================================
--- lldb/trunk/source/Target/TargetList.cpp (original)
+++ lldb/trunk/source/Target/TargetList.cpp Wed Aug 20 13:13:03 2014
@@ -89,6 +89,19 @@ TargetList::CreateTarget (Debugger &debu
 
     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 &debu
                         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 &debu
 
     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)





More information about the lldb-commits mailing list