Author: Greg Clayton Date: 2025-03-04T16:19:20-08:00 New Revision: 27901cec0e76d2cbf648b3b63d5b2fec1d46bb9c
URL: https://github.com/llvm/llvm-project/commit/27901cec0e76d2cbf648b3b63d5b2fec1d46bb9c DIFF: https://github.com/llvm/llvm-project/commit/27901cec0e76d2cbf648b3b63d5b2fec1d46bb9c.diff LOG: Add subsection and permissions support to ObjectFileJSON. (#129801) This patch adds the ability to create subsections in a section and allows permissions to be specified. Added: Modified: lldb/include/lldb/Core/Section.h lldb/source/Core/Section.cpp lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py Removed: ################################################################################ diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h index 4bf73e2e5a068..17b3cb454949f 100644 --- a/lldb/include/lldb/Core/Section.h +++ b/lldb/include/lldb/Core/Section.h @@ -105,6 +105,11 @@ struct JSONSection { std::optional<lldb::SectionType> type; std::optional<uint64_t> address; std::optional<uint64_t> size; + // Section permissions; + std::optional<bool> read; + std::optional<bool> write; + std::optional<bool> execute; + std::vector<JSONSection> subsections; }; class Section : public std::enable_shared_from_this<Section>, diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp index 96410a1ad497c..608e2a5fc3093 100644 --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -690,7 +690,10 @@ bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSection §ion, llvm::json::Path path) { llvm::json::ObjectMapper o(value, path); return o && o.map("name", section.name) && o.map("type", section.type) && - o.map("address", section.address) && o.map("size", section.size); + o.map("address", section.address) && o.map("size", section.size) && + o.map("read", section.read) && o.map("write", section.write) && + o.map("execute", section.execute) && + o.mapOptional("subsections", section.subsections); } bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type, diff --git a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp index 8e90fac46f348..0f9676b836b50 100644 --- a/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp +++ b/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp @@ -180,18 +180,55 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) { m_sections_up = std::make_unique<SectionList>(); lldb::user_id_t id = 1; - for (const auto §ion : m_sections) { - auto section_sp = std::make_shared<Section>( - GetModule(), this, - /*sect_id=*/id++, - /*name=*/ConstString(section.name), - /*sect_type=*/section.type.value_or(eSectionTypeCode), - /*file_vm_addr=*/section.address.value_or(0), - /*vm_size=*/section.size.value_or(0), - /*file_offset=*/0, - /*file_size=*/0, - /*log2align=*/0, - /*flags=*/0); + for (const auto &json_section : m_sections) { + auto make_section = [this, &id](const JSONSection §ion, + SectionSP parent_section_sp = + nullptr) -> SectionSP { + SectionSP section_sp; + if (parent_section_sp) { + section_sp = std::make_shared<Section>( + parent_section_sp, GetModule(), this, + /*sect_id=*/id++, + /*name=*/ConstString(section.name), + /*sect_type=*/section.type.value_or(eSectionTypeCode), + /*file_vm_addr=*/section.address.value_or(0) - + parent_section_sp->GetFileAddress(), + /*vm_size=*/section.size.value_or(0), + /*file_offset=*/0, + /*file_size=*/0, + /*log2align=*/0, + /*flags=*/0); + + } else { + section_sp = std::make_shared<Section>( + GetModule(), this, + /*sect_id=*/id++, + /*name=*/ConstString(section.name), + /*sect_type=*/section.type.value_or(eSectionTypeCode), + /*file_vm_addr=*/section.address.value_or(0), + /*vm_size=*/section.size.value_or(0), + /*file_offset=*/0, + /*file_size=*/0, + /*log2align=*/0, + /*flags=*/0); + } + uint32_t permissions = 0; + if (section.read.value_or(0)) + permissions |= lldb::ePermissionsReadable; + if (section.write.value_or(0)) + permissions |= lldb::ePermissionsWritable; + if (section.execute.value_or(0)) + permissions |= lldb::ePermissionsExecutable; + if (permissions) + section_sp->SetPermissions(permissions); + return section_sp; + }; + auto section_sp = make_section(json_section); + for (const auto &subsection : json_section.subsections) { + SectionSP subsection_sp = make_section(subsection, section_sp); + section_sp->GetChildren().AddSection(subsection_sp); + } + m_sections_up->AddSection(section_sp); unified_section_list.AddSection(section_sp); } diff --git a/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py b/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py index eee0144ad5706..510788b43d0db 100644 --- a/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py +++ b/lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py @@ -75,16 +75,33 @@ def test_module(self): "sections": [ { "name": "__TEXT", - "type": "code", + "type": "container", "address": TEXT_file_addr, "size": TEXT_size, + "read": True, + "write": False, + "execute": True, + "subsections": [ + { + "name": "__text", + "type": "code", + "address": TEXT_file_addr, + "size": TEXT_size, + "read": True, + "write": False, + "execute": True, + } + ], }, { "name": "__DATA", - "type": "code", + "type": "data", "address": DATA_file_addr, "size": DATA_size, - } + "read": True, + "write": True, + "execute": False, + }, ], "symbols": [ { @@ -108,17 +125,40 @@ def test_module(self): module = target.AddModule(self.toModuleSpec(json_object_file_c)) self.assertTrue(module.IsValid()) - text_section = module.GetSectionAtIndex(0) + TEXT_section = module.GetSectionAtIndex(0) + self.assertTrue(TEXT_section.IsValid()) + self.assertEqual(TEXT_section.GetName(), "__TEXT") + self.assertEqual(TEXT_section.file_addr, TEXT_file_addr) + self.assertEqual(TEXT_section.size, TEXT_size) + self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer) + self.assertEqual(TEXT_section.GetNumSubSections(), 1) + text_permissions = TEXT_section.GetPermissions() + self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0) + self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0) + self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0) + + text_section = TEXT_section.GetSubSectionAtIndex(0) self.assertTrue(text_section.IsValid()) - self.assertEqual(text_section.GetName(), "__TEXT") + self.assertEqual(text_section.GetName(), "__text") self.assertEqual(text_section.file_addr, TEXT_file_addr) self.assertEqual(text_section.size, TEXT_size) - - data_section = module.GetSectionAtIndex(1) - self.assertTrue(data_section.IsValid()) - self.assertEqual(data_section.GetName(), "__DATA") - self.assertEqual(data_section.file_addr, DATA_file_addr) - self.assertEqual(data_section.size, DATA_size) + self.assertEqual(text_section.GetSectionType(), lldb.eSectionTypeCode) + self.assertEqual(text_section.GetNumSubSections(), 0) + text_permissions = text_section.GetPermissions() + self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0) + self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0) + self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0) + + DATA_section = module.GetSectionAtIndex(1) + self.assertTrue(DATA_section.IsValid()) + self.assertEqual(DATA_section.GetName(), "__DATA") + self.assertEqual(DATA_section.file_addr, DATA_file_addr) + self.assertEqual(DATA_section.size, DATA_size) + self.assertEqual(DATA_section.GetSectionType(), lldb.eSectionTypeData) + data_permissions = DATA_section.GetPermissions() + self.assertTrue((data_permissions & lldb.ePermissionsReadable) != 0) + self.assertTrue((data_permissions & lldb.ePermissionsWritable) != 0) + self.assertFalse((data_permissions & lldb.ePermissionsExecutable) != 0) foo_symbol = module.FindSymbol("foo") self.assertTrue(foo_symbol.IsValid()) @@ -130,9 +170,9 @@ def test_module(self): self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr) self.assertEqual(bar_symbol.GetSize(), bar_size) - error = target.SetSectionLoadAddress(text_section, TEXT_file_addr + slide) + error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide) self.assertSuccess(error) - error = target.SetSectionLoadAddress(data_section, DATA_file_addr + slide) + error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide) self.assertSuccess(error) self.assertEqual(foo_symbol.addr.GetLoadAddress(target), foo_file_addr + slide) self.assertEqual(bar_symbol.addr.GetLoadAddress(target), bar_file_addr + slide) _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits