[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 ¤t_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 ®ion_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 ®ion_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 ®ion_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 ®ion_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