summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBError.h3
-rw-r--r--lldb/include/lldb/API/SBFileSpec.h1
-rw-r--r--lldb/include/lldb/API/SBProcess.h30
-rw-r--r--lldb/include/lldb/Core/ValueObject.h3
-rw-r--r--lldb/include/lldb/Target/DynamicLoader.h18
-rw-r--r--lldb/include/lldb/Target/Process.h28
-rw-r--r--lldb/include/lldb/lldb-defines.h1
-rw-r--r--lldb/source/API/SBError.cpp6
-rw-r--r--lldb/source/API/SBProcess.cpp21
-rw-r--r--lldb/source/Commands/CommandObjectExpression.cpp15
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp124
-rw-r--r--lldb/source/Core/ValueObject.cpp9
-rw-r--r--lldb/source/Expression/ClangUserExpression.cpp17
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp20
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h2
-rw-r--r--lldb/source/Target/Process.cpp136
16 files changed, 407 insertions, 27 deletions
diff --git a/lldb/include/lldb/API/SBError.h b/lldb/include/lldb/API/SBError.h
index 21f4e483d32..44b58ae0545 100644
--- a/lldb/include/lldb/API/SBError.h
+++ b/lldb/include/lldb/API/SBError.h
@@ -92,6 +92,9 @@ protected:
const lldb_private::Error &
operator*() const;
+ lldb_private::Error &
+ ref();
+
#endif
diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h
index 049ca902550..ed6613ad005 100644
--- a/lldb/include/lldb/API/SBFileSpec.h
+++ b/lldb/include/lldb/API/SBFileSpec.h
@@ -62,6 +62,7 @@ private:
friend class SBHostOS;
friend class SBLineEntry;
friend class SBModule;
+ friend class SBProcess;
friend class SBSourceManager;
friend class SBThread;
friend class SBTarget;
diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index ad612b92923..c7c67953864 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -103,40 +103,40 @@ public:
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 @@ public:
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;
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index 8b1ba1c3878..aaff85e876a 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -147,6 +147,9 @@ public:
Value &
GetValue();
+ bool
+ ResolveValue (ExecutionContextScope *exe_scope, Scalar &scalar);
+
const char *
GetLocationAsCString (ExecutionContextScope *exe_scope);
diff --git a/lldb/include/lldb/Target/DynamicLoader.h b/lldb/include/lldb/Target/DynamicLoader.h
index bed96785972..af125677274 100644
--- a/lldb/include/lldb/Target/DynamicLoader.h
+++ b/lldb/include/lldb/Target/DynamicLoader.h
@@ -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 @@ public:
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.
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 51fb04bfdd0..82a87aa4947 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -615,6 +615,33 @@ public:
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 @@ protected:
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.
diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index e927a9d48ce..38a689ce806 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -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
diff --git a/lldb/source/API/SBError.cpp b/lldb/source/API/SBError.cpp
index 935a869e57b..2e01cfa8ccf 100644
--- a/lldb/source/API/SBError.cpp
+++ b/lldb/source/API/SBError.cpp
@@ -199,6 +199,12 @@ SBError::get()
return m_opaque_ap.get();
}
+lldb_private::Error &
+SBError::ref()
+{
+ CreateIfNeeded();
+ return *m_opaque_ap;
+}
const lldb_private::Error &
SBError::operator*() const
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index 9ea9f754abc..0c52b6b15d1 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -703,3 +703,24 @@ SBProcess::GetDescription (SBStream &description)
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;
+}
+
+
diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp
index 7f7c780978a..2045c59d058 100644
--- a/lldb/source/Commands/CommandObjectExpression.cpp
+++ b/lldb/source/Commands/CommandObjectExpression.cpp
@@ -218,21 +218,6 @@ CommandObjectExpression::EvaluateExpression
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)
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 8c4ffdd96bb..88fdca3086b 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -853,6 +853,128 @@ public:
};
//-------------------------------------------------------------------------
+// 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 @@ CommandObjectMultiwordProcess::CommandObjectMultiwordProcess (CommandInterpreter
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)));
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 2efd4432d58..a3da90d9c3a 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -222,6 +222,15 @@ ValueObject::GetValue() const
}
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;
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp
index dc93d8e6971..5181c98c9aa 100644
--- a/lldb/source/Expression/ClangUserExpression.cpp
+++ b/lldb/source/Expression/ClangUserExpression.cpp
@@ -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 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
{
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;
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index fa46c77553a..bdfc47c48ff 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -1167,6 +1167,26 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop
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()
{
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
index 8f22dbdcb63..34ea8a46781 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
@@ -78,6 +78,8 @@ public:
GetStepThroughTrampolinePlan (lldb_private::Thread &thread,
bool stop_others);
+ virtual lldb_private::Error
+ CanLoadImage ();
//------------------------------------------------------------------
// PluginInterface protocol
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index d71626790bf..fa7ac71c89e 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -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 @@ Process::GetImageInfoAddress()
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()
{
OpenPOWER on IntegriCloud