Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions lldb/include/lldb/Core/Section.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,25 @@ class SectionList {
};

struct JSONSection {
std::optional<lldb::user_id_t> user_id;
std::string name;
std::optional<lldb::SectionType> type;
std::optional<uint64_t> address;
std::optional<uint64_t> size;
std::optional<uint64_t> file_offset;
std::optional<uint64_t> file_size;
std::optional<uint64_t> log2align;
std::optional<uint64_t> flags;

// Section permissions;
std::optional<bool> read;
std::optional<bool> write;
std::optional<bool> execute;

std::optional<bool> fake;
std::optional<bool> encrypted;
std::optional<bool> thread_specific;

std::vector<JSONSection> subsections;
};

Expand Down
34 changes: 19 additions & 15 deletions lldb/source/Core/Section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,34 +160,33 @@ const char *Section::GetTypeAsCString() const {
}

Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
user_id_t sect_id, ConstString name,
SectionType sect_type, addr_t file_addr, addr_t byte_size,
lldb::offset_t file_offset, lldb::offset_t file_size,
uint32_t log2align, uint32_t flags,
user_id_t sect_id, ConstString name, SectionType sect_type,
addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
uint32_t target_byte_size /*=1*/)
: ModuleChild(module_sp), UserID(sect_id), Flags(flags),
m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
m_file_addr(file_addr), m_byte_size(byte_size),
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
}
m_executable(false), m_relocated(false),
m_target_byte_size(target_byte_size) {}

Section::Section(const lldb::SectionSP &parent_section_sp,
const ModuleSP &module_sp, ObjectFile *obj_file,
user_id_t sect_id, ConstString name,
SectionType sect_type, addr_t file_addr, addr_t byte_size,
lldb::offset_t file_offset, lldb::offset_t file_size,
uint32_t log2align, uint32_t flags,
user_id_t sect_id, ConstString name, SectionType sect_type,
addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
uint32_t target_byte_size /*=1*/)
: ModuleChild(module_sp), UserID(sect_id), Flags(flags),
m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
m_file_addr(file_addr), m_byte_size(byte_size),
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
m_executable(false), m_relocated(false),
m_target_byte_size(target_byte_size) {
if (parent_section_sp)
m_parent_wp = parent_section_sp;
}
Expand Down Expand Up @@ -469,7 +468,6 @@ bool Section::ContainsOnlyDebugInfo() const {
return false;
}


#pragma mark SectionList

SectionList &SectionList::operator=(const SectionList &rhs) {
Expand Down Expand Up @@ -554,8 +552,7 @@ SectionSP SectionList::GetSectionAtIndex(size_t idx) const {
return sect_sp;
}

SectionSP
SectionList::FindSectionByName(ConstString section_dstr) const {
SectionSP SectionList::FindSectionByName(ConstString section_dstr) const {
SectionSP sect_sp;
// Check if we have a valid section string
if (section_dstr && !m_sections.empty()) {
Expand Down Expand Up @@ -693,7 +690,14 @@ bool fromJSON(const llvm::json::Value &value,
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);
o.mapOptional("subsections", section.subsections) &&
o.map("user_id", section.user_id) &&
o.map("file_offset", section.file_offset) &&
o.map("file_size", section.file_size) &&
o.map("log2align", section.log2align) &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just alignment instead of log2align?

o.map("flags", section.flags) && o.map("fake", section.fake) &&
o.map("encrypted", section.encrypted) &&
o.map("thread_specific", section.thread_specific);
}

bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type,
Expand Down
43 changes: 21 additions & 22 deletions lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,39 +179,35 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
return;
m_sections_up = std::make_unique<SectionList>();

lldb::user_id_t id = 1;
lldb::user_id_t id = 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;
auto sect_id = section.user_id.value_or(id + 1);
if (!section.user_id.has_value())
++id;
const auto name = ConstString(section.name);
const auto sect_type = section.type.value_or(eSectionTypeCode);
const auto vm_addr = section.address.value_or(0);
const auto vm_size = section.size.value_or(0);
const auto file_offset = section.file_offset.value_or(0);
const auto file_size = section.file_size.value_or(0);
const auto log2align = section.log2align.value_or(0);
const auto flags = section.flags.value_or(0);
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);
parent_section_sp, GetModule(), this, sect_id, name, sect_type,
vm_addr - parent_section_sp->GetFileAddress(), vm_size, file_offset,
file_size, log2align, flags);

} 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);
GetModule(), this, sect_id, name, sect_type, vm_addr, vm_size,
file_offset, file_size, log2align, flags);
}
// Set permissions
uint32_t permissions = 0;
if (section.read.value_or(0))
permissions |= lldb::ePermissionsReadable;
Expand All @@ -221,6 +217,9 @@ void ObjectFileJSON::CreateSections(SectionList &unified_section_list) {
permissions |= lldb::ePermissionsExecutable;
if (permissions)
section_sp->SetPermissions(permissions);
section_sp->SetIsFake(section.fake.value_or(false));
section_sp->SetIsEncrypted(section.encrypted.value_or(false));
section_sp->SetIsThreadSpecific(section.thread_specific.value_or(false));
return section_sp;
};
auto section_sp = make_section(json_section);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def test_module(self):
foo_file_addr = TEXT_file_addr + 0x100
bar_file_addr = DATA_file_addr + 0x10
TEXT_size = 0x222
text_size = 0x20
DATA_size = 0x333
foo_size = 0x11
bar_size = 0x22
Expand All @@ -74,10 +75,22 @@ def test_module(self):
"type": "sharedlibrary",
"sections": [
{
"user_id": 0x100,
"name": "__PAGEZERO",
"type": "container",
"address": 0,
"size": 0x100000000,
"flags": 0x101
},
{
"user_id": 0x200,
"name": "__TEXT",
"type": "container",
"address": TEXT_file_addr,
"size": TEXT_size,
"flags": 0x202,
"file_offset": 0,
"file_size": TEXT_size,
"read": True,
"write": False,
"execute": True,
Expand All @@ -86,10 +99,29 @@ def test_module(self):
"name": "__text",
"type": "code",
"address": TEXT_file_addr,
"size": TEXT_size,
"size": text_size,
"log2align": 2,
"read": True,
"write": False,
"execute": True,
},
{
"name": "__fake",
"address": TEXT_file_addr + 1 * text_size,
"size": text_size,
"fake": True
},
{
"name": "__encrypted",
"address": TEXT_file_addr + 2 * text_size,
"size": text_size,
"encrypted": True
},
{
"name": "__tls",
"address": TEXT_file_addr + 2 * text_size,
"size": text_size,
"thread_specific": True
}
],
},
Expand All @@ -101,6 +133,9 @@ def test_module(self):
"read": True,
"write": True,
"execute": False,
"flags": 0x303,
"file_offset": DATA_file_addr - TEXT_file_addr,
"file_size": DATA_size,
},
],
"symbols": [
Expand All @@ -127,33 +162,48 @@ def test_module(self):

TEXT_section = module.GetSectionAtIndex(0)
self.assertTrue(TEXT_section.IsValid())
self.assertEqual(TEXT_section.GetName(), "__PAGEZERO")
self.assertEqual(TEXT_section.file_addr, 0)
self.assertEqual(TEXT_section.size, 0x100000000)
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
self.assertEqual(TEXT_section.GetNumSubSections(), 0)
text_permissions = TEXT_section.GetPermissions()
self.assertFalse((text_permissions & lldb.ePermissionsReadable) != 0)
self.assertFalse((text_permissions & lldb.ePermissionsWritable) != 0)
self.assertFalse((text_permissions & lldb.ePermissionsExecutable) != 0)

TEXT_section = module.GetSectionAtIndex(1)
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.file_offset, 0)
self.assertEqual(TEXT_section.file_size, TEXT_size)
self.assertEqual(TEXT_section.GetSectionType(), lldb.eSectionTypeContainer)
self.assertEqual(TEXT_section.GetNumSubSections(), 1)
self.assertEqual(TEXT_section.GetNumSubSections(), 4)
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.file_addr, TEXT_file_addr)
self.assertEqual(text_section.size, TEXT_size)
self.assertEqual(text_section.size, text_size)
self.assertEqual(text_section.GetAlignment(), 4)
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)
DATA_section = module.GetSectionAtIndex(2)
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.file_offset, DATA_file_addr - TEXT_file_addr)
self.assertEqual(DATA_section.file_size, DATA_size)
self.assertEqual(DATA_section.GetSectionType(), lldb.eSectionTypeData)
data_permissions = DATA_section.GetPermissions()
self.assertTrue((data_permissions & lldb.ePermissionsReadable) != 0)
Expand All @@ -170,6 +220,19 @@ def test_module(self):
self.assertEqual(bar_symbol.addr.GetFileAddress(), bar_file_addr)
self.assertEqual(bar_symbol.GetSize(), bar_size)

# Verify the user_ids and flags are set correctly since there is no API
# for this on lldb.SBSection
self.expect("target modules dump sections c.json",
substrs = [
"0x0000000000000100 container [0x0000000000000000-0x0000000100000000) --- 0x00000000 0x00000000 0x00000101 c.json.__PAGEZERO",
"0x0000000000000200 container [0x0000000100000000-0x0000000100000222) r-x 0x00000000 0x00000222 0x00000202 c.json.__TEXT",
"0x0000000000000001 code [0x0000000100000000-0x0000000100000020) r-x 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__text",
"0x0000000000000002 code [0x0000000100000020-0x0000000100000040) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__fake",
"0x0000000000000003 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__encrypted",
"0x0000000000000004 code [0x0000000100000040-0x0000000100000060) --- 0x00000000 0x00000000 0x00000000 c.json.__TEXT.__tls",
"0x0000000000000005 data [0x0000000100001000-0x0000000100001333) rw- 0x00001000 0x00000333 0x00000303 c.json.__DATA"
])

error = target.SetSectionLoadAddress(TEXT_section, TEXT_file_addr + slide)
self.assertSuccess(error)
error = target.SetSectionLoadAddress(DATA_section, DATA_file_addr + slide)
Expand Down
Loading