Index: lldb/include/lldb/API/SBTarget.h =================================================================== --- lldb/include/lldb/API/SBTarget.h +++ lldb/include/lldb/API/SBTarget.h @@ -392,6 +392,27 @@ lldb::SBError SetModuleLoadAddress(lldb::SBModule module, int64_t sections_offset); + /// Slide all file addresses for all module sections so that \a module + /// appears to loaded at these slide addresses. + /// + /// When you need all sections within a module to be loaded at a + /// rigid slide from the addresses found in the module object file, + /// this function will allow you to easily and quickly slide all + /// module sections. + /// + /// \param[in] module + /// The module to load. + /// + /// \param[in] sections_offset + /// An offset that will be applied to all section file addresses + /// (the virtual addresses found in the object file itself). + /// + /// \return + /// An error to indicate success, fail, and any reason for + /// failure. + lldb::SBError SetModuleLoadAddressUnsigned(lldb::SBModule module, + uint64_t sections_offset); + /// Clear the section base load addresses for all sections in a module. /// /// \param[in] module Index: lldb/source/API/SBTarget.cpp =================================================================== --- lldb/source/API/SBTarget.cpp +++ lldb/source/API/SBTarget.cpp @@ -2093,6 +2093,18 @@ int64_t slide_offset) { LLDB_INSTRUMENT_VA(this, module, slide_offset); + if (slide_offset < 0) { + SBError sb_error; + sb_error.SetErrorStringWithFormat("slide must be positive"); + return sb_error; + } + + return SetModuleLoadAddressUnsigned(module, slide_offset); +} + +SBError SBTarget::SetModuleLoadAddressUnsigned(lldb::SBModule module, + uint64_t slide_offset) { + SBError sb_error; TargetSP target_sp(GetSP()); Index: lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py =================================================================== --- lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py +++ lldb/test/API/functionalities/multiple-slides/TestMultipleSlides.py @@ -36,6 +36,10 @@ self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS) self.assertEqual(second_sym.GetStartAddress().GetLoadAddress(target), lldb.LLDB_INVALID_ADDRESS) + # Can't use a negative slide + error = target.SetModuleLoadAddress(module, -1) + self.assertTrue(error.Fail()) + self.assertEqual(error.GetCString(), "slide must be positive") # View the first element of `first` and `second` with # no slide applied, but with load address set. @@ -43,7 +47,8 @@ # In memory, we have something like # 0x1000 - 0x17ff first[] # 0x1800 - 0x1fff second[] - target.SetModuleLoadAddress(module, 0) + error = target.SetModuleLoadAddressUnsigned(module, 0) + self.assertSuccess(error) self.expect("expression/d ((int*)&first)[0]", substrs=['= 5']) self.expect("expression/d ((int*)&second)[0]", substrs=['= 6']) self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target), @@ -60,7 +65,8 @@ # 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) + error = target.SetModuleLoadAddressUnsigned(module, first_size - 64) + self.assertSuccess(error) self.expect("expression/d ((int*)&first)[0]", substrs=['= 5']) self.expect("expression/d ((int*)&second)[0]", substrs=['= 6']) self.assertNotEqual(first_sym.GetStartAddress().GetLoadAddress(target), @@ -69,7 +75,8 @@ second_sym.GetStartAddress().GetFileAddress()) # Slide it back to the original vmaddr. - target.SetModuleLoadAddress(module, 0) + error = target.SetModuleLoadAddressUnsigned(module, 0) + self.assertSuccess(error) self.expect("expression/d ((int*)&first)[0]", substrs=['= 5']) self.expect("expression/d ((int*)&second)[0]", substrs=['= 6']) self.assertEqual(first_sym.GetStartAddress().GetLoadAddress(target),