summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Process.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2010-11-04 01:54:29 +0000
committerGreg Clayton <gclayton@apple.com>2010-11-04 01:54:29 +0000
commit8f343b09e946cce2ef79461b5a86d987f6a31748 (patch)
tree5e3d5709fe5b7468e9d24fa01ca2be63a81e5be5 /lldb/source/Target/Process.cpp
parent10af7c430a426ab649ac000152bc51c3601eb395 (diff)
downloadbcm5719-llvm-8f343b09e946cce2ef79461b5a86d987f6a31748.tar.gz
bcm5719-llvm-8f343b09e946cce2ef79461b5a86d987f6a31748.zip
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. llvm-svn: 118227
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