diff --git a/lldb/source/Target/SectionLoadList.cpp b/lldb/source/Target/SectionLoadList.cpp index 03160ee10dd84..a78ca3360f2ec 100644 --- a/lldb/source/Target/SectionLoadList.cpp +++ b/lldb/source/Target/SectionLoadList.cpp @@ -116,8 +116,18 @@ bool SectionLoadList::SetSectionLoadAddress(const lldb::SectionSP §ion, } } 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 { diff --git a/lldb/test/API/functionalities/multiple-slides/Makefile b/lldb/test/API/functionalities/multiple-slides/Makefile new file mode 100644 index 0000000000000..5f83deaa24d77 --- /dev/null +++ b/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 $@ + diff --git a/lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py b/lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py new file mode 100644 index 0000000000000..d89cc70a94333 --- /dev/null +++ b/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()) + diff --git a/lldb/test/API/functionalities/multiple-slides/main.c b/lldb/test/API/functionalities/multiple-slides/main.c new file mode 100644 index 0000000000000..f9c8fd8ff931d --- /dev/null +++ b/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]; +}