diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h --- a/lldb/include/lldb/Core/Section.h +++ b/lldb/include/lldb/Core/Section.h @@ -70,6 +70,10 @@ FindSectionContainingFileAddress(lldb::addr_t addr, uint32_t depth = UINT32_MAX) const; + /// Return true iff every byte in the given range belongs to one of the + /// sections in this list. + bool ContainsFileAddressRange(lldb::addr_t addr, lldb::addr_t size) const; + // Get the number of sections in this list only size_t GetSize() const { return m_sections.size(); } diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -563,6 +563,18 @@ return sect_sp; } +bool SectionList::ContainsFileAddressRange(addr_t file_addr, + addr_t size) const { + addr_t end = file_addr + size; + while (file_addr < end) { + SectionSP sect_sp = FindSectionContainingFileAddress(file_addr); + if (!sect_sp) + return false; + file_addr = sect_sp->GetFileAddress() + sect_sp->GetByteSize(); + } + return true; +} + bool SectionList::ContainsSection(user_id_t sect_id) const { return FindSectionByID(sect_id).get() != nullptr; } diff --git a/lldb/unittests/Core/CMakeLists.txt b/lldb/unittests/Core/CMakeLists.txt --- a/lldb/unittests/Core/CMakeLists.txt +++ b/lldb/unittests/Core/CMakeLists.txt @@ -3,6 +3,7 @@ MangledTest.cpp ModuleSpecTest.cpp RichManglingContextTest.cpp + SectionTest.cpp SourceManagerTest.cpp StreamCallbackTest.cpp UniqueCStringMapTest.cpp diff --git a/lldb/unittests/Core/SectionTest.cpp b/lldb/unittests/Core/SectionTest.cpp new file mode 100644 --- /dev/null +++ b/lldb/unittests/Core/SectionTest.cpp @@ -0,0 +1,67 @@ +//===-- ModuleSpecTest.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Section.h" +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "TestingSupport/SubsystemRAII.h" +#include "TestingSupport/TestUtilities.h" +#include "lldb/Core/Module.h" +#include "gtest/gtest.h" + +using namespace lldb; +using namespace lldb_private; + +TEST(SectionListTest, ContainsFileAddressRange) { + SubsystemRAII subsystems; + + auto ExpectedFile = TestFile::fromYaml(R"( +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0010 + Size: 0x0010 + - Name: .bar + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0020 + Size: 0x0010 + - Name: .baz + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x0031 + Size: 0x000f +... +)"); + ASSERT_THAT_EXPECTED(ExpectedFile, llvm::Succeeded()); + + auto M = std::make_shared(ExpectedFile->moduleSpec()); + SectionList *List = M->GetSectionList(); + ASSERT_TRUE(List); + EXPECT_TRUE(List->ContainsFileAddressRange(0x10, 0x1)); + EXPECT_TRUE(List->ContainsFileAddressRange(0x10, 0x10)); + EXPECT_TRUE(List->ContainsFileAddressRange(0x10, 0x11)); + EXPECT_TRUE(List->ContainsFileAddressRange(0x10, 0x20)); + EXPECT_FALSE(List->ContainsFileAddressRange(0x10, 0x21)); + + EXPECT_TRUE(List->ContainsFileAddressRange(0x08, 0x0)); + EXPECT_FALSE(List->ContainsFileAddressRange(0x08, 0x1)); + EXPECT_FALSE(List->ContainsFileAddressRange(0x08, 0x18)); + + EXPECT_TRUE(List->ContainsFileAddressRange(0x2f, 0x1)); + EXPECT_FALSE(List->ContainsFileAddressRange(0x2f, 0x2)); + EXPECT_FALSE(List->ContainsFileAddressRange(0x2f, 0x3)); + EXPECT_FALSE(List->ContainsFileAddressRange(0x30, 0x3)); + EXPECT_TRUE(List->ContainsFileAddressRange(0x31, 0x3)); +}