[Lldb-commits] [lldb] r276411 - Support loading files even when incorrect file name specified by the linker

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Fri Jul 22 05:55:35 PDT 2016


Author: tberghammer
Date: Fri Jul 22 07:55:35 2016
New Revision: 276411

URL: http://llvm.org/viewvc/llvm-project?rev=276411&view=rev
Log:
Support loading files even when incorrect file name specified by the linker

"Incorrect" file name seen on Android whene the main executable is
called "app_process32" (or 64) but the linker specifies the package
name (e.g. com.android.calculator2). Additionally it can be present
in case of some linker bugs.

This CL adds logic to try to fetch the correct file name from the proc
file system based on the base address sepcified by the linker in case
we are failed to load the module by name.

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

Modified:
    lldb/trunk/docs/lldb-gdb-remote.txt
    lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h
    lldb/trunk/include/lldb/Target/MemoryRegionInfo.h
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
    lldb/trunk/source/API/SBMemoryRegionInfo.cpp
    lldb/trunk/source/Core/DynamicLoader.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp

Modified: lldb/trunk/docs/lldb-gdb-remote.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/docs/lldb-gdb-remote.txt?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/docs/lldb-gdb-remote.txt (original)
+++ lldb/trunk/docs/lldb-gdb-remote.txt Fri Jul 22 07:55:35 2016
@@ -888,6 +888,12 @@ tuples to return are:
     
     permissions:<permissions>;  // <permissions> is a string that contains one
                                 // or more of the characters from "rwx"
+
+    name:<name>; // <name> is a hex encoded string that contains the name of
+                 // the memory region mapped at the given address. In case of
+                 // regions backed by a file it have to be the absolute path of
+                 // the file while for anonymous regions it have to be the name
+                 // associated to the region if that is available.
                                 
     error:<ascii-byte-error-string>; // where <ascii-byte-error-string> is
                                      // a hex encoded string value that 

Modified: lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h (original)
+++ lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h Fri Jul 22 07:55:35 2016
@@ -86,6 +86,19 @@ public:
     bool
     IsMapped ();
 
+    
+    //------------------------------------------------------------------
+    /// Returns the name of the memory region mapped at the given
+    /// address.
+    ///
+    /// @return
+    ///     In case of memory mapped files it is the absolute path of
+    ///     the file otherwise it is a name associated with the memory
+    ///     region. If no name can be determined the returns nullptr.
+    //------------------------------------------------------------------
+    const char *
+    GetName();
+
     bool
     operator == (const lldb::SBMemoryRegionInfo &rhs) const;
 

Modified: lldb/trunk/include/lldb/Target/MemoryRegionInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/MemoryRegionInfo.h?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/MemoryRegionInfo.h (original)
+++ lldb/trunk/include/lldb/Target/MemoryRegionInfo.h Fri Jul 22 07:55:35 2016
@@ -10,6 +10,7 @@
 #ifndef lldb_MemoryRegionInfo_h
 #define lldb_MemoryRegionInfo_h
 
+#include "lldb/Core/ConstString.h"
 #include "lldb/Core/RangeMap.h"
 #include "lldb/Utility/Range.h"
 
@@ -81,6 +82,12 @@ namespace lldb_private
         {
             return m_mapped;
         }
+
+        const ConstString&
+        GetName () const
+        {
+            return m_name;
+        }
         
         void
         SetReadable (OptionalBool val)
@@ -106,6 +113,12 @@ namespace lldb_private
             m_mapped = val;
         }
 
+        void
+        SetName (const char* name)
+        {
+            m_name = ConstString(name);
+        }
+
         //----------------------------------------------------------------------
         // Get permissions as a uint32_t that is a mask of one or more bits from
         // the lldb::Permissions
@@ -157,6 +170,7 @@ namespace lldb_private
         OptionalBool m_write;
         OptionalBool m_execute;
         OptionalBool m_mapped;
+        ConstString m_name;
     };
 }
 

Modified: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py Fri Jul 22 07:55:35 2016
@@ -698,7 +698,7 @@ class GdbRemoteTestCaseBase(TestBase):
 
         # Validate keys are known.
         for (key, val) in list(mem_region_dict.items()):
-            self.assertTrue(key in ["start", "size", "permissions", "error"])
+            self.assertTrue(key in ["start", "size", "permissions", "name", "error"])
             self.assertIsNotNone(val)
 
         # Return the dictionary of key-value pairs for the memory region.

Modified: lldb/trunk/source/API/SBMemoryRegionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBMemoryRegionInfo.cpp?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/source/API/SBMemoryRegionInfo.cpp (original)
+++ lldb/trunk/source/API/SBMemoryRegionInfo.cpp Fri Jul 22 07:55:35 2016
@@ -110,6 +110,11 @@ SBMemoryRegionInfo::IsMapped () {
     return m_opaque_ap->GetMapped() == MemoryRegionInfo::eYes;
 }
 
+const char *
+SBMemoryRegionInfo::GetName () {
+    return m_opaque_ap->GetName().AsCString();
+}
+
 bool
 SBMemoryRegionInfo::GetDescription (SBStream &description)
 {

Modified: lldb/trunk/source/Core/DynamicLoader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DynamicLoader.cpp?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/source/Core/DynamicLoader.cpp (original)
+++ lldb/trunk/source/Core/DynamicLoader.cpp Fri Jul 22 07:55:35 2016
@@ -12,13 +12,14 @@
 // Other libraries and framework includes
 // Project includes
 #include "lldb/lldb-private.h"
-#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
+#include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -177,37 +178,67 @@ DynamicLoader::LoadModuleAtAddress(const
 {
     Target &target = m_process->GetTarget();
     ModuleList &modules = target.GetImages();
+    ModuleSpec module_spec (file, target.GetArchitecture());
     ModuleSP module_sp;
 
-    ModuleSpec module_spec (file, target.GetArchitecture());
     if ((module_sp = modules.FindFirstModule (module_spec)))
     {
         UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
+        return module_sp;
     }
-    else if ((module_sp = target.GetSharedModule(module_spec)))
+
+    if ((module_sp = target.GetSharedModule(module_spec)))
     {
         UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
+        return module_sp;
     }
-    else
+
+    bool check_alternative_file_name = true;
+    if (base_addr_is_offset)
     {
-        if (base_addr_is_offset)
+        // Try to fetch the load address of the file from the process as we need absolute load
+        // address to read the file out of the memory instead of a load bias.
+        bool is_loaded = false;
+        lldb::addr_t load_addr;
+        Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
+        if (error.Success() && is_loaded)
         {
-            // Try to fetch the load address of the file from the process as we need absolute load
-            // address to read the file out of the memory instead of a load bias.
-            bool is_loaded = false;
-            lldb::addr_t load_addr;
-            Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
-            if (error.Success() && is_loaded)
-                base_addr = load_addr;
+            check_alternative_file_name = false;
+            base_addr = load_addr;
         }
+    }
 
-        if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr)))
+    // We failed to find the module based on its name. Lets try to check if we can find a
+    // different name based on the memory region info.
+    if (check_alternative_file_name)
+    {
+        MemoryRegionInfo memory_info;
+        Error error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
+        if (error.Success() && memory_info.GetMapped() && memory_info.GetRange().GetRangeBase() == base_addr)
         {
-            UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
-            target.GetImages().AppendIfNeeded(module_sp);
+            ModuleSpec new_module_spec(FileSpec(memory_info.GetName().AsCString(), false),
+                                       target.GetArchitecture());
+
+            if ((module_sp = modules.FindFirstModule(new_module_spec)))
+            {
+                UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+                return module_sp;
+            }
+
+            if ((module_sp = target.GetSharedModule(new_module_spec)))
+            {
+                UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+                return module_sp;
+            }
         }
     }
 
+    if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr)))
+    {
+        UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+        target.GetImages().AppendIfNeeded(module_sp);
+    }
+
     return module_sp;
 }
 

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Fri Jul 22 07:55:35 2016
@@ -1678,6 +1678,20 @@ ParseMemoryRegionInfoFromProcMapsLine (c
     else
         return Error ("unexpected /proc/{pid}/maps exec permission char");
 
+    line_extractor.GetChar();              // Read the private bit
+    line_extractor.SkipSpaces();           // Skip the separator
+    line_extractor.GetHexMaxU64(false, 0); // Read the offset
+    line_extractor.GetHexMaxU64(false, 0); // Read the major device number
+    line_extractor.GetChar();              // Read the device id separator
+    line_extractor.GetHexMaxU64(false, 0); // Read the major device number
+    line_extractor.SkipSpaces();           // Skip the separator
+    line_extractor.GetU64(0, 10);          // Read the inode number
+
+    line_extractor.SkipSpaces();
+    const char* name = line_extractor.Peek();
+    if (name)
+        memory_region_info.SetName(name);
+
     return Error ();
 }
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Fri Jul 22 07:55:35 2016
@@ -2458,6 +2458,13 @@ GDBRemoteCommunicationClient::GetMemoryR
                         region_info.SetMapped(MemoryRegionInfo::eNo);
                     }
                 }
+                else if (name.compare ("name") == 0)
+                {
+                    StringExtractorGDBRemote name_extractor;
+                    name_extractor.GetStringRef().swap(value);
+                    name_extractor.GetHexByteString(value);
+                    region_info.SetName(value.c_str());
+                }
                 else if (name.compare ("error") == 0)
                 {
                     StringExtractorGDBRemote name_extractor;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=276411&r1=276410&r2=276411&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Fri Jul 22 07:55:35 2016
@@ -2221,6 +2221,15 @@ GDBRemoteCommunicationServerLLGS::Handle
 
             response.PutChar (';');
         }
+
+        // Name
+        ConstString name = region_info.GetName();
+        if (name)
+        {
+            response.PutCString("name:");
+            response.PutCStringAsRawHex8(name.AsCString());
+            response.PutChar(';');
+        }
     }
 
     return SendPacketNoLock(response.GetData(), response.GetSize());




More information about the lldb-commits mailing list