From 727342134c503534c0944e46bbaf0065a1066ece Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 11 Mar 2022 11:55:41 -0500 Subject: [PATCH] Add 8086 length limit test. --- .../Mac/Clock SignalTests/x86DecoderTests.mm | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm b/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm index 68bf1abe1..b702b9605 100644 --- a/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/x86DecoderTests.mm @@ -64,8 +64,28 @@ template void test_far( // MARK: - Decoder +template +std::vector::InstructionT> +decode(const CollectionT &stream, bool set_32_bit = false) { + // Build instructions list with a byte-by-byte decoding. + std::vector::InstructionT> instructions; + + InstructionSet::x86::Decoder decoder; + decoder.set_32bit_protected_mode(set_32_bit); + + for(uint8_t item: stream) { + const auto [size, next] = decoder.decode(&item, 1); + if(size > 0) { + instructions.push_back(next); + } + } + + return instructions; +} + template -std::vector::InstructionT> decode(const std::initializer_list &stream, bool set_32_bit = false) { +std::vector::InstructionT> +decode(const std::initializer_list &stream, bool set_32_bit = false) { // Decode by offering up all data at once. std::vector::InstructionT> instructions; InstructionSet::x86::Decoder decoder; @@ -80,18 +100,17 @@ std::vector::InstructionT> decode(c } // Grab a byte-at-a-time decoding and check that it matches the previous. - { - InstructionSet::x86::Decoder decoder; - decoder.set_32bit_protected_mode(set_32_bit); + const auto byte_instructions = decode(std::vector{stream}, set_32_bit); - auto previous_instruction = instructions.begin(); - for(auto item: stream) { - const auto [size, next] = decoder.decode(&item, 1); - if(size > 0) { - XCTAssert(next == *previous_instruction); - ++previous_instruction; - } - } + XCTAssertEqual(byte_instructions.size(), instructions.size()); + + auto previous_instruction = instructions.begin(); + auto byte_instruction = byte_instructions.begin(); + while(previous_instruction != instructions.end()) { + XCTAssert(*previous_instruction == *byte_instruction); + + ++previous_instruction; + ++byte_instruction; } return instructions; @@ -557,6 +576,13 @@ std::vector::InstructionT> decode(c test(instructions[0], DataSize::DWord, Operation::ADD, Source::Immediate, ScaleIndexBase(Source::eDI), 0x9f683aa9, -0x42); } +- (void)test8086LengthLimit { + const std::vector all_prefix(65536, 0x26); + const auto instructions = decode(all_prefix); + XCTAssertEqual(instructions.size(), 1); + test(instructions[0], Operation::NOP); +} + - (void)test286LengthLimit { const auto instructions = decode({ 0x90,