diff --git a/src/jet/live/DataTypes.hpp b/src/jet/live/DataTypes.hpp index 8b1a5ab..e381211 100644 --- a/src/jet/live/DataTypes.hpp +++ b/src/jet/live/DataTypes.hpp @@ -101,8 +101,6 @@ namespace jet uint64_t relocationSymbolHash = 0; /** Relocation symbol hash. */ uint8_t size = 0; /** Size of relocation entry, in bytes (4, 8). */ - - void apply(const LiveContext* context); /** Applies relocation. */ }; // Mach-O specific structures diff --git a/src/jet/live/FunctionsHookingStep.cpp b/src/jet/live/FunctionsHookingStep.cpp index 692d005..5fa1014 100644 --- a/src/jet/live/FunctionsHookingStep.cpp +++ b/src/jet/live/FunctionsHookingStep.cpp @@ -34,6 +34,7 @@ namespace jet } else { hookedFunctions++; } + subhook_free(hook); } } diff --git a/src/jet/live/StaticsCopyStep.cpp b/src/jet/live/StaticsCopyStep.cpp index 745f00a..f5427d0 100644 --- a/src/jet/live/StaticsCopyStep.cpp +++ b/src/jet/live/StaticsCopyStep.cpp @@ -24,7 +24,7 @@ namespace jet break; } } - if (!oldVarPtr) { + if (!oldVarPtr || oldVarSize == 0) { continue; } diff --git a/src/jet/live/_linux/ElfProgramInfoLoader.cpp b/src/jet/live/_linux/ElfProgramInfoLoader.cpp index e7916b9..392d3db 100644 --- a/src/jet/live/_linux/ElfProgramInfoLoader.cpp +++ b/src/jet/live/_linux/ElfProgramInfoLoader.cpp @@ -90,6 +90,14 @@ namespace jet const auto& section = elfFile.sections[i]; elfContext.sectionNames[i] = section->get_name(); + // This one is needed to apply relocations of STT_SECTION symbols + Symbol sectionSymbol; + sectionSymbol.checkHash = false; + sectionSymbol.name = section->get_name(); + sectionSymbol.runtimeAddress = baseAddress + section->get_offset(); + sectionSymbol.size = 0; + res.variables[sectionSymbol.name].push_back(sectionSymbol); + if (section->get_type() == SHT_SYMTAB) { const ELFIO::symbol_section_accessor symbols{elfFile, section}; for (ElfW(Xword) j = 0; j < symbols.get_symbols_num(); j++) { @@ -297,16 +305,16 @@ namespace jet * Retrieved via r_offset. * S: Relocation entry’s correspondent symbol value. Z: Size of relocations entry’s symbol. */ - uintptr_t symRelAddr = 0; + intptr_t symRelAddr = 0; switch (type) { // Link-time relocation, we should fix it by ourself case R_X86_64_PC32: // 32, S + A – P reloc.size = sizeof(int32_t); - symRelAddr = static_cast(addend + 4); + symRelAddr = static_cast(addend + 4); break; case R_X86_64_PC64: // 64, S + A – P reloc.size = sizeof(int64_t); - symRelAddr = static_cast(addend + 4); + symRelAddr = static_cast(addend + 4); break; // Load time relocations, will be fixed by dynamic linker @@ -343,9 +351,26 @@ namespace jet continue; } - auto symFound = symbolsInSections[sectionIndex].find(symRelAddr); - if (symFound == symbolsInSections[sectionIndex].end()) { - context->events->addLog(LogSeverity::kError, "WTF"); + const auto& symsInSection = symbolsInSections[sectionIndex]; + auto symFound = symsInSection.find(static_cast(symRelAddr)); + if (symRelAddr < 0) { + symFound = symsInSection.begin(); + } + if (symFound == symsInSection.end()) { + symFound = symsInSection.upper_bound(static_cast(symRelAddr)); + if (symFound != symsInSection.begin()) { + symFound--; + } + } + if (symFound == symsInSection.end()) { + context->events->addLog(LogSeverity::kError, + "WTF: file " + el + ", " + + "section " + section->get_name() + ", " + + "target section index " + std::to_string(sectionIndex) + ", " + + "offset " + std::to_string(offset) + ", " + + "symbol " + std::to_string(symbol) + ", " + + "type " + std::to_string(type) + ", " + "addend " + std::to_string(addend)); continue; } diff --git a/src/jet/live/_linux/Utility.cpp b/src/jet/live/_linux/Utility.cpp index 480e269..beac89d 100644 --- a/src/jet/live/_linux/Utility.cpp +++ b/src/jet/live/_linux/Utility.cpp @@ -3,9 +3,9 @@ #include #include #include +#include #include #include -#include namespace jet { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3c35c41..6e4be17 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -66,6 +66,7 @@ target_sources(tests src/utility/ReloadAfterFailedCompilation1.cpp src/utility/ReloadAfterFailedCompilation2.cpp src/utility/OneFrameCompileReload.cpp + src/utility/ArrayRelocation.cpp src/good/ClassInstanceMethod_test.cpp src/good/CommonSection_test.cpp @@ -99,6 +100,7 @@ target_sources(tests src/good/LostModification_test.cpp src/good/ReloadAfterFailedCompilation_test.cpp src/good/OneFrameCompileReload_test.cpp + src/good/ArrayRelocation_test.cpp src/bad/LambdaFunctionWithCapturesBadCase2_test.cpp src/bad/LambdaFunctionWithCapturesBadCase_test.cpp diff --git a/tests/src/good/ArrayRelocation_test.cpp b/tests/src/good/ArrayRelocation_test.cpp new file mode 100644 index 0000000..328b409 --- /dev/null +++ b/tests/src/good/ArrayRelocation_test.cpp @@ -0,0 +1,20 @@ + +#include +#include "Globals.hpp" +#include "WaitForReload.hpp" +#include +#include "utility/ArrayRelocation.hpp" + +TEST_CASE("Relocation of array", "[variable]") +{ + arelTouchValues(); + + auto beforeReload = arelGetValue(); + REQUIRE(beforeReload == 543); + + std::cout << "JET_TEST: disable(arel_var:1); enable(arel_var:2)" << std::endl; + waitForReload(); + + auto afterReload = arelGetValue(); + REQUIRE(afterReload == 878); +} diff --git a/tests/src/utility/ArrayRelocation.cpp b/tests/src/utility/ArrayRelocation.cpp new file mode 100644 index 0000000..4b0ac50 --- /dev/null +++ b/tests/src/utility/ArrayRelocation.cpp @@ -0,0 +1,24 @@ + +#include "ArrayRelocation.hpp" + +namespace +{ + int values[] = { + 533, 868 + }; +} + +int arelTouchValues() +{ + int res = 0; + for (auto& el : values) { + res += (el += 10); + } + return res; +} + +int arelGetValue() +{ + return values[0]; // +// return values[1]; // +} diff --git a/tests/src/utility/ArrayRelocation.hpp b/tests/src/utility/ArrayRelocation.hpp new file mode 100644 index 0000000..80a164c --- /dev/null +++ b/tests/src/utility/ArrayRelocation.hpp @@ -0,0 +1,5 @@ + +#pragma once + +int arelTouchValues(); +int arelGetValue();