summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r--lldb/source/Target/Process.cpp136
1 files changed, 136 insertions, 0 deletions
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