diff --git a/src/asm_unmarshal.cpp b/src/asm_unmarshal.cpp index f11697bef..3a71f160d 100644 --- a/src/asm_unmarshal.cpp +++ b/src/asm_unmarshal.cpp @@ -88,26 +88,31 @@ struct Unmarshaller { auto getAluOp(size_t pc, ebpf_inst inst) -> std::variant { // First handle instructions that support a non-zero offset. + std::ostringstream oss; + oss << "invalid ALU op " << std::hex << "0x" << (int)inst.opcode; switch (inst.opcode & INST_ALU_OP_MASK) { case INST_ALU_OP_DIV: switch (inst.offset) { case 0: return Bin::Op::UDIV; case 1: return Bin::Op::SDIV; - default: throw InvalidInstruction{pc, "invalid ALU op 0x30"}; + default: throw InvalidInstruction{pc, oss.str().c_str()}; } case INST_ALU_OP_MOD: switch (inst.offset) { case 0: return Bin::Op::UMOD; case 1: return Bin::Op::SMOD; - default: throw InvalidInstruction{pc, "invalid ALU op 0x90"}; + default: throw InvalidInstruction{pc, oss.str().c_str()}; } case INST_ALU_OP_MOV: + if (inst.offset > 0 && !(inst.opcode & INST_SRC_REG)) { + throw InvalidInstruction{pc, oss.str().c_str()}; + } switch (inst.offset) { case 0: return Bin::Op::MOV; case 8: return Bin::Op::MOVSX8; case 16: return Bin::Op::MOVSX16; case 32: return Bin::Op::MOVSX32; - default: throw InvalidInstruction{pc, "invalid ALU op 0xb0"}; + default: throw InvalidInstruction{pc, oss.str().c_str()}; } } @@ -147,8 +152,8 @@ struct Unmarshaller { default: throw InvalidInstruction(pc, "invalid endian immediate"); } - case 0xe0: throw InvalidInstruction{pc, "invalid ALU op 0xe0"}; - case 0xf0: throw InvalidInstruction{pc, "invalid ALU op 0xf0"}; + case 0xe0: throw InvalidInstruction{pc, oss.str().c_str()}; + case 0xf0: throw InvalidInstruction{pc, oss.str().c_str()}; } return {}; } diff --git a/src/test/test_conformance.cpp b/src/test/test_conformance.cpp index ac7a308c3..b665a1da9 100644 --- a/src/test/test_conformance.cpp +++ b/src/test/test_conformance.cpp @@ -185,15 +185,10 @@ TEST_CONFORMANCE("mod64-by-zero-reg.data") TEST_CONFORMANCE("mod64.data") TEST_CONFORMANCE("mov.data") TEST_CONFORMANCE("mov64-sign-extend.data") -TEST_CONFORMANCE("movsx1632-imm.data") TEST_CONFORMANCE("movsx1632-reg.data") -TEST_CONFORMANCE("movsx1664-imm.data") TEST_CONFORMANCE("movsx1664-reg.data") -TEST_CONFORMANCE("movsx3264-imm.data") TEST_CONFORMANCE("movsx3264-reg.data") -TEST_CONFORMANCE("movsx832-imm.data") TEST_CONFORMANCE("movsx832-reg.data") -TEST_CONFORMANCE("movsx864-imm.data") TEST_CONFORMANCE("movsx864-reg.data") TEST_CONFORMANCE("mul32-imm.data") TEST_CONFORMANCE("mul32-reg-overflow.data") diff --git a/src/test/test_marshal.cpp b/src/test/test_marshal.cpp index 33773791f..b29da5ac7 100644 --- a/src/test/test_marshal.cpp +++ b/src/test/test_marshal.cpp @@ -274,4 +274,6 @@ TEST_CASE("fail unmarshal", "[disasm][marshal]") { check_unmarshal_fail(ebpf_inst{.opcode = 0x10 | INST_CLS_JMP32}, "0: jump out of bounds\n"); check_unmarshal_fail(ebpf_inst{.opcode = INST_ALU_OP_END | INST_CLS_ALU, .imm = 0}, "0: invalid endian immediate\n"); check_unmarshal_fail(ebpf_inst{.opcode = INST_ALU_OP_END | INST_CLS_ALU64, .imm = 0}, "0: invalid endian immediate\n"); + check_unmarshal_fail(ebpf_inst{.opcode = INST_ALU_OP_MOV | INST_SRC_IMM | INST_CLS_ALU, .offset = 8}, + "0: invalid ALU op 0xb4\n"); } diff --git a/test-data/movsx.yaml b/test-data/movsx.yaml index 7aa3d0f54..ef1fe399c 100644 --- a/test-data/movsx.yaml +++ b/test-data/movsx.yaml @@ -1,71 +1,6 @@ # Copyright (c) Prevail Verifier contributors. # SPDX-License-Identifier: MIT --- -test-case: movsx8 immediate to 32 bits - -pre: [] - -code: - : | - w1 s8= 384 ; 0x180 -> 0xFFFFFF80 - -post: - - r1.type=number - - r1.svalue=4294967168 - - r1.uvalue=4294967168 ---- -test-case: movsx16 immediate to 32 bits - -pre: [] - -code: - : | - w1 s16= 98304 ; 0x18000 -> 0xFFFF8000 - -post: - - r1.type=number - - r1.svalue=4294934528 - - r1.uvalue=4294934528 ---- -test-case: movsx8 immediate to 64 bits - -pre: [] - -code: - : | - r1 s8= 384 ; 0x180 -> 0xFFFFFFFFFFFFFF80 - -post: - - r1.type=number - - r1.svalue=-128 - - r1.uvalue=18446744073709551488 ---- -test-case: movsx16 immediate to 64 bits - -pre: [] - -code: - : | - r1 s16= 98304 ; 0x18000 -> 0xFFFFFFFFFFFF8000 - -post: - - r1.type=number - - r1.svalue=-32768 - - r1.uvalue=18446744073709518848 ---- -test-case: movsx32 immediate to 64 bits - -pre: [] - -code: - : | - r1 s32= 2147483648 ; 0x80000000 -> 0xFFFFFFFF80000000 - -post: - - r1.type=number - - r1.svalue=-2147483648 - - r1.uvalue=18446744071562067968 ---- test-case: movsx8 register to 32 bits pre: ["r1.svalue=384", "r1.uvalue=384", "r1.type=number", "r1.svalue=r1.uvalue"]