[Lldb-commits] [lldb] r255014 - Add a new option to Platform::LoadImage to install the image

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Tue Dec 8 05:43:59 PST 2015


Author: tberghammer
Date: Tue Dec  8 07:43:59 2015
New Revision: 255014

URL: http://llvm.org/viewvc/llvm-project?rev=255014&view=rev
Log:
Add a new option to Platform::LoadImage to install the image

This change introduce 3 different working mode for Platform::LoadImage
depending on the file specs specified.
* If only a remote file is specified then the remote file is loaded on
  the target (same behavior as before)
* If only a local file is specified then the local file is installed to
  the current working directory and then loaded from there.
* If both local and remote file is specified then the local file is
  installed to the specified location and then loaded from there.

The same options are exposed on the SB API with a new method LoadImage
method while the old signature presers its meaning.

On the command line the installation of the shared library can be specified
with the "--install" option of "process load".

Differential revision: http://reviews.llvm.org/D15152

Modified:
    lldb/trunk/include/lldb/API/SBProcess.h
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
    lldb/trunk/source/API/SBProcess.cpp
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
    lldb/trunk/source/Target/Platform.cpp

Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Tue Dec  8 07:43:59 2015
@@ -294,8 +294,56 @@ public:
     uint32_t
     GetNumSupportedHardwareWatchpoints (lldb::SBError &error) const;
 
+    //------------------------------------------------------------------
+    /// Load a shared library into this process.
+    ///
+    /// @param[in] remote_image_spec
+    ///     The path for the shared library on the target what you want
+    ///     to load.
+    ///
+    /// @param[out] error
+    ///     An error object that gets filled in with any errors that
+    ///     might occur when trying to load the shared library.
+    ///
+    /// @return
+    ///     A token that represents the shared library that can be
+    ///     later used to unload the shared library. A value of
+    ///     LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+    ///     library can't be opened.
+    //------------------------------------------------------------------
     uint32_t
-    LoadImage (lldb::SBFileSpec &image_spec, lldb::SBError &error);
+    LoadImage (lldb::SBFileSpec &remote_image_spec, lldb::SBError &error);
+
+    //------------------------------------------------------------------
+    /// Load a shared library into this process.
+    ///
+    /// @param[in] local_image_spec
+    ///     The file spec that points to the shared library that you
+    ///     want to load if the library is located on the host. The
+    ///     library will be copied over to the location specified by
+    ///     remote_image_spec or into the current working directory with
+    ///     the same filename if the remote_image_spec isn't specified.
+    ///
+    /// @param[in] remote_image_spec
+    ///     If local_image_spec is specified then the location where the
+    ///     library should be copied over from the host. If
+    ///     local_image_spec isn't specified, then the path for the
+    ///     shared library on the target what you want to load.
+    ///
+    /// @param[out] error
+    ///     An error object that gets filled in with any errors that
+    ///     might occur when trying to load the shared library.
+    ///
+    /// @return
+    ///     A token that represents the shared library that can be
+    ///     later used to unload the shared library. A value of
+    ///     LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
+    ///     library can't be opened.
+    //------------------------------------------------------------------
+    uint32_t
+    LoadImage (const lldb::SBFileSpec &local_image_spec,
+               const lldb::SBFileSpec &remote_image_spec,
+               lldb::SBError &error);
     
     lldb::SBError
     UnloadImage (uint32_t image_token);

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Tue Dec  8 07:43:59 2015
@@ -997,9 +997,18 @@ class ModuleCache;
         /// @param[in] process
         ///     The process to load the image.
         ///
-        /// @param[in] image_spec
-        ///     The image file spec that points to the shared library that
-        ///     you want to load.
+        /// @param[in] local_file
+        ///     The file spec that points to the shared library that you want
+        ///     to load if the library is located on the host. The library will
+        ///     be copied over to the location specified by remote_file or into
+        ///     the current working directory with the same filename if the
+        ///     remote_file isn't specified.
+        ///
+        /// @param[in] remote_file
+        ///     If local_file is specified then the location where the library
+        ///     should be copied over from the host. If local_file isn't
+        ///     specified, then the path for the shared library on the target
+        ///     what you want to load.
         ///
         /// @param[out] error
         ///     An error object that gets filled in with any errors that
@@ -1011,11 +1020,17 @@ class ModuleCache;
         ///     LLDB_INVALID_IMAGE_TOKEN will be returned if the shared
         ///     library can't be opened.
         //------------------------------------------------------------------
-        virtual uint32_t
+        uint32_t
         LoadImage (lldb_private::Process* process,
-                   const lldb_private::FileSpec& image_spec,
+                   const lldb_private::FileSpec& local_file,
+                   const lldb_private::FileSpec& remote_file,
                    lldb_private::Error& error);
 
+        virtual uint32_t
+        DoLoadImage (lldb_private::Process* process,
+                     const lldb_private::FileSpec& remote_file,
+                     lldb_private::Error& error);
+
         virtual Error
         UnloadImage (lldb_private::Process* process, uint32_t image_token);
 

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py Tue Dec  8 07:43:59 2015
@@ -210,19 +210,13 @@ class LoadUnloadTestCase(TestBase):
         else:
             dylibName = 'libloadunload_a.so'
 
-        if lldb.remote_platform:
-            # Don't use os.path.join as we have to use the path separator for the target
-            dylibPath = shlib_dir + '/' + dylibName
-        else:
-            dylibPath = dylibName
-
         # Make sure that a_function does not exist at this point.
         self.expect("image lookup -n a_function", "a_function should not exist yet",
                     error=True, matching=False, patterns = ["1 match found"])
 
         # Use lldb 'process load' to load the dylib.
-        self.expect("process load %s" % dylibPath, "%s loaded correctly" % dylibPath,
-            patterns = ['Loading "%s".*ok' % dylibPath,
+        self.expect("process load %s --install" % dylibName, "%s loaded correctly" % dylibName,
+            patterns = ['Loading "%s".*ok' % dylibName,
                         'Image [0-9]+ loaded'])
 
         # Search for and match the "Image ([0-9]+) loaded" pattern.

Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Tue Dec  8 07:43:59 2015
@@ -1288,7 +1288,15 @@ SBProcess::GetNumSupportedHardwareWatchp
 }
 
 uint32_t
-SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error)
+SBProcess::LoadImage (lldb::SBFileSpec &sb_remote_image_spec, lldb::SBError &sb_error)
+{
+    return LoadImage(SBFileSpec(), sb_remote_image_spec, sb_error);
+}
+
+uint32_t
+SBProcess::LoadImage (const lldb::SBFileSpec &sb_local_image_spec,
+                      const lldb::SBFileSpec &sb_remote_image_spec,
+                      lldb::SBError &sb_error)
 {
     ProcessSP process_sp(GetSP());
     if (process_sp)
@@ -1298,7 +1306,10 @@ SBProcess::LoadImage (lldb::SBFileSpec &
         {
             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
             PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
-            return platform_sp->LoadImage (process_sp.get(), *sb_image_spec, sb_error.ref());
+            return platform_sp->LoadImage (process_sp.get(),
+                                           *sb_local_image_spec,
+                                           *sb_remote_image_spec,
+                                           sb_error.ref());
         }
         else
         {

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Tue Dec  8 07:43:59 2015
@@ -1174,6 +1174,57 @@ public:
 class CommandObjectProcessLoad : public CommandObjectParsed
 {
 public:
+    class CommandOptions : public Options
+    {
+    public:
+        CommandOptions (CommandInterpreter &interpreter) :
+            Options(interpreter)
+        {
+            // Keep default values of all options in one place: OptionParsingStarting ()
+            OptionParsingStarting ();
+        }
+
+        ~CommandOptions () override = default;
+
+        Error
+        SetOptionValue (uint32_t option_idx, const char *option_arg) override
+        {
+            Error error;
+            const int short_option = m_getopt_table[option_idx].val;
+            switch (short_option)
+            {
+            case 'i':
+                do_install = true;
+                if (option_arg && option_arg[0])
+                    install_path.SetFile(option_arg, false);
+                break;
+            default:
+                error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+                break;
+            }
+            return error;
+        }
+
+        void
+        OptionParsingStarting () override
+        {
+            do_install = false;
+            install_path.Clear();
+        }
+
+        const OptionDefinition*
+        GetDefinitions () override
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+        static OptionDefinition g_option_table[];
+
+        // Instance variables to hold the values for command options.
+        bool do_install;
+        FileSpec install_path;
+    };
 
     CommandObjectProcessLoad (CommandInterpreter &interpreter) :
         CommandObjectParsed (interpreter,
@@ -1183,12 +1234,17 @@ public:
                              eCommandRequiresProcess       |
                              eCommandTryTargetAPILock      |
                              eCommandProcessMustBeLaunched |
-                             eCommandProcessMustBePaused   )
+                             eCommandProcessMustBePaused   ),
+        m_options (interpreter)
     {
     }
 
-    ~CommandObjectProcessLoad () override
+    ~CommandObjectProcessLoad () override = default;
+
+    Options *
+    GetOptions () override
     {
+        return &m_options;
     }
 
 protected:
@@ -1198,18 +1254,34 @@ protected:
         Process *process = m_exe_ctx.GetProcessPtr();
 
         const size_t argc = command.GetArgumentCount();
-        
         for (uint32_t i=0; i<argc; ++i)
         {
             Error error;
-            const char *image_path = command.GetArgumentAtIndex(i);
-            FileSpec image_spec (image_path, false);
             PlatformSP platform = process->GetTarget().GetPlatform();
-            platform->ResolveRemotePath(image_spec, image_spec);
-            uint32_t image_token = platform->LoadImage(process, image_spec, error);
+            const char *image_path = command.GetArgumentAtIndex(i);
+            uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN;
+
+            if (!m_options.do_install)
+            {
+                FileSpec image_spec (image_path, false);
+                platform->ResolveRemotePath(image_spec, image_spec);
+                image_token = platform->LoadImage(process, FileSpec(), image_spec, error);
+            }
+            else if (m_options.install_path)
+            {
+                FileSpec image_spec (image_path, true);
+                platform->ResolveRemotePath(m_options.install_path, m_options.install_path);
+                image_token = platform->LoadImage(process, image_spec, m_options.install_path, error);
+            }
+            else
+            {
+                FileSpec image_spec (image_path, true);
+                image_token = platform->LoadImage(process, image_spec, FileSpec(), error);
+            }
+
             if (image_token != LLDB_INVALID_IMAGE_TOKEN)
             {
-                result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);  
+                result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);
                 result.SetStatus (eReturnStatusSuccessFinishResult);
             }
             else
@@ -1220,8 +1292,16 @@ protected:
         }
         return result.Succeeded();
     }
+    
+    CommandOptions m_options;
 };
 
+OptionDefinition
+CommandObjectProcessLoad::CommandOptions::g_option_table[] =
+{
+    { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory."},
+    { 0,                false, nullptr,    0 , 0,                               nullptr, nullptr, 0, eArgTypeNone, nullptr }
+};
 
 //-------------------------------------------------------------------------
 // CommandObjectProcessUnload

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Tue Dec  8 07:43:59 2015
@@ -898,10 +898,12 @@ PlatformPOSIX::EvaluateLibdlExpression(l
 }
 
 uint32_t
-PlatformPOSIX::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error)
+PlatformPOSIX::DoLoadImage(lldb_private::Process* process,
+                           const lldb_private::FileSpec& remote_file,
+                           lldb_private::Error& error)
 {
     char path[PATH_MAX];
-    image_spec.GetPath(path, sizeof(path));
+    remote_file.GetPath(path, sizeof(path));
 
     StreamString expr;
     expr.Printf(R"(

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h Tue Dec  8 07:43:59 2015
@@ -174,9 +174,9 @@ public:
     DisconnectRemote () override;
 
     uint32_t
-    LoadImage (lldb_private::Process* process,
-               const lldb_private::FileSpec& image_spec,
-               lldb_private::Error& error) override;
+    DoLoadImage (lldb_private::Process* process,
+                 const lldb_private::FileSpec& remote_file,
+                 lldb_private::Error& error) override;
 
     lldb_private::Error
     UnloadImage (lldb_private::Process* process, uint32_t image_token) override;

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=255014&r1=255013&r2=255014&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Tue Dec  8 07:43:59 2015
@@ -1985,7 +1985,51 @@ Platform::GetUnixSignals()
 }
 
 uint32_t
-Platform::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error)
+Platform::LoadImage(lldb_private::Process* process,
+                    const lldb_private::FileSpec& local_file,
+                    const lldb_private::FileSpec& remote_file,
+                    lldb_private::Error& error)
+{
+    if (local_file && remote_file)
+    {
+        // Both local and remote file was specified. Install the local file to the given location.
+        if (IsRemote() || local_file != remote_file)
+        {
+            error = Install(local_file, remote_file);
+            if (error.Fail())
+                return LLDB_INVALID_IMAGE_TOKEN;
+        }
+        return DoLoadImage(process, remote_file, error);
+    }
+
+    if (local_file)
+    {
+        // Only local file was specified. Install it to the current working directory.
+        FileSpec target_file = GetWorkingDirectory();
+        target_file.AppendPathComponent(local_file.GetFilename().AsCString());
+        if (IsRemote() || local_file != target_file)
+        {
+            error = Install(local_file, target_file);
+            if (error.Fail())
+                return LLDB_INVALID_IMAGE_TOKEN;
+        }
+        return DoLoadImage(process, target_file, error);
+    }
+
+    if (remote_file)
+    {
+        // Only remote file was specified so we don't have to do any copying
+        return DoLoadImage(process, remote_file, error);
+    }
+
+    error.SetErrorString("Neither local nor remote file was specified");
+    return LLDB_INVALID_IMAGE_TOKEN;
+}
+
+uint32_t
+Platform::DoLoadImage (lldb_private::Process* process,
+                       const lldb_private::FileSpec& remote_file,
+                       lldb_private::Error& error)
 {
     error.SetErrorString("LoadImage is not supported on the current platform");
     return LLDB_INVALID_IMAGE_TOKEN;
@@ -1994,5 +2038,5 @@ Platform::LoadImage(lldb_private::Proces
 Error
 Platform::UnloadImage(lldb_private::Process* process, uint32_t image_token)
 {
-    return Error("UnLoadImage is not supported on the current platform");
+    return Error("UnloadImage is not supported on the current platform");
 }




More information about the lldb-commits mailing list