[Lldb-commits] [lldb] 27901ce - Add subsection and permissions support to ObjectFileJSON. (#129801)

via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 4 16:19:24 PST 2025


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 &section, 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 &section : 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 &section,
+                                    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)


        


More information about the lldb-commits mailing list