feat(code): show count of repalced instructions

This commit is contained in:
boykopovar 2026-08-05 13:57:10 +03:00
parent 8c44cf4a52
commit b62ffe327d
5 changed files with 21 additions and 9 deletions

View File

@ -9,6 +9,7 @@ add_executable(relinker
${CMAKE_CURRENT_SOURCE_DIR}/io/src/ByteWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/src/FileReader.cpp
${CMAKE_CURRENT_SOURCE_DIR}/io/src/FileWriter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/codegen/src/Amd64OnlyConverter.cpp
${CMAKE_CURRENT_SOURCE_DIR}/codegen/src/InstructionScanner.cpp
${CMAKE_CURRENT_SOURCE_DIR}/codegen/src/x86/X64InstructionDecoder.cpp
${CMAKE_CURRENT_SOURCE_DIR}/codegen/src/x86/X64InstructionRewriter.cpp

View File

@ -28,6 +28,11 @@ struct RewriteResult {
std::vector<AddressAdjustment> Adjustments;
};
struct ConvertResult {
std::vector<std::uint8_t> Bytes;
std::size_t ReplacedCount;
};
}
#endif

View File

@ -1,8 +1,8 @@
#ifndef CODEGEN_IAMD64ONLYCONVERTER_HPP
#define CODEGEN_IAMD64ONLYCONVERTER_HPP
#include <codegen/CodegenTypes.hpp>
#include <domain/Types.hpp>
#include <cstdint>
#include <memory>
#include <vector>
@ -12,7 +12,7 @@ class IAmd64OnlyConverter {
public:
virtual ~IAmd64OnlyConverter() = default;
[[nodiscard]] virtual std::vector<std::uint8_t> Convert(
[[nodiscard]] virtual ConvertResult Convert(
std::vector<std::uint8_t> fileBytes,
const std::vector<Domain::ProgramHeader>& codeSegments
) const = 0;

View File

@ -10,7 +10,7 @@ namespace {
class Amd64OnlyConverter : public IAmd64OnlyConverter {
public:
[[nodiscard]] std::vector<std::uint8_t> Convert(
[[nodiscard]] ConvertResult Convert(
std::vector<std::uint8_t> fileBytes,
const std::vector<Domain::ProgramHeader>& codeSegments
) const override;
@ -20,13 +20,13 @@ private:
std::unique_ptr<IAmd64OnlyInstructionMatcher> _matcher = MakeAmd64OnlyInstructionMatcher();
std::unique_ptr<IInstructionScanner> _scanner = MakeInstructionScanner();
void _convertSegment(
std::size_t _convertSegment(
std::vector<std::uint8_t>& fileBytes,
const Domain::ProgramHeader& ph
) const;
};
void Amd64OnlyConverter::_convertSegment(
std::size_t Amd64OnlyConverter::_convertSegment(
std::vector<std::uint8_t>& fileBytes,
const Domain::ProgramHeader& ph
) const {
@ -40,6 +40,7 @@ void Amd64OnlyConverter::_convertSegment(
const auto matches = _scanner->ScanCodeSection(seg, 0, seg.size());
std::int64_t shift = 0;
std::size_t count = 0;
for (const auto& match : matches) {
const auto shiftedOffset = static_cast<std::int64_t>(match.Offset) + shift;
@ -56,20 +57,23 @@ void Amd64OnlyConverter::_convertSegment(
shift += static_cast<std::int64_t>(result->ReplacementBytes.size()) -
static_cast<std::int64_t>(match.Length);
seg = std::move(rewriteResult.Bytes);
++count;
}
const auto copySize = std::min(seg.size(), segSize);
std::copy(seg.begin(), seg.begin() + copySize, fileBytes.begin() + segOffset);
return count;
}
std::vector<std::uint8_t> Amd64OnlyConverter::Convert(
ConvertResult Amd64OnlyConverter::Convert(
std::vector<std::uint8_t> fileBytes,
const std::vector<Domain::ProgramHeader>& codeSegments
) const {
std::size_t total = 0;
for (const auto& ph : codeSegments) {
_convertSegment(fileBytes, ph);
total += _convertSegment(fileBytes, ph);
}
return fileBytes;
return {std::move(fileBytes), total};
}
}

View File

@ -56,7 +56,9 @@ int main(const int argc, char* argv[]) {
if (toIntel) {
const Relinker::ElfReader elfReader(sourceBytes);
const auto converter = Codegen::MakeAmd64OnlyConverter();
fileWriter.Write(outputElfPath, converter->Convert(std::move(sourceBytes), elfReader.ReadCodeSegments()));
auto result = converter->Convert(std::move(sourceBytes), elfReader.ReadCodeSegments());
fileWriter.Write(outputElfPath, std::move(result.Bytes));
std::cout << "OK: " << result.ReplacedCount << " instructions replaced\n";
return 0;
}