Skip to content

Commit 865121c

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). (cherry picked from commit 37ad33e39ac960178e4cf02e5598db35a279ae21) (cherry picked from commit 31724b1)
1 parent f6ba211 commit 865121c

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
@@ -1473,6 +1473,11 @@ class Process : public std::enable_shared_from_this<Process>,
14731473
/// platforms where there is a difference (only Arm Thumb at this time).
14741474
lldb::addr_t FixAnyAddress(lldb::addr_t pc);
14751475

1476+
/// Strip pointer metadata except for the bits necessary to authenticate a
1477+
/// memory access. This is useful, for example, if `address` requires
1478+
/// authentication and it is going to be consumed in JITed code.
1479+
lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t address);
1480+
14761481
/// Get the Modification ID of the process.
14771482
///
14781483
/// \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
@@ -6133,6 +6133,12 @@ addr_t Process::FixAnyAddress(addr_t addr) {
61336133
return addr;
61346134
}
61356135

6136+
addr_t Process::FixAnyAddressPreservingAuthentication(addr_t addr) {
6137+
if (ABISP abi_sp = GetABI())
6138+
addr = abi_sp->FixAnyAddressPreservingAuthentication(addr);
6139+
return addr;
6140+
}
6141+
61366142
void Process::DidExec() {
61376143
Log *log = GetLog(LLDBLog::Process);
61386144
LLDB_LOGF(log, "Process::%s()", __FUNCTION__);

lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py

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

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

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

0 commit comments

Comments
 (0)