summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2024-04-03 16:40:34 -0700
committerGitHub <noreply@github.com>2024-04-03 16:40:34 -0700
commit622851a9059694487811a7f6078312fc2cce5486 (patch)
tree27c9c3f65ba21df4d5030a30c90248034a6955f8
parent750843875254b1d493f4d7c3d3921c1bced55b7c (diff)
[lldb] Set static Module's load addresses via ObjectFile (#87439)
This is a followup to https://github.com/llvm/llvm-project/pull/86359 "[lldb] [ObjectFileMachO] LLVM_COV is not mapped into firmware memory (#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
-rw-r--r--lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp40
1 files changed, 16 insertions, 24 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
index a39aa2280ab8..545998123dda 100644
--- a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
@@ -84,51 +84,43 @@ void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
// Disable JIT for static dynamic loader targets
m_process->SetCanJIT(false);
+ Target &target = m_process->GetTarget();
for (ModuleSP module_sp : module_list.Modules()) {
if (module_sp) {
bool changed = false;
+ bool no_load_addresses = true;
+ // If this module has a section with a load address set in
+ // the target, assume all necessary work is already done. There
+ // may be sections without a load address set intentionally
+ // and we don't want to mutate that.
+ // For a module with no load addresses set, set the load addresses
+ // to slide == 0, the same as the file addresses, in the target.
ObjectFile *image_object_file = module_sp->GetObjectFile();
if (image_object_file) {
SectionList *section_list = image_object_file->GetSectionList();
if (section_list) {
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment that
- // is at file offset zero which also has bytes (a file size that is
- // greater than zero) in the object file.
-
- // Determine the slide amount (if any)
const size_t num_sections = section_list->GetSize();
- size_t sect_idx = 0;
- for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
- // Iterate through the object file sections to find the first
- // section that starts of file offset zero and that has bytes in
- // the file...
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
if (section_sp) {
- // If this section already has a load address set in the target,
- // don't re-set it to the file address. Something may have
- // set it to a more correct value already.
- if (m_process->GetTarget()
- .GetSectionLoadList()
- .GetSectionLoadAddress(section_sp) !=
- LLDB_INVALID_ADDRESS) {
- continue;
+ if (target.GetSectionLoadList().GetSectionLoadAddress(
+ section_sp) != LLDB_INVALID_ADDRESS) {
+ no_load_addresses = false;
+ break;
}
- if (m_process->GetTarget().SetSectionLoadAddress(
- section_sp, section_sp->GetFileAddress()))
- changed = true;
}
}
}
}
+ if (no_load_addresses)
+ module_sp->SetLoadAddress(target, 0, true /*value_is_offset*/, changed);
if (changed)
loaded_module_list.AppendIfNeeded(module_sp);
}
}
- m_process->GetTarget().ModulesDidLoad(loaded_module_list);
+ target.ModulesDidLoad(loaded_module_list);
}
ThreadPlanSP