jasonmolenda updated this revision to Diff 462000. jasonmolenda added a comment.
Getting back to this old patch. When I lost track of it, @DavidSpickett was saying that the test case was still not clear -- I was loading a section at an address, checking that I could read values out of arrays, then setting the section to a different address and seeing that I could still read the value out of the arrays. I added comments to these two key parts of the test file, # View the first element of `first` and `second` with # no slide applied, but with load address set. # # In memory, we have something like # 0x1000 - 0x17ff first[] # 0x1800 - 0x1fff second[] target.SetModuleLoadAddress(module, 0) self.expect("p/d ((int*)&first)[0]", substrs=['= 5']) self.expect("p/d ((int*)&second)[0]", substrs=['= 6']) self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target), first_sym.GetStartAddress().GetFileAddress()) self.assertEqual(second_sym.GetStartAddress().GetLoadAddress(target), second_sym.GetStartAddress().GetFileAddress()) # Slide it a little bit less than the size of the first array. # # In memory, we have something like # 0xfc0 - 0x17bf first[] # 0x17c0 - 0x1fbf second[] # # but if the original entries are still present in lldb, # the beginning address of second[] will get a load address # of 0x1800, instead of 0x17c0 (0x1800-64) as we need to get. target.SetModuleLoadAddress(module, first_size - 64) self.expect("p/d ((int*)&first)[0]", substrs=['= 5']) self.expect("p/d ((int*)&second)[0]", substrs=['= 6']) self.assertNotEqual(first_sym.GetStartAddress().GetLoadAddress(target), first_sym.GetStartAddress().GetFileAddress()) self.assertNotEqual(second_sym.GetStartAddress().GetLoadAddress(target), second_sym.GetStartAddress().GetFileAddress()) The inferior is never actually run, so I can change the load addresses of the sections around and it ultimately should read the data out of the file on disk every time. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D130534/new/ https://reviews.llvm.org/D130534 Files: lldb/source/Target/SectionLoadList.cpp lldb/test/API/functionalities/multiple-slides/Makefile lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py lldb/test/API/functionalities/multiple-slides/main.c
Index: lldb/test/API/functionalities/multiple-slides/main.c =================================================================== --- /dev/null +++ lldb/test/API/functionalities/multiple-slides/main.c @@ -0,0 +1,5 @@ +int first[2048] = { 5 }; +int second[2048] = { 6 }; +int main() { + return first[0] + second[0]; +} Index: lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py =================================================================== --- /dev/null +++ lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py @@ -0,0 +1,79 @@ +""" +Test that a binary can be slid to different load addresses correctly +""" + + + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class MultipleSlidesTestCase(TestBase): + + NO_DEBUG_INFO_TESTCASE = True + def test_mulitple_slides(self): + """Test that a binary can be slid multiple times correctly.""" + self.build() + exe = self.getBuildArtifact("a.out") + err = lldb.SBError() + load_dependent_modules = False + target = self.dbg.CreateTarget(exe, '', '', load_dependent_modules, err) + self.assertTrue(target.IsValid()) + module = target.GetModuleAtIndex(0) + self.assertTrue(module.IsValid()) + + first_sym = target.FindSymbols("first").GetContextAtIndex(0).GetSymbol() + second_sym = target.FindSymbols("second").GetContextAtIndex(0).GetSymbol() + first_size = first_sym.GetEndAddress().GetOffset() - first_sym.GetStartAddress().GetOffset() + second_size = second_sym.GetEndAddress().GetOffset() - second_sym.GetStartAddress().GetOffset() + + # View the first element of `first` and `second` while + # they have no load address set. + self.expect("p/d ((int*)&first)[0]", substrs=['= 5']) + self.expect("p/d ((int*)&second)[0]", substrs=['= 6']) + self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS) + self.assertEqual(second_sym.GetStartAddress().GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS) + + + # View the first element of `first` and `second` with + # no slide applied, but with load address set. + # + # In memory, we have something like + # 0x1000 - 0x17ff first[] + # 0x1800 - 0x1fff second[] + target.SetModuleLoadAddress(module, 0) + self.expect("p/d ((int*)&first)[0]", substrs=['= 5']) + self.expect("p/d ((int*)&second)[0]", substrs=['= 6']) + self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target), + first_sym.GetStartAddress().GetFileAddress()) + self.assertEqual(second_sym.GetStartAddress().GetLoadAddress(target), + second_sym.GetStartAddress().GetFileAddress()) + + # Slide it a little bit less than the size of the first array. + # + # In memory, we have something like + # 0xfc0 - 0x17bf first[] + # 0x17c0 - 0x1fbf second[] + # + # but if the original entries are still present in lldb, + # the beginning address of second[] will get a load address + # of 0x1800, instead of 0x17c0 (0x1800-64) as we need to get. + target.SetModuleLoadAddress(module, first_size - 64) + self.expect("p/d ((int*)&first)[0]", substrs=['= 5']) + self.expect("p/d ((int*)&second)[0]", substrs=['= 6']) + self.assertNotEqual(first_sym.GetStartAddress().GetLoadAddress(target), + first_sym.GetStartAddress().GetFileAddress()) + self.assertNotEqual(second_sym.GetStartAddress().GetLoadAddress(target), + second_sym.GetStartAddress().GetFileAddress()) + + # Slide it back to the original vmaddr. + target.SetModuleLoadAddress(module, 0) + self.expect("p/d ((int*)&first)[0]", substrs=['= 5']) + self.expect("p/d ((int*)&second)[0]", substrs=['= 6']) + self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target), + first_sym.GetStartAddress().GetFileAddress()) + self.assertEqual(second_sym.GetStartAddress().GetLoadAddress(target), + second_sym.GetStartAddress().GetFileAddress()) + Index: lldb/test/API/functionalities/multiple-slides/Makefile =================================================================== --- /dev/null +++ lldb/test/API/functionalities/multiple-slides/Makefile @@ -0,0 +1,12 @@ +C_SOURCES := main.c +MAKE_DSYM := NO + +include Makefile.rules + +# lldb has a separate bug where this test case +# does not work if we have debug info - after +# sliding the binary, the address of `first` and +# `second` are not slid for some reason on Darwin. +main.o: main.c + $(CC) $(CFLAGS_NO_DEBUG) -c $< -o $@ + Index: lldb/source/Target/SectionLoadList.cpp =================================================================== --- lldb/source/Target/SectionLoadList.cpp +++ lldb/source/Target/SectionLoadList.cpp @@ -116,8 +116,18 @@ } } ats_pos->second = section; - } else + } else { + // Remove the old address->section entry, if + // there is one. + for (const auto &entry : m_addr_to_sect) { + if (entry.second == section) { + const auto &it_pos = m_addr_to_sect.find(entry.first); + m_addr_to_sect.erase(it_pos); + break; + } + } m_addr_to_sect[load_addr] = section; + } return true; // Changed } else {
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits