[Lldb-commits] [lldb] r118227 - in /lldb/trunk: include/lldb/ include/lldb/API/ include/lldb/Core/ include/lldb/Target/ source/API/ source/Commands/ source/Core/ source/Expression/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Target/

Greg Clayton gclayton at apple.com
Wed Nov 3 18:54:29 PDT 2010


Author: gclayton
Date: Wed Nov  3 20:54:29 2010
New Revision: 118227

URL: http://llvm.org/viewvc/llvm-project?rev=118227&view=rev
Log:
Added support for loading and unloading shared libraries. This was done by
adding support into lldb_private::Process:

    virtual uint32_t
    lldb_private::Process::LoadImage (const FileSpec &image_spec, 
                                      Error &error);

    virtual Error
    lldb_private::Process::UnloadImage (uint32_t image_token);

There is a default implementation that should work for both linux and MacOSX.
This ability has also been exported through the SBProcess API:

    uint32_t
    lldb::SBProcess::LoadImage (lldb::SBFileSpec &image_spec, 
                                lldb::SBError &error);

    lldb::SBError
    lldb::SBProcess::UnloadImage (uint32_t image_token);

Modified the DynamicLoader plug-in interface to require it to be able to 
tell us if it is currently possible to load/unload a shared library:

    virtual lldb_private::Error
    DynamicLoader::CanLoadImage () = 0;

This way the dynamic loader plug-ins are allows to veto whether we can 
currently load a shared library since the dynamic loader might know if it is
currenlty loading/unloading shared libraries. It might also know about the
current host system and know where to check to make sure runtime or malloc
locks are currently being held.

Modified the expression parser to have ClangUserExpression::Evaluate() be
the one that causes the dynamic checkers to be loaded instead of other code
that shouldn't have to worry about it.





Modified:
    lldb/trunk/include/lldb/API/SBError.h
    lldb/trunk/include/lldb/API/SBFileSpec.h
    lldb/trunk/include/lldb/API/SBProcess.h
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Target/DynamicLoader.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/lldb-defines.h
    lldb/trunk/source/API/SBError.cpp
    lldb/trunk/source/API/SBProcess.cpp
    lldb/trunk/source/Commands/CommandObjectExpression.cpp
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
    lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/API/SBError.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBError.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBError.h (original)
+++ lldb/trunk/include/lldb/API/SBError.h Wed Nov  3 20:54:29 2010
@@ -92,6 +92,9 @@
     const lldb_private::Error &
     operator*() const;
 
+    lldb_private::Error &
+    ref();
+
 #endif
 
 

Modified: lldb/trunk/include/lldb/API/SBFileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBFileSpec.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBFileSpec.h (original)
+++ lldb/trunk/include/lldb/API/SBFileSpec.h Wed Nov  3 20:54:29 2010
@@ -62,6 +62,7 @@
     friend class SBHostOS;
     friend class SBLineEntry;
     friend class SBModule;
+    friend class SBProcess;
     friend class SBSourceManager;
     friend class SBThread;
     friend class SBTarget;

Modified: lldb/trunk/include/lldb/API/SBProcess.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBProcess.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBProcess.h (original)
+++ lldb/trunk/include/lldb/API/SBProcess.h Wed Nov  3 20:54:29 2010
@@ -103,40 +103,40 @@
     uint32_t
     GetAddressByteSize() const;
 
-    SBError
+    lldb::SBError
     Destroy ();
 
     lldb::pid_t
     AttachByPID (lldb::pid_t pid);  // DEPRECATED
 
-    // DEPRECATED: relocated to "SBProcess SBTarget::AttachToProcess (lldb::pid_t pid, SBError& error)"
-    SBError
+    // DEPRECATED: relocated to "SBProcess SBTarget::AttachToProcess (lldb::pid_t pid, lldb::SBError& error)"
+    lldb::SBError
     Attach (lldb::pid_t pid);
 
-    // DEPRECATED: relocated to "SBProcess SBTarget::AttachToProcess (const char *name, bool wait_for_launch, SBError& error)"
-    SBError
+    // DEPRECATED: relocated to "SBProcess SBTarget::AttachToProcess (const char *name, bool wait_for_launch, lldb::SBError& error)"
+    lldb::SBError
     AttachByName (const char *name, bool wait_for_launch);
 
-    SBError
+    lldb::SBError
     Continue ();
 
-    SBError
+    lldb::SBError
     Stop ();
 
-    SBError
+    lldb::SBError
     Kill ();
 
-    SBError
+    lldb::SBError
     Detach ();
 
-    SBError
+    lldb::SBError
     Signal (int signal);
 
     size_t
-    ReadMemory (addr_t addr, void *buf, size_t size, SBError &error);
+    ReadMemory (addr_t addr, void *buf, size_t size, lldb::SBError &error);
 
     size_t
-    WriteMemory (addr_t addr, const void *buf, size_t size, SBError &error);
+    WriteMemory (addr_t addr, const void *buf, size_t size, lldb::SBError &error);
 
     // Events
     static lldb::StateType
@@ -154,6 +154,12 @@
     bool
     GetDescription (lldb::SBStream &description);
 
+    uint32_t
+    LoadImage (lldb::SBFileSpec &image_spec, lldb::SBError &error);
+    
+    lldb::SBError
+    UnloadImage (uint32_t image_token);
+
 protected:
     friend class SBAddress;
     friend class SBBreakpoint;

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Wed Nov  3 20:54:29 2010
@@ -147,6 +147,9 @@
     Value &
     GetValue();
 
+    bool
+    ResolveValue (ExecutionContextScope *exe_scope, Scalar &scalar);
+
     const char *
     GetLocationAsCString (ExecutionContextScope *exe_scope);
 

Modified: lldb/trunk/include/lldb/Target/DynamicLoader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/DynamicLoader.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/DynamicLoader.h (original)
+++ lldb/trunk/include/lldb/Target/DynamicLoader.h Wed Nov  3 20:54:29 2010
@@ -12,6 +12,7 @@
 
 // Project includes
 #include "lldb/lldb-private.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Core/PluginInterface.h"
 
 namespace lldb_private {
@@ -138,6 +139,23 @@
     virtual lldb::ThreadPlanSP
     GetStepThroughTrampolinePlan (Thread &thread, bool stop_others) = 0;
 
+
+    //------------------------------------------------------------------
+    /// Ask if it is ok to try and load or unload an shared library 
+    /// (image).
+    ///
+    /// The dynamic loader often knows when it would be ok to try and
+    /// load or unload a shared library. This function call allows the
+    /// dynamic loader plug-ins to check any current dyld state to make
+    /// sure it is an ok time to load a shared library.
+    ///
+    /// @return
+    ///     \b True if it is currently ok to try and load a shared 
+    ///     library into the process, \b false otherwise.
+    //------------------------------------------------------------------
+    virtual Error
+    CanLoadImage () = 0;
+
 protected:
     //------------------------------------------------------------------
     // Member variables.

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Wed Nov  3 20:54:29 2010
@@ -615,6 +615,33 @@
     GetImageInfoAddress ();
 
     //------------------------------------------------------------------
+    /// Load a shared library into this process.
+    ///
+    /// Try and load a shared library into the current process. This
+    /// call might fail in the dynamic loader plug-in says it isn't safe
+    /// to try and load shared libraries at the moment.
+    ///
+    /// @param[in] image_spec
+    ///     The image file spec that points to the shared library that
+    ///     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.
+    //------------------------------------------------------------------
+    virtual uint32_t
+    LoadImage (const FileSpec &image_spec, Error &error);
+
+    virtual Error
+    UnloadImage (uint32_t image_token);
+
+    //------------------------------------------------------------------
     /// Register for process and thread notifications.
     ///
     /// Clients can register nofication callbacks by filling out a
@@ -1642,6 +1669,7 @@
     std::string                 m_exit_string;          ///< A textual description of why a process exited.
     ThreadList                  m_thread_list;          ///< The threads for this process.
     std::vector<Notifications>  m_notifications;        ///< The list of notifications that this process can deliver.
+    std::vector<lldb::addr_t>   m_image_tokens;
     Listener                    &m_listener;
     BreakpointSiteList          m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend
                                                         ///< to insert in the target.

Modified: lldb/trunk/include/lldb/lldb-defines.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-defines.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-defines.h (original)
+++ lldb/trunk/include/lldb/lldb-defines.h Wed Nov  3 20:54:29 2010
@@ -55,6 +55,7 @@
 //----------------------------------------------------------------------
 #define LLDB_INVALID_ADDRESS            UINT64_MAX
 #define LLDB_INVALID_INDEX32            UINT32_MAX
+#define LLDB_INVALID_IMAGE_TOKEN        UINT32_MAX
 #define LLDB_INVALID_REGNUM             UINT32_MAX
 #define LLDB_INVALID_UID                UINT32_MAX
 #define LLDB_INVALID_PROCESS_ID         0

Modified: lldb/trunk/source/API/SBError.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBError.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/API/SBError.cpp (original)
+++ lldb/trunk/source/API/SBError.cpp Wed Nov  3 20:54:29 2010
@@ -199,6 +199,12 @@
     return m_opaque_ap.get();
 }
 
+lldb_private::Error &
+SBError::ref()
+{
+    CreateIfNeeded();
+    return *m_opaque_ap;
+}
 
 const lldb_private::Error &
 SBError::operator*() const

Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Wed Nov  3 20:54:29 2010
@@ -703,3 +703,24 @@
 
     return true;
 }
+
+uint32_t
+SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error)
+{
+    if (m_opaque_sp)
+        m_opaque_sp->LoadImage (*sb_image_spec, sb_error.ref());
+    return LLDB_INVALID_IMAGE_TOKEN;
+}
+    
+lldb::SBError
+SBProcess::UnloadImage (uint32_t image_token)
+{
+    lldb::SBError sb_error;
+    if (m_opaque_sp)
+        sb_error.SetError (m_opaque_sp->UnloadImage (image_token));
+    else
+        sb_error.SetErrorString("invalid process");
+    return sb_error;
+}
+
+

Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Wed Nov  3 20:54:29 2010
@@ -218,21 +218,6 @@
         return false;
     }
     
-    if (!m_exe_ctx.process->GetDynamicCheckers())
-    {
-        DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
-        
-        StreamString install_errors;
-        
-        if (!dynamic_checkers->Install(install_errors, m_exe_ctx))
-        {
-            error_stream.Printf("Couldn't install dynamic checkers into the execution context: %s\n", install_errors.GetData());
-            return false;
-        }
-        
-        m_exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
-    }
-    
     const char *prefix = NULL;
     
     if (m_exe_ctx.target)

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Wed Nov  3 20:54:29 2010
@@ -853,6 +853,128 @@
 };
 
 //-------------------------------------------------------------------------
+// CommandObjectProcessLoad
+//-------------------------------------------------------------------------
+
+class CommandObjectProcessLoad : public CommandObject
+{
+public:
+
+    CommandObjectProcessLoad (CommandInterpreter &interpreter) :
+        CommandObject (interpreter,
+                       "process load",
+                       "Load a shared library into the current process.",
+                       "process load <filename> [<filename> ...]",
+                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+    {
+    }
+
+    ~CommandObjectProcessLoad ()
+    {
+    }
+
+    bool
+    Execute (Args& command,
+             CommandReturnObject &result)
+    {
+        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError ("must have a valid process in order to load a shared library");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        const uint32_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);
+            uint32_t image_token = process->LoadImage(image_spec, error);
+            if (image_token != LLDB_INVALID_IMAGE_TOKEN)
+            {
+                result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token);  
+                result.SetStatus (eReturnStatusSuccessFinishResult);
+            }
+            else
+            {
+                result.AppendErrorWithFormat ("failed to load '%s': %s", image_path, error.AsCString());
+                result.SetStatus (eReturnStatusFailed);
+            }
+        }
+        return result.Succeeded();
+    }
+};
+
+
+//-------------------------------------------------------------------------
+// CommandObjectProcessUnload
+//-------------------------------------------------------------------------
+
+class CommandObjectProcessUnload : public CommandObject
+{
+public:
+
+    CommandObjectProcessUnload (CommandInterpreter &interpreter) :
+        CommandObject (interpreter,
+                       "process unload",
+                       "Unload a shared library from the current process using the index returned by a previous call to \"process load\".",
+                       "process unload <index>",
+                       eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
+    {
+    }
+
+    ~CommandObjectProcessUnload ()
+    {
+    }
+
+    bool
+    Execute (Args& command,
+             CommandReturnObject &result)
+    {
+        Process *process = m_interpreter.GetDebugger().GetExecutionContext().process;
+        if (process == NULL)
+        {
+            result.AppendError ("must have a valid process in order to load a shared library");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+        const uint32_t argc = command.GetArgumentCount();
+        
+        for (uint32_t i=0; i<argc; ++i)
+        {
+            const char *image_token_cstr = command.GetArgumentAtIndex(i);
+            uint32_t image_token = Args::StringToUInt32(image_token_cstr, LLDB_INVALID_IMAGE_TOKEN, 0);
+            if (image_token == LLDB_INVALID_IMAGE_TOKEN)
+            {
+                result.AppendErrorWithFormat ("invalid image index argument '%s'", image_token_cstr);
+                result.SetStatus (eReturnStatusFailed);
+                break;
+            }
+            else
+            {
+                Error error (process->UnloadImage(image_token));
+                if (error.Success())
+                {
+                    result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token);  
+                    result.SetStatus (eReturnStatusSuccessFinishResult);
+                }
+                else
+                {
+                    result.AppendErrorWithFormat ("failed to unload image: %s", error.AsCString());
+                    result.SetStatus (eReturnStatusFailed);
+                    break;
+                }
+            }
+        }
+        return result.Succeeded();
+    }
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectProcessSignal
 //-------------------------------------------------------------------------
 
@@ -1450,6 +1572,8 @@
     LoadSubCommand ("launch",      CommandObjectSP (new CommandObjectProcessLaunch (interpreter)));
     LoadSubCommand ("continue",    CommandObjectSP (new CommandObjectProcessContinue (interpreter)));
     LoadSubCommand ("detach",      CommandObjectSP (new CommandObjectProcessDetach (interpreter)));
+    LoadSubCommand ("load",        CommandObjectSP (new CommandObjectProcessLoad (interpreter)));
+    LoadSubCommand ("unload",      CommandObjectSP (new CommandObjectProcessUnload (interpreter)));
     LoadSubCommand ("signal",      CommandObjectSP (new CommandObjectProcessSignal (interpreter)));
     LoadSubCommand ("handle",      CommandObjectSP (new CommandObjectProcessHandle (interpreter)));
     LoadSubCommand ("status",      CommandObjectSP (new CommandObjectProcessStatus (interpreter)));

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Wed Nov  3 20:54:29 2010
@@ -222,6 +222,15 @@
 }
 
 bool
+ValueObject::ResolveValue (ExecutionContextScope *exe_scope, Scalar &scalar)
+{
+    ExecutionContext exe_ctx;
+    exe_scope->CalculateExecutionContext(exe_ctx);
+    scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
+    return scalar.IsValid();
+}
+
+bool
 ValueObject::GetValueIsValid () const
 {
     return m_value_is_valid;

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Wed Nov  3 20:54:29 2010
@@ -30,6 +30,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
 
@@ -437,6 +438,22 @@
 {
     Error error;
     lldb::ValueObjectSP result_valobj_sp;
+    
+    if (exe_ctx.process == NULL)
+        return result_valobj_sp;
+
+    if (!exe_ctx.process->GetDynamicCheckers())
+    {
+        DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
+        
+        StreamString install_errors;
+        
+        if (!dynamic_checkers->Install(install_errors, exe_ctx))
+            return result_valobj_sp;
+        
+        exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
+    }
+    
     ClangUserExpression user_expression (expr_cstr, expr_prefix);
     
     StreamString error_stream;

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Wed Nov  3 20:54:29 2010
@@ -1167,6 +1167,26 @@
     return thread_plan_sp;
 }
 
+Error
+DynamicLoaderMacOSXDYLD::CanLoadImage ()
+{
+    Error error;
+    // In order for us to tell if we can load a shared library we verify that
+    // the dylib_info_addr isn't zero (which means no shared libraries have
+    // been set yet, or dyld is currently mucking with the shared library list).
+    if (ReadAllImageInfosStructure ())
+    {
+        // TODO: also check the _dyld_global_lock_held variable in libSystem.B.dylib?
+        // TODO: check the malloc lock?
+        // TODO: check the objective C lock?
+        if (m_dyld_all_image_infos.dylib_info_addr != 0)
+            return error; // Success
+    }
+
+    error.SetErrorString("unsafe to load or unload shared libraries");
+    return error;
+}
+
 void
 DynamicLoaderMacOSXDYLD::Initialize()
 {

Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Wed Nov  3 20:54:29 2010
@@ -78,6 +78,8 @@
     GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
                                   bool stop_others);
 
+    virtual lldb_private::Error
+    CanLoadImage ();
 
     //------------------------------------------------------------------
     // PluginInterface protocol

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=118227&r1=118226&r2=118227&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Nov  3 20:54:29 2010
@@ -21,6 +21,7 @@
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Target/ABI.h"
+#include "lldb/Target/DynamicLoader.h"
 #include "lldb/Target/LanguageRuntime.h"
 #include "lldb/Target/CPPLanguageRuntime.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
@@ -471,6 +472,141 @@
     return LLDB_INVALID_ADDRESS;
 }
 
+//----------------------------------------------------------------------
+// LoadImage
+//
+// This function provides a default implementation that works for most
+// unix variants. Any Process subclasses that need to do shared library
+// loading differently should override LoadImage and UnloadImage and
+// do what is needed.
+//----------------------------------------------------------------------
+uint32_t
+Process::LoadImage (const FileSpec &image_spec, Error &error)
+{
+    DynamicLoader *loader = GetDynamicLoader();
+    if (loader)
+    {
+        error = loader->CanLoadImage();
+        if (error.Fail())
+            return LLDB_INVALID_IMAGE_TOKEN;
+    }
+    
+    if (error.Success())
+    {
+        ThreadSP thread_sp(GetThreadList ().GetSelectedThread());
+        if (thread_sp == NULL)
+            thread_sp = GetThreadList ().GetThreadAtIndex(0, true);
+        
+        if (thread_sp)
+        {
+            StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex (0));
+            
+            if (frame_sp)
+            {
+                ExecutionContext exe_ctx;
+                frame_sp->CalculateExecutionContext (exe_ctx);
+    
+                StreamString expr;
+                char path[PATH_MAX];
+                image_spec.GetPath(path, sizeof(path));
+                expr.Printf("dlopen (\"%s\", 2)", path);
+                const char *prefix = "extern \"C\" void* dlopen (const char *path, int mode);\n";
+                lldb::ValueObjectSP result_valobj_sp (ClangUserExpression::Evaluate (exe_ctx, expr.GetData(), prefix));
+                if (result_valobj_sp->GetError().Success())
+                {
+                    Scalar scalar;
+                    if (result_valobj_sp->ResolveValue (frame_sp.get(), scalar))
+                    {
+                        addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
+                        if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS)
+                        {
+                            uint32_t image_token = m_image_tokens.size();
+                            m_image_tokens.push_back (image_ptr);
+                            return image_token;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return LLDB_INVALID_IMAGE_TOKEN;
+}
+
+//----------------------------------------------------------------------
+// UnloadImage
+//
+// This function provides a default implementation that works for most
+// unix variants. Any Process subclasses that need to do shared library
+// loading differently should override LoadImage and UnloadImage and
+// do what is needed.
+//----------------------------------------------------------------------
+Error
+Process::UnloadImage (uint32_t image_token)
+{
+    Error error;
+    if (image_token < m_image_tokens.size())
+    {
+        const addr_t image_addr = m_image_tokens[image_token];
+        if (image_addr == LLDB_INVALID_ADDRESS)
+        {
+            error.SetErrorString("image already unloaded");
+        }
+        else
+        {
+            DynamicLoader *loader = GetDynamicLoader();
+            if (loader)
+                error = loader->CanLoadImage();
+            
+            if (error.Success())
+            {
+                ThreadSP thread_sp(GetThreadList ().GetSelectedThread());
+                if (thread_sp == NULL)
+                    thread_sp = GetThreadList ().GetThreadAtIndex(0, true);
+                
+                if (thread_sp)
+                {
+                    StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex (0));
+                    
+                    if (frame_sp)
+                    {
+                        ExecutionContext exe_ctx;
+                        frame_sp->CalculateExecutionContext (exe_ctx);
+            
+                        StreamString expr;
+                        expr.Printf("dlclose ((void *)0x%llx)", image_addr);
+                        const char *prefix = "extern \"C\" int dlclose(void* handle);\n";
+                        lldb::ValueObjectSP result_valobj_sp (ClangUserExpression::Evaluate (exe_ctx, expr.GetData(), prefix));
+                        if (result_valobj_sp->GetError().Success())
+                        {
+                            Scalar scalar;
+                            if (result_valobj_sp->ResolveValue (frame_sp.get(), scalar))
+                            {
+                                if (scalar.UInt(1))
+                                {
+                                    error.SetErrorStringWithFormat("expression failed: \"%s\"", expr.GetData());
+                                }
+                                else
+                                {
+                                    m_image_tokens[image_token] = LLDB_INVALID_ADDRESS;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            error = result_valobj_sp->GetError();
+                        }
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        error.SetErrorString("invalid image token");
+    }
+    return error;
+}
+
 DynamicLoader *
 Process::GetDynamicLoader()
 {





More information about the lldb-commits mailing list