jasonmolenda created this revision. jasonmolenda added reviewers: JDevlieghere, jingham. jasonmolenda added a project: LLDB. Herald added a subscriber: Michael137. Herald added a project: All. jasonmolenda requested review of this revision. Herald added a subscriber: lldb-commits.
When the IRInterpreter runs, and needs to store things in inferior memory, and it cannot allocate a memory region in the inferior, IRMemoryMap::FindSpace will create a buffer in lldb memory with a target address, and that will be used. If the target address overlaps with the address of an actual memory region in the inferior process, attempts to access the genuine memory there in IRInterpreted expressions will instead access lldb's local scratch memory. The Process may not support any way to query memory regions, so the solution Sean has picked in years past was to pick an especially unlikely address. Obviously, we have a program that puts things at this address. Given that 64-bit systems do not genuinely have 64 bits of address space, we can pick a better address. This patch changes the current unlikely address, 0xffffffff00000000, to 0xdead0fff00000000. Still in high memory, but because bit 62 is now 0 with this address, it cannot overlap with an actual virtual address unless there was a system alling for 62 bits of addressable address space. This is unlikely to happen soon. I wrote a test which loads a binary into lldb, and slides the DATA segment around to different addresses, testing that the global variable in that DATA segment can still be read, as well as testing that if the DATA segment is slid to this impossible address, we get the incorrect value for the global. This patch also fixes an incorrect way of getting the Target in `DWARFExpression::Evaluate` which gets a StackFrame from the ExecutionContext passed in, and uses that to get the Target, instead of simply using the Target, when calculating the load address of the address just read. This had the effect of always returning the original file address, even when I loaded the segment at different addresses, in this test where there's no running process. I looked through DWARFExpression briefly and didn't see any other code doing this. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137682 Files: lldb/source/Expression/DWARFExpression.cpp lldb/source/Expression/IRMemoryMap.cpp lldb/test/API/lang/c/high-mem-global/Makefile lldb/test/API/lang/c/high-mem-global/TestHighMemGlobal.py lldb/test/API/lang/c/high-mem-global/main.c
Index: lldb/test/API/lang/c/high-mem-global/main.c =================================================================== --- /dev/null +++ lldb/test/API/lang/c/high-mem-global/main.c @@ -0,0 +1,9 @@ + +struct mystruct { + int c, d, e; +} global = {1, 2, 3}; + +int main () +{ + return global.c; // break here +} Index: lldb/test/API/lang/c/high-mem-global/TestHighMemGlobal.py =================================================================== --- /dev/null +++ lldb/test/API/lang/c/high-mem-global/TestHighMemGlobal.py @@ -0,0 +1,52 @@ +"""Look that lldb can display a global loaded in high memory at an addressable address.""" + + +import lldb +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.decorators import * + +class TestHighMemGlobal(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + + @skipUnlessDarwin # hardcoding of __DATA segment name + def test_command_line(self): + """Test that we can display a global variable loaded in high memory.""" + self.build() + + exe = self.getBuildArtifact("a.out") + err = lldb.SBError() + + target = self.dbg.CreateTarget(exe, '', '', False, err) + self.assertTrue(target.IsValid()) + module = target.GetModuleAtIndex(0) + self.assertTrue(module.IsValid()) + data_segment = module.FindSection("__DATA") + self.assertTrue(data_segment.IsValid()) + err.Clear() + + self.expect("p global.c", substrs=[' = 1']) + + err = target.SetSectionLoadAddress(data_segment, 0xffffffff00000000) + self.assertTrue(err.Success()) + self.expect("p global.c", substrs=[' = 1']) + + err = target.SetSectionLoadAddress(data_segment, 0x0000088100004000) + self.assertTrue(err.Success()) + self.expect("p global.c", substrs=[' = 1']) + + # This is an address in IRMemoryMap::FindSpace where it has an + # lldb-side buffer of memory that's used in IR interpreters when + # memory cannot be allocated in the inferior / functions cannot + # be jitted. + err = target.SetSectionLoadAddress(data_segment, 0xdead0fff00000000) + self.assertTrue(err.Success()) + + # The global variable `global` is now overlayed by this + # IRMemoryMap special buffer, and now we cannot see the variable. + # If the IRInterpreter some day is able to distinguish between + # an addr_t in its IRMemoryMap local buffer versus inferior process + # memory, this test would no longer pass. + self.runCmd("p int $tmp = global.c") + self.expect("p $tmp != 1", substrs=[' = true']) Index: lldb/test/API/lang/c/high-mem-global/Makefile =================================================================== --- /dev/null +++ lldb/test/API/lang/c/high-mem-global/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules Index: lldb/source/Expression/IRMemoryMap.cpp =================================================================== --- lldb/source/Expression/IRMemoryMap.cpp +++ lldb/source/Expression/IRMemoryMap.cpp @@ -143,7 +143,7 @@ if (address_byte_size != UINT32_MAX) { switch (address_byte_size) { case 8: - ret = 0xffffffff00000000ull; + ret = 0xdead0fff00000000ull; break; case 4: ret = 0xee000000ull; Index: lldb/source/Expression/DWARFExpression.cpp =================================================================== --- lldb/source/Expression/DWARFExpression.cpp +++ lldb/source/Expression/DWARFExpression.cpp @@ -917,9 +917,8 @@ stack.back().SetValueType(Value::ValueType::FileAddress); // Convert the file address to a load address, so subsequent // DWARF operators can operate on it. - if (frame) - stack.back().ConvertToLoadAddress(module_sp.get(), - frame->CalculateTarget().get()); + if (target) + stack.back().ConvertToLoadAddress(module_sp.get(), target); } break;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits