Skip to content

Commit 95c4f1e

Browse files
committed
[lldb] Set static Module's load addresses via ObjectFile (llvm#87439)
This is a followup to llvm#86359 "[lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory (llvm#86359)" where I treat LLVM_COV segments in a Mach-O binary as non-loadable. There is another codepath in `DynamicLoaderStatic::LoadAllImagesAtFileAddresses` which is called to set the load addresses for a Module to the file addresses. It has no logic to detect a segment that is not loaded in virtual memory (ObjectFileMachO::SectionIsLoadable), so it would set the load address for this LLVM_COV segment to the file address and shadow actual code, breaking lldb behavior. This method currently sets the load address for any section that doesn't have a load address set already. This presumes that a Module was added to the Target, some mechanism set the correct load address for SOME segments, and then this method is going to set the other segments to a no-slide value, assuming they were forgotten. ObjectFile base class doesn't, today, vend a SectionIsLoadable method, but we do have ObjectFile::SetLoadAddress and at a higher level, Module::SetLoadAddress, when we're setting the same slide to all segments. That's the behavior we want in this method. If any section has a load address, we don't touch this Module. Otherwise we set all sections to have a load address that is the same as the file address. I also audited the other parts of lldb that are calling SectionList::SectionLoadAddress and looked if they should be more correctly using Module::SetLoadAddress for the entire binary. But in most cases, we have the potential for different slides for different sections so this section-by-section approach must be taken. rdar://125800290 (cherry picked from commit 622851a)
1 parent f264422 commit 95c4f1e

File tree

1 file changed

+16
-24
lines changed

1 file changed

+16
-24
lines changed

lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,51 +84,43 @@ void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
8484
// Disable JIT for static dynamic loader targets
8585
m_process->SetCanJIT(false);
8686

87+
Target &target = m_process->GetTarget();
8788
for (ModuleSP module_sp : module_list.Modules()) {
8889
if (module_sp) {
8990
bool changed = false;
91+
bool no_load_addresses = true;
92+
// If this module has a section with a load address set in
93+
// the target, assume all necessary work is already done. There
94+
// may be sections without a load address set intentionally
95+
// and we don't want to mutate that.
96+
// For a module with no load addresses set, set the load addresses
97+
// to slide == 0, the same as the file addresses, in the target.
9098
ObjectFile *image_object_file = module_sp->GetObjectFile();
9199
if (image_object_file) {
92100
SectionList *section_list = image_object_file->GetSectionList();
93101
if (section_list) {
94-
// All sections listed in the dyld image info structure will all
95-
// either be fixed up already, or they will all be off by a single
96-
// slide amount that is determined by finding the first segment that
97-
// is at file offset zero which also has bytes (a file size that is
98-
// greater than zero) in the object file.
99-
100-
// Determine the slide amount (if any)
101102
const size_t num_sections = section_list->GetSize();
102-
size_t sect_idx = 0;
103-
for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
104-
// Iterate through the object file sections to find the first
105-
// section that starts of file offset zero and that has bytes in
106-
// the file...
103+
for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
107104
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
108105
if (section_sp) {
109-
// If this section already has a load address set in the target,
110-
// don't re-set it to the file address. Something may have
111-
// set it to a more correct value already.
112-
if (m_process->GetTarget()
113-
.GetSectionLoadList()
114-
.GetSectionLoadAddress(section_sp) !=
115-
LLDB_INVALID_ADDRESS) {
116-
continue;
106+
if (target.GetSectionLoadList().GetSectionLoadAddress(
107+
section_sp) != LLDB_INVALID_ADDRESS) {
108+
no_load_addresses = false;
109+
break;
117110
}
118-
if (m_process->GetTarget().SetSectionLoadAddress(
119-
section_sp, section_sp->GetFileAddress()))
120-
changed = true;
121111
}
122112
}
123113
}
124114
}
115+
if (no_load_addresses)
116+
module_sp->SetLoadAddress(target, 0, true /*value_is_offset*/, changed);
125117

126118
if (changed)
127119
loaded_module_list.AppendIfNeeded(module_sp);
128120
}
129121
}
130122

131-
m_process->GetTarget().ModulesDidLoad(loaded_module_list);
123+
target.ModulesDidLoad(loaded_module_list);
132124
}
133125

134126
ThreadPlanSP

0 commit comments

Comments
 (0)