Skip to content

Commit 31724b1

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)
1 parent 1c84c9b commit 31724b1

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
@@ -140,6 +140,10 @@ class ABI : public PluginInterface {
140140
return FixDataAddress(pc);
141141
}
142142

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

145149
virtual void

lldb/include/lldb/Target/Process.h

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

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

lldb/source/Expression/IRMemoryMap.cpp

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

650650
Scalar scalar(pointer);
651651

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

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

849+
addr_t ABIMacOSX_arm64::FixAnyAddressPreservingAuthentication(addr_t addr) {
850+
// Save the old MTE tag and restore it later.
851+
constexpr addr_t mte_mask = 0x0f00000000000000ULL;
852+
addr_t old_mte_tag = addr & mte_mask;
853+
854+
addr_t fixed_addr = FixDataAddress(addr);
855+
return old_mte_tag | (fixed_addr & (~mte_mask));
856+
}
857+
849858
void ABIMacOSX_arm64::Initialize() {
850859
PluginManager::RegisterPlugin(GetPluginNameStatic(), pluginDesc,
851860
CreateInstance);

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

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

6565
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override;
6666
lldb::addr_t FixDataAddress(lldb::addr_t pc) override;
67+
lldb::addr_t FixAnyAddressPreservingAuthentication(lldb::addr_t pc) override;
6768

6869
// Static Functions
6970

lldb/source/Target/Process.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6048,6 +6048,12 @@ addr_t Process::FixAnyAddress(addr_t addr) {
60486048
return addr;
60496049
}
60506050

6051+
addr_t Process::FixAnyAddressPreservingAuthentication(addr_t addr) {
6052+
if (ABISP abi_sp = GetABI())
6053+
addr = abi_sp->FixAnyAddressPreservingAuthentication(addr);
6054+
return addr;
6055+
}
6056+
60516057
void Process::DidExec() {
60526058
Log *log = GetLog(LLDBLog::Process);
60536059
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
@@ -39,8 +39,15 @@ def test(self):
3939
symbols_file = self.create_symbols_file()
4040
self.runCmd(f"target module add {symbols_file}")
4141

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

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

0 commit comments

Comments
 (0)