Skip to content

Commit 91c0ef6

Browse files
authored
[lldb] [ObjectFileMachO] BSS segments are loadable segments (#96983)
ObjectFileMachO::SetLoadAddress sets the address of each segment in a binary in a Target, but it ignores segments that are not loaded in the virtual address space. It was marking segments that were purely BSS -- having no content in the file, but in zero-initialized memory when running in the virtual address space -- as not-loadable, unless they were named "DATA". This works pretty well for typical userland binaries, but in less Darwin environments, there may be BSS segments with other names, that ARE loadable. I looked at the origin of SectionIsLoadable's check for this, and it was a cleanup by Greg in 2018 where we had three different implementations of the idea in ObjectFileMachO and one of them skipped zero-file-size segments (BSS), which made it into the centralized SectionIsLoadable method. Also add some logging to the DynamicLoader log channel when loading a binary - it's the first place I look when debugging segment address setting bugs, and it wasn't emitting anything. rdar://129870649
1 parent 6f60d2b commit 91c0ef6

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6159,10 +6159,6 @@ Section *ObjectFileMachO::GetMachHeaderSection() {
61596159
bool ObjectFileMachO::SectionIsLoadable(const Section *section) {
61606160
if (!section)
61616161
return false;
6162-
const bool is_dsym = (m_header.filetype == MH_DSYM);
6163-
if (section->GetFileSize() == 0 && !is_dsym &&
6164-
section->GetName() != GetSegmentNameDATA())
6165-
return false;
61666162
if (section->IsThreadSpecific())
61676163
return false;
61686164
if (GetModule().get() != section->GetModule().get())
@@ -6202,6 +6198,7 @@ lldb::addr_t ObjectFileMachO::CalculateSectionLoadAddressForMemoryImage(
62026198

62036199
bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
62046200
bool value_is_offset) {
6201+
Log *log(GetLog(LLDBLog::DynamicLoader));
62056202
ModuleSP module_sp = GetModule();
62066203
if (!module_sp)
62076204
return false;
@@ -6217,17 +6214,33 @@ bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
62176214
// malformed.
62186215
const bool warn_multiple = true;
62196216

6217+
if (log) {
6218+
StreamString logmsg;
6219+
logmsg << "ObjectFileMachO::SetLoadAddress ";
6220+
if (GetFileSpec())
6221+
logmsg << "path='" << GetFileSpec().GetPath() << "' ";
6222+
if (GetUUID()) {
6223+
logmsg << "uuid=" << GetUUID().GetAsString();
6224+
}
6225+
LLDB_LOGF(log, "%s", logmsg.GetData());
6226+
}
62206227
if (value_is_offset) {
62216228
// "value" is an offset to apply to each top level segment
62226229
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
62236230
// Iterate through the object file sections to find all of the
62246231
// sections that size on disk (to avoid __PAGEZERO) and load them
62256232
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
6226-
if (SectionIsLoadable(section_sp.get()))
6233+
if (SectionIsLoadable(section_sp.get())) {
6234+
LLDB_LOGF(log,
6235+
"ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
6236+
"0x%" PRIx64,
6237+
section_sp->GetName().AsCString(),
6238+
section_sp->GetFileAddress() + value);
62276239
if (target.GetSectionLoadList().SetSectionLoadAddress(
62286240
section_sp, section_sp->GetFileAddress() + value,
62296241
warn_multiple))
62306242
++num_loaded_sections;
6243+
}
62316244
}
62326245
} else {
62336246
// "value" is the new base address of the mach_header, adjust each
@@ -6242,6 +6255,10 @@ bool ObjectFileMachO::SetLoadAddress(Target &target, lldb::addr_t value,
62426255
CalculateSectionLoadAddressForMemoryImage(
62436256
value, mach_header_section, section_sp.get());
62446257
if (section_load_addr != LLDB_INVALID_ADDRESS) {
6258+
LLDB_LOGF(log,
6259+
"ObjectFileMachO::SetLoadAddress segment '%s' load addr is "
6260+
"0x%" PRIx64,
6261+
section_sp->GetName().AsCString(), section_load_addr);
62456262
if (target.GetSectionLoadList().SetSectionLoadAddress(
62466263
section_sp, section_load_addr, warn_multiple))
62476264
++num_loaded_sections;

0 commit comments

Comments
 (0)