Skip to content

[NFC][lldb] Adapt LLDB to RemoteInspection's RemoteAddress changes #10981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
134 changes: 63 additions & 71 deletions lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ bool LLDBMemoryReader::queryDataLayout(DataLayoutQueryType type, void *inBuffer,
return false;
// The mask returned by the process masks out the non-addressable bits.
uint64_t mask_pattern = ~ptrauth_mask;
// LLDBMemoryReader sets LLDB_FILE_ADDRESS_BIT to distinguish process
// addresses and file addresses that point into a reflection section on
// disk. Setting the bit in the mask ensures it isn't accidentally cleared
// by ptrauth stripping.
mask_pattern |= LLDB_FILE_ADDRESS_BIT;
memcpy(outBuffer, &mask_pattern, m_process.GetAddressByteSize());
return true;
}
Expand Down Expand Up @@ -84,7 +79,7 @@ swift::remote::RemoteAddress
LLDBMemoryReader::getSymbolAddress(const std::string &name) {
lldbassert(!name.empty());
if (name.empty())
return swift::remote::RemoteAddress(nullptr);
return swift::remote::RemoteAddress();

Log *log = GetLog(LLDBLog::Types);

Expand All @@ -97,7 +92,7 @@ LLDBMemoryReader::getSymbolAddress(const std::string &name) {
name_cs, lldb::eSymbolTypeAny, sc_list);
if (!sc_list.GetSize()) {
LLDB_LOGV(log, "[MemoryReader] symbol resolution failed {0}", name);
return swift::remote::RemoteAddress(nullptr);
return swift::remote::RemoteAddress();
}

SymbolContext sym_ctx;
Expand All @@ -118,14 +113,15 @@ LLDBMemoryReader::getSymbolAddress(const std::string &name) {
if (sym_ctx.symbol) {
auto load_addr = sym_ctx.symbol->GetLoadAddress(&m_process.GetTarget());
LLDB_LOGV(log, "[MemoryReader] symbol resolved to {0:x}", load_addr);
return swift::remote::RemoteAddress(load_addr);
return swift::remote::RemoteAddress(
load_addr, swift::remote::RemoteAddress::DefaultAddressSpace);
}
}

// Empty list, resolution failed.
if (sc_list.GetSize() == 0) {
LLDB_LOGV(log, "[MemoryReader] symbol resolution failed {0}", name);
return swift::remote::RemoteAddress(nullptr);
return swift::remote::RemoteAddress();
}

// If there's a single symbol, then we're golden. If there's more than
Expand All @@ -140,11 +136,12 @@ LLDBMemoryReader::getSymbolAddress(const std::string &name) {
load_addr, m_process.GetAddressByteSize(), 0, error, true);
if (sym_value != other_sym_value) {
LLDB_LOGV(log, "[MemoryReader] symbol resolution failed {0}", name);
return swift::remote::RemoteAddress(nullptr);
return swift::remote::RemoteAddress();
}
}
LLDB_LOGV(log, "[MemoryReader] symbol resolved to {0}", load_addr);
return swift::remote::RemoteAddress(load_addr);
return swift::remote::RemoteAddress(
load_addr, swift::remote::RemoteAddress::DefaultAddressSpace);
}

static std::unique_ptr<swift::SwiftObjectFileFormat>
Expand Down Expand Up @@ -179,8 +176,7 @@ LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) {
if (!target.GetSwiftUseReflectionSymbols())
return {};

std::optional<Address> maybeAddr =
resolveRemoteAddress(address.getAddressData());
std::optional<Address> maybeAddr = remoteAddressToLLDBAddress(address);
// This is not an assert, but should never happen.
if (!maybeAddr)
return {};
Expand All @@ -191,7 +187,7 @@ LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) {
addr = *maybeAddr;
} else {
// `address` is a real load address.
if (!target.ResolveLoadAddress(address.getAddressData(), addr))
if (!target.ResolveLoadAddress(address.getRawAddress(), addr))
return {};
}

Expand All @@ -214,7 +210,7 @@ LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) {
// aware of local symbols, so avoid returning those.
using namespace swift::Demangle;
if (isSwiftSymbol(mangledName) && !isOldFunctionTypeMangling(mangledName))
return {{mangledName, 0}};
return swift::remote::RemoteAbsolutePointer{mangledName, 0, address};
}

return {};
Expand All @@ -228,23 +224,28 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
// We may have gotten a pointer to a process address, try to map it back
// to a tagged address so further memory reads originating from it benefit
// from the file-cache optimization.
swift::remote::RemoteAbsolutePointer process_pointer("", readValue);
swift::remote::RemoteAbsolutePointer process_pointer{
swift::remote::RemoteAddress{readValue, address.getAddressSpace()}};

if (!readMetadataFromFileCacheEnabled())
if (!readMetadataFromFileCacheEnabled()) {
assert(address.getAddressSpace() ==
swift::remote::RemoteAddress::DefaultAddressSpace &&
"Unexpected address space!");
return process_pointer;
}

// Try to strip the pointer before checking if we have it mapped.
auto strippedPointer = signedPointerStripper(process_pointer);
if (strippedPointer.isResolved())
readValue = strippedPointer.getOffset();
if (auto resolved = strippedPointer.getResolvedAddress())
readValue = resolved.getRawAddress();

auto &target = m_process.GetTarget();
Address addr;
if (!target.ResolveLoadAddress(readValue, addr)) {
LLDB_LOGV(log,
"[MemoryReader] Could not resolve load address of pointer {0:x} "
"read from {1:x}.",
readValue, address.getAddressData());
readValue, address.getRawAddress());
return process_pointer;
}

Expand All @@ -262,15 +263,15 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
LLDB_LOG(log,
"[MemoryReader] Could not resolve find module containing pointer "
"{0:x} read from {1:x}.",
readValue, address.getAddressData());
readValue, address.getRawAddress());
return process_pointer;
}

// If the containing image is the first registered one, the image's tagged
// start address for it is the first tagged address. Otherwise, the previous
// pair's address is the start tagged address.
// start address for it is zero. Otherwise, the previous pair's address is the
// start of the new address.
uint64_t start_tagged_address = pair_iterator == m_range_module_map.begin()
? LLDB_FILE_ADDRESS_BIT
? 0
: std::prev(pair_iterator)->first;

auto *section_list = module_containing_pointer->GetSectionList();
Expand All @@ -289,13 +290,16 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
LLDB_LOG(log,
"[MemoryReader] Pointer {0:x} read from {1:x} resolved to tagged "
"address {2:x}, which is outside its image address space.",
readValue, address.getAddressData(), tagged_address);
readValue, address.getRawAddress(), tagged_address);
return process_pointer;
}

swift::remote::RemoteAbsolutePointer tagged_pointer("", tagged_address);
if (tagged_address !=
(uint64_t)signedPointerStripper(tagged_pointer).getOffset()) {
swift::remote::RemoteAbsolutePointer tagged_pointer{
swift::remote::RemoteAddress{tagged_address, LLDBAddressSpace}};

if (tagged_address != (uint64_t)signedPointerStripper(tagged_pointer)
.getResolvedAddress()
.getRawAddress()) {
lldbassert(false &&
"Tagged pointer runs into pointer authentication mask!");
return process_pointer;
Expand All @@ -304,7 +308,7 @@ LLDBMemoryReader::resolvePointer(swift::remote::RemoteAddress address,
LLDB_LOGV(log,
"[MemoryReader] Successfully resolved pointer {0:x} read from "
"{1:x} to tagged address {2:x}.",
readValue, address.getAddressData(), tagged_address);
readValue, address.getRawAddress(), tagged_address);
return tagged_pointer;
}

Expand All @@ -313,7 +317,7 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address,
Log *log = GetLog(LLDBLog::Types);
if (m_local_buffer) {
bool overflow = false;
auto addr = address.getAddressData();
auto addr = address.getRawAddress();
auto end = llvm::SaturatingAdd(addr, size, &overflow);
if (overflow) {
LLDB_LOGV(log, "[MemoryReader] address {0:x} + size {1} overflows", addr,
Expand All @@ -331,16 +335,16 @@ bool LLDBMemoryReader::readBytes(swift::remote::RemoteAddress address,
}

LLDB_LOGV(log, "[MemoryReader] asked to read {0} bytes at address {1:x}",
size, address.getAddressData());
size, address.getRawAddress());
std::optional<Address> maybeAddr =
resolveRemoteAddressFromSymbolObjectFile(address.getAddressData());
resolveRemoteAddressFromSymbolObjectFile(address);

if (!maybeAddr)
maybeAddr = resolveRemoteAddress(address.getAddressData());
maybeAddr = remoteAddressToLLDBAddress(address);

if (!maybeAddr) {
LLDB_LOGV(log, "[MemoryReader] could not resolve address {0:x}",
address.getAddressData());
address.getRawAddress());
return false;
}
auto addr = *maybeAddr;
Expand Down Expand Up @@ -407,17 +411,17 @@ bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address,
return std::string(stream.GetData());
};
LLDB_LOGV(log, "[MemoryReader] asked to read string data at address {0:x}",
address.getAddressData());
address.getRawAddress());

std::optional<Address> maybeAddr =
resolveRemoteAddressFromSymbolObjectFile(address.getAddressData());
resolveRemoteAddressFromSymbolObjectFile(address);

if (!maybeAddr)
maybeAddr = resolveRemoteAddress(address.getAddressData());
maybeAddr = remoteAddressToLLDBAddress(address);

if (!maybeAddr) {
LLDB_LOGV(log, "[MemoryReader] could not resolve address {0:x}",
address.getAddressData());
address.getRawAddress());
return false;
}
auto addr = *maybeAddr;
Expand Down Expand Up @@ -453,7 +457,7 @@ bool LLDBMemoryReader::readString(swift::remote::RemoteAddress address,

MemoryReaderLocalBufferHolder::~MemoryReaderLocalBufferHolder() {
if (m_memory_reader)
m_memory_reader->popLocalBuffer();
m_memory_reader->popLocalBuffer();
}

MemoryReaderLocalBufferHolder
Expand Down Expand Up @@ -482,12 +486,9 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module,
"Trying to register symbol object file, but reading from it is "
"disabled!");

// The first available address is the mask, since subsequent images are mapped
// in ascending order, all of them will contain this mask.
uint64_t module_start_address = LLDB_FILE_ADDRESS_BIT;
uint64_t module_start_address = 0;
if (!m_range_module_map.empty())
// We map the images contiguously one after the other, all with the tag bit
// set.
// We map the images contiguously one after the other.
// The address that maps the last module is exactly the address the new
// module should start at.
module_start_address = m_range_module_map.back().first;
Expand Down Expand Up @@ -533,15 +534,6 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module,
auto size = end_file_address - start_file_address;
auto module_end_address = module_start_address + size;

if (module_end_address !=
(uint64_t)signedPointerStripper(
swift::remote::RemoteAbsolutePointer("", module_end_address))
.getOffset()) {
LLDB_LOG(GetLog(LLDBLog::Types),
"[MemoryReader] module to address map ran into pointer "
"authentication mask!");
return {};
}
// The address for the next image is the next pointer aligned address
// available after the end of the current image.
uint64_t next_module_start_address = llvm::alignTo(module_end_address, 8);
Expand All @@ -555,18 +547,18 @@ LLDBMemoryReader::addModuleToAddressMap(ModuleSP module,

std::optional<std::pair<uint64_t, lldb::ModuleSP>>
LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress(
uint64_t tagged_address) const {
swift::remote::RemoteAddress tagged_address) const {
Log *log(GetLog(LLDBLog::Types));

if (!readMetadataFromFileCacheEnabled())
return {};

// If the address contains our mask, this is an image we registered.
if (!(tagged_address & LLDB_FILE_ADDRESS_BIT))
if (tagged_address.getAddressSpace() != LLDBAddressSpace)
return {};

// Dummy pair with the address we're looking for.
auto comparison_pair = std::make_pair(tagged_address, ModuleSP());
auto comparison_pair =
std::make_pair(tagged_address.getRawAddress(), ModuleSP());

// Explicitly compare only the addresses, never the modules in the pairs.
auto pair_iterator = std::lower_bound(
Expand All @@ -578,7 +570,7 @@ LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress(
LLDB_LOG(log,
"[MemoryReader] Address {0:x} is larger than the upper bound "
"address of the mapped in modules",
tagged_address);
tagged_address.getRawAddress());
return {};
}

Expand All @@ -590,14 +582,13 @@ LLDBMemoryReader::getFileAddressAndModuleForTaggedAddress(
}
uint64_t file_address;
if (pair_iterator == m_range_module_map.begin())
// Since this is the first registered module,
// clearing the tag bit will give the virtual file address.
file_address = tagged_address & ~LLDB_FILE_ADDRESS_BIT;
file_address = tagged_address.getRawAddress();
else
// The end of the previous section is the start of the current one.
// We also need to add the first section's file address since we remove it
// when constructing the range to module map.
file_address = tagged_address - std::prev(pair_iterator)->first;
file_address =
(tagged_address - std::prev(pair_iterator)->first).getRawAddress();

// We also need to add the module's file address, since we subtract it when
// building the range to module map.
Expand All @@ -609,27 +600,28 @@ std::optional<swift::reflection::RemoteAddress>
LLDBMemoryReader::resolveRemoteAddress(
swift::reflection::RemoteAddress address) const {
std::optional<Address> lldb_address =
LLDBMemoryReader::resolveRemoteAddress(address.getAddressData());
LLDBMemoryReader::remoteAddressToLLDBAddress(address);
if (!lldb_address)
return {};
lldb::addr_t addr = lldb_address->GetLoadAddress(&m_process.GetTarget());
if (addr != LLDB_INVALID_ADDRESS)
return swift::reflection::RemoteAddress(addr);
return swift::reflection::RemoteAddress(
addr, swift::reflection::RemoteAddress::DefaultAddressSpace);
return {};
}

std::optional<Address>
LLDBMemoryReader::resolveRemoteAddress(uint64_t address) const {
std::optional<Address> LLDBMemoryReader::remoteAddressToLLDBAddress(
swift::remote::RemoteAddress address) const {
Log *log(GetLog(LLDBLog::Types));
auto maybe_pair = getFileAddressAndModuleForTaggedAddress(address);
if (!maybe_pair)
return Address(address);
return Address(address.getRawAddress());

uint64_t file_address = maybe_pair->first;
ModuleSP module = maybe_pair->second;

if (m_modules_with_metadata_in_symbol_obj_file.count(module))
return Address(address);
return Address(address.getRawAddress());

auto *object_file = module->GetObjectFile();
if (!object_file)
Expand All @@ -645,7 +637,7 @@ LLDBMemoryReader::resolveRemoteAddress(uint64_t address) const {
LLDB_LOGV(log,
"[MemoryReader] Successfully resolved mapped address {0:x} into "
"file address {1:x}",
address, resolved.GetFileAddress());
address.getRawAddress(), resolved.GetFileAddress());
return resolved;
}
auto *sec_list = module->GetSectionList();
Expand Down Expand Up @@ -689,7 +681,7 @@ LLDBMemoryReader::resolveRemoteAddress(uint64_t address) const {

std::optional<Address>
LLDBMemoryReader::resolveRemoteAddressFromSymbolObjectFile(
uint64_t address) const {
swift::remote::RemoteAddress address) const {
Log *log(GetLog(LLDBLog::Types));

if (!m_process.GetTarget().GetSwiftReadMetadataFromDSYM())
Expand Down Expand Up @@ -733,7 +725,7 @@ LLDBMemoryReader::resolveRemoteAddressFromSymbolObjectFile(
LLDB_LOGV(log,
"[MemoryReader] Successfully resolved mapped address {0:x} into "
"file address {1:x} from symbol object file.",
address, file_address);
address.getRawAddress(), file_address);
return resolved;
}

Expand Down
Loading