diff options
9 files changed, 118 insertions, 19 deletions
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt index a882c4abda0..2fec87bdaf5 100644 --- a/lldb/docs/lldb-gdb-remote.txt +++ b/lldb/docs/lldb-gdb-remote.txt @@ -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 diff --git a/lldb/include/lldb/API/SBMemoryRegionInfo.h b/lldb/include/lldb/API/SBMemoryRegionInfo.h index fadd0760891..16b767ff233 100644 --- a/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -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; diff --git a/lldb/include/lldb/Target/MemoryRegionInfo.h b/lldb/include/lldb/Target/MemoryRegionInfo.h index 5c82a1f294d..9c042905ef7 100644 --- a/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/lldb/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 @@ 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; }; } diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py index d63ddbe3999..4db630d50d1 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py @@ -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. diff --git a/lldb/source/API/SBMemoryRegionInfo.cpp b/lldb/source/API/SBMemoryRegionInfo.cpp index 53b180787af..1e4dd769644 100644 --- a/lldb/source/API/SBMemoryRegionInfo.cpp +++ b/lldb/source/API/SBMemoryRegionInfo.cpp @@ -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) { diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index f41ff4a80c8..625cccc8e88 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/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 @@ DynamicLoader::LoadModuleAtAddress(const FileSpec &file, { 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; } diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index ae32a777773..6d822ce200f 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1678,6 +1678,20 @@ ParseMemoryRegionInfoFromProcMapsLine (const std::string &maps_line, MemoryRegio 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 (); } diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index ac76889079a..ba018be812b 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -2458,6 +2458,13 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr, 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; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index ede69769c79..4721e23f559 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -2221,6 +2221,15 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfo (StringExtractorGDBRe 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()); |