This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
JDevlieghere marked 3 inline comments as done.
Closed by commit rG4add853647b3: [lldb] Improve platform handling in 
CreateTargetInternal (authored by JDevlieghere).
Herald added a project: LLDB.

Changed prior to commit:
  https://reviews.llvm.org/D84809?vs=281421&id=281659#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D84809/new/

https://reviews.llvm.org/D84809

Files:
  lldb/source/Commands/CommandObjectTarget.cpp
  lldb/source/Target/TargetList.cpp
  lldb/test/API/commands/target/basic/TestTargetCommand.py
  lldb/test/API/commands/target/basic/bogus.yaml

Index: lldb/test/API/commands/target/basic/bogus.yaml
===================================================================
--- /dev/null
+++ lldb/test/API/commands/target/basic/bogus.yaml
@@ -0,0 +1,194 @@
+--- !fat-mach-o
+FatHeader:
+  magic:           0xCAFEBABE
+  nfat_arch:       3
+FatArchs:
+  - cputype:         0x0000000C
+    cpusubtype:      0x00000009
+    offset:          0x0000000000004000
+    size:            200
+    align:           14
+  - cputype:         0x0000000C
+    cpusubtype:      0x0000000B
+    offset:          0x0000000000008000
+    size:            200
+    align:           14
+  - cputype:         0x0100000C
+    cpusubtype:      0x00000000
+    offset:          0x000000000000C000
+    size:            332
+    align:           14
+Slices:
+  - !mach-o
+    FileHeader:
+      magic:           0xFEEDFACE
+      # Bogus
+      cputype:         0x00000003
+      cpusubtype:      0x00000009
+      filetype:        0x00000001
+      ncmds:           4
+      sizeofcmds:      112
+      flags:           0x00002000
+    LoadCommands:
+      - cmd:             LC_SEGMENT
+        cmdsize:         56
+        segname:         ''
+        vmaddr:          0
+        vmsize:          0
+        fileoff:         0
+        filesize:        0
+        maxprot:         7
+        initprot:        7
+        nsects:          0
+        flags:           0
+      - cmd:             LC_SYMTAB
+        cmdsize:         24
+        symoff:          172
+        nsyms:           1
+        stroff:          184
+        strsize:         16
+      - cmd:             LC_VERSION_MIN_IPHONEOS
+        cmdsize:         16
+        version:         327680
+        sdk:             0
+      - cmd:             LC_DATA_IN_CODE
+        cmdsize:         16
+        dataoff:         172
+        datasize:        0
+    LinkEditData:
+      NameList:
+        - n_strx:          4
+          n_type:          0x01
+          n_sect:          0
+          n_desc:          512
+          n_value:         4
+      StringTable:
+        - ''
+        - ''
+        - ''
+        - ''
+        - _armv7_var
+        - ''
+  - !mach-o
+    FileHeader:
+      magic:           0xFEEDFACE
+      # Bogus
+      cputype:         0x00000002
+      cpusubtype:      0x0000000B
+      filetype:        0x00000001
+      ncmds:           4
+      sizeofcmds:      112
+      flags:           0x00002000
+    LoadCommands:
+      - cmd:             LC_SEGMENT
+        cmdsize:         56
+        segname:         ''
+        vmaddr:          0
+        vmsize:          0
+        fileoff:         0
+        filesize:        0
+        maxprot:         7
+        initprot:        7
+        nsects:          0
+        flags:           0
+      - cmd:             LC_SYMTAB
+        cmdsize:         24
+        symoff:          172
+        nsyms:           1
+        stroff:          184
+        strsize:         16
+      - cmd:             LC_VERSION_MIN_IPHONEOS
+        cmdsize:         16
+        version:         327680
+        sdk:             0
+      - cmd:             LC_DATA_IN_CODE
+        cmdsize:         16
+        dataoff:         172
+        datasize:        0
+    LinkEditData:
+      NameList:
+        - n_strx:          4
+          n_type:          0x01
+          n_sect:          0
+          n_desc:          512
+          n_value:         4
+      StringTable:
+        - ''
+        - ''
+        - ''
+        - ''
+        - _armv7s_var
+  - !mach-o
+    FileHeader:
+      magic:           0xFEEDFACF
+      # Bogus
+      cputype:         0x00000001
+      cpusubtype:      0x00000000
+      filetype:        0x00000001
+      ncmds:           4
+      sizeofcmds:      208
+      flags:           0x00002000
+      reserved:        0x00000000
+    LoadCommands:
+      - cmd:             LC_SEGMENT_64
+        cmdsize:         152
+        segname:         ''
+        vmaddr:          0
+        vmsize:          0
+        fileoff:         272
+        filesize:        0
+        maxprot:         7
+        initprot:        7
+        nsects:          1
+        flags:           0
+        Sections:
+          - sectname:        __text
+            segname:         __TEXT
+            addr:            0x0000000000000000
+            size:            0
+            offset:          0x00000110
+            align:           0
+            reloff:          0x00000000
+            nreloc:          0
+            flags:           0x80000400
+            reserved1:       0x00000000
+            reserved2:       0x00000000
+            reserved3:       0x00000000
+            content:         ''
+      - cmd:             LC_SYMTAB
+        cmdsize:         24
+        symoff:          276
+        nsyms:           2
+        stroff:          308
+        strsize:         24
+      - cmd:             LC_VERSION_MIN_IPHONEOS
+        cmdsize:         16
+        version:         327680
+        sdk:             0
+      - cmd:             LC_DATA_IN_CODE
+        cmdsize:         16
+        dataoff:         276
+        datasize:        0
+    LinkEditData:
+      NameList:
+        - n_strx:          15
+          n_type:          0x0E
+          n_sect:          1
+          n_desc:          0
+          n_value:         0
+        - n_strx:          4
+          n_type:          0x01
+          n_sect:          0
+          n_desc:          512
+          n_value:         4
+      StringTable:
+        - ''
+        - ''
+        - ''
+        - ''
+        - _arm64_var
+        - ltmp0
+        - ''
+        - ''
+        - ''
+...
Index: lldb/test/API/commands/target/basic/TestTargetCommand.py
===================================================================
--- lldb/test/API/commands/target/basic/TestTargetCommand.py
+++ lldb/test/API/commands/target/basic/TestTargetCommand.py
@@ -115,6 +115,33 @@
 
         self.runCmd("target list")
 
+    @no_debug_info_test
+    def test_target_create_invalid_arch(self):
+        exe = self.getBuildArtifact("a.out")
+        self.expect("target create {} --arch doesntexist".format(exe), error=True,
+                    patterns=["error: invalid triple 'doesntexist'"])
+
+    @no_debug_info_test
+    def test_target_create_platform(self):
+        self.buildB()
+        exe = self.getBuildArtifact("b.out")
+        self.expect("target create {} --platform host".format(exe))
+
+    @no_debug_info_test
+    def test_target_create_unsupported_platform(self):
+        yaml = os.path.join(self.getSourceDir(), "bogus.yaml")
+        exe = self.getBuildArtifact("bogus")
+        self.yaml2obj(yaml, exe)
+        self.expect("target create {}".format(exe), error=True,
+                    patterns=['error: no matching platforms found for this file'])
+
+    @no_debug_info_test
+    def test_target_create_invalid_platform(self):
+        self.buildB()
+        exe = self.getBuildArtifact("b.out")
+        self.expect("target create {} --platform doesntexist".format(exe), error=True,
+                    patterns=['error: unable to find a plug-in for the platform named "doesntexist"'])
+
     def do_target_variable_command(self, exe_name):
         """Exercise 'target variable' command before and after starting the inferior."""
         self.runCmd("file " + self.getBuildArtifact(exe_name),
Index: lldb/source/Target/TargetList.cpp
===================================================================
--- lldb/source/Target/TargetList.cpp
+++ lldb/source/Target/TargetList.cpp
@@ -75,55 +75,49 @@
     const OptionGroupPlatform *platform_options, TargetSP &target_sp,
     bool is_dummy_target) {
   Status error;
-  PlatformSP platform_sp;
 
-  // This is purposely left empty unless it is specified by triple_cstr. If not
-  // initialized via triple_cstr, then the currently selected platform will set
-  // the architecture correctly.
+  // Let's start by looking at the selected platform.
+  PlatformSP platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
+
+  // This variable corresponds to the architecture specified by the triple
+  // string. If that string was empty the currently selected platform will
+  // determine the architecture.
   const ArchSpec arch(triple_str);
-  if (!triple_str.empty()) {
-    if (!arch.IsValid()) {
-      error.SetErrorStringWithFormat("invalid triple '%s'",
-                                     triple_str.str().c_str());
-      return error;
-    }
+  if (!triple_str.empty() && !arch.IsValid()) {
+    error.SetErrorStringWithFormat("invalid triple '%s'",
+                                   triple_str.str().c_str());
+    return error;
   }
 
   ArchSpec platform_arch(arch);
 
-  bool prefer_platform_arch = false;
-
-  CommandInterpreter &interpreter = debugger.GetCommandInterpreter();
-
-  // let's see if there is already an existing platform before we go creating
-  // another...
-  platform_sp = debugger.GetPlatformList().GetSelectedPlatform();
-
-  if (platform_options && platform_options->PlatformWasSpecified()) {
-    // Create a new platform if it doesn't match the selected platform
-    if (!platform_options->PlatformMatches(platform_sp)) {
-      const bool select_platform = true;
-      platform_sp = platform_options->CreatePlatformWithOptions(
-          interpreter, arch, select_platform, error, platform_arch);
-      if (!platform_sp)
-        return error;
-    }
+  // Create a new platform if a platform was specified in the platform options
+  // and doesn't match the selected platform.
+  if (platform_options && platform_options->PlatformWasSpecified() &&
+      !platform_options->PlatformMatches(platform_sp)) {
+    const bool select_platform = true;
+    platform_sp = platform_options->CreatePlatformWithOptions(
+        debugger.GetCommandInterpreter(), arch, select_platform, error,
+        platform_arch);
+    if (!platform_sp)
+      return error;
   }
 
+  bool prefer_platform_arch = false;
+
   if (!user_exe_path.empty()) {
-    ModuleSpecList module_specs;
-    ModuleSpec module_spec;
-    module_spec.GetFileSpec().SetFile(user_exe_path, FileSpec::Style::native);
+    ModuleSpec module_spec(FileSpec(user_exe_path, FileSpec::Style::native));
     FileSystem::Instance().Resolve(module_spec.GetFileSpec());
-
     // Resolve the executable in case we are given a path to a application
-    // bundle like a .app bundle on MacOSX
+    // bundle like a .app bundle on MacOSX.
     Host::ResolveExecutableInBundle(module_spec.GetFileSpec());
 
     lldb::offset_t file_offset = 0;
     lldb::offset_t file_size = 0;
+    ModuleSpecList module_specs;
     const size_t num_specs = ObjectFile::GetModuleSpecifications(
         module_spec.GetFileSpec(), file_offset, file_size, module_specs);
+
     if (num_specs > 0) {
       ModuleSpec matching_module_spec;
 
@@ -134,7 +128,7 @@
                     matching_module_spec.GetArchitecture())) {
               // If the OS or vendor weren't specified, then adopt the module's
               // architecture so that the platform matching can be more
-              // accurate
+              // accurate.
               if (!platform_arch.TripleOSWasSpecified() ||
                   !platform_arch.TripleVendorWasSpecified()) {
                 prefer_platform_arch = true;
@@ -155,113 +149,107 @@
               return error;
             }
           } else {
-            // Only one arch and none was specified
+            // Only one arch and none was specified.
             prefer_platform_arch = true;
             platform_arch = matching_module_spec.GetArchitecture();
           }
         }
+      } else if (arch.IsValid()) {
+        // A (valid) architecture was specified.
+        module_spec.GetArchitecture() = arch;
+        if (module_specs.FindMatchingModuleSpec(module_spec,
+                                                matching_module_spec)) {
+          prefer_platform_arch = true;
+          platform_arch = matching_module_spec.GetArchitecture();
+        }
       } else {
-        if (arch.IsValid()) {
-          module_spec.GetArchitecture() = arch;
-          if (module_specs.FindMatchingModuleSpec(module_spec,
-                                                  matching_module_spec)) {
-            prefer_platform_arch = true;
-            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::GetHostPlatform();
-          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, nullptr)) {
-                  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, nullptr)) {
-                  platforms.push_back(host_platform_sp);
-                  continue;
-                }
+        // No architecture specified, check if there is only one platform for
+        // all of the architectures.
+        PlatformSP host_platform_sp = Platform::GetHostPlatform();
+        std::vector<PlatformSP> platforms;
+        for (size_t i = 0; i < num_specs; ++i) {
+          ModuleSpec module_spec;
+          if (module_specs.GetModuleSpecAtIndex(i, module_spec)) {
+            // First consider the platform specified by the user, if any, and
+            // the selected platform otherwise.
+            if (platform_sp) {
+              if (platform_sp->IsCompatibleArchitecture(
+                      module_spec.GetArchitecture(), false, nullptr)) {
+                platforms.push_back(platform_sp);
+                continue;
               }
+            }
 
-              // Just find a platform that matches the architecture in the
-              // executable file
-              PlatformSP fallback_platform_sp(
-                  Platform::GetPlatformForArchitecture(
-                      module_spec.GetArchitecture(), nullptr));
-              if (fallback_platform_sp) {
-                platforms.push_back(fallback_platform_sp);
+            // Now consider the host platform if it is different from the
+            // specified/selected platform.
+            if (host_platform_sp &&
+                (!platform_sp ||
+                 host_platform_sp->GetName() != platform_sp->GetName())) {
+              if (host_platform_sp->IsCompatibleArchitecture(
+                      module_spec.GetArchitecture(), false, nullptr)) {
+                platforms.push_back(host_platform_sp);
+                continue;
               }
             }
-          }
 
-          Platform *platform_ptr = nullptr;
-          bool more_than_one_platforms = false;
-          for (const auto &the_platform_sp : platforms) {
-            if (platform_ptr) {
-              if (platform_ptr->GetName() != the_platform_sp->GetName()) {
-                more_than_one_platforms = true;
-                platform_ptr = nullptr;
-                break;
-              }
-            } else {
-              platform_ptr = the_platform_sp.get();
+            // Finally find a platform that matches the architecture in the
+            // executable file.
+            PlatformSP fallback_platform_sp(
+                Platform::GetPlatformForArchitecture(
+                    module_spec.GetArchitecture(), nullptr));
+            if (fallback_platform_sp) {
+              platforms.push_back(fallback_platform_sp);
             }
           }
+        }
 
+        Platform *platform_ptr = nullptr;
+        bool more_than_one_platforms = false;
+        for (const auto &the_platform_sp : platforms) {
           if (platform_ptr) {
-            // All platforms for all modules in the executable match, so we can
-            // select this platform
-            platform_sp = platforms.front();
-          } else if (!more_than_one_platforms) {
-            // No platforms claim to support this file
-            error.SetErrorString("No matching platforms found for this file, "
-                                 "specify one with the --platform option");
-            return error;
+            if (platform_ptr->GetName() != the_platform_sp->GetName()) {
+              more_than_one_platforms = true;
+              platform_ptr = nullptr;
+              break;
+            }
           } 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());
-              }
+            platform_ptr = the_platform_sp.get();
+          }
+        }
+
+        if (platform_ptr) {
+          // All platforms for all modules in the executable match, so we can
+          // select this platform.
+          platform_sp = platforms.front();
+        } else if (!more_than_one_platforms) {
+          // No platforms claim to support this file.
+          error.SetErrorString("no matching platforms found for this file");
+          return error;
+        } else {
+          // More than one platform claims to support this file.
+          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());
-            return error;
           }
+          error_strm.Printf("), specify an architecture to disambiguate");
+          error.SetErrorString(error_strm.GetString());
+          return error;
         }
       }
     }
   }
 
   // If we have a valid architecture, make sure the current platform is
-  // compatible with that architecture
+  // compatible with that architecture.
   if (!prefer_platform_arch && arch.IsValid()) {
     if (!platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch)) {
       platform_sp = Platform::GetPlatformForArchitecture(arch, &platform_arch);
@@ -269,8 +257,8 @@
         debugger.GetPlatformList().SetSelectedPlatform(platform_sp);
     }
   } else if (platform_arch.IsValid()) {
-    // if "arch" isn't valid, yet "platform_arch" is, it means we have an
-    // executable file with a single architecture which should be used
+    // If "arch" isn't valid, yet "platform_arch" is, it means we have an
+    // executable file with a single architecture which should be used.
     ArchSpec fixed_platform_arch;
     if (!platform_sp->IsCompatibleArchitecture(platform_arch, false,
                                                &fixed_platform_arch)) {
@@ -284,10 +272,9 @@
   if (!platform_arch.IsValid())
     platform_arch = arch;
 
-  error = TargetList::CreateTargetInternal(
+  return TargetList::CreateTargetInternal(
       debugger, user_exe_path, platform_arch, load_dependent_files, platform_sp,
       target_sp, is_dummy_target);
-  return error;
 }
 
 lldb::TargetSP TargetList::GetDummyTarget(lldb_private::Debugger &debugger) {
Index: lldb/source/Commands/CommandObjectTarget.cpp
===================================================================
--- lldb/source/Commands/CommandObjectTarget.cpp
+++ lldb/source/Commands/CommandObjectTarget.cpp
@@ -23,6 +23,7 @@
 #include "lldb/Interpreter/OptionGroupBoolean.h"
 #include "lldb/Interpreter/OptionGroupFile.h"
 #include "lldb/Interpreter/OptionGroupFormat.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
 #include "lldb/Interpreter/OptionGroupString.h"
 #include "lldb/Interpreter/OptionGroupUInt64.h"
 #include "lldb/Interpreter/OptionGroupUUID.h"
@@ -214,6 +215,7 @@
             "Create a target using the argument as the main executable.",
             nullptr),
         m_option_group(), m_arch_option(),
+        m_platform_options(true), // Include the --platform option.
         m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
                     "Fullpath to a core file to use for this target."),
         m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
@@ -240,6 +242,7 @@
     m_arguments.push_back(arg);
 
     m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
+    m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
     m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
     m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
     m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
@@ -311,7 +314,8 @@
       llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
       Status error(debugger.GetTargetList().CreateTarget(
           debugger, file_path, arch_cstr,
-          m_add_dependents.m_load_dependent_files, nullptr, target_sp));
+          m_add_dependents.m_load_dependent_files, &m_platform_options,
+          target_sp));
 
       if (target_sp) {
         // Only get the platform after we create the target because we might
@@ -442,6 +446,7 @@
 private:
   OptionGroupOptions m_option_group;
   OptionGroupArchitecture m_arch_option;
+  OptionGroupPlatform m_platform_options;
   OptionGroupFile m_core_file;
   OptionGroupFile m_symbol_file;
   OptionGroupFile m_remote_file;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to