Index: lldb/trunk/docs/lldb-gdb-remote.txt =================================================================== --- lldb/trunk/docs/lldb-gdb-remote.txt +++ lldb/trunk/docs/lldb-gdb-remote.txt @@ -888,6 +888,12 @@ permissions:; // is a string that contains one // or more of the characters from "rwx" + + 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:; // where is // a hex encoded string value that Index: lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h =================================================================== --- lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h +++ lldb/trunk/include/lldb/API/SBMemoryRegionInfo.h @@ -86,6 +86,19 @@ 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; Index: lldb/trunk/include/lldb/Target/MemoryRegionInfo.h =================================================================== --- lldb/trunk/include/lldb/Target/MemoryRegionInfo.h +++ lldb/trunk/include/lldb/Target/MemoryRegionInfo.h @@ -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 @@ { return m_mapped; } + + const ConstString& + GetName () const + { + return m_name; + } void SetReadable (OptionalBool val) @@ -106,6 +113,12 @@ 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 @@ OptionalBool m_write; OptionalBool m_execute; OptionalBool m_mapped; + ConstString m_name; }; } Index: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py =================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -698,7 +698,7 @@ # 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. Index: lldb/trunk/source/API/SBMemoryRegionInfo.cpp =================================================================== --- lldb/trunk/source/API/SBMemoryRegionInfo.cpp +++ lldb/trunk/source/API/SBMemoryRegionInfo.cpp @@ -110,6 +110,11 @@ return m_opaque_ap->GetMapped() == MemoryRegionInfo::eYes; } +const char * +SBMemoryRegionInfo::GetName () { + return m_opaque_ap->GetName().AsCString(); +} + bool SBMemoryRegionInfo::GetDescription (SBStream &description) { Index: lldb/trunk/source/Core/DynamicLoader.cpp =================================================================== --- lldb/trunk/source/Core/DynamicLoader.cpp +++ lldb/trunk/source/Core/DynamicLoader.cpp @@ -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 @@ { 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; } Index: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1678,6 +1678,20 @@ 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 (); } Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2458,6 +2458,13 @@ 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; Index: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -2221,6 +2221,15 @@ 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());