diff --git a/lldb/source/Expression/IRMemoryMap.cpp b/lldb/source/Expression/IRMemoryMap.cpp index 150699352a2e3..26e59b76a4dac 100644 --- a/lldb/source/Expression/IRMemoryMap.cpp +++ b/lldb/source/Expression/IRMemoryMap.cpp @@ -640,6 +640,15 @@ void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address, lldb::addr_t address, Status &error) { error.Clear(); + /// Only ask the Process to fix the address if this address belongs to the + /// process. An address belongs to the process if the Allocation policy is not + /// eAllocationPolicyHostOnly. + auto it = FindAllocation(address, 1); + if (it == m_allocations.end() || + it->second.m_policy != AllocationPolicy::eAllocationPolicyHostOnly) + if (auto process_sp = GetProcessWP().lock()) + address = process_sp->FixAnyAddress(address); + Scalar scalar(address); WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error); diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/Makefile b/lldb/test/API/macosx/arm-pointer-metadata-stripping/Makefile new file mode 100644 index 0000000000000..c9319d6e6888a --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/Makefile @@ -0,0 +1,2 @@ +C_SOURCES := main.c +include Makefile.rules diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py b/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py new file mode 100644 index 0000000000000..f61945b3eb4c9 --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/TestArmPointerMetadataStripping.py @@ -0,0 +1,48 @@ +import lldb +import json +import os +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +@skipUnlessDarwin +@skipIf(archs=no_match(["arm64", "arm64e"])) +class TestArmPointerMetadataStripping(TestBase): + # Use extra_symbols.json as a template to add a new symbol whose address + # contains non-zero high order bits set. + def create_symbols_file(self): + template_path = os.path.join(self.getSourceDir(), "extra_symbols.json") + with open(template_path, "r") as f: + symbols_data = json.load(f) + + target = self.dbg.GetSelectedTarget() + symbols_data["triple"] = target.GetTriple() + + module = target.GetModuleAtIndex(0) + symbols_data["uuid"] = module.GetUUIDString() + + json_filename = self.getBuildArtifact("extra_symbols.json") + with open(json_filename, "w") as file: + json.dump(symbols_data, file, indent=4) + + return json_filename + + def test(self): + self.build() + src = lldb.SBFileSpec("main.c") + target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( + self, "break here", src + ) + + symbols_file = self.create_symbols_file() + self.runCmd(f"target module add {symbols_file}") + + # The high order bits should be stripped. + self.expect_expr("get_high_bits(&myglobal_json)", result_value="0") + + # Mark all bits as used for addresses and ensure bits are no longer stripped. + self.runCmd("settings set target.process.virtual-addressable-bits 64") + self.expect_expr( + "get_high_bits(&myglobal_json)", result_value=str(0x1200000000000000) + ) diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/extra_symbols.json b/lldb/test/API/macosx/arm-pointer-metadata-stripping/extra_symbols.json new file mode 100644 index 0000000000000..5c2503d508b42 --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/extra_symbols.json @@ -0,0 +1,21 @@ +{ + "triple": "replace me", + "uuid": "replace me", + "type": "executable", + "sections": [ + { + "name": "__DATA", + "type": "data", + "address": 1297224342667202580, + "size": 16 + } + ], + "symbols": [ + { + "name": "myglobal_json", + "size": 8, + "type": "data", + "address": 1297224342667202580 + } + ] +} diff --git a/lldb/test/API/macosx/arm-pointer-metadata-stripping/main.c b/lldb/test/API/macosx/arm-pointer-metadata-stripping/main.c new file mode 100644 index 0000000000000..05a85133caf72 --- /dev/null +++ b/lldb/test/API/macosx/arm-pointer-metadata-stripping/main.c @@ -0,0 +1,13 @@ +#include + +uintptr_t get_high_bits(void *ptr) { + uintptr_t address_bits = 56; + uintptr_t mask = ~((1ULL << address_bits) - 1); + uintptr_t ptrtoint = (uintptr_t)ptr; + uintptr_t high_bits = ptrtoint & mask; + return high_bits; +} + +int main() { + return 0; // break here +}