diff options
Diffstat (limited to 'lldb/source/Plugins')
6 files changed, 120 insertions, 16 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 383cbb1bfe7..eb477c4c582 100644 --- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -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); diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 457e8bd4caa..5f8242211b7 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -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()) diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index d2ca541f2b3..3d03bdc2d80 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -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::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) { diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 54196d8b1c5..4bcbb363d3f 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -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; diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 69006b2bdad..a97c01d532a 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -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() { diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h index 7b5b6adae85..0e808524202 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -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; |