Index: lldb/trunk/include/lldb/Target/Platform.h =================================================================== --- lldb/trunk/include/lldb/Target/Platform.h +++ lldb/trunk/include/lldb/Target/Platform.h @@ -987,9 +987,41 @@ virtual uint32_t GetDefaultMemoryCacheLineSize() { return 0; } + //------------------------------------------------------------------ + /// 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] process + /// The process to load the image. + /// + /// @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 (lldb_private::Process* process, + const lldb_private::FileSpec& image_spec, + lldb_private::Error& error); + + virtual Error + UnloadImage (lldb_private::Process* process, uint32_t image_token); + protected: bool m_is_host; - // Set to true when we are able to actually set the OS version while + // Set to true when we are able to actually set the OS version while // being connected. For remote platforms, we might set the version ahead // of time before we actually connect and this version might change when // we actually connect to a remote platform. For the host platform this Index: lldb/trunk/include/lldb/Target/Process.h =================================================================== --- lldb/trunk/include/lldb/Target/Process.h +++ lldb/trunk/include/lldb/Target/Process.h @@ -1235,33 +1235,6 @@ 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); - - //------------------------------------------------------------------ /// Called when the process is about to broadcast a public stop. /// /// There are public and private stops. Private stops are when the @@ -3160,6 +3133,15 @@ return Error("Not supported"); } + size_t + AddImageToken(lldb::addr_t image_ptr); + + lldb::addr_t + GetImagePtrFromToken(size_t token) const; + + void + ResetImageToken(size_t token); + protected: void SetState (lldb::EventSP &event_sp); Index: lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py @@ -182,7 +182,6 @@ @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support @skipUnlessListedRemote(['android']) - @expectedFailureAndroid # dlopen and dlclose prefixed with "__dl_" on android causing JIT compilation issues @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently def test_lldb_process_load_and_unload_commands(self): """Test that lldb process load/unload command work correctly.""" @@ -205,21 +204,24 @@ shlib_dir = lldb.remote_platform.GetWorkingDirectory() else: shlib_dir = self.mydir - # Make sure that a_function does not exist at this point. - self.expect("image lookup -n a_function", "a_function should not exist yet", - error=True, matching=False, - patterns = ["1 match found .* %s" % shlib_dir]) - if lldb.remote_platform: - dylibName = os.path.join(shlib_dir, 'libloadunload_a.so') - elif self.platformIsDarwin(): + if self.platformIsDarwin(): dylibName = 'libloadunload_a.dylib' else: dylibName = 'libloadunload_a.so' + if lldb.remote_platform: + dylibPath = os.path.join(shlib_dir, dylibName) + else: + dylibPath = dylibName + + # Make sure that a_function does not exist at this point. + self.expect("image lookup -n a_function", "a_function should not exist yet", + error=True, matching=False, patterns = ["1 match found"]) + # Use lldb 'process load' to load the dylib. - self.expect("process load %s" % dylibName, "%s loaded correctly" % dylibName, - patterns = ['Loading "%s".*ok' % dylibName, + self.expect("process load %s" % dylibPath, "%s loaded correctly" % dylibPath, + patterns = ['Loading "%s".*ok' % dylibPath, 'Image [0-9]+ loaded']) # Search for and match the "Image ([0-9]+) loaded" pattern. @@ -234,7 +236,7 @@ # Now we should have an entry for a_function. self.expect("image lookup -n a_function", "a_function should now exist", - patterns = ["1 match found .*%s" % shlib_dir]) + patterns = ["1 match found .*%s" % dylibName]) # Use lldb 'process unload' to unload the dylib. self.expect("process unload %s" % index, "%s unloaded correctly" % dylibName, Index: lldb/trunk/source/API/SBProcess.cpp =================================================================== --- lldb/trunk/source/API/SBProcess.cpp +++ lldb/trunk/source/API/SBProcess.cpp @@ -1297,7 +1297,8 @@ if (stop_locker.TryLock(&process_sp->GetRunLock())) { Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - return process_sp->LoadImage (*sb_image_spec, sb_error.ref()); + PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); + return platform_sp->LoadImage (process_sp.get(), *sb_image_spec, sb_error.ref()); } else { @@ -1322,7 +1323,8 @@ if (stop_locker.TryLock(&process_sp->GetRunLock())) { Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); - sb_error.SetError (process_sp->UnloadImage (image_token)); + PlatformSP platform_sp = process_sp->GetTarget().GetPlatform(); + sb_error.SetError (platform_sp->UnloadImage (process_sp.get(), image_token)); } else { Index: lldb/trunk/source/Commands/CommandObjectProcess.cpp =================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp @@ -1204,8 +1204,9 @@ Error error; const char *image_path = command.GetArgumentAtIndex(i); FileSpec image_spec (image_path, false); - process->GetTarget().GetPlatform()->ResolveRemotePath(image_spec, image_spec); - uint32_t image_token = process->LoadImage(image_spec, error); + PlatformSP platform = process->GetTarget().GetPlatform(); + platform->ResolveRemotePath(image_spec, image_spec); + uint32_t image_token = platform->LoadImage(process, image_spec, error); if (image_token != LLDB_INVALID_IMAGE_TOKEN) { result.AppendMessageWithFormat ("Loading \"%s\"...ok\nImage %u loaded.\n", image_path, image_token); @@ -1267,7 +1268,7 @@ } else { - Error error (process->UnloadImage(image_token)); + Error error (process->GetTarget().GetPlatform()->UnloadImage(process, image_token)); if (error.Success()) { result.AppendMessageWithFormat ("Unloading shared library with index %u...ok\n", image_token); Index: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h +++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h @@ -84,6 +84,14 @@ uint32_t GetDefaultMemoryCacheLineSize() override; + uint32_t + LoadImage (lldb_private::Process* process, + const lldb_private::FileSpec& image_spec, + lldb_private::Error& error) override; + + lldb_private::Error + UnloadImage (lldb_private::Process* process, uint32_t image_token) override; + protected: const char * GetCacheHostname () override; Index: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -13,7 +13,9 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/StringConvert.h" #include "Utility/UriParser.h" @@ -374,3 +376,91 @@ m_update_os_version = 0; return m_major_os_version != 0; } + +uint32_t +PlatformAndroid::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error) +{ + char path[PATH_MAX]; + image_spec.GetPath(path, sizeof(path)); + + StreamString expr; + expr.Printf(R"( + struct __lldb_dlopen_result { void *image_ptr; const char *error_str; } the_result; + the_result.image_ptr = __dl_dlopen ("%s", 2); + if (the_result.image_ptr == (void*)0x0) + the_result.error_str = __dl_dlerror(); + else + the_result.error_str = (const char*)0x0; + the_result; + )", + path); + const char *prefix = R"( + extern "C" void* __dl_dlopen(const char* path, int mode); + extern "C" const char *__dl_dlerror(void); + )"; + lldb::ValueObjectSP result_valobj_sp; + error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp); + if (error.Fail()) + return LLDB_INVALID_IMAGE_TOKEN; + + error = result_valobj_sp->GetError(); + if (error.Fail()) + return LLDB_INVALID_IMAGE_TOKEN; + + Scalar scalar; + ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true); + if (!image_ptr_sp || !image_ptr_sp->ResolveValue(scalar)) + { + error.SetErrorStringWithFormat("unable to load '%s'", path); + return LLDB_INVALID_IMAGE_TOKEN; + } + + addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS); + if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS) + return process->AddImageToken(image_ptr); + + if (image_ptr == 0) + { + ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true); + if (error_str_sp && error_str_sp->IsCStringContainer(true)) + { + DataBufferSP buffer_sp(new DataBufferHeap(10240,0)); + size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240).first; + if (error.Success() && num_chars > 0) + error.SetErrorStringWithFormat("dlopen error: %s", buffer_sp->GetBytes()); + else + error.SetErrorStringWithFormat("dlopen failed for unknown reasons."); + return LLDB_INVALID_IMAGE_TOKEN; + } + } + error.SetErrorStringWithFormat("unable to load '%s'", path); + return LLDB_INVALID_IMAGE_TOKEN; +} + +Error +PlatformAndroid::UnloadImage (lldb_private::Process* process, uint32_t image_token) +{ + const addr_t image_addr = process->GetImagePtrFromToken(image_token); + if (image_addr == LLDB_INVALID_ADDRESS) + return Error("Invalid image token"); + + StreamString expr; + expr.Printf("__dl_dlclose((void*)0x%" PRIx64 ")", image_addr); + const char *prefix = "extern \"C\" int __dl_dlclose(void* handle);\n"; + lldb::ValueObjectSP result_valobj_sp; + Error error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp); + if (error.Fail()) + return error; + + if (result_valobj_sp->GetError().Fail()) + return result_valobj_sp->GetError(); + + Scalar scalar; + if (result_valobj_sp->ResolveValue(scalar)) + { + if (scalar.UInt(1)) + return Error("expression failed: \"%s\"", expr.GetData()); + process->ResetImageToken(image_token); + } + return Error(); +} Index: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -173,11 +173,24 @@ lldb_private::Error DisconnectRemote () override; + uint32_t + LoadImage (lldb_private::Process* process, + const lldb_private::FileSpec& image_spec, + lldb_private::Error& error) override; + + lldb_private::Error + UnloadImage (lldb_private::Process* process, uint32_t image_token) override; + protected: std::unique_ptr m_options; - lldb::PlatformSP m_remote_platform_sp; // Allow multiple ways to connect to a remote POSIX-compliant OS - + + lldb_private::Error + EvaluateLibdlExpression(lldb_private::Process* process, + const char *expr_cstr, + const char *expr_prefix, + lldb::ValueObjectSP& result_valobj_sp); + private: DISALLOW_COPY_AND_ASSIGN (PlatformPOSIX); }; Index: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -19,13 +19,18 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Expression/UserExpression.h" #include "lldb/Host/File.h" #include "lldb/Host/FileCache.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Target/DynamicLoader.h" +#include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/ProcessLaunchInfo.h" +#include "lldb/Target/Thread.h" using namespace lldb; using namespace lldb_private; @@ -846,6 +851,140 @@ void PlatformPOSIX::CalculateTrapHandlerSymbolNames () -{ +{ m_trap_handlers.push_back (ConstString ("_sigtramp")); -} +} + +Error +PlatformPOSIX::EvaluateLibdlExpression(lldb_private::Process* process, + const char* expr_cstr, + const char* expr_prefix, + lldb::ValueObjectSP& result_valobj_sp) +{ + DynamicLoader *loader = process->GetDynamicLoader(); + if (loader) + { + Error error = loader->CanLoadImage(); + if (error.Fail()) + return error; + } + + ThreadSP thread_sp(process->GetThreadList().GetSelectedThread()); + if (!thread_sp) + return Error("Selected thread isn't valid"); + + StackFrameSP frame_sp(thread_sp->GetStackFrameAtIndex(0)); + if (!frame_sp) + return Error("Frame 0 isn't valid"); + + ExecutionContext exe_ctx; + frame_sp->CalculateExecutionContext(exe_ctx); + EvaluateExpressionOptions expr_options; + expr_options.SetUnwindOnError(true); + expr_options.SetIgnoreBreakpoints(true); + expr_options.SetExecutionPolicy(eExecutionPolicyAlways); + expr_options.SetLanguage(eLanguageTypeC_plus_plus); + + Error expr_error; + UserExpression::Evaluate(exe_ctx, + expr_options, + expr_cstr, + expr_prefix, + result_valobj_sp, + expr_error); + if (result_valobj_sp->GetError().Fail()) + return result_valobj_sp->GetError(); + return Error(); +} + +uint32_t +PlatformPOSIX::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error) +{ + char path[PATH_MAX]; + image_spec.GetPath(path, sizeof(path)); + + StreamString expr; + expr.Printf(R"( + struct __lldb_dlopen_result { void *image_ptr; const char *error_str; } the_result; + the_result.image_ptr = dlopen ("%s", 2); + if (the_result.image_ptr == (void *) 0x0) + { + the_result.error_str = dlerror(); + } + else + { + the_result.error_str = (const char *) 0x0; + } + the_result; + )", + path); + const char *prefix = R"( + extern "C" void* dlopen (const char *path, int mode); + extern "C" const char *dlerror (void); + )"; + lldb::ValueObjectSP result_valobj_sp; + error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp); + if (error.Fail()) + return LLDB_INVALID_IMAGE_TOKEN; + + error = result_valobj_sp->GetError(); + if (error.Fail()) + return LLDB_INVALID_IMAGE_TOKEN; + + Scalar scalar; + ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true); + if (!image_ptr_sp || !image_ptr_sp->ResolveValue(scalar)) + { + error.SetErrorStringWithFormat("unable to load '%s'", path); + return LLDB_INVALID_IMAGE_TOKEN; + } + + addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS); + if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS) + return process->AddImageToken(image_ptr); + + if (image_ptr == 0) + { + ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true); + if (error_str_sp && error_str_sp->IsCStringContainer(true)) + { + DataBufferSP buffer_sp(new DataBufferHeap(10240,0)); + size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240).first; + if (error.Success() && num_chars > 0) + error.SetErrorStringWithFormat("dlopen error: %s", buffer_sp->GetBytes()); + else + error.SetErrorStringWithFormat("dlopen failed for unknown reasons."); + return LLDB_INVALID_IMAGE_TOKEN; + } + } + error.SetErrorStringWithFormat("unable to load '%s'", path); + return LLDB_INVALID_IMAGE_TOKEN; +} + +Error +PlatformPOSIX::UnloadImage (lldb_private::Process* process, uint32_t image_token) +{ + const addr_t image_addr = process->GetImagePtrFromToken(image_token); + if (image_addr == LLDB_INVALID_ADDRESS) + return Error("Invalid image token"); + + StreamString expr; + expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr); + const char *prefix = "extern \"C\" int dlclose(void* handle);\n"; + lldb::ValueObjectSP result_valobj_sp; + Error error = EvaluateLibdlExpression(process, expr.GetData(), prefix, result_valobj_sp); + if (error.Fail()) + return error; + + if (result_valobj_sp->GetError().Fail()) + return result_valobj_sp->GetError(); + + Scalar scalar; + if (result_valobj_sp->ResolveValue(scalar)) + { + if (scalar.UInt(1)) + return Error("expression failed: \"%s\"", expr.GetData()); + process->ResetImageToken(image_token); + } + return Error(); +} Index: lldb/trunk/source/Target/Platform.cpp =================================================================== --- lldb/trunk/source/Target/Platform.cpp +++ lldb/trunk/source/Target/Platform.cpp @@ -1983,3 +1983,16 @@ return Host::GetUnixSignals(); return GetRemoteUnixSignals(); } + +uint32_t +Platform::LoadImage(lldb_private::Process* process, const FileSpec& image_spec, Error& error) +{ + error.SetErrorString("LoadImage is not supported on the current platform"); + return LLDB_INVALID_IMAGE_TOKEN; +} + +Error +Platform::UnloadImage(lldb_private::Process* process, uint32_t image_token) +{ + return Error("UnLoadImage is not supported on the current platform"); +} Index: lldb/trunk/source/Target/Process.cpp =================================================================== --- lldb/trunk/source/Target/Process.cpp +++ lldb/trunk/source/Target/Process.cpp @@ -1885,223 +1885,6 @@ 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) -{ - if (m_finalizing) - { - error.SetErrorString("process is tearing itself down"); - return LLDB_INVALID_IMAGE_TOKEN; - } - - char path[PATH_MAX]; - image_spec.GetPath(path, sizeof(path)); - - 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) - { - StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex (0)); - - if (frame_sp) - { - ExecutionContext exe_ctx; - frame_sp->CalculateExecutionContext (exe_ctx); - EvaluateExpressionOptions expr_options; - expr_options.SetUnwindOnError(true); - expr_options.SetIgnoreBreakpoints(true); - expr_options.SetExecutionPolicy(eExecutionPolicyAlways); - expr_options.SetResultIsInternal(true); - expr_options.SetLanguage(eLanguageTypeC_plus_plus); - - StreamString expr; - expr.Printf(R"( - struct __lldb_dlopen_result { void *image_ptr; const char *error_str; } the_result; - the_result.image_ptr = dlopen ("%s", 2); - if (the_result.image_ptr == (void *) 0x0) - { - the_result.error_str = dlerror(); - } - else - { - the_result.error_str = (const char *) 0x0; - } - the_result; - )", - path); - const char *prefix = R"( - extern "C" void* dlopen (const char *path, int mode); - extern "C" const char *dlerror (void); - )"; - lldb::ValueObjectSP result_valobj_sp; - Error expr_error; - UserExpression::Evaluate (exe_ctx, - expr_options, - expr.GetData(), - prefix, - result_valobj_sp, - expr_error); - if (expr_error.Success()) - { - error = result_valobj_sp->GetError(); - if (error.Success()) - { - Scalar scalar; - ValueObjectSP image_ptr_sp = result_valobj_sp->GetChildAtIndex(0, true); - if (image_ptr_sp && image_ptr_sp->ResolveValue (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; - } - else if (image_ptr == 0) - { - ValueObjectSP error_str_sp = result_valobj_sp->GetChildAtIndex(1, true); - if (error_str_sp) - { - if (error_str_sp->IsCStringContainer(true)) - { - DataBufferSP buffer_sp(new DataBufferHeap(10240,0)); - size_t num_chars = error_str_sp->ReadPointedString (buffer_sp, error, 10240).first; - if (error.Success() && num_chars > 0) - { - error.Clear(); - error.SetErrorStringWithFormat("dlopen error: %s", buffer_sp->GetBytes()); - } - else - { - error.Clear(); - error.SetErrorStringWithFormat("dlopen failed for unknown reasons."); - } - } - } - } - } - } - } - else - error = expr_error; - } - } - } - if (!error.AsCString()) - error.SetErrorStringWithFormat("unable to load '%s'", path); - 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 (m_finalizing) - { - error.SetErrorString("process is tearing itself down"); - return 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) - { - StackFrameSP frame_sp (thread_sp->GetStackFrameAtIndex (0)); - - if (frame_sp) - { - ExecutionContext exe_ctx; - frame_sp->CalculateExecutionContext (exe_ctx); - EvaluateExpressionOptions expr_options; - expr_options.SetUnwindOnError(true); - expr_options.SetIgnoreBreakpoints(true); - expr_options.SetExecutionPolicy(eExecutionPolicyAlways); - expr_options.SetLanguage(eLanguageTypeC_plus_plus); - - StreamString expr; - expr.Printf("dlclose ((void *)0x%" PRIx64 ")", image_addr); - const char *prefix = "extern \"C\" int dlclose(void* handle);\n"; - lldb::ValueObjectSP result_valobj_sp; - Error expr_error; - UserExpression::Evaluate (exe_ctx, - expr_options, - expr.GetData(), - prefix, - result_valobj_sp, - expr_error); - if (result_valobj_sp->GetError().Success()) - { - Scalar scalar; - if (result_valobj_sp->ResolveValue (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; -} - const lldb::ABISP & Process::GetABI() { @@ -6723,3 +6506,25 @@ module_spec.Clear(); return false; } + +size_t +Process::AddImageToken(lldb::addr_t image_ptr) +{ + m_image_tokens.push_back(image_ptr); + return m_image_tokens.size() - 1; +} + +lldb::addr_t +Process::GetImagePtrFromToken(size_t token) const +{ + if (token < m_image_tokens.size()) + return m_image_tokens[token]; + return LLDB_INVALID_IMAGE_TOKEN; +} + +void +Process::ResetImageToken(size_t token) +{ + if (token < m_image_tokens.size()) + m_image_tokens[token] = LLDB_INVALID_IMAGE_TOKEN; +} \ No newline at end of file