diff --git a/core/relinker/elfpatcher/src/windows/WindowsTlsBuilder.cpp b/core/relinker/elfpatcher/src/windows/WindowsTlsBuilder.cpp index e50f17c0ce..19ff13e378 100644 --- a/core/relinker/elfpatcher/src/windows/WindowsTlsBuilder.cpp +++ b/core/relinker/elfpatcher/src/windows/WindowsTlsBuilder.cpp @@ -158,8 +158,8 @@ PeDirectory WindowsTlsBuilder::Build(const std::vector& source, co throw Domain::RelinkerException("Short guest TLS instruction ends its segment", header.Offset + offset); const auto next = decoder.DecodeInstruction(bytes + length, header.FileSize - offset - length); const bool relativeBranch = - (next.FlowKind == Codegen::ControlFlowKind::ConditionalBranch && (next.IsTwoByteOpcode ? next.Opcode >= 0x80 && next.Opcode <= 0x8f : next.Opcode >= 0x70 && next.Opcode <= 0x7f)) || - (next.FlowKind == Codegen::ControlFlowKind::UnconditionalJump && !next.HasRipRelativeDisp && !next.IsTwoByteOpcode && (next.Opcode == 0xe9 || next.Opcode == 0xeb)); + (next.FlowKind == Codegen::ControlFlowKind::ConditionalBranch && !next.TruncatesBranchTarget && (next.IsTwoByteOpcode ? next.Opcode >= 0x80 && next.Opcode <= 0x8f : next.Opcode >= 0x70 && next.Opcode <= 0x7f)) || + (next.FlowKind == Codegen::ControlFlowKind::UnconditionalJump && !next.TruncatesBranchTarget && !next.HasRipRelativeDisp && !next.IsTwoByteOpcode && (next.Opcode == 0xe9 || next.Opcode == 0xeb)); if (!relativeBranch && (next.FlowKind != Codegen::ControlFlowKind::Sequential || next.HasBranchTarget || next.SegmentPrefix != 0)) throw Domain::RelinkerException("Short guest TLS instruction is followed by an instruction that cannot move", header.Offset + offset + length); std::vector movedBytes(bytes + length, bytes + length + next.Length); diff --git a/core/relinker/relinker/tests/test_tls_function_coverage.py b/core/relinker/relinker/tests/test_tls_function_coverage.py index 6c30aada25..ef20c1c1a1 100644 --- a/core/relinker/relinker/tests/test_tls_function_coverage.py +++ b/core/relinker/relinker/tests/test_tls_function_coverage.py @@ -747,6 +747,10 @@ def main(): "short-before-tls": bytes.fromhex("64 48 8b 03 64 48 8b 03 c3"), "short-alu-before-return": bytes.fromhex("64 48 33 03 c3"), "short-before-loop": bytes.fromhex("64 48 33 03 e2 00"), + "short-before-word-jcc8": bytes.fromhex("64 48 33 03 66 75 00 c3"), + "short-before-word-jmp8": bytes.fromhex("64 48 33 03 66 eb 00 c3"), + "short-before-word-jmp16": bytes.fromhex("64 48 33 03 66 e9 00 00 c3"), + "short-before-word-jcc16": bytes.fromhex("64 48 33 03 66 0f 85 00 00 c3"), }.items(): convert(name, make_image("register", "unwind", body=instruction), "Short guest TLS instruction is followed by an instruction that cannot move", error_offset=0x1244)