void Decode_multiple_instrs_with_one_instance() { var reader16 = new DecodeMultipleCodeReader(); var reader32 = new DecodeMultipleCodeReader(); var reader64 = new DecodeMultipleCodeReader(); var decoderDict16 = new Dictionary <DecoderOptions, Decoder>(); var decoderDict32 = new Dictionary <DecoderOptions, Decoder>(); var decoderDict64 = new Dictionary <DecoderOptions, Decoder>(); foreach (var info in DecoderTestUtils.GetDecoderTests(includeOtherTests: false, includeInvalid: true)) { var data = HexUtils.ToByteArray(info.HexBytes); var decoder = Decoder.Create(info.Bitness, new ByteArrayCodeReader(data), info.Options); Decoder decoderAll; switch (info.Bitness) { case 16: decoder.IP = DecoderConstants.DEFAULT_IP16; reader16.SetArray(data); if (!decoderDict16.TryGetValue(info.Options, out decoderAll)) { decoderDict16.Add(info.Options, decoderAll = Decoder.Create(info.Bitness, reader16, info.Options)); } break; case 32: decoder.IP = DecoderConstants.DEFAULT_IP32; reader32.SetArray(data); if (!decoderDict32.TryGetValue(info.Options, out decoderAll)) { decoderDict32.Add(info.Options, decoderAll = Decoder.Create(info.Bitness, reader32, info.Options)); } break; case 64: decoder.IP = DecoderConstants.DEFAULT_IP64; reader64.SetArray(data); if (!decoderDict64.TryGetValue(info.Options, out decoderAll)) { decoderDict64.Add(info.Options, decoderAll = Decoder.Create(info.Bitness, reader64, info.Options)); } break; default: throw new InvalidOperationException(); } decoderAll.IP = decoder.IP; var instruction1 = decoder.Decode(); var instruction2 = decoderAll.Decode(); var co1 = decoder.GetConstantOffsets(instruction1); var co2 = decoderAll.GetConstantOffsets(instruction2); Assert.Equal(info.Code, instruction1.Code); Assert.True(Instruction.EqualsAllBits(instruction1, instruction2)); VerifyConstantOffsets(co1, co2); } }
void Decode_multiple_instrs_with_one_instance() { var reader16 = new DecodeMultipleCodeReader(); var reader32 = new DecodeMultipleCodeReader(); var reader64 = new DecodeMultipleCodeReader(); var decoderDict16 = new Dictionary <DecoderOptions, Decoder>(); var decoderDict32 = new Dictionary <DecoderOptions, Decoder>(); var decoderDict64 = new Dictionary <DecoderOptions, Decoder>(); foreach (var info in DecoderTestUtils.GetDecoderTests(needHexBytes: true, includeOtherTests: false)) { var data = HexUtils.ToByteArray(info.HexBytes); var decoder = Decoder.Create(info.Bitness, new ByteArrayCodeReader(data), info.Options); Decoder decoderAll; switch (info.Bitness) { case 16: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP16; reader16.SetArray(data); if (!decoderDict16.TryGetValue(info.Options, out decoderAll)) { decoderDict16.Add(info.Options, decoderAll = Decoder.Create16(reader16, info.Options)); } break; case 32: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP32; reader32.SetArray(data); if (!decoderDict32.TryGetValue(info.Options, out decoderAll)) { decoderDict32.Add(info.Options, decoderAll = Decoder.Create32(reader32, info.Options)); } break; case 64: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP64; reader64.SetArray(data); if (!decoderDict64.TryGetValue(info.Options, out decoderAll)) { decoderDict64.Add(info.Options, decoderAll = Decoder.Create64(reader64, info.Options)); } break; default: throw new InvalidOperationException(); } decoderAll.InstructionPointer = decoder.InstructionPointer; var instr1 = decoder.Decode(); var instr2 = decoderAll.Decode(); Assert.Equal(info.Code, instr1.Code); Assert.True(Instruction.TEST_BitByBitEquals(instr1, instr2)); } }
void Decode_with_too_few_bytes_left() { foreach (var tc in DecoderTestUtils.GetDecoderTests(includeOtherTests: true, includeInvalid: false)) { var bytes = HexUtils.ToByteArray(tc.HexBytes); for (int i = 0; i + 1 < bytes.Length; i++) { var decoder = Decoder.Create(tc.Bitness, new ByteArrayCodeReader(bytes, 0, i), tc.Options); decoder.IP = 0x1000; decoder.Decode(out var instr); Assert.Equal(0x1000UL + (ulong)i, decoder.IP); Assert.Equal(Code.INVALID, instr.Code); Assert.Equal(DecoderError.NoMoreBytes, decoder.LastError); } } }
void Decode_multiple_instrs_with_one_instance() { var reader16 = new DecodeMultipleCodeReader(); var reader32 = new DecodeMultipleCodeReader(); var reader64 = new DecodeMultipleCodeReader(); var decoderAll16 = Decoder.Create16(reader16); var decoderAll32 = Decoder.Create32(reader32); var decoderAll64 = Decoder.Create64(reader64); foreach (var info in DecoderTestUtils.GetDecoderTests(needHexBytes: true, includeOtherTests: false)) { var data = HexUtils.ToByteArray(info.HexBytes); var decoder = Decoder.Create(info.Bitness, new ByteArrayCodeReader(data)); Decoder decoderAll; switch (info.Bitness) { case 16: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP16; reader16.SetArray(data); decoderAll = decoderAll16; break; case 32: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP32; reader32.SetArray(data); decoderAll = decoderAll32; break; case 64: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP64; reader64.SetArray(data); decoderAll = decoderAll64; break; default: throw new InvalidOperationException(); } decoderAll.InstructionPointer = decoder.InstructionPointer; var instr1 = decoder.Decode(); var instr2 = decoderAll.Decode(); Assert.Equal(info.Code, instr1.Code); Assert.True(Instruction.TEST_BitByBitEquals(ref instr1, ref instr2)); } }
void Make_sure_all_Code_values_are_tested_in_16_32_64_bit_modes() { const byte T16 = 0x01; const byte T32 = 0x02; const byte T64 = 0x04; var tested = new byte[IcedConstants.NumberOfCodeValues]; tested[(int)Code.INVALID] = T16 | T32 | T64; foreach (var info in DecoderTestUtils.GetDecoderTests(includeOtherTests: false, includeInvalid: false)) { Assert.False(DecoderTestUtils.NotDecoded.Contains(info.Code), $"{info.Code} has a decoder test but it shouldn't be decoded"); tested[(int)info.Code] |= info.Bitness switch { 16 => T16, 32 => T32, 64 => T64, _ => throw new InvalidOperationException(), }; } #if ENCODER foreach (var info in NonDecodedInstructions.GetTests()) { tested[(int)info.instruction.Code] |= info.bitness switch { 16 => T16, 32 => T32, 64 => T64, _ => throw new InvalidOperationException(), }; } #else foreach (var code in NonDecodedCodeValues1632) { tested[(int)code] |= T16 | T32; } foreach (var code in NonDecodedCodeValues) { tested[(int)code] |= T16 | T32 | T64; } #endif foreach (var c in DecoderTestUtils.NotDecoded) { Assert.DoesNotContain(c, DecoderTestUtils.Code32Only); Assert.DoesNotContain(c, DecoderTestUtils.Code64Only); } foreach (var c in DecoderTestUtils.NotDecoded32Only) { tested[(int)c] ^= T64; } foreach (var c in DecoderTestUtils.NotDecoded64Only) { tested[(int)c] ^= T16 | T32; } foreach (var c in DecoderTestUtils.Code32Only) { Assert.DoesNotContain(c, DecoderTestUtils.Code64Only); tested[(int)c] ^= T64; } foreach (var c in DecoderTestUtils.Code64Only) { Assert.DoesNotContain(c, DecoderTestUtils.Code32Only); tested[(int)c] ^= T16 | T32; } var sb16 = new StringBuilder(); var sb32 = new StringBuilder(); var sb64 = new StringBuilder(); int missing16 = 0, missing32 = 0, missing64 = 0; var codeNames = ToEnumConverter.GetCodeNames(); Assert.Equal(tested.Length, codeNames.Length); for (int i = 0; i < tested.Length; i++) { if (tested[i] != (T16 | T32 | T64) && !CodeUtils.IsIgnored(codeNames[i])) { if ((tested[i] & T16) == 0) { sb16.Append(codeNames[i] + " "); missing16++; } if ((tested[i] & T32) == 0) { sb32.Append(codeNames[i] + " "); missing32++; } if ((tested[i] & T64) == 0) { sb64.Append(codeNames[i] + " "); missing64++; } } } Assert.Equal("16: 0 ins ", $"16: {missing16} ins " + sb16.ToString()); Assert.Equal("32: 0 ins ", $"32: {missing32} ins " + sb32.ToString()); Assert.Equal("64: 0 ins ", $"64: {missing64} ins " + sb64.ToString()); }
void Make_sure_all_Code_values_are_tested_in_16_32_64_bit_modes() { int numCodeValues = -1; foreach (var f in typeof(Code).GetFields()) { if (f.IsLiteral) { int value = (int)f.GetValue(null); Assert.Equal(numCodeValues + 1, value); numCodeValues = value; } } numCodeValues++; const byte T16 = 0x01; const byte T32 = 0x02; const byte T64 = 0x04; var tested = new byte[numCodeValues]; tested[(int)Code.INVALID] = T16 | T32 | T64; foreach (var info in DecoderTestUtils.GetDecoderTests(includeOtherTests: false, includeInvalid: false)) { Assert.False(DecoderTestUtils.NotDecoded.Contains(info.Code), $"{info.Code} has a decoder test but it shouldn't be decoded"); byte testedFlags; if (info.Bitness == 16) { testedFlags = T16; } else if (info.Bitness == 32) { testedFlags = T32; } else if (info.Bitness == 64) { testedFlags = T64; } else { continue; } tested[(int)info.Code] |= testedFlags; } #if !NO_ENCODER foreach (var info in NonDecodedInstructions.GetTests()) { byte testedFlags; if (info.bitness == 16) { testedFlags = T16; } else if (info.bitness == 32) { testedFlags = T32; } else if (info.bitness == 64) { testedFlags = T64; } else { continue; } tested[(int)info.instruction.Code] |= testedFlags; } #endif foreach (var c in DecoderTestUtils.NotDecoded) { Assert.DoesNotContain(c, DecoderTestUtils.Code32Only); Assert.DoesNotContain(c, DecoderTestUtils.Code64Only); } foreach (var c in DecoderTestUtils.NotDecoded32Only) { tested[(int)c] ^= T64; } foreach (var c in DecoderTestUtils.NotDecoded64Only) { tested[(int)c] ^= T16 | T32; } foreach (var c in DecoderTestUtils.Code32Only) { Assert.DoesNotContain(c, DecoderTestUtils.Code64Only); tested[(int)c] ^= T64; } foreach (var c in DecoderTestUtils.Code64Only) { Assert.DoesNotContain(c, DecoderTestUtils.Code32Only); tested[(int)c] ^= T16 | T32; } var sb16 = new StringBuilder(); var sb32 = new StringBuilder(); var sb64 = new StringBuilder(); int missing16 = 0, missing32 = 0, missing64 = 0; var codeNames = Enum.GetNames(typeof(Code)); Assert.Equal(tested.Length, codeNames.Length); for (int i = 0; i < tested.Length; i++) { if (tested[i] != (T16 | T32 | T64)) { if ((tested[i] & T16) == 0) { sb16.Append(codeNames[i] + " "); missing16++; } if ((tested[i] & T32) == 0) { sb32.Append(codeNames[i] + " "); missing32++; } if ((tested[i] & T64) == 0) { sb64.Append(codeNames[i] + " "); missing64++; } } } Assert.Equal("16: 0 ins ", $"16: {missing16} ins " + sb16.ToString()); Assert.Equal("32: 0 ins ", $"32: {missing32} ins " + sb32.ToString()); Assert.Equal("64: 0 ins ", $"64: {missing64} ins " + sb64.ToString()); }