Skip to content

Commit 8ac359b

Browse files
authored
Add complete ObjectFileJSON support for sections. (#129916)
Sections now support specifying: - user IDs - file offset/size - alignment - flags - bool values for fake, encrypted and thread specific sections
1 parent 0ea5223 commit 8ac359b

File tree

5 files changed

+171
-47
lines changed

5 files changed

+171
-47
lines changed

lldb/docs/use/symbolfilejson.rst

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,61 @@ sections
7474
* ``type``: a string representing the section type (see below).
7575
* ``address``: a number representing the section file address.
7676
* ``size``: a number representing the section size in bytes.
77+
* ``read``: a boolean value indicating if the section has read permissions.
78+
* ``write``: a boolean value indicating if the section has write permissions.
79+
* ``execute``: a boolean value indicating if the section has execute permissions.
80+
* ``subsections``: An array of child sections in the same format.
81+
* ``user_id``: a number representing the section identifier.
82+
* ``file_offset``: a number that represents the offset in the file for this section's contents.
83+
* ``file_size``: a number that represents the size in bytes in the file for this section's contents.
84+
* ``alignment``: a boolean value indicating if the section has execute permissions.
85+
* ``fake``: a boolean value indicating if the section is fake.
86+
* ``encrypted``: a boolean value indicating if the section is encrypted.
87+
* ``thread_specific``: a boolean value indicating if the section is thread specific.
7788

7889
.. code-block:: JSON
7990
8091
{
81-
"name": "__TEXT",
82-
"type": "code",
83-
"address": 0,
84-
"size": 546,
92+
"user_id": 256,
93+
"name": "__TEXT",
94+
"type": "code",
95+
"address": 0,
96+
"size": 546,
97+
"file_offset": 0,
98+
"file_size": 4096,
99+
"read": true,
100+
"write": false,
101+
"executable": true,
102+
"subsections": [
103+
{
104+
"name": "__text",
105+
"type": "code",
106+
"address": 0,
107+
"size": 200,
108+
"alignment": 2,
109+
"read": true,
110+
"write": false,
111+
"execute": true
112+
},
113+
{
114+
"name": "__fake",
115+
"address": 200,
116+
"size": 10,
117+
"fake": true
118+
},
119+
{
120+
"name": "__encrypted",
121+
"address": 210,
122+
"size": 20,
123+
"encrypted": true
124+
},
125+
{
126+
"name": "__tls",
127+
"address": 230,
128+
"size": 30,
129+
"thread_specific": true
130+
}
131+
]
85132
}
86133
87134
The ``type`` field accepts the following values: ``code``, ``container``,

lldb/include/lldb/Core/Section.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,25 @@ class SectionList {
101101
};
102102

103103
struct JSONSection {
104+
std::optional<lldb::user_id_t> user_id;
104105
std::string name;
105106
std::optional<lldb::SectionType> type;
106107
std::optional<uint64_t> address;
107108
std::optional<uint64_t> size;
109+
std::optional<uint64_t> file_offset;
110+
std::optional<uint64_t> file_size;
111+
std::optional<uint64_t> log2align;
112+
std::optional<uint64_t> flags;
113+
108114
// Section permissions;
109115
std::optional<bool> read;
110116
std::optional<bool> write;
111117
std::optional<bool> execute;
118+
119+
std::optional<bool> fake;
120+
std::optional<bool> encrypted;
121+
std::optional<bool> thread_specific;
122+
112123
std::vector<JSONSection> subsections;
113124
};
114125

lldb/source/Core/Section.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -160,34 +160,33 @@ const char *Section::GetTypeAsCString() const {
160160
}
161161

162162
Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
163-
user_id_t sect_id, ConstString name,
164-
SectionType sect_type, addr_t file_addr, addr_t byte_size,
165-
lldb::offset_t file_offset, lldb::offset_t file_size,
166-
uint32_t log2align, uint32_t flags,
163+
user_id_t sect_id, ConstString name, SectionType sect_type,
164+
addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
165+
lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
167166
uint32_t target_byte_size /*=1*/)
168167
: ModuleChild(module_sp), UserID(sect_id), Flags(flags),
169168
m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
170169
m_file_addr(file_addr), m_byte_size(byte_size),
171170
m_file_offset(file_offset), m_file_size(file_size),
172171
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
173172
m_thread_specific(false), m_readable(false), m_writable(false),
174-
m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
175-
}
173+
m_executable(false), m_relocated(false),
174+
m_target_byte_size(target_byte_size) {}
176175

177176
Section::Section(const lldb::SectionSP &parent_section_sp,
178177
const ModuleSP &module_sp, ObjectFile *obj_file,
179-
user_id_t sect_id, ConstString name,
180-
SectionType sect_type, addr_t file_addr, addr_t byte_size,
181-
lldb::offset_t file_offset, lldb::offset_t file_size,
182-
uint32_t log2align, uint32_t flags,
178+
user_id_t sect_id, ConstString name, SectionType sect_type,
179+
addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
180+
lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
183181
uint32_t target_byte_size /*=1*/)
184182
: ModuleChild(module_sp), UserID(sect_id), Flags(flags),
185183
m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
186184
m_file_addr(file_addr), m_byte_size(byte_size),
187185
m_file_offset(file_offset), m_file_size(file_size),
188186
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
189187
m_thread_specific(false), m_readable(false), m_writable(false),
190-
m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
188+
m_executable(false), m_relocated(false),
189+
m_target_byte_size(target_byte_size) {
191190
if (parent_section_sp)
192191
m_parent_wp = parent_section_sp;
193192
}
@@ -469,7 +468,6 @@ bool Section::ContainsOnlyDebugInfo() const {
469468
return false;
470469
}
471470

472-
473471
#pragma mark SectionList
474472

475473
SectionList &SectionList::operator=(const SectionList &rhs) {
@@ -554,8 +552,7 @@ SectionSP SectionList::GetSectionAtIndex(size_t idx) const {
554552
return sect_sp;
555553
}
556554

557-
SectionSP
558-
SectionList::FindSectionByName(ConstString section_dstr) const {
555+
SectionSP SectionList::FindSectionByName(ConstString section_dstr) const {
559556
SectionSP sect_sp;
560557
// Check if we have a valid section string
561558
if (section_dstr && !m_sections.empty()) {
@@ -693,7 +690,14 @@ bool fromJSON(const llvm::json::Value &value,
693690
o.map("address", section.address) && o.map("size", section.size) &&
694691
o.map("read", section.read) && o.map("write", section.write) &&
695692
o.map("execute", section.execute) &&
696-
o.mapOptional("subsections", section.subsections);
693+
o.mapOptional("subsections", section.subsections) &&
694+
o.map("user_id", section.user_id) &&
695+
o.map("file_offset", section.file_offset) &&
696+
o.map("file_size", section.file_size) &&
697+
o.map("alignment", section.log2align) &&
698+
o.map("flags", section.flags) && o.map("fake", section.fake) &&
699+
o.map("encrypted", section.encrypted) &&
700+
o.map("thread_specific", section.thread_specific);
697701
}
698702

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

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

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -179,39 +179,35 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
179179
return;
180180
m_sections_up = std::make_unique<SectionList>();
181181

182-
lldb::user_id_t id = 1;
182+
lldb::user_id_t id = 0;
183183
for (const auto &json_section : m_sections) {
184184
auto make_section = [this, &id](const JSONSection &section,
185185
SectionSP parent_section_sp =
186186
nullptr) -> SectionSP {
187187
SectionSP section_sp;
188+
auto sect_id = section.user_id.value_or(id + 1);
189+
if (!section.user_id.has_value())
190+
++id;
191+
const auto name = ConstString(section.name);
192+
const auto sect_type = section.type.value_or(eSectionTypeCode);
193+
const auto vm_addr = section.address.value_or(0);
194+
const auto vm_size = section.size.value_or(0);
195+
const auto file_offset = section.file_offset.value_or(0);
196+
const auto file_size = section.file_size.value_or(0);
197+
const auto log2align = section.log2align.value_or(0);
198+
const auto flags = section.flags.value_or(0);
188199
if (parent_section_sp) {
189200
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+
parent_section_sp, GetModule(), this, sect_id, name, sect_type,
202+
vm_addr - parent_section_sp->GetFileAddress(), vm_size, file_offset,
203+
file_size, log2align, flags);
201204

202205
} else {
203206
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);
207+
GetModule(), this, sect_id, name, sect_type, vm_addr, vm_size,
208+
file_offset, file_size, log2align, flags);
214209
}
210+
// Set permissions
215211
uint32_t permissions = 0;
216212
if (section.read.value_or(0))
217213
permissions |= lldb::ePermissionsReadable;
@@ -221,6 +217,9 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
221217
permissions |= lldb::ePermissionsExecutable;
222218
if (permissions)
223219
section_sp->SetPermissions(permissions);
220+
section_sp->SetIsFake(section.fake.value_or(false));
221+
section_sp->SetIsEncrypted(section.encrypted.value_or(false));
222+
section_sp->SetIsThreadSpecific(section.thread_specific.value_or(false));
224223
return section_sp;
225224
};
226225
auto section_sp = make_section(json_section);

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

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def test_module(self):
6464
foo_file_addr = TEXT_file_addr + 0x100
6565
bar_file_addr = DATA_file_addr + 0x10
6666
TEXT_size = 0x222
67+
text_size = 0x20
6768
DATA_size = 0x333
6869
foo_size = 0x11
6970
bar_size = 0x22
@@ -74,10 +75,22 @@ def test_module(self):
7475
"type": "sharedlibrary",
7576
"sections": [
7677
{
78+
"user_id": 0x100,
79+
"name": "__PAGEZERO",
80+
"type": "container",
81+
"address": 0,
82+
"size": 0x100000000,
83+
"flags": 0x101
84+
},
85+
{
86+
"user_id": 0x200,
7787
"name": "__TEXT",
7888
"type": "container",
7989
"address": TEXT_file_addr,
8090
"size": TEXT_size,
91+
"flags": 0x202,
92+
"file_offset": 0,
93+
"file_size": TEXT_size,
8194
"read": True,
8295
"write": False,
8396
"execute": True,
@@ -86,10 +99,29 @@ def test_module(self):
8699
"name": "__text",
87100
"type": "code",
88101
"address": TEXT_file_addr,
89-
"size": TEXT_size,
102+
"size": text_size,
103+
"alignment": 2,
90104
"read": True,
91105
"write": False,
92106
"execute": True,
107+
},
108+
{
109+
"name": "__fake",
110+
"address": TEXT_file_addr + 1 * text_size,
111+
"size": text_size,
112+
"fake": True
113+
},
114+
{
115+
"name": "__encrypted",
116+
"address": TEXT_file_addr + 2 * text_size,
117+
"size": text_size,
118+
"encrypted": True
119+
},
120+
{
121+
"name": "__tls",
122+
"address": TEXT_file_addr + 2 * text_size,
123+
"size": text_size,
124+
"thread_specific": True
93125
}
94126
],
95127
},
@@ -101,6 +133,9 @@ def test_module(self):
101133
"read": True,
102134
"write": True,
103135
"execute": False,
136+
"flags": 0x303,
137+
"file_offset": DATA_file_addr - TEXT_file_addr,
138+
"file_size": DATA_size,
104139
},
105140
],
106141
"symbols": [
@@ -127,33 +162,48 @@ def test_module(self):
127162

128163
TEXT_section = module.GetSectionAtIndex(0)
129164
self.assertTrue(TEXT_section.IsValid())
165+
self.assertEqual(TEXT_section.GetName(), "__PAGEZERO")
166+
self.assertEqual(TEXT_section.file_addr, 0)
167+
self.assertEqual(TEXT_section.size, 0x100000000)
168+
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
169+
self.assertEqual(TEXT_section.GetNumSubSections(), 0)
170+
text_permissions = TEXT_section.GetPermissions()
171+
self.assertFalse((text_permissions & lldb.ePermissionsReadable) != 0)
172+
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
173+
self.assertFalse((text_permissions & lldb.ePermissionsExecutable) != 0)
174+
175+
TEXT_section = module.GetSectionAtIndex(1)
176+
self.assertTrue(TEXT_section.IsValid())
130177
self.assertEqual(TEXT_section.GetName(), "__TEXT")
131178
self.assertEqual(TEXT_section.file_addr, TEXT_file_addr)
132179
self.assertEqual(TEXT_section.size, TEXT_size)
180+
self.assertEqual(TEXT_section.file_offset, 0)
181+
self.assertEqual(TEXT_section.file_size, TEXT_size)
133182
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
134-
self.assertEqual(TEXT_section.GetNumSubSections(), 1)
183+
self.assertEqual(TEXT_section.GetNumSubSections(), 4)
135184
text_permissions = TEXT_section.GetPermissions()
136185
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
137186
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
138187
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
139188

140189
text_section = TEXT_section.GetSubSectionAtIndex(0)
141-
self.assertTrue(text_section.IsValid())
142190
self.assertEqual(text_section.GetName(), "__text")
143-
self.assertEqual(text_section.file_addr, TEXT_file_addr)
144-
self.assertEqual(text_section.size, TEXT_size)
191+
self.assertEqual(text_section.size, text_size)
192+
self.assertEqual(text_section.GetAlignment(), 4)
145193
self.assertEqual(text_section.GetSectionType(), lldb.eSectionTypeCode)
146194
self.assertEqual(text_section.GetNumSubSections(), 0)
147195
text_permissions = text_section.GetPermissions()
148196
self.assertTrue((text_permissions & lldb.ePermissionsReadable) != 0)
149197
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
150198
self.assertTrue((text_permissions & lldb.ePermissionsExecutable) != 0)
151199

152-
DATA_section = module.GetSectionAtIndex(1)
200+
DATA_section = module.GetSectionAtIndex(2)
153201
self.assertTrue(DATA_section.IsValid())
154202
self.assertEqual(DATA_section.GetName(), "__DATA")
155203
self.assertEqual(DATA_section.file_addr, DATA_file_addr)
156204
self.assertEqual(DATA_section.size, DATA_size)
205+
self.assertEqual(DATA_section.file_offset, DATA_file_addr - TEXT_file_addr)
206+
self.assertEqual(DATA_section.file_size, DATA_size)
157207
self.assertEqual(DATA_section.GetSectionType(), lldb.eSectionTypeData)
158208
data_permissions = DATA_section.GetPermissions()
159209
self.assertTrue((data_permissions & lldb.ePermissionsReadable) != 0)
@@ -170,6 +220,19 @@ def test_module(self):
170220
self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr)
171221
self.assertEqual(bar_symbol.GetSize(), bar_size)
172222

223+
# Verify the user_ids and flags are set correctly since there is no API
224+
# for this on lldb.SBSection
225+
self.expect("target modules dump sections c.json",
226+
substrs = [
227+
"0x0000000000000100 container [0x0000000000000000-0x0000000100000000) --- 0x00000000 0x00000000 0x00000101 c.json.__PAGEZERO",
228+
"0x0000000000000200 container [0x0000000100000000-0x0000000100000222) r-x 0x00000000 0x00000222 0x00000202 c.json.__TEXT",
229+
"0x0000000000000001 code [0x0000000100000000-0x0000000100000020) r-x 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__text",
230+
"0x0000000000000002 code [0x0000000100000020-0x0000000100000040) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__fake",
231+
"0x0000000000000003 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__encrypted",
232+
"0x0000000000000004 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__tls",
233+
"0x0000000000000005 data [0x0000000100001000-0x0000000100001333) rw- 0x00001000 0x00000333 0x00000303 c.json.__DATA"
234+
])
235+
173236
error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide)
174237
self.assertSuccess(error)
175238
error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide)

0 commit comments

Comments
 (0)