Skip to content

Commit cba7da1

Browse files
[lldb] Introduce Process::FixAnyAddressPreservingAuthentication
This is yet another variant of the Fix{Code,Data}Address methods, but tailored for pointers that both: 1. Are going to be used in-process, 2. Require authentication metadata. Currently, the callsite inside IRMemoryMap::WritePointerToMemory is an example of 1; the pointer written to memory will be used by JITed code during expression evaluation. An example of (2) can be found in the MTE extension on arm processors. An MTE-tagged pointer must preserve its normal bits in order for load instructions to complete without faulting. However, PAC bits must be stripped, as codegen for some expressions may generate regular load instructions for accesses to those (instead of the special PAC instructions).
1 parent b21dd44 commit cba7da1

File tree

7 files changed

+34
-2
lines changed

7 files changed

+34
-2
lines changed

lldb/include/lldb/Target/ABI.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class ABI : public PluginInterface {
141141
return FixDataAddress(pc);
142142
}
143143

144+
virtual lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) {
145+
return FixAnyAddress(pc);
146+
}
147+
144148
llvm::MCRegisterInfo &GetMCRegisterInfo() { return *m_mc_register_info_up; }
145149

146150
virtual void

lldb/include/lldb/Target/Process.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,6 +1464,11 @@ class Process : public std::enable_shared_from_this<Process>,
14641464
/// platforms where there is a difference (only Arm Thumb at this time).
14651465
lldb::addr_t FixAnyAddress(lldb::addr_t pc);
14661466

1467+
/// Strip pointer metadata except for the bits necessary to authenticate a
1468+
/// memory access. This is useful, for example, if `address` requires
1469+
/// authentication and it is going to be consumed in JITed code.
1470+
lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t address);
1471+
14671472
/// Get the Modification ID of the process.
14681473
///
14691474
/// \return

lldb/source/Expression/IRMemoryMap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address,
647647
if (it == m_allocations.end() ||
648648
it->second.m_policy != AllocationPolicy::eAllocationPolicyHostOnly)
649649
if (auto process_sp = GetProcessWP().lock())
650-
pointer = process_sp->FixAnyAddress(pointer);
650+
pointer = process_sp->FixAnyAddressPreservingAuthentication(pointer);
651651

652652
Scalar scalar(pointer);
653653

lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,15 @@ addr_t ABIMacOSX_arm64::FixDataAddress(addr_t addr) {
792792
return DoFixAddr(addr, false /*is_code*/, GetProcessSP());
793793
}
794794

795+
addr_t ABIMacOSX_arm64::FixAnyAddressPreservingAuthentication(addr_t addr) {
796+
// Save the old MTE tag and restore it later.
797+
constexpr addr_t mte_mask = 0x0f00000000000000ULL;
798+
addr_t old_mte_tag = addr & mte_mask;
799+
800+
addr_t fixed_addr = FixDataAddress(addr);
801+
return old_mte_tag | (fixed_addr & (~mte_mask));
802+
}
803+
795804
void ABIMacOSX_arm64::Initialize() {
796805
PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
797806
CreateInstance);

lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class ABIMacOSX_arm64 : public ABIAArch64 {
5959

6060
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
6161
lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
62+
lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) override;
6263

6364
// Static Functions
6465

lldb/source/Target/Process.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5971,6 +5971,12 @@ addr_t Process::FixAnyAddress(addr_t addr) {
59715971
return addr;
59725972
}
59735973

5974+
addr_t Process::FixAnyAddressPreservingAuthentication(addr_t addr) {
5975+
if (ABISP abi_sp = GetABI())
5976+
addr = abi_sp->FixAnyAddressPreservingAuthentication(addr);
5977+
return addr;
5978+
}
5979+
59745980
void Process::DidExec() {
59755981
Log *log = GetLog(LLDBLog::Process);
59765982
LLDB_LOGF(log, "Process::%s()", __FUNCTION__);

lldb/test/API/pointer-nonaddressable-bits/TestArmPointerMetadataStripping.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,15 @@ def test(self):
4141
symbols_file = self.create_symbols_file()
4242
self.runCmd(f"target module add {symbols_file}")
4343

44+
# The address of myglobal_json is: 0x1200AAAAAAAB1014
4445
# The high order bits should be stripped.
45-
self.expect_expr("get_high_bits(&myglobal_json)", result_value="0")
46+
# On Darwin platforms, the lower nibble of the most significant byte is preserved.
47+
if platform.system() == "Darwin":
48+
expected_value = str(0x200000000000000)
49+
else:
50+
expected_value = "0"
51+
52+
self.expect_expr("get_high_bits(&myglobal_json)", result_value=expected_value)
4653

4754
# Mark all bits as used for addresses and ensure bits are no longer stripped.
4855
self.runCmd("settings set target.process.virtual-addressable-bits 64")

0 commit comments

Comments
 (0)