jasonmolenda created this revision. jasonmolenda added reviewers: DavidSpickett, jingham, clayborg. jasonmolenda added a project: LLDB. Herald added subscribers: JDevlieghere, kristof.beyls. Herald added a project: All. jasonmolenda requested review of this revision. Herald added a subscriber: lldb-commits.
We've had a few people doing SB API scripting who have asked for access to the Process settings of address masks, and API to fix address+metadata down to just addressable memory. We're mostly focused on AArch64 these days at Apple so the number of addressing bits is what everyone is really asking for, but given that Linux's native representation is an address mask which can express things number-of-bits cannot, the SB API needs to represent that way, I think. I'm also including the "Highmem" variants here, which makes for a not great looking SB API additions, but I know someone is going to need it. I'm open to suggestions or rejections of including this. There is an environment I need to support where they have items in both high and low memory (in the same execution level) with different page table settings for both so they have different numbers of addressing bits for low and high memory. This is quite uncommon I think -- if you have code running in high and low memory simultaneously, it's usually a kernel in high memory at EL1 and userland in low memory at EL0 and on Darwin they run with the same page table setups. For the internal Process API, I didn't mind having these separate Highmem accessors which only differed from the base ones when we're in this situation of low & high memory on AArch64 having different page table setups. The only user of this is the Apple AArch64 ABI plugin when fixing addresses, so it wasn't something most people needed to consider. But putting it in SBProcess, it locks the API down more. Adding Fix*Address is obvious. No tests written yet, I didn't want to get ahead of myself. Given that I can get / set the address masks with these API, it will be easy enough to mutate it, run some uint64_t's through the Fix*Address API and confirm they're modified. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D155905 Files: lldb/include/lldb/API/SBProcess.h lldb/source/API/SBProcess.cpp
Index: lldb/source/API/SBProcess.cpp =================================================================== --- lldb/source/API/SBProcess.cpp +++ lldb/source/API/SBProcess.cpp @@ -1243,6 +1243,83 @@ return sb_proc_info; } +addr_t SBProcess::GetCodeAddressMask() { + LLDB_INSTRUMENT_VA(this); + addr_t default_mask = 0; + if (ProcessSP process_sp = GetSP()) + return process_sp->GetCodeAddressMask(); + return default_mask; +} + +addr_t SBProcess::GetDataAddressMask() { + LLDB_INSTRUMENT_VA(this); + addr_t default_mask = 0; + if (ProcessSP process_sp = GetSP()) + return process_sp->GetDataAddressMask(); + return default_mask; +} + +addr_t SBProcess::GetHighmemCodeAddressMask() { + LLDB_INSTRUMENT_VA(this); + addr_t default_mask = 0; + if (ProcessSP process_sp = GetSP()) + return process_sp->GetHighmemCodeAddressMask(); + return default_mask; +} + +addr_t SBProcess::GetHighmemDataAddressMask() { + LLDB_INSTRUMENT_VA(this); + addr_t default_mask = 0; + if (ProcessSP process_sp = GetSP()) + return process_sp->GetHighmemDataAddressMask(); + return default_mask; +} + +void SBProcess::SetCodeAddressMask(addr_t mask) { + LLDB_INSTRUMENT_VA(this, mask); + if (ProcessSP process_sp = GetSP()) + process_sp->SetCodeAddressMask(mask); +} + +void SBProcess::SetDataAddressMask(addr_t mask) { + LLDB_INSTRUMENT_VA(this, mask); + if (ProcessSP process_sp = GetSP()) + process_sp->SetDataAddressMask(mask); +} + +void SBProcess::SetHighmemCodeAddressMask(addr_t mask) { + LLDB_INSTRUMENT_VA(this, mask); + if (ProcessSP process_sp = GetSP()) + process_sp->SetHighmemCodeAddressMask(mask); +} + +void SBProcess::SetHighmemDataAddressMask(addr_t mask) { + LLDB_INSTRUMENT_VA(this, mask); + if (ProcessSP process_sp = GetSP()) + process_sp->SetHighmemDataAddressMask(mask); +} + +addr_t SBProcess::FixCodeAddress(addr_t addr) { + LLDB_INSTRUMENT_VA(this, addr); + if (ProcessSP process_sp = GetSP()) + return process_sp->FixCodeAddress(addr); + return addr; +} + +addr_t SBProcess::FixDataAddress(addr_t addr) { + LLDB_INSTRUMENT_VA(this, addr); + if (ProcessSP process_sp = GetSP()) + return process_sp->FixDataAddress(addr); + return addr; +} + +addr_t SBProcess::FixAnyAddress(addr_t addr) { + LLDB_INSTRUMENT_VA(this, addr); + if (ProcessSP process_sp = GetSP()) + return process_sp->FixAnyAddress(addr); + return addr; +} + lldb::addr_t SBProcess::AllocateMemory(size_t size, uint32_t permissions, lldb::SBError &sb_error) { LLDB_INSTRUMENT_VA(this, size, permissions, sb_error); Index: lldb/include/lldb/API/SBProcess.h =================================================================== --- lldb/include/lldb/API/SBProcess.h +++ lldb/include/lldb/API/SBProcess.h @@ -398,6 +398,60 @@ /// valid. lldb::SBProcessInfo GetProcessInfo(); + /// Get the current address mask that may be applied to addresses + /// before reading from memory. The bits which are not relevant/valid + /// for addressing should be set. + /// + /// The user may override this value via the + /// target.process.virtual-addressable-bits setting, and the FixCodeAddress / + /// FixDataAddress will use the setting value instead of the Process address + /// mask. + /// + /// If the low ten bits are the only valid bits for addressing, + /// this would be the correct mask: + /// + /// (lldb) p/x ~((1ULL << 10) - 1) + /// (unsigned long long) 0xfffffffffffffc00 + lldb::addr_t GetCodeAddressMask(); + lldb::addr_t GetDataAddressMask(); + + /// If there is a separate address mask for low memory (starts with 0) + /// addresses high memory (starts with 0xf) addresses, this will return + /// the high memory address masks. It is uncommon to have a target + /// that executes in both high and low memory, with different address masks, + /// but it does occur. + lldb::addr_t GetHighmemCodeAddressMask(); + lldb::addr_t GetHighmemDataAddressMask(); + + /// Set the current address mask that may be applied to addresses + /// before reading from memory. The bits which are not relevant/valid + /// for addressing will be set. + /// + /// If the low ten bits are the only valid bits for addressing, + /// this would be the mask returned: + /// + /// (lldb) p/x ~((1ULL << 10) - 1) + /// (unsigned long long) 0xfffffffffffffc00 + void SetCodeAddressMask(lldb::addr_t mask); + void SetDataAddressMask(lldb::addr_t mask); + + /// If there is a separate address mask for low memory (starts with 0) + /// addresses high memory (starts with 0xf) addresses, this will set + /// the high memory address masks. It is uncommon to have a target + /// that executes in both high and low memory, with different address masks, + /// but it does occur. + void SetHighmemCodeAddressMask(lldb::addr_t mask); + void SetHighmemDataAddressMask(lldb::addr_t mask); + + /// Given an address that may contain non-addressable metadata, and + /// we want to resolve it to addressable memory, this will use the + /// process address masks (or the target.process.virtual-addressable-bits + /// setting specified by the user) to remove the non-addressable bits and + /// return the actual address. + lldb::addr_t FixCodeAddress(lldb::addr_t addr); + lldb::addr_t FixDataAddress(lldb::addr_t addr); + lldb::addr_t FixAnyAddress(lldb::addr_t addr); + /// Allocate memory within the process. /// /// This function will allocate memory in the process's address space.
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits