diff options
author | Greg Clayton <gclayton@apple.com> | 2010-11-04 01:54:29 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2010-11-04 01:54:29 +0000 |
commit | 8f343b09e946cce2ef79461b5a86d987f6a31748 (patch) | |
tree | 5e3d5709fe5b7468e9d24fa01ca2be63a81e5be5 /lldb/source/Target/Process.cpp | |
parent | 10af7c430a426ab649ac000152bc51c3601eb395 (diff) | |
download | bcm5719-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.cpp | 136 |
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() { |