Skip to content

Commit c527460

Browse files
committed
[lldb] Subtract module start address when building addr to module map
When building the LLDBMemoryReader module to address map, it was assumed that a module would start at address 0, when this was not necessarily true. If many modules had a high start file address, the module map could potentially use up all the available space, and potentially clash with the pointer authentication mask. This patch accounts subtracts the module's start address when building the map, and also verifies that the addresses handed out can't be affected by the pointer authentication mask. rdar://106055569
1 parent 417f36c commit c527460

File tree

2 files changed

+57
-10
lines changed

2 files changed

+57
-10
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,16 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
229229
? LLDB_FILE_ADDRESS_BIT
230230
: std::prev(pair_iterator)->first;
231231

232-
uint64_t tagged_address = start_tagged_address + addr.GetFileAddress();
232+
auto *section_list = module_containing_pointer->GetSectionList();
233+
if (section_list->GetSize() == 0) {
234+
LLDB_LOG(log,
235+
"[MemoryReader] Module with empty section list.");
236+
return {};
237+
}
238+
239+
uint64_t tagged_address =
240+
start_tagged_address + addr.GetFileAddress() -
241+
section_list->GetSectionAtIndex(0)->GetFileAddress();
233242

234243
if (tagged_address >= std::get<uint64_t>(*pair_iterator)) {
235244
// If the tagged address invades the next image's tagged address space,
@@ -241,11 +250,19 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
241250
return process_pointer;
242251
}
243252

253+
swift::remote::RemoteAbsolutePointer tagged_pointer("", tagged_address);
254+
if (tagged_address !=
255+
(uint64_t)signedPointerStripper(tagged_pointer).getOffset()) {
256+
lldb_assert(false, "Tagged pointer runs into pointer authentication mask!",
257+
__FUNCTION__, __FILE__, __LINE__);
258+
return process_pointer;
259+
}
260+
244261
LLDB_LOGV(log,
245262
"[MemoryReader] Successfully resolved pointer {0:x} read from "
246263
"{1:x} to tagged address {2:x}.",
247264
readValue, address.getAddressData(), tagged_address);
248-
return swift::remote::RemoteAbsolutePointer("", tagged_address);
265+
return tagged_pointer;
249266
}
250267

251268
bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address,
@@ -454,13 +471,28 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module,
454471
if (section_list_size == 0)
455472
return {};
456473

474+
auto first_section = section_list->GetSectionAtIndex(0);
457475
auto last_section =
458476
section_list->GetSectionAtIndex(section_list->GetSize() - 1);
459-
// The virtual file address + the size of last section gives us the total size
460-
// of this image in memory.
461-
uint64_t size = last_section->GetFileAddress() + last_section->GetByteSize();
477+
478+
// The total size is the last section's file address plus size, subtracting the
479+
// first section's file address.
480+
auto start_file_address = first_section->GetFileAddress();
481+
uint64_t end_file_address =
482+
last_section->GetFileAddress() + last_section->GetByteSize();
483+
auto size = end_file_address - start_file_address;
462484
auto module_end_address = module_start_address + size;
463485

486+
if (module_end_address !=
487+
(uint64_t)signedPointerStripper(
488+
swift::remote::RemoteAbsolutePointer("", module_end_address))
489+
.getOffset()) {
490+
lldb_assert(false,
491+
"LLDBMemoryReader module to address map ran into pointer "
492+
"authentication mask!",
493+
__FUNCTION__, __FILE__, __LINE__);
494+
return {};
495+
}
464496
// The address for the next image is the next pointer aligned address
465497
// available after the end of the current image.
466498
uint64_t next_module_start_address = llvm::alignTo(module_end_address, 8);
@@ -502,15 +534,26 @@ LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress(
502534
}
503535

504536
ModuleSP module = pair_iterator->second;
537+
auto *section_list = module->GetSectionList();
538+
if (section_list->GetSize() == 0) {
539+
LLDB_LOG(log,
540+
"[MemoryReader] Module with empty section list.");
541+
return {};
542+
}
505543
uint64_t file_address;
506544
if (pair_iterator == m_range_module_map.begin())
507545
// Since this is the first registered module,
508546
// clearing the tag bit will give the virtual file address.
509547
file_address = tagged_address & ~LLDB_FILE_ADDRESS_BIT;
510548
else
511549
// The end of the previous section is the start of the current one.
550+
// We also need to add the first section's file address since we remove it
551+
// when constructing the range to module map.
512552
file_address = tagged_address - std::prev(pair_iterator)->first;
513553

554+
// We also need to add the module's file address, since we subtract it when
555+
// building the range to module map.
556+
file_address += section_list->GetSectionAtIndex(0)->GetFileAddress();
514557
return {{file_address, module}};
515558
}
516559

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,9 @@ SwiftLanguageRuntimeImpl::AddObjectFileToReflectionContext(
771771
std::tie(start_address, end_address) = *maybe_start_and_end;
772772

773773
auto *section_list = object_file->GetSectionList();
774+
if (section_list->GetSize() == 0)
775+
return false;
776+
774777
auto segment_iter = llvm::find_if(*section_list, [&](auto segment) {
775778
return segment->GetName() == segment_name.begin();
776779
});
@@ -813,11 +816,12 @@ SwiftLanguageRuntimeImpl::AddObjectFileToReflectionContext(
813816
std::memcpy(Buf, data.begin(), size);
814817

815818
// The section's address is the start address for this image
816-
// added with the section's virtual address. We need to use the
817-
// virtual address instead of the file offset because the offsets
818-
// encoded in the reflection section are calculated in the virtual
819-
// address space.
820-
auto address = start_address + section->GetFileAddress();
819+
// added with the section's virtual address subtracting the start of the
820+
// module's address. We need to use the virtual address instead of the
821+
// file offset because the offsets encoded in the reflection section are
822+
// calculated in the virtual address space.
823+
auto address = start_address + section->GetFileAddress() -
824+
section_list->GetSectionAtIndex(0)->GetFileAddress();
821825
assert(address <= end_address && "Address outside of range!");
822826

823827
swift::remote::RemoteRef<void> remote_ref(address, Buf);

0 commit comments

Comments
 (0)