Skip to content

Commit 27901ce

Browse files
authored
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.
1 parent e697c99 commit 27901ce

File tree

4 files changed

+111
-26
lines changed

4 files changed

+111
-26
lines changed

lldb/include/lldb/Core/Section.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ struct JSONSection {
105105
std::optional<lldb::SectionType> type;
106106
std::optional<uint64_t> address;
107107
std::optional<uint64_t> size;
108+
// Section permissions;
109+
std::optional<bool> read;
110+
std::optional<bool> write;
111+
std::optional<bool> execute;
112+
std::vector<JSONSection> subsections;
108113
};
109114

110115
class Section : public std::enable_shared_from_this<Section>,

lldb/source/Core/Section.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,10 @@ bool fromJSON(const llvm::json::Value &value,
690690
lldb_private::JSONSection &section, llvm::json::Path path) {
691691
llvm::json::ObjectMapper o(value, path);
692692
return o && o.map("name", section.name) && o.map("type", section.type) &&
693-
o.map("address", section.address) && o.map("size", section.size);
693+
o.map("address", section.address) && o.map("size", section.size) &&
694+
o.map("read", section.read) && o.map("write", section.write) &&
695+
o.map("execute", section.execute) &&
696+
o.mapOptional("subsections", section.subsections);
694697
}
695698

696699
bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type,

lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -180,18 +180,55 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
180180
m_sections_up = std::make_unique<SectionList>();
181181

182182
lldb::user_id_t id = 1;
183-
for (const auto &section : m_sections) {
184-
auto section_sp = std::make_shared<Section>(
185-
GetModule(), this,
186-
/*sect_id=*/id++,
187-
/*name=*/ConstString(section.name),
188-
/*sect_type=*/section.type.value_or(eSectionTypeCode),
189-
/*file_vm_addr=*/section.address.value_or(0),
190-
/*vm_size=*/section.size.value_or(0),
191-
/*file_offset=*/0,
192-
/*file_size=*/0,
193-
/*log2align=*/0,
194-
/*flags=*/0);
183+
for (const auto &json_section : m_sections) {
184+
auto make_section = [this, &id](const JSONSection &section,
185+
SectionSP parent_section_sp =
186+
nullptr) -> SectionSP {
187+
SectionSP section_sp;
188+
if (parent_section_sp) {
189+
section_sp = std::make_shared<Section>(
190+
parent_section_sp, GetModule(), this,
191+
/*sect_id=*/id++,
192+
/*name=*/ConstString(section.name),
193+
/*sect_type=*/section.type.value_or(eSectionTypeCode),
194+
/*file_vm_addr=*/section.address.value_or(0) -
195+
parent_section_sp->GetFileAddress(),
196+
/*vm_size=*/section.size.value_or(0),
197+
/*file_offset=*/0,
198+
/*file_size=*/0,
199+
/*log2align=*/0,
200+
/*flags=*/0);
201+
202+
} else {
203+
section_sp = std::make_shared<Section>(
204+
GetModule(), this,
205+
/*sect_id=*/id++,
206+
/*name=*/ConstString(section.name),
207+
/*sect_type=*/section.type.value_or(eSectionTypeCode),
208+
/*file_vm_addr=*/section.address.value_or(0),
209+
/*vm_size=*/section.size.value_or(0),
210+
/*file_offset=*/0,
211+
/*file_size=*/0,
212+
/*log2align=*/0,
213+
/*flags=*/0);
214+
}
215+
uint32_t permissions = 0;
216+
if (section.read.value_or(0))
217+
permissions |= lldb::ePermissionsReadable;
218+
if (section.write.value_or(0))
219+
permissions |= lldb::ePermissionsWritable;
220+
if (section.execute.value_or(0))
221+
permissions |= lldb::ePermissionsExecutable;
222+
if (permissions)
223+
section_sp->SetPermissions(permissions);
224+
return section_sp;
225+
};
226+
auto section_sp = make_section(json_section);
227+
for (const auto &subsection : json_section.subsections) {
228+
SectionSP subsection_sp = make_section(subsection, section_sp);
229+
section_sp->GetChildren().AddSection(subsection_sp);
230+
}
231+
195232
m_sections_up->AddSection(section_sp);
196233
unified_section_list.AddSection(section_sp);
197234
}

lldb/test/API/functionalities/json/object-file/TestObjectFileJSON.py

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,33 @@ def test_module(self):
7575
"sections": [
7676
{
7777
"name": "__TEXT",
78-
"type": "code",
78+
"type": "container",
7979
"address": TEXT_file_addr,
8080
"size": TEXT_size,
81+
"read": True,
82+
"write": False,
83+
"execute": True,
84+
"subsections": [
85+
{
86+
"name": "__text",
87+
"type": "code",
88+
"address": TEXT_file_addr,
89+
"size": TEXT_size,
90+
"read": True,
91+
"write": False,
92+
"execute": True,
93+
}
94+
],
8195
},
8296
{
8397
"name": "__DATA",
84-
"type": "code",
98+
"type": "data",
8599
"address": DATA_file_addr,
86100
"size": DATA_size,
87-
}
101+
"read": True,
102+
"write": True,
103+
"execute": False,
104+
},
88105
],
89106
"symbols": [
90107
{
@@ -108,17 +125,40 @@ def test_module(self):
108125
module = target.AddModule(self.toModuleSpec(json_object_file_c))
109126
self.assertTrue(module.IsValid())
110127

111-
text_section = module.GetSectionAtIndex(0)
128+
TEXT_section = module.GetSectionAtIndex(0)
129+
self.assertTrue(TEXT_section.IsValid())
130+
self.assertEqual(TEXT_section.GetName(), "__TEXT")
131+
self.assertEqual(TEXT_section.file_addr, TEXT_file_addr)
132+
self.assertEqual(TEXT_section.size, TEXT_size)
133+
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
134+
self.assertEqual(TEXT_section.GetNumSubSections(), 1)
135+
text_permissions = TEXT_section.GetPermissions()
136+
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
137+
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
138+
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
139+
140+
text_section = TEXT_section.GetSubSectionAtIndex(0)
112141
self.assertTrue(text_section.IsValid())
113-
self.assertEqual(text_section.GetName(), "__TEXT")
142+
self.assertEqual(text_section.GetName(), "__text")
114143
self.assertEqual(text_section.file_addr, TEXT_file_addr)
115144
self.assertEqual(text_section.size, TEXT_size)
116-
117-
data_section = module.GetSectionAtIndex(1)
118-
self.assertTrue(data_section.IsValid())
119-
self.assertEqual(data_section.GetName(), "__DATA")
120-
self.assertEqual(data_section.file_addr, DATA_file_addr)
121-
self.assertEqual(data_section.size, DATA_size)
145+
self.assertEqual(text_section.GetSectionType(), lldb.eSectionTypeCode)
146+
self.assertEqual(text_section.GetNumSubSections(), 0)
147+
text_permissions = text_section.GetPermissions()
148+
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
149+
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
150+
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
151+
152+
DATA_section = module.GetSectionAtIndex(1)
153+
self.assertTrue(DATA_section.IsValid())
154+
self.assertEqual(DATA_section.GetName(), "__DATA")
155+
self.assertEqual(DATA_section.file_addr, DATA_file_addr)
156+
self.assertEqual(DATA_section.size, DATA_size)
157+
self.assertEqual(DATA_section.GetSectionType(), lldb.eSectionTypeData)
158+
data_permissions = DATA_section.GetPermissions()
159+
self.assertTrue((data_permissions & lldb.ePermissionsReadable) != 0)
160+
self.assertTrue((data_permissions & lldb.ePermissionsWritable) != 0)
161+
self.assertFalse((data_permissions & lldb.ePermissionsExecutable) != 0)
122162

123163
foo_symbol = module.FindSymbol("foo")
124164
self.assertTrue(foo_symbol.IsValid())
@@ -130,9 +170,9 @@ def test_module(self):
130170
self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr)
131171
self.assertEqual(bar_symbol.GetSize(), bar_size)
132172

133-
error = target.SetSectionLoadAddress(text_section, TEXT_file_addr + slide)
173+
error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide)
134174
self.assertSuccess(error)
135-
error = target.SetSectionLoadAddress(data_section, DATA_file_addr + slide)
175+
error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide)
136176
self.assertSuccess(error)
137177
self.assertEqual(foo_symbol.addr.GetLoadAddress(target), foo_file_addr + slide)
138178
self.assertEqual(bar_symbol.addr.GetLoadAddress(target), bar_file_addr + slide)

0 commit comments

Comments
 (0)