[Lldb-commits] [lldb] r254504 - Fix "process load/unload" on android

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 2 03:58:52 PST 2015


Author: tberghammer
Date: Wed Dec  2 05:58:51 2015
New Revision: 254504

URL: http://llvm.org/viewvc/llvm-project?rev=254504&view=rev
Log:
Fix "process load/unload" on android

On android the symbols exposed by libdl (dlopen, dlclose, dlerror)
prefixed by "__dl_". This change moves the handling of process
load/unload to the platform object and override it for android to
handle the special prefix.

Differential revision: http://reviews.llvm.org/D11465

Modified:
    lldb/trunk/include/lldb/Target/Platform.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
    lldb/trunk/source/API/SBProcess.cpp
    lldb/trunk/source/Commands/CommandObjectProcess.cpp
    lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp
    lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Target/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Platform.h?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Platform.h (original)
+++ lldb/trunk/include/lldb/Target/Platform.h Wed Dec  2 05:58:51 2015
@@ -987,9 +987,41 @@ class ModuleCache;
         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

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Wed Dec  2 05:58:51 2015
@@ -1235,33 +1235,6 @@ 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);
-
-    //------------------------------------------------------------------
     /// 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 @@ public:
         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);

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py Wed Dec  2 05:58:51 2015
@@ -182,7 +182,6 @@ class LoadUnloadTestCase(TestBase):
 
     @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 @@ class LoadUnloadTestCase(TestBase):
             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 @@ class LoadUnloadTestCase(TestBase):
 
         # 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,

Modified: lldb/trunk/source/API/SBProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBProcess.cpp?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/API/SBProcess.cpp (original)
+++ lldb/trunk/source/API/SBProcess.cpp Wed Dec  2 05:58:51 2015
@@ -1297,7 +1297,8 @@ SBProcess::LoadImage (lldb::SBFileSpec &
         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 @@ SBProcess::UnloadImage (uint32_t image_t
         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
         {

Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Wed Dec  2 05:58:51 2015
@@ -1204,8 +1204,9 @@ protected:
             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 @@ protected:
             }
             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);  

Modified: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.cpp Wed Dec  2 05:58:51 2015
@@ -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 @@ PlatformAndroid::GetRemoteOSVersion ()
     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();
+}

Modified: lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h (original)
+++ lldb/trunk/source/Plugins/Platform/Android/PlatformAndroid.h Wed Dec  2 05:58:51 2015
@@ -84,6 +84,14 @@ namespace platform_android {
         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;

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp Wed Dec  2 05:58:51 2015
@@ -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 @@ PlatformPOSIX::DebugProcess (ProcessLaun
 
 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();
+}

Modified: lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h (original)
+++ lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.h Wed Dec  2 05:58:51 2015
@@ -173,11 +173,24 @@ public:
     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<lldb_private::OptionGroupOptions> 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);
 };

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Wed Dec  2 05:58:51 2015
@@ -1983,3 +1983,16 @@ Platform::GetUnixSignals()
         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");
+}

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=254504&r1=254503&r2=254504&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Wed Dec  2 05:58:51 2015
@@ -1885,223 +1885,6 @@ 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)
-{
-    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 @@ Process::GetModuleSpec(const FileSpec& m
     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




More information about the lldb-commits mailing list