From a90ab20eb90e952538b9984539af795332e231fc Mon Sep 17 00:00:00 2001 From: Dave Thaler Date: Sun, 28 Jan 2024 11:07:13 -0800 Subject: [PATCH] More marshaling tests * Add negative tests for bad offset for instructions that vary by offset value * Add marshaling tests for unconditional byteswap * Add marshaling tests for signed division and modulo * Add marshaling tests for sign extension Signed-off-by: Dave Thaler --- src/asm_unmarshal.cpp | 6 +++--- src/test/test_marshal.cpp | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/asm_unmarshal.cpp b/src/asm_unmarshal.cpp index 9560d0320..4a6af8308 100644 --- a/src/asm_unmarshal.cpp +++ b/src/asm_unmarshal.cpp @@ -101,13 +101,13 @@ struct Unmarshaller { 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, make_opcode_message("invalid offset for", inst.opcode)); } 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, make_opcode_message("invalid offset for", inst.opcode)); } case INST_ALU_OP_MOV: switch (inst.offset) { @@ -115,7 +115,7 @@ struct Unmarshaller { 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, make_opcode_message("invalid offset for", inst.opcode)); } } diff --git a/src/test/test_marshal.cpp b/src/test/test_marshal.cpp index 20700855f..ffe0c8d02 100644 --- a/src/test/test_marshal.cpp +++ b/src/test/test_marshal.cpp @@ -58,7 +58,8 @@ static const auto ws = {1, 2, 4, 8}; TEST_CASE("disasm_marshal", "[disasm][marshal]") { SECTION("Bin") { auto ops = {Bin::Op::MOV, Bin::Op::ADD, Bin::Op::SUB, Bin::Op::MUL, Bin::Op::UDIV, Bin::Op::UMOD, - Bin::Op::OR, Bin::Op::AND, Bin::Op::LSH, Bin::Op::RSH, Bin::Op::ARSH, Bin::Op::XOR}; + Bin::Op::OR, Bin::Op::AND, Bin::Op::LSH, Bin::Op::RSH, Bin::Op::ARSH, Bin::Op::XOR, + Bin::Op::SDIV, Bin::Op::SMOD, Bin::Op::MOVSX8, Bin::Op::MOVSX16, Bin::Op::MOVSX32}; SECTION("Reg src") { for (auto op : ops) { compare_marshal_unmarshal(Bin{.op = op, .dst = Reg{1}, .v = Reg{2}, .is64 = true}); @@ -90,6 +91,9 @@ TEST_CASE("disasm_marshal", "[disasm][marshal]") { Un::Op::LE32, Un::Op::LE64, Un::Op::NEG, + Un::Op::SWAP16, + Un::Op::SWAP32, + Un::Op::SWAP64 }; for (auto op : ops) compare_marshal_unmarshal(Un{.op = op, .dst = Reg{1}}); @@ -287,6 +291,16 @@ TEST_CASE("fail unmarshal off0 opcodes", "[disasm][marshal]") { } } +TEST_CASE("fail unmarshal offset opcodes", "[disasm][marshal]") { + // The following opcodes are defined for multiple other offset values, but not offset = 2 for example. + uint8_t off2_opcodes[] = {0x34, 0x37, 0x3c, 0x3f, 0x94, 0x97, 0x9c, 0x9f, 0xb4, 0xb7, 0xbc, 0xbf}; + for (int i = 0; i < sizeof(off2_opcodes); i++) { + std::ostringstream oss; + oss << "0: invalid offset for op 0x" << std::hex << (int)off2_opcodes[i] << std::endl; + check_unmarshal_fail(ebpf_inst{.opcode = off2_opcodes[i], .offset = 2}, oss.str().c_str()); + } +} + TEST_CASE("fail unmarshal misc", "[disasm][marshal]") { check_unmarshal_fail(ebpf_inst{.opcode = /* 0x06 */ INST_CLS_JMP32}, "0: jump out of bounds\n"); check_unmarshal_fail(ebpf_inst{.opcode = /* 0x16 */ 0x10 | INST_CLS_JMP32}, "0: jump out of bounds\n");