forked from OSchip/llvm-project
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. llvm-svn: 272276
This commit is contained in:
parent
ecdbb765fa
commit
3385fa08bf
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
@ -1766,6 +1768,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 (CommandInterpreter &interpreter) :
|
|||
"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;
|
||||
|
|
|
@ -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, uint32_t depth) const
|
|||
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, bool slide_children)
|
|||
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 *target, bool show_header, uint32_t depth)
|
|||
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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2032,6 +2032,9 @@ ObjectFileELF::CreateSections(SectionList &unified_section_list)
|
|||
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(SectionList &unified_section_list)
|
|||
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);
|
||||
|
|
|
@ -1625,6 +1625,10 @@ ObjectFileMachO::CreateSections (SectionList &unified_section_list)
|
|||
}
|
||||
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 (SectionList &unified_section_list)
|
|||
|
||||
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 (SectionList &unified_section_list)
|
|||
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 (SectionList &unified_section_list)
|
|||
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())
|
||||
|
|
|
@ -14,15 +14,16 @@
|
|||
#include <mutex>
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/Module.h"
|
||||
#include "lldb/Core/ModuleSpec.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/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/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::AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *head
|
|||
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 addr, void *buf, size_t size, Error &er
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 target_sp, bool plugin_specified_by_nam
|
|||
//----------------------------------------------------------------------
|
||||
// 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 addr, void *buf, size_t size, Error &error
|
|||
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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue