[Lldb-commits] [lldb] r272276 - Since our expression parser needs to locate areas of memory that are not in use when you have a process that can't JIT code, like core file debugging, the core file process plug-ins should be able to override the Process::GetMemoryRegionInfo(...) function.

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Thu Jun 9 09:34:07 PDT 2016


Author: gclayton
Date: Thu Jun  9 11:34:06 2016
New Revision: 272276

URL: http://llvm.org/viewvc/llvm-project?rev=272276&view=rev
Log:
Since our expression parser needs to locate areas of memory that are not in use when you have a process that can't JIT code, like core file debugging, the core file process plug-ins should be able to override the Process::GetMemoryRegionInfo(...) function.

In order to make this happen, I have added permissions to sections so that we can know what the permissions are for a given section, and modified both core file plug-ins to override Process::GetMemoryRegionInfo() and answer things correctly.


Modified:
    lldb/trunk/include/lldb/Core/RangeMap.h
    lldb/trunk/include/lldb/Core/Section.h
    lldb/trunk/include/lldb/Target/MemoryRegionInfo.h
    lldb/trunk/source/Commands/CommandObjectMemory.cpp
    lldb/trunk/source/Core/Section.cpp
    lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp
    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h

Modified: lldb/trunk/include/lldb/Core/RangeMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RangeMap.h?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RangeMap.h (original)
+++ lldb/trunk/include/lldb/Core/RangeMap.h Thu Jun  9 11:34:06 2016
@@ -1340,7 +1340,27 @@ namespace lldb_private {
             }
             return nullptr;
         }
-        
+
+        const Entry *
+        FindEntryThatContainsOrFollows(B addr) const
+        {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+            assert(IsSorted());
+#endif
+            if (!m_entries.empty())
+            {
+                typename Collection::const_iterator end = m_entries.end();
+                typename Collection::const_iterator pos =
+                    std::lower_bound(m_entries.begin(), end, addr, [](const Entry &lhs, B rhs_base) -> bool {
+                        return lhs.GetRangeBase() < rhs_base;
+                    });
+
+                if (pos != end)
+                    return &(*pos);
+            }
+            return nullptr;
+        }
+
         Entry *
         Back()
         {

Modified: lldb/trunk/include/lldb/Core/Section.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Section.h?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Section.h (original)
+++ lldb/trunk/include/lldb/Core/Section.h Thu Jun  9 11:34:06 2016
@@ -273,7 +273,19 @@ public:
     {
         m_thread_specific = b;
     }
-    
+
+    //------------------------------------------------------------------
+    /// Get the permissions as OR'ed bits from lldb::Permissions
+    //------------------------------------------------------------------
+    uint32_t
+    GetPermissions() const;
+
+    //------------------------------------------------------------------
+    /// Set the permissions using bits OR'ed from lldb::Permissions
+    //------------------------------------------------------------------
+    void
+    SetPermissions(uint32_t permissions);
+
     ObjectFile *
     GetObjectFile ()
     {
@@ -356,12 +368,15 @@ protected:
     lldb::offset_t  m_file_size;        // Object file size (can be smaller than m_byte_size for zero filled sections...)
     uint32_t        m_log2align;        // log_2(align) of the section (i.e. section has to be aligned to 2^m_log2align)
     SectionList     m_children;         // Child sections
-    bool            m_fake:1,           // If true, then this section only can contain the address if one of its
+    bool m_fake : 1,                    // If true, then this section only can contain the address if one of its
                                         // children contains an address. This allows for gaps between the children
                                         // that are contained in the address range for this section, but do not produce
                                         // hits unless the children contain the address.
-                    m_encrypted:1,      // Set to true if the contents are encrypted
-                    m_thread_specific:1;// This section is thread specific
+        m_encrypted : 1,                // Set to true if the contents are encrypted
+        m_thread_specific : 1,          // This section is thread specific
+        m_readable : 1,                 // If this section has read permissions
+        m_writable : 1,                 // If this section has write permissions
+        m_executable : 1;               // If this section has executable permissions
     uint32_t        m_target_byte_size; // Some architectures have non-8-bit byte size. This is specified as
                                         // as a multiple number of a host bytes   
 private:

Modified: lldb/trunk/include/lldb/Target/MemoryRegionInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/MemoryRegionInfo.h?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/MemoryRegionInfo.h (original)
+++ lldb/trunk/include/lldb/Target/MemoryRegionInfo.h Thu Jun  9 11:34:06 2016
@@ -92,7 +92,36 @@ namespace lldb_private
         {
             m_execute = val;
         }
-        
+
+        //----------------------------------------------------------------------
+        // Get permissions as a uint32_t that is a mask of one or more bits from
+        // the lldb::Permissions
+        //----------------------------------------------------------------------
+        uint32_t
+        GetLLDBPermissions() const
+        {
+            uint32_t permissions = 0;
+            if (m_read)
+                permissions |= lldb::ePermissionsReadable;
+            if (m_write)
+                permissions |= lldb::ePermissionsWritable;
+            if (m_execute)
+                permissions |= lldb::ePermissionsExecutable;
+            return permissions;
+        }
+
+        //----------------------------------------------------------------------
+        // Set permissions from a uint32_t that contains one or more bits from
+        // the lldb::Permissions
+        //----------------------------------------------------------------------
+        void
+        SetLLDBPermissions(uint32_t permissions)
+        {
+            m_read = (permissions & lldb::ePermissionsReadable) ? eYes : eNo;
+            m_write = (permissions & lldb::ePermissionsWritable) ? eYes : eNo;
+            m_execute = (permissions & lldb::ePermissionsExecutable) ? eYes : eNo;
+        }
+
     protected:
         RangeType m_range;
         OptionalBool m_read;

Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Thu Jun  9 11:34:06 2016
@@ -16,27 +16,29 @@
 
 // Project includes
 #include "CommandObjectMemory.h"
+#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/ValueObjectMemory.h"
 #include "lldb/DataFormatters/ValueObjectPrinter.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Interpreter/Options.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/OptionGroupFormat.h"
 #include "lldb/Interpreter/OptionGroupOutputFile.h"
 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
 #include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Interpreter/Options.h"
 #include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/TypeList.h"
 #include "lldb/Target/MemoryHistory.h"
+#include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Thread.h"
@@ -1767,6 +1769,109 @@ protected:
 };
 
 //-------------------------------------------------------------------------
+// CommandObjectMemoryRegion
+//-------------------------------------------------------------------------
+#pragma mark CommandObjectMemoryRegion
+
+class CommandObjectMemoryRegion : public CommandObjectParsed
+{
+public:
+    CommandObjectMemoryRegion(CommandInterpreter &interpreter)
+        : CommandObjectParsed(interpreter, "memory region",
+                              "Get information on a memory region that contains an address in the current process.",
+                              "memory region ADDR",
+                              eCommandRequiresProcess | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched),
+          m_prev_end_addr(LLDB_INVALID_ADDRESS)
+    {
+    }
+
+    ~CommandObjectMemoryRegion() override = default;
+
+protected:
+    bool
+    DoExecute(Args &command, CommandReturnObject &result) override
+    {
+        ProcessSP process_sp = m_exe_ctx.GetProcessSP();
+        if (process_sp)
+        {
+            Error error;
+            lldb::addr_t load_addr = m_prev_end_addr;
+            m_prev_end_addr = LLDB_INVALID_ADDRESS;
+
+            const size_t argc = command.GetArgumentCount();
+            if (argc > 1 || (argc == 0 && load_addr == LLDB_INVALID_ADDRESS))
+            {
+                result.AppendErrorWithFormat("'%s' takes one argument:\nUsage: %s\n", m_cmd_name.c_str(),
+                                             m_cmd_syntax.c_str());
+                result.SetStatus(eReturnStatusFailed);
+            }
+            else
+            {
+                const char *load_addr_cstr = command.GetArgumentAtIndex(0);
+                if (command.GetArgumentCount() == 1)
+                {
+                    load_addr = Args::StringToAddress(&m_exe_ctx, load_addr_cstr, LLDB_INVALID_ADDRESS, &error);
+                    if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS)
+                    {
+                        result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n", load_addr_cstr,
+                                                     error.AsCString());
+                        result.SetStatus(eReturnStatusFailed);
+                    }
+                }
+
+                lldb_private::MemoryRegionInfo range_info;
+                error = process_sp->GetMemoryRegionInfo(load_addr, range_info);
+                if (error.Success())
+                {
+                    lldb_private::Address addr;
+                    ConstString section_name;
+                    if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr))
+                    {
+                        SectionSP section_sp(addr.GetSection());
+                        if (section_sp)
+                        {
+                            // Got the top most section, not the deepest section
+                            while (section_sp->GetParent())
+                                section_sp = section_sp->GetParent();
+                            section_name = section_sp->GetName();
+                        }
+                    }
+                    result.AppendMessageWithFormat(
+                        "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") %c%c%c%s%s\n", range_info.GetRange().GetRangeBase(),
+                        range_info.GetRange().GetRangeEnd(), range_info.GetReadable() ? 'r' : '-',
+                        range_info.GetWritable() ? 'w' : '-', range_info.GetExecutable() ? 'x' : '-',
+                        section_name ? " " : "", section_name ? section_name.AsCString() : "");
+                    m_prev_end_addr = range_info.GetRange().GetRangeEnd();
+                    result.SetStatus(eReturnStatusSuccessFinishResult);
+                }
+                else
+                {
+                    result.SetStatus(eReturnStatusFailed);
+                    result.AppendErrorWithFormat("%s\n", error.AsCString());
+                }
+            }
+        }
+        else
+        {
+            m_prev_end_addr = LLDB_INVALID_ADDRESS;
+            result.AppendError("invalid process");
+            result.SetStatus(eReturnStatusFailed);
+        }
+        return result.Succeeded();
+    }
+
+    const char *
+    GetRepeatCommand(Args &current_command_args, uint32_t index) override
+    {
+        // If we repeat this command, repeat it without any arguments so we can
+        // show the next memory range
+        return m_cmd_name.c_str();
+    }
+
+    lldb::addr_t m_prev_end_addr;
+};
+
+//-------------------------------------------------------------------------
 // CommandObjectMemory
 //-------------------------------------------------------------------------
 
@@ -1776,10 +1881,11 @@ CommandObjectMemory::CommandObjectMemory
                             "A set of commands for operating on memory.",
                             "memory <subcommand> [<subcommand-options>]")
 {
-    LoadSubCommand ("find", CommandObjectSP (new CommandObjectMemoryFind (interpreter)));
-    LoadSubCommand ("read",  CommandObjectSP (new CommandObjectMemoryRead (interpreter)));
-    LoadSubCommand ("write", CommandObjectSP (new CommandObjectMemoryWrite (interpreter)));
-    LoadSubCommand ("history", CommandObjectSP (new CommandObjectMemoryHistory (interpreter)));
+    LoadSubCommand("find", CommandObjectSP(new CommandObjectMemoryFind(interpreter)));
+    LoadSubCommand("read", CommandObjectSP(new CommandObjectMemoryRead(interpreter)));
+    LoadSubCommand("write", CommandObjectSP(new CommandObjectMemoryWrite(interpreter)));
+    LoadSubCommand("history", CommandObjectSP(new CommandObjectMemoryHistory(interpreter)));
+    LoadSubCommand("region", CommandObjectSP(new CommandObjectMemoryRegion(interpreter)));
 }
 
 CommandObjectMemory::~CommandObjectMemory() = default;

Modified: lldb/trunk/source/Core/Section.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Section.cpp?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Core/Section.cpp (original)
+++ lldb/trunk/source/Core/Section.cpp Thu Jun  9 11:34:06 2016
@@ -17,70 +17,58 @@
 using namespace lldb;
 using namespace lldb_private;
 
-Section::Section (const ModuleSP &module_sp,
-                  ObjectFile *obj_file,
-                  user_id_t sect_id,
-                  const ConstString &name,
-                  SectionType sect_type,
-                  addr_t file_addr,
-                  addr_t byte_size,
-                  lldb::offset_t file_offset,
-                  lldb::offset_t file_size,
-                  uint32_t log2align,
-                  uint32_t flags,
-                  uint32_t target_byte_size/*=1*/) :
-    ModuleChild     (module_sp),
-    UserID          (sect_id),
-    Flags           (flags),
-    m_obj_file      (obj_file),
-    m_type          (sect_type),
-    m_parent_wp     (),
-    m_name          (name),
-    m_file_addr     (file_addr),
-    m_byte_size     (byte_size),
-    m_file_offset   (file_offset),
-    m_file_size     (file_size),
-    m_log2align     (log2align),
-    m_children      (),
-    m_fake          (false),
-    m_encrypted     (false),
-    m_thread_specific (false),
-    m_target_byte_size(target_byte_size)
+Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file, user_id_t sect_id, const ConstString &name,
+                 SectionType sect_type, addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
+                 lldb::offset_t file_size, uint32_t log2align, uint32_t flags, uint32_t target_byte_size /*=1*/)
+    : ModuleChild(module_sp),
+      UserID(sect_id),
+      Flags(flags),
+      m_obj_file(obj_file),
+      m_type(sect_type),
+      m_parent_wp(),
+      m_name(name),
+      m_file_addr(file_addr),
+      m_byte_size(byte_size),
+      m_file_offset(file_offset),
+      m_file_size(file_size),
+      m_log2align(log2align),
+      m_children(),
+      m_fake(false),
+      m_encrypted(false),
+      m_thread_specific(false),
+      m_readable(false),
+      m_writable(false),
+      m_executable(false),
+      m_target_byte_size(target_byte_size)
 {
 //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
 //            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
 }
 
-Section::Section (const lldb::SectionSP &parent_section_sp,
-                  const ModuleSP &module_sp,
-                  ObjectFile *obj_file,
-                  user_id_t sect_id,
-                  const ConstString &name,
-                  SectionType sect_type,
-                  addr_t file_addr,
-                  addr_t byte_size,
-                  lldb::offset_t file_offset,
-                  lldb::offset_t file_size,
-                  uint32_t log2align,
-                  uint32_t flags,
-                  uint32_t target_byte_size/*=1*/) :
-    ModuleChild     (module_sp),
-    UserID          (sect_id),
-    Flags           (flags),
-    m_obj_file      (obj_file),
-    m_type          (sect_type),
-    m_parent_wp     (),
-    m_name          (name),
-    m_file_addr     (file_addr),
-    m_byte_size     (byte_size),
-    m_file_offset   (file_offset),
-    m_file_size     (file_size),
-    m_log2align     (log2align),
-    m_children      (),
-    m_fake          (false),
-    m_encrypted     (false),
-    m_thread_specific (false),
-    m_target_byte_size(target_byte_size)
+Section::Section(const lldb::SectionSP &parent_section_sp, const ModuleSP &module_sp, ObjectFile *obj_file,
+                 user_id_t sect_id, const ConstString &name, SectionType sect_type, addr_t file_addr, addr_t byte_size,
+                 lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
+                 uint32_t target_byte_size /*=1*/)
+    : ModuleChild(module_sp),
+      UserID(sect_id),
+      Flags(flags),
+      m_obj_file(obj_file),
+      m_type(sect_type),
+      m_parent_wp(),
+      m_name(name),
+      m_file_addr(file_addr),
+      m_byte_size(byte_size),
+      m_file_offset(file_offset),
+      m_file_size(file_size),
+      m_log2align(log2align),
+      m_children(),
+      m_fake(false),
+      m_encrypted(false),
+      m_thread_specific(false),
+      m_readable(false),
+      m_writable(false),
+      m_executable(false),
+      m_target_byte_size(target_byte_size)
 {
 //    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
 //            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
@@ -252,7 +240,8 @@ Section::Dump (Stream *s, Target *target
         range.Dump (s, 0);
     }
 
-    s->Printf("%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get());
+    s->Printf("%c %c%c%c  0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_readable ? 'r' : '-',
+              m_writable ? 'w' : '-', m_executable ? 'x' : '-', m_file_offset, m_file_size, Get());
 
     DumpName (s);
 
@@ -317,6 +306,33 @@ Section::Slide (addr_t slide_amount, boo
     return false;
 }
 
+//------------------------------------------------------------------
+/// Get the permissions as OR'ed bits from lldb::Permissions
+//------------------------------------------------------------------
+uint32_t
+Section::GetPermissions() const
+{
+    uint32_t permissions = 0;
+    if (m_readable)
+        permissions |= ePermissionsReadable;
+    if (m_writable)
+        permissions |= ePermissionsWritable;
+    if (m_executable)
+        permissions |= ePermissionsExecutable;
+    return permissions;
+}
+
+//------------------------------------------------------------------
+/// Set the permissions using bits OR'ed from lldb::Permissions
+//------------------------------------------------------------------
+void
+Section::SetPermissions(uint32_t permissions)
+{
+    m_readable = (permissions & ePermissionsReadable) != 0;
+    m_writable = (permissions & ePermissionsWritable) != 0;
+    m_executable = (permissions & ePermissionsExecutable) != 0;
+}
+
 lldb::offset_t
 Section::GetSectionData (void *dst, lldb::offset_t dst_len, lldb::offset_t offset)
 {
@@ -565,9 +581,12 @@ SectionList::Dump (Stream *s, Target *ta
     if (show_header && !m_sections.empty())
     {
         s->Indent();
-        s->Printf(    "SectID     Type             %s Address                             File Off.  File Size  Flags      Section Name\n", target_has_loaded_sections ? "Load" : "File");
+        s->Printf("SectID     Type             %s Address                             Perm File Off.  File Size  Flags "
+                  "     Section Name\n",
+                  target_has_loaded_sections ? "Load" : "File");
         s->Indent();
-        s->PutCString("---------- ---------------- ---------------------------------------  ---------- ---------- ---------- ----------------------------\n");
+        s->PutCString("---------- ---------------- ---------------------------------------  ---- ---------- ---------- "
+                      "---------- ----------------------------\n");
     }
 
 

Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Thu Jun  9 11:34:06 2016
@@ -2032,6 +2032,9 @@ ObjectFileELF::CreateSections(SectionLis
             else if (name == g_sect_name_arm_extab)                   sect_type = eSectionTypeARMextab;
             else if (name == g_sect_name_go_symtab)                   sect_type = eSectionTypeGoSymtab;
 
+            const uint32_t permissions = ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0) |
+                                         ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0) |
+                                         ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0);
             switch (header.sh_type)
             {
                 case SHT_SYMTAB:
@@ -2083,6 +2086,7 @@ ObjectFileELF::CreateSections(SectionLis
                                               header.sh_flags,    // Flags for this section.
                                               target_bytes_size));// Number of host bytes per target byte
 
+            section_sp->SetPermissions(permissions);
             if (is_thread_specific)
                 section_sp->SetIsThreadSpecific (is_thread_specific);
             m_sections_ap->AddSection(section_sp);

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Thu Jun  9 11:34:06 2016
@@ -1625,6 +1625,10 @@ ObjectFileMachO::CreateSections (Section
                     }
                     if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
                     {
+                        const uint32_t segment_permissions =
+                            ((load_cmd.initprot & VM_PROT_READ) ? ePermissionsReadable : 0) |
+                            ((load_cmd.initprot & VM_PROT_WRITE) ? ePermissionsWritable : 0) |
+                            ((load_cmd.initprot & VM_PROT_EXECUTE) ? ePermissionsExecutable : 0);
 
                         const bool segment_is_encrypted = (load_cmd.flags & SG_PROTECTED_VERSION_1) != 0;
 
@@ -1651,6 +1655,7 @@ ObjectFileMachO::CreateSections (Section
 
                             segment_sp->SetIsEncrypted (segment_is_encrypted);
                             m_sections_ap->AddSection(segment_sp);
+                            segment_sp->SetPermissions(segment_permissions);
                             if (add_to_unified)
                                 unified_section_list.AddSection(segment_sp);
                         }
@@ -1782,7 +1787,7 @@ ObjectFileMachO::CreateSections (Section
                                                                       sect64.align,
                                                                       load_cmd.flags));      // Flags for this section
                                         segment_sp->SetIsFake(true);
-                                        
+                                        segment_sp->SetPermissions(segment_permissions);
                                         m_sections_ap->AddSection(segment_sp);
                                         if (add_to_unified)
                                             unified_section_list.AddSection(segment_sp);
@@ -1932,6 +1937,7 @@ ObjectFileMachO::CreateSections (Section
                                     section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
 
                                 section_sp->SetIsEncrypted (segment_is_encrypted || section_is_encrypted);
+                                section_sp->SetPermissions(segment_permissions);
                                 segment_sp->GetChildren().AddSection(section_sp);
 
                                 if (segment_sp->IsFake())

Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp Thu Jun  9 11:34:06 2016
@@ -14,15 +14,16 @@
 #include <mutex>
 
 // Other libraries and framework includes
-#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/State.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Target/Target.h"
 #include "lldb/Target/DynamicLoader.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Target/UnixSignals.h"
 
 #include "llvm/Support/ELF.h"
@@ -148,7 +149,7 @@ ProcessElfCore::GetPluginVersion()
 lldb::addr_t
 ProcessElfCore::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header)
 {
-    lldb::addr_t addr = header->p_vaddr;
+    const lldb::addr_t addr = header->p_vaddr;
     FileRange file_range (header->p_offset, header->p_filesz);
     VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range);
 
@@ -166,6 +167,14 @@ ProcessElfCore::AddAddressRangeFromLoadS
         m_core_aranges.Append(range_entry);
     }
 
+    // Keep a separate map of permissions that that isn't coalesced so all ranges
+    // are maintained.
+    const uint32_t permissions = ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0) |
+                                 ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0) |
+                                 ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0);
+
+    m_core_range_infos.Append(VMRangeToPermissions::Entry(addr, header->p_memsz, permissions));
+
     return addr;
 }
 
@@ -227,7 +236,10 @@ ProcessElfCore::DoLoadCore ()
     }
 
     if (!ranges_are_sorted)
+    {
         m_core_aranges.Sort();
+        m_core_range_infos.Sort();
+    }
 
     // Even if the architecture is set in the target, we need to override
     // it to match the core file which is always single arch.
@@ -315,6 +327,38 @@ ProcessElfCore::ReadMemory (lldb::addr_t
     return DoReadMemory (addr, buf, size, error);
 }
 
+Error
+ProcessElfCore::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &region_info)
+{
+    region_info.Clear();
+    const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+    if (permission_entry)
+    {
+        if (permission_entry->Contains(load_addr))
+        {
+            region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+            region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+            const Flags permissions(permission_entry->data);
+            region_info.SetReadable(permissions.Test(lldb::ePermissionsReadable) ? MemoryRegionInfo::eYes
+                                                                                 : MemoryRegionInfo::eNo);
+            region_info.SetWritable(permissions.Test(lldb::ePermissionsWritable) ? MemoryRegionInfo::eYes
+                                                                                 : MemoryRegionInfo::eNo);
+            region_info.SetExecutable(permissions.Test(lldb::ePermissionsExecutable) ? MemoryRegionInfo::eYes
+                                                                                     : MemoryRegionInfo::eNo);
+        }
+        else if (load_addr < permission_entry->GetRangeBase())
+        {
+            region_info.GetRange().SetRangeBase(load_addr);
+            region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+            region_info.SetReadable(MemoryRegionInfo::eNo);
+            region_info.SetWritable(MemoryRegionInfo::eNo);
+            region_info.SetExecutable(MemoryRegionInfo::eNo);
+        }
+        return Error();
+    }
+    return Error("invalid address");
+}
+
 size_t
 ProcessElfCore::DoReadMemory (lldb::addr_t addr, void *buf, size_t size, Error &error)
 {

Modified: lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h (original)
+++ lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h Thu Jun  9 11:34:06 2016
@@ -102,6 +102,9 @@ public:
 
     size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
 
+    lldb_private::Error
+    GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
+
     lldb::addr_t GetImageInfoAddress() override;
 
     lldb_private::ArchSpec
@@ -135,6 +138,7 @@ private:
     //------------------------------------------------------------------
     typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
     typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
 
     lldb::ModuleSP m_core_module_sp;
     lldb_private::FileSpec m_core_file;
@@ -155,6 +159,9 @@ private:
     // Address ranges found in the core
     VMRangeToFileOffset m_core_aranges;
 
+    // Permissions for all ranges
+    VMRangeToPermissions m_core_range_infos;
+
     // NT_FILE entries found from the NOTE segment
     std::vector<NT_FILE_Entry> m_nt_file_entries;
 

Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp Thu Jun  9 11:34:06 2016
@@ -18,14 +18,15 @@
 // Other libraries and framework includes
 #include "lldb/Core/DataBuffer.h"
 #include "lldb/Core/Debugger.h"
-#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/State.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 
@@ -122,14 +123,15 @@ ProcessMachCore::CanDebug(lldb::TargetSP
 //----------------------------------------------------------------------
 // ProcessMachCore constructor
 //----------------------------------------------------------------------
-ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec &core_file) :
-    Process (target_sp, listener_sp),
-    m_core_aranges (),
-    m_core_module_sp (),
-    m_core_file (core_file),
-    m_dyld_addr (LLDB_INVALID_ADDRESS),
-    m_mach_kernel_addr (LLDB_INVALID_ADDRESS),
-    m_dyld_plugin_name ()
+ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, ListenerSP listener_sp, const FileSpec &core_file)
+    : Process(target_sp, listener_sp),
+      m_core_aranges(),
+      m_core_range_infos(),
+      m_core_module_sp(),
+      m_core_file(core_file),
+      m_dyld_addr(LLDB_INVALID_ADDRESS),
+      m_mach_kernel_addr(LLDB_INVALID_ADDRESS),
+      m_dyld_plugin_name()
 {
 }
 
@@ -304,11 +306,14 @@ ProcessMachCore::DoLoadCore ()
             {
                 m_core_aranges.Append(range_entry);
             }
+            m_core_range_infos.Append(
+                VMRangeToPermissions::Entry(section_vm_addr, section->GetByteSize(), section->GetPermissions()));
         }
     }
     if (!ranges_are_sorted)
     {
         m_core_aranges.Sort();
+        m_core_range_infos.Sort();
     }
 
     if (m_dyld_addr == LLDB_INVALID_ADDRESS || m_mach_kernel_addr == LLDB_INVALID_ADDRESS)
@@ -522,6 +527,39 @@ ProcessMachCore::DoReadMemory (addr_t ad
     return 0;
 }
 
+Error
+ProcessMachCore::GetMemoryRegionInfo(addr_t load_addr, MemoryRegionInfo &region_info)
+{
+    region_info.Clear();
+    const VMRangeToPermissions::Entry *permission_entry = m_core_range_infos.FindEntryThatContainsOrFollows(load_addr);
+    if (permission_entry)
+    {
+        if (permission_entry->Contains(load_addr))
+        {
+            region_info.GetRange().SetRangeBase(permission_entry->GetRangeBase());
+            region_info.GetRange().SetRangeEnd(permission_entry->GetRangeEnd());
+            const Flags permissions(permission_entry->data);
+            region_info.SetReadable(permissions.Test(ePermissionsReadable) ? MemoryRegionInfo::eYes
+                                                                           : MemoryRegionInfo::eNo);
+            region_info.SetWritable(permissions.Test(ePermissionsWritable) ? MemoryRegionInfo::eYes
+                                                                           : MemoryRegionInfo::eNo);
+            region_info.SetExecutable(permissions.Test(ePermissionsExecutable) ? MemoryRegionInfo::eYes
+                                                                               : MemoryRegionInfo::eNo);
+        }
+        else if (load_addr < permission_entry->GetRangeBase())
+        {
+            region_info.GetRange().SetRangeBase(load_addr);
+            region_info.GetRange().SetRangeEnd(permission_entry->GetRangeBase());
+            region_info.SetReadable(MemoryRegionInfo::eNo);
+            region_info.SetWritable(MemoryRegionInfo::eNo);
+            region_info.SetExecutable(MemoryRegionInfo::eNo);
+        }
+        return Error();
+    }
+
+    return Error("invalid address");
+}
+
 void
 ProcessMachCore::Clear()
 {

Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h?rev=272276&r1=272275&r2=272276&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h Thu Jun  9 11:34:06 2016
@@ -103,7 +103,10 @@ public:
     
     size_t
     DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error) override;
-    
+
+    lldb_private::Error
+    GetMemoryRegionInfo(lldb::addr_t load_addr, lldb_private::MemoryRegionInfo &region_info) override;
+
     lldb::addr_t
     GetImageInfoAddress () override;
 
@@ -150,8 +153,10 @@ private:
     //------------------------------------------------------------------
     typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
     typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
+    typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t> VMRangeToPermissions;
 
     VMRangeToFileOffset m_core_aranges;
+    VMRangeToPermissions m_core_range_infos;
     lldb::ModuleSP m_core_module_sp;
     lldb_private::FileSpec m_core_file;
     lldb::addr_t m_dyld_addr;




More information about the lldb-commits mailing list