From 77761ba0328affc100b71233489cdda2b9934364 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 14:01:18 -0500 Subject: [PATCH 1/7] Added the format strings for LDRT encodings A1 and A2. --- src/frontend/decoder/arm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index a02339a4..fb2f6c26 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -197,8 +197,8 @@ boost::optional&> DecodeArm(u32 instruction) { //INST(&V::arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnndddd00001111mmmm"), //INST(&V::arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----"), //INST(&V::arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----"), - //INST(&V::arm_LDRT, "LDRT (A1)", "----0100-011--------------------"), - //INST(&V::arm_LDRT, "LDRT (A2)", "----0110-011---------------0----"), + //INST(&V::arm_LDRT, "LDRT (A1)", "cccc0100u011nnnnttttvvvvvvvvvvvv"), + //INST(&V::arm_LDRT, "LDRT (A2)", "cccc0110u011nnnnttttvvvvvrr0mmmm"), //INST(&V::arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnddddvvvvvvvvvvvv"), //INST(&V::arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnddddvvvvvrr0mmmm"), //INST(&V::arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnddddvvvvvvvvvvvv"), From 5d5ea9325cccc1a21ff9da58e76e8696cbe488a7 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 14:05:53 -0500 Subject: [PATCH 2/7] Added format strings for ARM STRT encodings A1 and A2 --- src/frontend/decoder/arm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index fb2f6c26..a54541d4 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -211,8 +211,8 @@ boost::optional&> DecodeArm(u32 instruction) { //INST(&V::arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnndddd00001011mmmm"), //INST(&V::arm_STRHT, "STRHT (A1)", "----0000-110------------1011----"), //INST(&V::arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----"), - //INST(&V::arm_STRT, "STRT (A1)", "----0100-010--------------------"), - //INST(&V::arm_STRT, "STRT (A2)", "----0110-010---------------0----"), + //INST(&V::arm_STRT, "STRT (A1)", "cccc0100u010nnnnttttvvvvvvvvvvvv"), + //INST(&V::arm_STRT, "STRT (A2)", "cccc0110u010nnnnttttvvvvvrr0mmmm"), // Load/Store Multiple instructions //INST(&V::arm_LDM, "LDM", "cccc100pu0w1nnnnxxxxxxxxxxxxxxxx"), // all From 8617bf80a19a161680c4c7ce0248688fba7e8c50 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 14:18:39 -0500 Subject: [PATCH 3/7] Added format strings for ARM LDRBT encodings A1 and A2 --- src/frontend/decoder/arm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index a54541d4..070a6521 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -181,8 +181,8 @@ boost::optional&> DecodeArm(u32 instruction) { //INST(&V::arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnddddvvvvvrr0mmmm"), //INST(&V::arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnddddvvvvvvvvvvvv"), //INST(&V::arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnddddvvvvvrr0mmmm"), - //INST(&V::arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------"), - //INST(&V::arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----"), + //INST(&V::arm_LDRBT, "LDRBT (A1)", "cccc0100u111nnnnttttvvvvvvvvvvvv"), + //INST(&V::arm_LDRBT, "LDRBT (A2)", "cccc0110u111nnnnttttvvvvvrr0mmmm"), //INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv"), // v5E //INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm"), // v5E //INST(&V::arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv"), From ccc61472b956c33317cf48c5982f9fb187537d0d Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 14:20:58 -0500 Subject: [PATCH 4/7] Added format strings for ARM STRBT encodings A1 and A2 --- src/frontend/decoder/arm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/decoder/arm.h b/src/frontend/decoder/arm.h index 070a6521..d7ffd709 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/decoder/arm.h @@ -203,8 +203,8 @@ boost::optional&> DecodeArm(u32 instruction) { //INST(&V::arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnddddvvvvvrr0mmmm"), //INST(&V::arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnddddvvvvvvvvvvvv"), //INST(&V::arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnddddvvvvvrr0mmmm"), - //INST(&V::arm_STRBT, "STRBT (A1)", "----0100-110--------------------"), - //INST(&V::arm_STRBT, "STRBT (A2)", "----0110-110---------------0----"), + //INST(&V::arm_STRBT, "STRBT (A1)", "cccc0100u110nnnnttttvvvvvvvvvvvv"), + //INST(&V::arm_STRBT, "STRBT (A2)", "cccc0110u110nnnnttttvvvvvrr0mmmm"), //INST(&V::arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnddddvvvv1111vvvv"), // v5E //INST(&V::arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnndddd00001111mmmm"), // v5E //INST(&V::arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnddddvvvv1011vvvv"), From c330d9e0e30253ebf42eecfbdedc3c67f3d82caa Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 16:10:35 -0500 Subject: [PATCH 5/7] Increase the chance of generating instructions without conditions in the REV/REVSH/REV16 tests. --- tests/arm/fuzz_arm.cpp | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tests/arm/fuzz_arm.cpp b/tests/arm/fuzz_arm.cpp index d2834eb6..ae19305e 100644 --- a/tests/arm/fuzz_arm.cpp +++ b/tests/arm/fuzz_arm.cpp @@ -366,29 +366,44 @@ TEST_CASE("Fuzz ARM reversal instructions", "[JitX64]") { return Dynarmic::Common::Bits<0, 3>(instr) != 0b1111 && Dynarmic::Common::Bits<12, 15>(instr) != 0b1111; }; - const std::array reg_instructions = { + const std::array rev_instructions = { { - InstructionGenerator("cccc011010111111dddd11110011mmmm", is_valid), - InstructionGenerator("cccc011010111111dddd11111011mmmm", is_valid), - InstructionGenerator("cccc011011111111dddd11111011mmmm", is_valid), + InstructionGenerator("0000011010111111dddd11110011mmmm", is_valid), + InstructionGenerator("0000011010111111dddd11111011mmmm", is_valid), + InstructionGenerator("0000011011111111dddd11111011mmmm", is_valid), } }; SECTION("REV tests") { - FuzzJitArm(1, 1, 10000, [®_instructions]() -> u32 { - return reg_instructions[0].Generate(); + FuzzJitArm(1, 1, 10000, [&rev_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + return rev_instructions[0].Generate() | (cond << 28); }); } SECTION("REV16 tests") { - FuzzJitArm(1, 1, 10000, [®_instructions]() -> u32 { - return reg_instructions[1].Generate(); + FuzzJitArm(1, 1, 10000, [&rev_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + return rev_instructions[1].Generate() | (cond << 28); }); } SECTION("REVSH tests") { - FuzzJitArm(1, 1, 10000, [®_instructions]() -> u32 { - return reg_instructions[2].Generate(); + FuzzJitArm(1, 1, 10000, [&rev_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + return rev_instructions[2].Generate() | (cond << 28); }); } } From 426ffc997182ae53aacef23fafbf40bf69cdec54 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 16:13:02 -0500 Subject: [PATCH 6/7] Added ARM fuzz tests for LDRD/LDR/LDRT/LDRB/LDRBT/LDRH and STRD/STR/STRT/STRB/STRBT/STRH. These tests do not test the behavior of writing to the PC. --- tests/arm/fuzz_arm.cpp | 151 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/tests/arm/fuzz_arm.cpp b/tests/arm/fuzz_arm.cpp index ae19305e..230dd716 100644 --- a/tests/arm/fuzz_arm.cpp +++ b/tests/arm/fuzz_arm.cpp @@ -407,3 +407,154 @@ TEST_CASE("Fuzz ARM reversal instructions", "[JitX64]") { }); } } + +TEST_CASE("Fuzz ARM Load/Store instructions", "[JitX64]") { + auto forbid_r15 = [](u32 inst) -> bool { + return Dynarmic::Common::Bits<12, 15>(inst) != 0b1111; + }; + + auto forbid_r14_and_r15 = [](u32 inst) -> bool { + return Dynarmic::Common::Bits<13, 15>(inst) != 0b111; + }; + + const std::array doubleword_instructions = { + { + // Load + InstructionGenerator("0000000pu1w0nnnnddd0vvvv1101vvvv", forbid_r14_and_r15), + InstructionGenerator("0000000pu0w0nnnnddd000001101mmmm", forbid_r14_and_r15), + + // Store + InstructionGenerator("0000000pu1w0nnnnddd0vvvv1111vvvv", forbid_r14_and_r15), + InstructionGenerator("0000000pu0w0nnnnddd000001111mmmm", forbid_r14_and_r15), + } + }; + + const std::array word_instructions = { + { + // Load + InstructionGenerator("0000010pu0w1nnnnddddvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("0000011pu0w1nnnnddddvvvvvrr0mmmm", forbid_r15), + InstructionGenerator("00000100u011nnnnttttmmmmmmmmmmmm", forbid_r15), + InstructionGenerator("00000110u011nnnnttttvvvvvrr0mmmm", forbid_r15), + + // Store + InstructionGenerator("0000010pu0w0nnnnddddvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("0000011pu0w0nnnnddddvvvvvrr0mmmm", forbid_r15), + InstructionGenerator("00000100u010nnnnttttvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("00000110u010nnnnttttvvvvvrr0mmmm", forbid_r15), + } + }; + + const std::array halfword_instructions = { + { + // Load + InstructionGenerator("0000000pu1w1nnnnddddvvvv1011vvvv", forbid_r15), + InstructionGenerator("0000000pu0w1nnnndddd00001011mmmm", forbid_r15), + // InstructionGenerator("----0000-111------------1011----"), // LDRHT (A1) Not available in ARMv6K + // InstructionGenerator("----0000-011--------00001011----"), // LDRHT (A2) Not available in ARMv6K + InstructionGenerator("0000000pu1w1nnnnddddvvvv1111vvvv", forbid_r15), + InstructionGenerator("0000000pu0w1nnnndddd00001111mmmm", forbid_r15), + // InstructionGenerator("----0000-111------------1111----"), // LDRSHT (A1) Not available in ARMv6K + // InstructionGenerator("----0000-011--------00001111----"), // LDRSHT (A2) Not available in ARMv6K + + + // Store + InstructionGenerator("0000000pu1w0nnnnddddvvvv1011vvvv", forbid_r15), + InstructionGenerator("0000000pu0w0nnnndddd00001011mmmm", forbid_r15), + // InstructionGenerator("----0000-110------------1011----"), // STRHT (A1) Not available in ARMv6K + // InstructionGenerator("----0000-010--------00001011----"), // STRHT (A2) Not available in ARMv6K + } + }; + + const std::array byte_instructions = { + { + // Load + InstructionGenerator("0000010pu1w1nnnnddddvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("0000011pu1w1nnnnddddvvvvvrr0mmmm", forbid_r15), + InstructionGenerator("00000100u111nnnnttttvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("00000110u111nnnnttttvvvvvrr0mmmm", forbid_r15), + InstructionGenerator("0000000pu1w1nnnnddddvvvv1101vvvv", forbid_r15), + InstructionGenerator("0000000pu0w1nnnndddd00001101mmmm", forbid_r15), + // InstructionGenerator("----0000-111------------1101----"), // LDRSBT (A1) Not available in ARMv6K + // InstructionGenerator("----0000-011--------00001101----"), // LDRSBT (A2) Not available in ARMv6K + + + // Store + InstructionGenerator("0000010pu1w0nnnnddddvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("0000011pu1w0nnnnddddvvvvvrr0mmmm", forbid_r15), + InstructionGenerator("00000100u110nnnnttttvvvvvvvvvvvv", forbid_r15), + InstructionGenerator("00000110u110nnnnttttvvvvvrr0mmmm", forbid_r15), + } + }; + + SECTION("Doubleword tests") { + FuzzJitArm(1, 1, 10000, [&doubleword_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + + return doubleword_instructions[RandInt(0, doubleword_instructions.size() - 1)].Generate() | (cond << 28); + }); + } + + SECTION("Word tests") { + FuzzJitArm(1, 1, 10000, [&word_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + return word_instructions[RandInt(0, word_instructions.size() - 1)].Generate() | (cond << 28); + }); + } + + SECTION("Halfword tests") { + FuzzJitArm(1, 1, 10000, [&halfword_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + return halfword_instructions[RandInt(0, halfword_instructions.size() - 1)].Generate() | (cond << 28); + }); + } + + SECTION("Byte tests") { + FuzzJitArm(1, 1, 10000, [&byte_instructions]() -> u32 { + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + return byte_instructions[RandInt(0, byte_instructions.size() - 1)].Generate() | (cond << 28); + }); + } + + SECTION("Mixed tests") { + FuzzJitArm(10, 10, 10000, [&]() -> u32 { + size_t selection = RandInt(0, 3); + + u32 cond = 0xE; + // Have a one-in-twenty-five chance of actually having a cond. + if (RandInt(1, 25) == 1) { + cond = RandInt(0x0, 0xD); + } + + switch (selection) { + case 0: + return doubleword_instructions[RandInt(0, doubleword_instructions.size() - 1)].Generate() | (cond << 28); + case 1: + return word_instructions[RandInt(0, word_instructions.size() - 1)].Generate() | (cond << 28); + case 2: + return halfword_instructions[RandInt(0, halfword_instructions.size() - 1)].Generate() | (cond << 28); + case 3: + return byte_instructions[RandInt(0, byte_instructions.size() - 1)].Generate() | (cond << 28); + } + + return 0; + }); + } + +} \ No newline at end of file From fce8f75077d40a2028185bf4685bd40eed4d50f0 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 18 Jul 2016 16:13:33 -0500 Subject: [PATCH 7/7] Added a dummy (always fail) ARM test about Load/Store instructions that write to the PC. --- tests/arm/fuzz_arm.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/arm/fuzz_arm.cpp b/tests/arm/fuzz_arm.cpp index 230dd716..a520448f 100644 --- a/tests/arm/fuzz_arm.cpp +++ b/tests/arm/fuzz_arm.cpp @@ -557,4 +557,8 @@ TEST_CASE("Fuzz ARM Load/Store instructions", "[JitX64]") { }); } + SECTION("Write to PC") { + // TODO + FAIL(); + } } \ No newline at end of file