diff --git a/core/relinker/codegen/src/x86/X64InstructionDecoder.cpp b/core/relinker/codegen/src/x86/X64InstructionDecoder.cpp index f905d2df43..a3f7f3962d 100644 --- a/core/relinker/codegen/src/x86/X64InstructionDecoder.cpp +++ b/core/relinker/codegen/src/x86/X64InstructionDecoder.cpp @@ -488,12 +488,12 @@ DecodedInstructionInfo X64InstructionDecoder::DecodeInstruction( } return info; } - if (reg == 3) { - info.FlowKind = ControlFlowKind::IndirectCall; - return info; - } - if (reg == 5) { - info.FlowKind = ControlFlowKind::IndirectJump; + if (reg == 3 || reg == 5) { + if (mod == ModRmModIndirect && rm == ModRmRmRipRelative) { + info.HasRipRelativeDisp = true; + info.RipRelativeDispOffset = pos + 1; + } + info.FlowKind = reg == 3 ? ControlFlowKind::IndirectCall : ControlFlowKind::IndirectJump; return info; } } diff --git a/core/relinker/codegen/tests/DecoderLengthTests.cpp b/core/relinker/codegen/tests/DecoderLengthTests.cpp index e141e1539e..54dd90df2b 100644 --- a/core/relinker/codegen/tests/DecoderLengthTests.cpp +++ b/core/relinker/codegen/tests/DecoderLengthTests.cpp @@ -1,4 +1,5 @@ #include "DecoderLengthCases.hpp" +#include "DecoderMetadataCases.hpp" #include #include #include @@ -77,6 +78,27 @@ int main() { } catch (const Codegen::CodegenException&) { } } + for (const auto& testCase : kDecoderRipRelativeCases) { + const std::string name = testCase.Bytes; + auto bytes = parse(testCase.Bytes); + require(bytes.size() == testCase.Length, "RIP-relative case " + name + " does not hold its own length"); + bytes.insert(bytes.end(), 15, 0x90); + require(decodedLength(decoder, bytes, name) == testCase.Length, "Wrong length for " + name); + const auto info = decoder.DecodeInstruction(bytes.data(), bytes.size()); + require(info.HasRipRelativeDisp, "RIP-relative operand of " + name + " was not reported"); + require(info.RipRelativeDispOffset == testCase.DisplacementOffset, "Wrong RIP-relative displacement offset for " + name); + } + for (const auto& testCase : kDecoderBranchCases) { + const std::string name = testCase.Bytes; + auto bytes = parse(testCase.Bytes); + require(bytes.size() == testCase.Length, "Branch case " + name + " does not hold its own length"); + bytes.insert(bytes.end(), 15, 0x90); + const auto info = decoder.DecodeInstruction(bytes.data(), bytes.size()); + require(info.Length == testCase.Length, "Wrong length for " + name); + require(info.FlowKind == testCase.FlowKind, "Wrong control flow kind for " + name); + require(info.HasBranchTarget == testCase.HasBranchTarget, "Wrong branch target presence for " + name); + require(!testCase.HasBranchTarget || info.BranchDisp == testCase.BranchDisp, "Wrong branch displacement for " + name); + } const auto threeDNow = parse("0f0f0d11223344a6"); const auto threeDNowInfo = decoder.DecodeInstruction(threeDNow.data(), threeDNow.size()); require(threeDNowInfo.HasModRm && threeDNowInfo.ModRmByte == 0x0d, "3DNow! ModRM was not reported"); diff --git a/core/relinker/codegen/tests/DecoderMetadataCases.hpp b/core/relinker/codegen/tests/DecoderMetadataCases.hpp new file mode 100644 index 0000000000..c685b184ea --- /dev/null +++ b/core/relinker/codegen/tests/DecoderMetadataCases.hpp @@ -0,0 +1,792 @@ +#ifndef CODEGEN_TESTS_DECODERMETADATACASES_HPP +#define CODEGEN_TESTS_DECODERMETADATACASES_HPP + +#include +#include +#include + +struct DecoderRipRelativeCase { + const char* Bytes; + std::size_t Length; + std::size_t DisplacementOffset; +}; + +struct DecoderBranchCase { + const char* Bytes; + std::size_t Length; + Codegen::ControlFlowKind FlowKind; + bool HasBranchTarget; + std::int64_t BranchDisp; +}; + +inline constexpr DecoderRipRelativeCase kDecoderRipRelativeCases[] = { + {"ff0511111111", 6, 2}, + {"ff0d11111111", 6, 2}, + {"ff1511111111", 6, 2}, + {"ff1d11111111", 6, 2}, + {"ff2511111111", 6, 2}, + {"ff2d11111111", 6, 2}, + {"ff3511111111", 6, 2}, + {"000511111111", 6, 2}, + {"010511111111", 6, 2}, + {"020511111111", 6, 2}, + {"030511111111", 6, 2}, + {"080511111111", 6, 2}, + {"090511111111", 6, 2}, + {"0a0511111111", 6, 2}, + {"0b0511111111", 6, 2}, + {"100511111111", 6, 2}, + {"110511111111", 6, 2}, + {"120511111111", 6, 2}, + {"130511111111", 6, 2}, + {"180511111111", 6, 2}, + {"190511111111", 6, 2}, + {"1a0511111111", 6, 2}, + {"1b0511111111", 6, 2}, + {"200511111111", 6, 2}, + {"210511111111", 6, 2}, + {"220511111111", 6, 2}, + {"230511111111", 6, 2}, + {"280511111111", 6, 2}, + {"290511111111", 6, 2}, + {"2a0511111111", 6, 2}, + {"2b0511111111", 6, 2}, + {"300511111111", 6, 2}, + {"310511111111", 6, 2}, + {"320511111111", 6, 2}, + {"330511111111", 6, 2}, + {"380511111111", 6, 2}, + {"390511111111", 6, 2}, + {"3a0511111111", 6, 2}, + {"3b0511111111", 6, 2}, + {"630511111111", 6, 2}, + {"666905111111111111", 9, 3}, + {"69051111111111111111", 10, 2}, + {"6b051111111111", 7, 2}, + {"80051111111111", 7, 2}, + {"668105111111111111", 9, 3}, + {"81051111111111111111", 10, 2}, + {"83051111111111", 7, 2}, + {"840511111111", 6, 2}, + {"850511111111", 6, 2}, + {"860511111111", 6, 2}, + {"870511111111", 6, 2}, + {"880511111111", 6, 2}, + {"890511111111", 6, 2}, + {"8a0511111111", 6, 2}, + {"8b0511111111", 6, 2}, + {"8c0511111111", 6, 2}, + {"8d0511111111", 6, 2}, + {"8e0511111111", 6, 2}, + {"c0051111111111", 7, 2}, + {"c1051111111111", 7, 2}, + {"c6051111111111", 7, 2}, + {"66c705111111111111", 9, 3}, + {"c7051111111111111111", 10, 2}, + {"d00511111111", 6, 2}, + {"d10511111111", 6, 2}, + {"d20511111111", 6, 2}, + {"d30511111111", 6, 2}, + {"d80511111111", 6, 2}, + {"d90511111111", 6, 2}, + {"da0511111111", 6, 2}, + {"db0511111111", 6, 2}, + {"dc0511111111", 6, 2}, + {"dd0511111111", 6, 2}, + {"de0511111111", 6, 2}, + {"df0511111111", 6, 2}, + {"f61511111111", 6, 2}, + {"f6051111111111", 7, 2}, + {"f71511111111", 6, 2}, + {"66f705111111111111", 9, 3}, + {"f7051111111111111111", 10, 2}, + {"fe0511111111", 6, 2}, + {"0f000511111111", 7, 3}, + {"0f010511111111", 7, 3}, + {"0f020511111111", 7, 3}, + {"0f030511111111", 7, 3}, + {"0f0d0511111111", 7, 3}, + {"0f100511111111", 7, 3}, + {"0f110511111111", 7, 3}, + {"0f120511111111", 7, 3}, + {"0f130511111111", 7, 3}, + {"0f140511111111", 7, 3}, + {"0f150511111111", 7, 3}, + {"0f160511111111", 7, 3}, + {"0f170511111111", 7, 3}, + {"0f180511111111", 7, 3}, + {"0f190511111111", 7, 3}, + {"0f1a0511111111", 7, 3}, + {"0f1b0511111111", 7, 3}, + {"0f1c0511111111", 7, 3}, + {"0f1d0511111111", 7, 3}, + {"0f1e0511111111", 7, 3}, + {"0f1f0511111111", 7, 3}, + {"0f280511111111", 7, 3}, + {"0f290511111111", 7, 3}, + {"0f2a0511111111", 7, 3}, + {"0f2b0511111111", 7, 3}, + {"0f2c0511111111", 7, 3}, + {"0f2d0511111111", 7, 3}, + {"0f2e0511111111", 7, 3}, + {"0f2f0511111111", 7, 3}, + {"0f400511111111", 7, 3}, + {"0f410511111111", 7, 3}, + {"0f420511111111", 7, 3}, + {"0f430511111111", 7, 3}, + {"0f440511111111", 7, 3}, + {"0f450511111111", 7, 3}, + {"0f460511111111", 7, 3}, + {"0f470511111111", 7, 3}, + {"0f480511111111", 7, 3}, + {"0f490511111111", 7, 3}, + {"0f4a0511111111", 7, 3}, + {"0f4b0511111111", 7, 3}, + {"0f4c0511111111", 7, 3}, + {"0f4d0511111111", 7, 3}, + {"0f4e0511111111", 7, 3}, + {"0f4f0511111111", 7, 3}, + {"0f510511111111", 7, 3}, + {"0f520511111111", 7, 3}, + {"0f530511111111", 7, 3}, + {"0f540511111111", 7, 3}, + {"0f550511111111", 7, 3}, + {"0f560511111111", 7, 3}, + {"0f570511111111", 7, 3}, + {"0f580511111111", 7, 3}, + {"0f590511111111", 7, 3}, + {"0f5a0511111111", 7, 3}, + {"0f5b0511111111", 7, 3}, + {"0f5c0511111111", 7, 3}, + {"0f5d0511111111", 7, 3}, + {"0f5e0511111111", 7, 3}, + {"0f5f0511111111", 7, 3}, + {"0f600511111111", 7, 3}, + {"0f610511111111", 7, 3}, + {"0f620511111111", 7, 3}, + {"0f630511111111", 7, 3}, + {"0f640511111111", 7, 3}, + {"0f650511111111", 7, 3}, + {"0f660511111111", 7, 3}, + {"0f670511111111", 7, 3}, + {"0f680511111111", 7, 3}, + {"0f690511111111", 7, 3}, + {"0f6a0511111111", 7, 3}, + {"0f6b0511111111", 7, 3}, + {"660f6c0511111111", 8, 4}, + {"660f6d0511111111", 8, 4}, + {"0f6e0511111111", 7, 3}, + {"0f6f0511111111", 7, 3}, + {"0f70051111111111", 8, 3}, + {"0f740511111111", 7, 3}, + {"0f750511111111", 7, 3}, + {"0f760511111111", 7, 3}, + {"660f7c0511111111", 8, 4}, + {"660f7d0511111111", 8, 4}, + {"0f7e0511111111", 7, 3}, + {"0f7f0511111111", 7, 3}, + {"0f900511111111", 7, 3}, + {"0f910511111111", 7, 3}, + {"0f920511111111", 7, 3}, + {"0f930511111111", 7, 3}, + {"0f940511111111", 7, 3}, + {"0f950511111111", 7, 3}, + {"0f960511111111", 7, 3}, + {"0f970511111111", 7, 3}, + {"0f980511111111", 7, 3}, + {"0f990511111111", 7, 3}, + {"0f9a0511111111", 7, 3}, + {"0f9b0511111111", 7, 3}, + {"0f9c0511111111", 7, 3}, + {"0f9d0511111111", 7, 3}, + {"0f9e0511111111", 7, 3}, + {"0f9f0511111111", 7, 3}, + {"0fa30511111111", 7, 3}, + {"0fa4051111111111", 8, 3}, + {"0fa50511111111", 7, 3}, + {"0fab0511111111", 7, 3}, + {"0fac051111111111", 8, 3}, + {"0fad0511111111", 7, 3}, + {"0fae0511111111", 7, 3}, + {"0faf0511111111", 7, 3}, + {"0fb00511111111", 7, 3}, + {"0fb10511111111", 7, 3}, + {"0fb20511111111", 7, 3}, + {"0fb30511111111", 7, 3}, + {"0fb40511111111", 7, 3}, + {"0fb50511111111", 7, 3}, + {"0fb60511111111", 7, 3}, + {"0fb70511111111", 7, 3}, + {"f30fb80511111111", 8, 4}, + {"0fb90511111111", 7, 3}, + {"0fba251111111111", 8, 3}, + {"0fbb0511111111", 7, 3}, + {"0fbc0511111111", 7, 3}, + {"0fbd0511111111", 7, 3}, + {"0fbe0511111111", 7, 3}, + {"0fbf0511111111", 7, 3}, + {"0fc00511111111", 7, 3}, + {"0fc10511111111", 7, 3}, + {"0fc2051111111111", 8, 3}, + {"0fc30511111111", 7, 3}, + {"0fc4051111111111", 8, 3}, + {"0fc6051111111111", 8, 3}, + {"0fc70d11111111", 7, 3}, + {"660fd00511111111", 8, 4}, + {"0fd10511111111", 7, 3}, + {"0fd20511111111", 7, 3}, + {"0fd30511111111", 7, 3}, + {"0fd40511111111", 7, 3}, + {"0fd50511111111", 7, 3}, + {"660fd60511111111", 8, 4}, + {"0fd80511111111", 7, 3}, + {"0fd90511111111", 7, 3}, + {"0fda0511111111", 7, 3}, + {"0fdb0511111111", 7, 3}, + {"0fdc0511111111", 7, 3}, + {"0fdd0511111111", 7, 3}, + {"0fde0511111111", 7, 3}, + {"0fdf0511111111", 7, 3}, + {"0fe00511111111", 7, 3}, + {"0fe10511111111", 7, 3}, + {"0fe20511111111", 7, 3}, + {"0fe30511111111", 7, 3}, + {"0fe40511111111", 7, 3}, + {"0fe50511111111", 7, 3}, + {"660fe60511111111", 8, 4}, + {"0fe70511111111", 7, 3}, + {"0fe80511111111", 7, 3}, + {"0fe90511111111", 7, 3}, + {"0fea0511111111", 7, 3}, + {"0feb0511111111", 7, 3}, + {"0fec0511111111", 7, 3}, + {"0fed0511111111", 7, 3}, + {"0fee0511111111", 7, 3}, + {"0fef0511111111", 7, 3}, + {"f20ff00511111111", 8, 4}, + {"0ff10511111111", 7, 3}, + {"0ff20511111111", 7, 3}, + {"0ff30511111111", 7, 3}, + {"0ff40511111111", 7, 3}, + {"0ff50511111111", 7, 3}, + {"0ff60511111111", 7, 3}, + {"0ff80511111111", 7, 3}, + {"0ff90511111111", 7, 3}, + {"0ffa0511111111", 7, 3}, + {"0ffb0511111111", 7, 3}, + {"0ffc0511111111", 7, 3}, + {"0ffd0511111111", 7, 3}, + {"0ffe0511111111", 7, 3}, + {"0f38000511111111", 8, 4}, + {"0f38010511111111", 8, 4}, + {"0f38020511111111", 8, 4}, + {"0f38030511111111", 8, 4}, + {"0f38040511111111", 8, 4}, + {"0f38050511111111", 8, 4}, + {"0f38060511111111", 8, 4}, + {"0f38070511111111", 8, 4}, + {"0f38080511111111", 8, 4}, + {"0f38090511111111", 8, 4}, + {"0f380a0511111111", 8, 4}, + {"0f380b0511111111", 8, 4}, + {"660f38100511111111", 9, 5}, + {"660f38140511111111", 9, 5}, + {"660f38150511111111", 9, 5}, + {"660f38170511111111", 9, 5}, + {"0f381c0511111111", 8, 4}, + {"0f381d0511111111", 8, 4}, + {"0f381e0511111111", 8, 4}, + {"660f38200511111111", 9, 5}, + {"660f38210511111111", 9, 5}, + {"660f38220511111111", 9, 5}, + {"660f38230511111111", 9, 5}, + {"660f38240511111111", 9, 5}, + {"660f38250511111111", 9, 5}, + {"660f38280511111111", 9, 5}, + {"660f38290511111111", 9, 5}, + {"660f382a0511111111", 9, 5}, + {"660f382b0511111111", 9, 5}, + {"660f38300511111111", 9, 5}, + {"660f38310511111111", 9, 5}, + {"660f38320511111111", 9, 5}, + {"660f38330511111111", 9, 5}, + {"660f38340511111111", 9, 5}, + {"660f38350511111111", 9, 5}, + {"660f38370511111111", 9, 5}, + {"660f38380511111111", 9, 5}, + {"660f38390511111111", 9, 5}, + {"660f383a0511111111", 9, 5}, + {"660f383b0511111111", 9, 5}, + {"660f383c0511111111", 9, 5}, + {"660f383d0511111111", 9, 5}, + {"660f383e0511111111", 9, 5}, + {"660f383f0511111111", 9, 5}, + {"660f38400511111111", 9, 5}, + {"660f38410511111111", 9, 5}, + {"660f38820511111111", 9, 5}, + {"0f38c80511111111", 8, 4}, + {"0f38c90511111111", 8, 4}, + {"0f38ca0511111111", 8, 4}, + {"0f38cb0511111111", 8, 4}, + {"0f38cc0511111111", 8, 4}, + {"0f38cd0511111111", 8, 4}, + {"f30f38d80511111111", 9, 5}, + {"660f38db0511111111", 9, 5}, + {"660f38dc0511111111", 9, 5}, + {"660f38dd0511111111", 9, 5}, + {"660f38de0511111111", 9, 5}, + {"660f38df0511111111", 9, 5}, + {"0f38f00511111111", 8, 4}, + {"0f38f10511111111", 8, 4}, + {"660f38f60511111111", 9, 5}, + {"660f3a08051111111111", 10, 5}, + {"660f3a09051111111111", 10, 5}, + {"660f3a0a051111111111", 10, 5}, + {"660f3a0b051111111111", 10, 5}, + {"660f3a0c051111111111", 10, 5}, + {"660f3a0d051111111111", 10, 5}, + {"660f3a0e051111111111", 10, 5}, + {"0f3a0f051111111111", 9, 4}, + {"660f3a14051111111111", 10, 5}, + {"660f3a15051111111111", 10, 5}, + {"660f3a16051111111111", 10, 5}, + {"660f3a17051111111111", 10, 5}, + {"660f3a20051111111111", 10, 5}, + {"660f3a21051111111111", 10, 5}, + {"660f3a22051111111111", 10, 5}, + {"660f3a40051111111111", 10, 5}, + {"660f3a41051111111111", 10, 5}, + {"660f3a42051111111111", 10, 5}, + {"660f3a44051111111111", 10, 5}, + {"660f3a60051111111111", 10, 5}, + {"660f3a61051111111111", 10, 5}, + {"660f3a62051111111111", 10, 5}, + {"660f3a63051111111111", 10, 5}, + {"0f3acc051111111111", 9, 4}, + {"660f3adf051111111111", 10, 5}, + {"c5f8100511111111", 8, 4}, + {"c5f8110511111111", 8, 4}, + {"c5f8120511111111", 8, 4}, + {"c5f8130511111111", 8, 4}, + {"c5f8140511111111", 8, 4}, + {"c5f8150511111111", 8, 4}, + {"c5f8160511111111", 8, 4}, + {"c5f8170511111111", 8, 4}, + {"c5f8280511111111", 8, 4}, + {"c5f8290511111111", 8, 4}, + {"c5fa2a0511111111", 8, 4}, + {"c5f82b0511111111", 8, 4}, + {"c5fa2c0511111111", 8, 4}, + {"c5fa2d0511111111", 8, 4}, + {"c5f82e0511111111", 8, 4}, + {"c5f82f0511111111", 8, 4}, + {"c5f8510511111111", 8, 4}, + {"c5f8520511111111", 8, 4}, + {"c5f8530511111111", 8, 4}, + {"c5f8540511111111", 8, 4}, + {"c5f8550511111111", 8, 4}, + {"c5f8560511111111", 8, 4}, + {"c5f8570511111111", 8, 4}, + {"c5f8580511111111", 8, 4}, + {"c5f8590511111111", 8, 4}, + {"c5f85a0511111111", 8, 4}, + {"c5f85b0511111111", 8, 4}, + {"c5f85c0511111111", 8, 4}, + {"c5f85d0511111111", 8, 4}, + {"c5f85e0511111111", 8, 4}, + {"c5f85f0511111111", 8, 4}, + {"c5f9600511111111", 8, 4}, + {"c5f9610511111111", 8, 4}, + {"c5f9620511111111", 8, 4}, + {"c5f9630511111111", 8, 4}, + {"c5f9640511111111", 8, 4}, + {"c5f9650511111111", 8, 4}, + {"c5f9660511111111", 8, 4}, + {"c5f9670511111111", 8, 4}, + {"c5f9680511111111", 8, 4}, + {"c5f9690511111111", 8, 4}, + {"c5f96a0511111111", 8, 4}, + {"c5f96b0511111111", 8, 4}, + {"c5f96c0511111111", 8, 4}, + {"c5f96d0511111111", 8, 4}, + {"c5f96e0511111111", 8, 4}, + {"c5f96f0511111111", 8, 4}, + {"c5f970051111111111", 9, 4}, + {"c5f9740511111111", 8, 4}, + {"c5f9750511111111", 8, 4}, + {"c5f9760511111111", 8, 4}, + {"c5f97c0511111111", 8, 4}, + {"c5f97d0511111111", 8, 4}, + {"c5f97e0511111111", 8, 4}, + {"c5f97f0511111111", 8, 4}, + {"c5f8ae1511111111", 8, 4}, + {"c5f8c2051111111111", 9, 4}, + {"c5f9c4051111111111", 9, 4}, + {"c5f8c6051111111111", 9, 4}, + {"c5f9d00511111111", 8, 4}, + {"c5f9d10511111111", 8, 4}, + {"c5f9d20511111111", 8, 4}, + {"c5f9d30511111111", 8, 4}, + {"c5f9d40511111111", 8, 4}, + {"c5f9d50511111111", 8, 4}, + {"c5f9d60511111111", 8, 4}, + {"c5f9d80511111111", 8, 4}, + {"c5f9d90511111111", 8, 4}, + {"c5f9da0511111111", 8, 4}, + {"c5f9db0511111111", 8, 4}, + {"c5f9dc0511111111", 8, 4}, + {"c5f9dd0511111111", 8, 4}, + {"c5f9de0511111111", 8, 4}, + {"c5f9df0511111111", 8, 4}, + {"c5f9e00511111111", 8, 4}, + {"c5f9e10511111111", 8, 4}, + {"c5f9e20511111111", 8, 4}, + {"c5f9e30511111111", 8, 4}, + {"c5f9e40511111111", 8, 4}, + {"c5f9e50511111111", 8, 4}, + {"c5f9e60511111111", 8, 4}, + {"c5f9e70511111111", 8, 4}, + {"c5f9e80511111111", 8, 4}, + {"c5f9e90511111111", 8, 4}, + {"c5f9ea0511111111", 8, 4}, + {"c5f9eb0511111111", 8, 4}, + {"c5f9ec0511111111", 8, 4}, + {"c5f9ed0511111111", 8, 4}, + {"c5f9ee0511111111", 8, 4}, + {"c5f9ef0511111111", 8, 4}, + {"c5fbf00511111111", 8, 4}, + {"c5f9f10511111111", 8, 4}, + {"c5f9f20511111111", 8, 4}, + {"c5f9f30511111111", 8, 4}, + {"c5f9f40511111111", 8, 4}, + {"c5f9f50511111111", 8, 4}, + {"c5f9f60511111111", 8, 4}, + {"c5f9f80511111111", 8, 4}, + {"c5f9f90511111111", 8, 4}, + {"c5f9fa0511111111", 8, 4}, + {"c5f9fb0511111111", 8, 4}, + {"c5f9fc0511111111", 8, 4}, + {"c5f9fd0511111111", 8, 4}, + {"c5f9fe0511111111", 8, 4}, + {"c4e178100511111111", 9, 5}, + {"c4e178110511111111", 9, 5}, + {"c4e178120511111111", 9, 5}, + {"c4e178130511111111", 9, 5}, + {"c4e178140511111111", 9, 5}, + {"c4e178150511111111", 9, 5}, + {"c4e178160511111111", 9, 5}, + {"c4e178170511111111", 9, 5}, + {"c4e178280511111111", 9, 5}, + {"c4e178290511111111", 9, 5}, + {"c4e17a2a0511111111", 9, 5}, + {"c4e1782b0511111111", 9, 5}, + {"c4e17a2c0511111111", 9, 5}, + {"c4e17a2d0511111111", 9, 5}, + {"c4e1782e0511111111", 9, 5}, + {"c4e1782f0511111111", 9, 5}, + {"c4e178510511111111", 9, 5}, + {"c4e178520511111111", 9, 5}, + {"c4e178530511111111", 9, 5}, + {"c4e178540511111111", 9, 5}, + {"c4e178550511111111", 9, 5}, + {"c4e178560511111111", 9, 5}, + {"c4e178570511111111", 9, 5}, + {"c4e178580511111111", 9, 5}, + {"c4e178590511111111", 9, 5}, + {"c4e1785a0511111111", 9, 5}, + {"c4e1785b0511111111", 9, 5}, + {"c4e1785c0511111111", 9, 5}, + {"c4e1785d0511111111", 9, 5}, + {"c4e1785e0511111111", 9, 5}, + {"c4e1785f0511111111", 9, 5}, + {"c4e179600511111111", 9, 5}, + {"c4e179610511111111", 9, 5}, + {"c4e179620511111111", 9, 5}, + {"c4e179630511111111", 9, 5}, + {"c4e179640511111111", 9, 5}, + {"c4e179650511111111", 9, 5}, + {"c4e179660511111111", 9, 5}, + {"c4e179670511111111", 9, 5}, + {"c4e179680511111111", 9, 5}, + {"c4e179690511111111", 9, 5}, + {"c4e1796a0511111111", 9, 5}, + {"c4e1796b0511111111", 9, 5}, + {"c4e1796c0511111111", 9, 5}, + {"c4e1796d0511111111", 9, 5}, + {"c4e1796e0511111111", 9, 5}, + {"c4e1796f0511111111", 9, 5}, + {"c4e17970051111111111", 10, 5}, + {"c4e179740511111111", 9, 5}, + {"c4e179750511111111", 9, 5}, + {"c4e179760511111111", 9, 5}, + {"c4e1797c0511111111", 9, 5}, + {"c4e1797d0511111111", 9, 5}, + {"c4e1797e0511111111", 9, 5}, + {"c4e1797f0511111111", 9, 5}, + {"c4e178ae1511111111", 9, 5}, + {"c4e178c2051111111111", 10, 5}, + {"c4e179c4051111111111", 10, 5}, + {"c4e178c6051111111111", 10, 5}, + {"c4e179d00511111111", 9, 5}, + {"c4e179d10511111111", 9, 5}, + {"c4e179d20511111111", 9, 5}, + {"c4e179d30511111111", 9, 5}, + {"c4e179d40511111111", 9, 5}, + {"c4e179d50511111111", 9, 5}, + {"c4e179d60511111111", 9, 5}, + {"c4e179d80511111111", 9, 5}, + {"c4e179d90511111111", 9, 5}, + {"c4e179da0511111111", 9, 5}, + {"c4e179db0511111111", 9, 5}, + {"c4e179dc0511111111", 9, 5}, + {"c4e179dd0511111111", 9, 5}, + {"c4e179de0511111111", 9, 5}, + {"c4e179df0511111111", 9, 5}, + {"c4e179e00511111111", 9, 5}, + {"c4e179e10511111111", 9, 5}, + {"c4e179e20511111111", 9, 5}, + {"c4e179e30511111111", 9, 5}, + {"c4e179e40511111111", 9, 5}, + {"c4e179e50511111111", 9, 5}, + {"c4e179e60511111111", 9, 5}, + {"c4e179e70511111111", 9, 5}, + {"c4e179e80511111111", 9, 5}, + {"c4e179e90511111111", 9, 5}, + {"c4e179ea0511111111", 9, 5}, + {"c4e179eb0511111111", 9, 5}, + {"c4e179ec0511111111", 9, 5}, + {"c4e179ed0511111111", 9, 5}, + {"c4e179ee0511111111", 9, 5}, + {"c4e179ef0511111111", 9, 5}, + {"c4e17bf00511111111", 9, 5}, + {"c4e179f10511111111", 9, 5}, + {"c4e179f20511111111", 9, 5}, + {"c4e179f30511111111", 9, 5}, + {"c4e179f40511111111", 9, 5}, + {"c4e179f50511111111", 9, 5}, + {"c4e179f60511111111", 9, 5}, + {"c4e179f80511111111", 9, 5}, + {"c4e179f90511111111", 9, 5}, + {"c4e179fa0511111111", 9, 5}, + {"c4e179fb0511111111", 9, 5}, + {"c4e179fc0511111111", 9, 5}, + {"c4e179fd0511111111", 9, 5}, + {"c4e179fe0511111111", 9, 5}, + {"c4e279000511111111", 9, 5}, + {"c4e279010511111111", 9, 5}, + {"c4e279020511111111", 9, 5}, + {"c4e279030511111111", 9, 5}, + {"c4e279040511111111", 9, 5}, + {"c4e279050511111111", 9, 5}, + {"c4e279060511111111", 9, 5}, + {"c4e279070511111111", 9, 5}, + {"c4e279080511111111", 9, 5}, + {"c4e279090511111111", 9, 5}, + {"c4e2790a0511111111", 9, 5}, + {"c4e2790b0511111111", 9, 5}, + {"c4e2790c0511111111", 9, 5}, + {"c4e2790d0511111111", 9, 5}, + {"c4e2790e0511111111", 9, 5}, + {"c4e2790f0511111111", 9, 5}, + {"c4e279130511111111", 9, 5}, + {"c4e27d160511111111", 9, 5}, + {"c4e279170511111111", 9, 5}, + {"c4e279180511111111", 9, 5}, + {"c4e27d190511111111", 9, 5}, + {"c4e27d1a0511111111", 9, 5}, + {"c4e2791c0511111111", 9, 5}, + {"c4e2791d0511111111", 9, 5}, + {"c4e2791e0511111111", 9, 5}, + {"c4e279200511111111", 9, 5}, + {"c4e279210511111111", 9, 5}, + {"c4e279220511111111", 9, 5}, + {"c4e279230511111111", 9, 5}, + {"c4e279240511111111", 9, 5}, + {"c4e279250511111111", 9, 5}, + {"c4e279280511111111", 9, 5}, + {"c4e279290511111111", 9, 5}, + {"c4e2792a0511111111", 9, 5}, + {"c4e2792b0511111111", 9, 5}, + {"c4e2792c0511111111", 9, 5}, + {"c4e2792d0511111111", 9, 5}, + {"c4e2792e0511111111", 9, 5}, + {"c4e2792f0511111111", 9, 5}, + {"c4e279300511111111", 9, 5}, + {"c4e279310511111111", 9, 5}, + {"c4e279320511111111", 9, 5}, + {"c4e279330511111111", 9, 5}, + {"c4e279340511111111", 9, 5}, + {"c4e279350511111111", 9, 5}, + {"c4e27d360511111111", 9, 5}, + {"c4e279370511111111", 9, 5}, + {"c4e279380511111111", 9, 5}, + {"c4e279390511111111", 9, 5}, + {"c4e2793a0511111111", 9, 5}, + {"c4e2793b0511111111", 9, 5}, + {"c4e2793c0511111111", 9, 5}, + {"c4e2793d0511111111", 9, 5}, + {"c4e2793e0511111111", 9, 5}, + {"c4e2793f0511111111", 9, 5}, + {"c4e279400511111111", 9, 5}, + {"c4e279410511111111", 9, 5}, + {"c4e279450511111111", 9, 5}, + {"c4e279460511111111", 9, 5}, + {"c4e279470511111111", 9, 5}, + {"c4e279580511111111", 9, 5}, + {"c4e279590511111111", 9, 5}, + {"c4e27d5a0511111111", 9, 5}, + {"c4e279780511111111", 9, 5}, + {"c4e279790511111111", 9, 5}, + {"c4e2798c0511111111", 9, 5}, + {"c4e2798e0511111111", 9, 5}, + {"c4e279960511111111", 9, 5}, + {"c4e279970511111111", 9, 5}, + {"c4e279980511111111", 9, 5}, + {"c4e279990511111111", 9, 5}, + {"c4e2799a0511111111", 9, 5}, + {"c4e2799b0511111111", 9, 5}, + {"c4e2799c0511111111", 9, 5}, + {"c4e2799d0511111111", 9, 5}, + {"c4e2799e0511111111", 9, 5}, + {"c4e2799f0511111111", 9, 5}, + {"c4e279a60511111111", 9, 5}, + {"c4e279a70511111111", 9, 5}, + {"c4e279a80511111111", 9, 5}, + {"c4e279a90511111111", 9, 5}, + {"c4e279aa0511111111", 9, 5}, + {"c4e279ab0511111111", 9, 5}, + {"c4e279ac0511111111", 9, 5}, + {"c4e279ad0511111111", 9, 5}, + {"c4e279ae0511111111", 9, 5}, + {"c4e279af0511111111", 9, 5}, + {"c4e279b60511111111", 9, 5}, + {"c4e279b70511111111", 9, 5}, + {"c4e279b80511111111", 9, 5}, + {"c4e279b90511111111", 9, 5}, + {"c4e279ba0511111111", 9, 5}, + {"c4e279bb0511111111", 9, 5}, + {"c4e279bc0511111111", 9, 5}, + {"c4e279bd0511111111", 9, 5}, + {"c4e279be0511111111", 9, 5}, + {"c4e279bf0511111111", 9, 5}, + {"c4e279db0511111111", 9, 5}, + {"c4e279dc0511111111", 9, 5}, + {"c4e279dd0511111111", 9, 5}, + {"c4e279de0511111111", 9, 5}, + {"c4e279df0511111111", 9, 5}, + {"c4e278f20511111111", 9, 5}, + {"c4e278f30d11111111", 9, 5}, + {"c4e278f50511111111", 9, 5}, + {"c4e27bf60511111111", 9, 5}, + {"c4e278f70511111111", 9, 5}, + {"c4e3fd00051111111111", 10, 5}, + {"c4e3fd01051111111111", 10, 5}, + {"c4e37902051111111111", 10, 5}, + {"c4e37904051111111111", 10, 5}, + {"c4e37905051111111111", 10, 5}, + {"c4e37d06051111111111", 10, 5}, + {"c4e37908051111111111", 10, 5}, + {"c4e37909051111111111", 10, 5}, + {"c4e3790a051111111111", 10, 5}, + {"c4e3790b051111111111", 10, 5}, + {"c4e3790c051111111111", 10, 5}, + {"c4e3790d051111111111", 10, 5}, + {"c4e3790e051111111111", 10, 5}, + {"c4e3790f051111111111", 10, 5}, + {"c4e37914051111111111", 10, 5}, + {"c4e37915051111111111", 10, 5}, + {"c4e37916051111111111", 10, 5}, + {"c4e37917051111111111", 10, 5}, + {"c4e37d18051111111111", 10, 5}, + {"c4e37d19051111111111", 10, 5}, + {"c4e3791d051111111111", 10, 5}, + {"c4e37920051111111111", 10, 5}, + {"c4e37921051111111111", 10, 5}, + {"c4e37922051111111111", 10, 5}, + {"c4e37d38051111111111", 10, 5}, + {"c4e37d39051111111111", 10, 5}, + {"c4e37940051111111111", 10, 5}, + {"c4e37941051111111111", 10, 5}, + {"c4e37942051111111111", 10, 5}, + {"c4e37944051111111111", 10, 5}, + {"c4e37d46051111111111", 10, 5}, + {"c4e3794a051111111111", 10, 5}, + {"c4e3794b051111111111", 10, 5}, + {"c4e3794c051111111111", 10, 5}, + {"c4e37960051111111111", 10, 5}, + {"c4e37961051111111111", 10, 5}, + {"c4e37962051111111111", 10, 5}, + {"c4e37963051111111111", 10, 5}, + {"c4e379df051111111111", 10, 5}, + {"c4e37bf0051111111111", 10, 5}, +}; + +inline constexpr DecoderBranchCase kDecoderBranchCases[] = { + {"0f0b", 2, Codegen::ControlFlowKind::Trap, false, 0}, + {"0f80c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f81c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f82c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f83c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f84c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f85c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f86c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f87c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f88c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f89c0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f8ac0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f8bc0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f8cc0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f8dc0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f8ec0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0f8fc0111111", 6, Codegen::ControlFlowKind::ConditionalBranch, true, 286331328}, + {"0fb9c0", 3, Codegen::ControlFlowKind::Trap, false, 0}, + {"480fb9c0", 4, Codegen::ControlFlowKind::Trap, false, 0}, + {"48cac011", 4, Codegen::ControlFlowKind::Return, false, 0}, + {"48cb", 2, Codegen::ControlFlowKind::Return, false, 0}, + {"660fb9c0", 4, Codegen::ControlFlowKind::Trap, false, 0}, + {"66c2c011", 4, Codegen::ControlFlowKind::Return, false, 0}, + {"66c3", 2, Codegen::ControlFlowKind::Return, false, 0}, + {"66cac011", 4, Codegen::ControlFlowKind::Return, false, 0}, + {"66cb", 2, Codegen::ControlFlowKind::Return, false, 0}, + {"66ff18", 3, Codegen::ControlFlowKind::IndirectCall, false, 0}, + {"66ff28", 3, Codegen::ControlFlowKind::IndirectJump, false, 0}, + {"66ffd0", 3, Codegen::ControlFlowKind::IndirectCall, false, 0}, + {"66ffe0", 3, Codegen::ControlFlowKind::IndirectJump, false, 0}, + {"70c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"71c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"72c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"73c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"74c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"75c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"76c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"77c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"78c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"79c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"7ac0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"7bc0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"7cc0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"7dc0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"7ec0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"7fc0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"c2c011", 3, Codegen::ControlFlowKind::Return, false, 0}, + {"c3", 1, Codegen::ControlFlowKind::Return, false, 0}, + {"cac011", 3, Codegen::ControlFlowKind::Return, false, 0}, + {"cb", 1, Codegen::ControlFlowKind::Return, false, 0}, + {"e0c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"e1c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"e2c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"e3c0", 2, Codegen::ControlFlowKind::ConditionalBranch, true, -64}, + {"e8c0111111", 5, Codegen::ControlFlowKind::Call, true, 286331328}, + {"e9c0111111", 5, Codegen::ControlFlowKind::UnconditionalJump, true, 286331328}, + {"ebc0", 2, Codegen::ControlFlowKind::UnconditionalJump, true, -64}, + {"ff1511111111", 6, Codegen::ControlFlowKind::Call, false, 0}, + {"ff1d11111111", 6, Codegen::ControlFlowKind::IndirectCall, false, 0}, + {"ff2511111111", 6, Codegen::ControlFlowKind::UnconditionalJump, true, 286331153}, + {"ff2d11111111", 6, Codegen::ControlFlowKind::IndirectJump, false, 0}, + {"ff18", 2, Codegen::ControlFlowKind::IndirectCall, false, 0}, + {"ff28", 2, Codegen::ControlFlowKind::IndirectJump, false, 0}, + {"ffd0", 2, Codegen::ControlFlowKind::IndirectCall, false, 0}, + {"ffe0", 2, Codegen::ControlFlowKind::IndirectJump, false, 0}, +}; + +#endif diff --git a/docs/dev/debt/relinker.md b/docs/dev/debt/relinker.md index e5841ca308..2ce4cc5356 100644 --- a/docs/dev/debt/relinker.md +++ b/docs/dev/debt/relinker.md @@ -6,6 +6,7 @@ - The executable file that [relinker](../../../core/relinker/elfpatcher/src/windows/WindowsPeWriter.cpp) generates opens a console when launched, unless it is relinked with `--windows-gui`, which selects the GUI subsystem. A GUI build started from Explorer has no standard output or error handle, so everything it prints is lost, including the entry stub's errors and crash reports (#3282). - Converted Windows main executables [omit `DYNAMIC_BASE`](../../../core/relinker/elfpatcher/src/windows/WindowsPeWriter.cpp) by default, not only with `--windows-fixed-base`: on the console the executable lies inside the 40-bit window that the title's own `sceLibcMspaceCreate` checks (#3043). Relocations are kept, so if `0x140000000` is taken Windows relocates the image, possibly above that window. Verified only on Windows 10. - [SDK memory-management syscall traps](../../../core/relinker/relinker/src/analysis/SyscallScanner.cpp) under `--trap-sdk-syscall-stubs` recognize three exact instruction sequences from [ps5-payload-dev SDK libc/mman.c](https://github.com/ps5-payload-dev/sdk/blob/12cf3dda40/libc/mman.c), observed in Nuvio Maxd 0.5.15 (PPSA99288): syscall 74 and the two syscall 477 paths, with their argument preparation and carry-flag error handling. Matching requires a decoded instruction boundary and the complete sequence inside the scanned code range. Other SDK/compiler output remains rejected. The matched syscall becomes `UD2`; this does not implement mmap or mprotect and a call still faults. +- The [instruction decoder](../../../core/relinker/codegen/src/x86/X64InstructionDecoder.cpp) decodes a near CALL, JMP or Jcc with an operand-size prefix (`66`) as Intel does, with a 32-bit or 8-bit displacement and a 64-bit target. AMD processors, the console included, read a 16-bit displacement for `66 E8`, `66 E9` and `66 0F 80`-`8F` and truncate the target of every near branch with that prefix, rel8 forms included, to 16 bits. Compilers do not emit these forms; the relinker's length and target for them do not match the console. - `--to-intel` does not lower RDPRU/MCOMMIT; the [matcher](../../../core/relinker/codegen/src/x86/Amd64OnlyInstructionMatcher.cpp) fails the relink instead. - The length-changing path of the [instruction rewriter](../../../core/relinker/codegen/src/x86/X64InstructionRewriter.cpp) is not used by the [converter](../../../core/relinker/codegen/src/Amd64OnlyConverter.cpp): it does not adjust data-to-code references (relocations, FDEs, jump tables) or segment sizes, so every substitution keeps the instruction length. - A `PT_SCE_RELRO` segment that no `PT_LOAD` covers, the PS4 layout, is [loaded](../../../core/relinker/relinker/src/parsing/ElfReader.cpp) as a read-write `PT_LOAD` and stays writable after relocation; FreeBSD rtld makes `PT_GNU_RELRO` read-only once relocation is done, and what the console does with `PT_SCE_RELRO` is not checked.