Skip to content

Commit f88eadd

Browse files
[lldb] Call FixUpPointer in WritePointerToMemory (try 2) (#153585)
In architectures where pointers may contain metadata, such as arm64e, the metadata may need to be cleaned prior to sending this pointer to be used in expression evaluation generated code. This patch is a step towards allowing consumers of pointers to decide whether they want to keep or remove metadata, as opposed to discarding metadata at the moment pointers are created. See #150537. This was tested running the LLDB test suite on arm64e. (The first attempt at this patch caused a failure in TestScriptedProcessEmptyMemoryRegion.py. This test exercises a case where IRMemoryMap uses host memory in its allocations; pointers to such allocations should not be fixed, which is what the original patch failed to account for).
1 parent 9a3aedb commit f88eadd

File tree

5 files changed

+93
-0
lines changed

5 files changed

+93
-0
lines changed

lldb/source/Expression/IRMemoryMap.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,15 @@ void IRMemoryMap::WritePointerToMemory(lldb::addr_t process_address,
640640
lldb::addr_t address, Status &error) {
641641
error.Clear();
642642

643+
/// Only ask the Process to fix the address if this address belongs to the
644+
/// process. An address belongs to the process if the Allocation policy is not
645+
/// eAllocationPolicyHostOnly.
646+
auto it = FindAllocation(address, 1);
647+
if (it == m_allocations.end() ||
648+
it->second.m_policy != AllocationPolicy::eAllocationPolicyHostOnly)
649+
if (auto process_sp = GetProcessWP().lock())
650+
address = process_sp->FixAnyAddress(address);
651+
643652
Scalar scalar(address);
644653

645654
WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
C_SOURCES := main.c
2+
include Makefile.rules
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import lldb
2+
import json
3+
import os
4+
from lldbsuite.test.decorators import *
5+
from lldbsuite.test.lldbtest import *
6+
from lldbsuite.test import lldbutil
7+
8+
9+
@skipUnlessDarwin
10+
@skipIf(archs=no_match(["arm64", "arm64e"]))
11+
class TestArmPointerMetadataStripping(TestBase):
12+
# Use extra_symbols.json as a template to add a new symbol whose address
13+
# contains non-zero high order bits set.
14+
def create_symbols_file(self):
15+
template_path = os.path.join(self.getSourceDir(), "extra_symbols.json")
16+
with open(template_path, "r") as f:
17+
symbols_data = json.load(f)
18+
19+
target = self.dbg.GetSelectedTarget()
20+
symbols_data["triple"] = target.GetTriple()
21+
22+
module = target.GetModuleAtIndex(0)
23+
symbols_data["uuid"] = module.GetUUIDString()
24+
25+
json_filename = self.getBuildArtifact("extra_symbols.json")
26+
with open(json_filename, "w") as file:
27+
json.dump(symbols_data, file, indent=4)
28+
29+
return json_filename
30+
31+
def test(self):
32+
self.build()
33+
src = lldb.SBFileSpec("main.c")
34+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
35+
self, "break here", src
36+
)
37+
38+
symbols_file = self.create_symbols_file()
39+
self.runCmd(f"target module add {symbols_file}")
40+
41+
# The high order bits should be stripped.
42+
self.expect_expr("get_high_bits(&myglobal_json)", result_value="0")
43+
44+
# Mark all bits as used for addresses and ensure bits are no longer stripped.
45+
self.runCmd("settings set target.process.virtual-addressable-bits 64")
46+
self.expect_expr(
47+
"get_high_bits(&myglobal_json)", result_value=str(0x1200000000000000)
48+
)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"triple": "replace me",
3+
"uuid": "replace me",
4+
"type": "executable",
5+
"sections": [
6+
{
7+
"name": "__DATA",
8+
"type": "data",
9+
"address": 1297224342667202580,
10+
"size": 16
11+
}
12+
],
13+
"symbols": [
14+
{
15+
"name": "myglobal_json",
16+
"size": 8,
17+
"type": "data",
18+
"address": 1297224342667202580
19+
}
20+
]
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <stdint.h>
2+
3+
uintptr_t get_high_bits(void *ptr) {
4+
uintptr_t address_bits = 56;
5+
uintptr_t mask = ~((1ULL << address_bits) - 1);
6+
uintptr_t ptrtoint = (uintptr_t)ptr;
7+
uintptr_t high_bits = ptrtoint & mask;
8+
return high_bits;
9+
}
10+
11+
int main() {
12+
return 0; // break here
13+
}

0 commit comments

Comments
 (0)