diff options
| -rw-r--r-- | src/long_mode/display.rs | 28 | ||||
| -rw-r--r-- | src/protected_mode/display.rs | 28 | ||||
| -rw-r--r-- | src/real_mode/display.rs | 28 | ||||
| -rw-r--r-- | test/long_mode/mod.rs | 17 | ||||
| -rw-r--r-- | test/protected_mode/mod.rs | 17 | ||||
| -rw-r--r-- | test/real_mode/mod.rs | 17 | 
6 files changed, 111 insertions, 24 deletions
diff --git a/src/long_mode/display.rs b/src/long_mode/display.rs index 68189f0..59efe38 100644 --- a/src/long_mode/display.rs +++ b/src/long_mode/display.rs @@ -3338,6 +3338,34 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:          out.write_str(" ")?;          let x = Operand::from_spec(instr, instr.operands[0]); + +        const RELATIVE_BRANCHES: [Opcode; 21] = [ +            Opcode::JMP, Opcode::JRCXZ, +            Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, +            Opcode::JO, Opcode::JNO, +            Opcode::JB, Opcode::JNB, +            Opcode::JZ, Opcode::JNZ, +            Opcode::JNA, Opcode::JA, +            Opcode::JS, Opcode::JNS, +            Opcode::JP, Opcode::JNP, +            Opcode::JL, Opcode::JGE, +            Opcode::JLE, Opcode::JG, +        ]; + +        if instr.operands[0] == OperandSpec::ImmI8 || instr.operands[0] == OperandSpec::ImmI32 { +            if RELATIVE_BRANCHES.contains(&instr.opcode) { +                return match x { +                    Operand::ImmediateI8(rel) => { +                        write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) +                    } +                    Operand::ImmediateI32(rel) => { +                        write!(out, "$+{}", colors.number(signed_i32_hex(rel))) +                    } +                    _ => { unreachable!() } +                }; +            } +        } +          if x.is_memory() {              out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;              out.write_str(" ")?; diff --git a/src/protected_mode/display.rs b/src/protected_mode/display.rs index 987221e..72bfcb4 100644 --- a/src/protected_mode/display.rs +++ b/src/protected_mode/display.rs @@ -3351,6 +3351,34 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:          out.write_str(" ")?;          let x = Operand::from_spec(instr, instr.operands[0]); + +        const RELATIVE_BRANCHES: [Opcode; 21] = [ +            Opcode::JMP, Opcode::JECXZ, +            Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, +            Opcode::JO, Opcode::JNO, +            Opcode::JB, Opcode::JNB, +            Opcode::JZ, Opcode::JNZ, +            Opcode::JNA, Opcode::JA, +            Opcode::JS, Opcode::JNS, +            Opcode::JP, Opcode::JNP, +            Opcode::JL, Opcode::JGE, +            Opcode::JLE, Opcode::JG, +        ]; + +        if instr.operands[0] == OperandSpec::ImmI8 || instr.operands[0] == OperandSpec::ImmI32 { +            if RELATIVE_BRANCHES.contains(&instr.opcode) { +                return match x { +                    Operand::ImmediateI8(rel) => { +                        write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) +                    } +                    Operand::ImmediateI32(rel) => { +                        write!(out, "$+{}", colors.number(signed_i32_hex(rel))) +                    } +                    _ => { unreachable!() } +                }; +            } +        } +          if x.is_memory() {              out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;              out.write_str(" ")?; diff --git a/src/real_mode/display.rs b/src/real_mode/display.rs index 9ba8284..f514974 100644 --- a/src/real_mode/display.rs +++ b/src/real_mode/display.rs @@ -3351,6 +3351,34 @@ fn contextualize_intel<T: fmt::Write, Y: YaxColors>(instr: &Instruction, colors:          out.write_str(" ")?;          let x = Operand::from_spec(instr, instr.operands[0]); + +        const RELATIVE_BRANCHES: [Opcode; 21] = [ +            Opcode::JMP, Opcode::JCXZ, +            Opcode::LOOP, Opcode::LOOPZ, Opcode::LOOPNZ, +            Opcode::JO, Opcode::JNO, +            Opcode::JB, Opcode::JNB, +            Opcode::JZ, Opcode::JNZ, +            Opcode::JNA, Opcode::JA, +            Opcode::JS, Opcode::JNS, +            Opcode::JP, Opcode::JNP, +            Opcode::JL, Opcode::JGE, +            Opcode::JLE, Opcode::JG, +        ]; + +        if instr.operands[0] == OperandSpec::ImmI8 || instr.operands[0] == OperandSpec::ImmI32 { +            if RELATIVE_BRANCHES.contains(&instr.opcode) { +                return match x { +                    Operand::ImmediateI8(rel) => { +                        write!(out, "$+{}", colors.number(signed_i32_hex(rel as i32))) +                    } +                    Operand::ImmediateI32(rel) => { +                        write!(out, "$+{}", colors.number(signed_i32_hex(rel))) +                    } +                    _ => { unreachable!() } +                }; +            } +        } +          if x.is_memory() {              out.write_str(MEM_SIZE_STRINGS[instr.mem_size as usize - 1])?;              out.write_str(" ")?; diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs index bfe21bd..61ea63d 100644 --- a/test/long_mode/mod.rs +++ b/test/long_mode/mod.rs @@ -1208,10 +1208,10 @@ fn test_prefixes() {  #[test]  fn test_control_flow() { -    test_display(&[0x73, 0x31], "jnb 0x31"); -    test_display(&[0x72, 0x5a], "jb 0x5a"); -    test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna 0x18b"); -    test_display(&[0x74, 0x47], "jz 0x47"); +    test_display(&[0x73, 0x31], "jnb $+0x31"); +    test_display(&[0x72, 0x5a], "jb $+0x5a"); +    test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna $+0x18b"); +    test_display(&[0x74, 0x47], "jz $+0x47");      test_display(&[0xff, 0x15, 0x7e, 0x72, 0x24, 0x00], "call qword [rip + 0x24727e]");      test_display(&[0xff, 0x24, 0xcd, 0x70, 0xa0, 0xbc, 0x01], "jmp qword [rcx * 8 + 0x1bca070]");      test_display(&[0xff, 0xe0], "jmp rax"); @@ -1219,10 +1219,11 @@ fn test_control_flow() {      test_display(&[0x67, 0xff, 0xe0], "jmp rax");      test_invalid(&[0xff, 0xd8]);      test_display(&[0xff, 0x18], "callf mword [rax]"); -    test_display(&[0xe0, 0x12], "loopnz 0x12"); -    test_display(&[0xe1, 0x12], "loopz 0x12"); -    test_display(&[0xe2, 0x12], "loop 0x12"); -    test_display(&[0xe3, 0x12], "jrcxz 0x12"); +    test_display(&[0xe0, 0x12], "loopnz $+0x12"); +    test_display(&[0xe1, 0x12], "loopz $+0x12"); +    test_display(&[0xe2, 0x12], "loop $+0x12"); +    test_display(&[0xe3, 0x12], "jrcxz $+0x12"); +    test_display(&[0xe3, 0xf0], "jrcxz $+-0x10");      test_display(&[0xc3], "ret");  } diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index c03a19d..5ed69ed 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -1094,10 +1094,10 @@ fn test_prefixes() {  #[test]  fn test_control_flow() { -    test_display(&[0x73, 0x31], "jnb 0x31"); -    test_display(&[0x72, 0x5a], "jb 0x5a"); -    test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna 0x18b"); -    test_display(&[0x74, 0x47], "jz 0x47"); +    test_display(&[0x73, 0x31], "jnb $+0x31"); +    test_display(&[0x72, 0x5a], "jb $+0x5a"); +    test_display(&[0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00], "jna $+0x18b"); +    test_display(&[0x74, 0x47], "jz $+0x47");      test_display(&[0xff, 0x15, 0x7e, 0x72, 0x24, 0x00], "call dword [0x24727e]");      test_display(&[0xff, 0x24, 0xcd, 0x70, 0xa0, 0xbc, 0x01], "jmp dword [ecx * 8 + 0x1bca070]");      test_display(&[0xff, 0xe0], "jmp eax"); @@ -1105,10 +1105,11 @@ fn test_control_flow() {      test_display(&[0x67, 0xff, 0xe0], "jmp eax");      test_invalid(&[0xff, 0xd8]);      test_display(&[0xff, 0x18], "callf far [eax]"); -    test_display(&[0xe0, 0x12], "loopnz 0x12"); -    test_display(&[0xe1, 0x12], "loopz 0x12"); -    test_display(&[0xe2, 0x12], "loop 0x12"); -    test_display(&[0xe3, 0x12], "jecxz 0x12"); +    test_display(&[0xe0, 0x12], "loopnz $+0x12"); +    test_display(&[0xe1, 0x12], "loopz $+0x12"); +    test_display(&[0xe2, 0x12], "loop $+0x12"); +    test_display(&[0xe3, 0x12], "jecxz $+0x12"); +    test_display(&[0xe3, 0xf0], "jecxz $+-0x10");      test_display(&[0xc3], "ret");  } diff --git a/test/real_mode/mod.rs b/test/real_mode/mod.rs index 82ccfab..6005f07 100644 --- a/test/real_mode/mod.rs +++ b/test/real_mode/mod.rs @@ -262,7 +262,7 @@ fn test_real_mode() {      test_display(&[0x0f, 0x7e, 0xcf], "movd edi, mm1");      test_display(&[0x0f, 0x7f, 0x0f], "movq qword [bx], mm1");      test_display(&[0x0f, 0x7f, 0xcf], "movq mm7, mm1"); -    test_display(&[0x0f, 0x86, 0x8b, 0x01], "jna 0x18b"); +    test_display(&[0x0f, 0x86, 0x8b, 0x01], "jna $+0x18b");      test_display(&[0x0f, 0x97, 0x00], "seta byte [bx + si]");      test_display(&[0x0f, 0x97, 0x08], "seta byte [bx + si]");      test_display(&[0x0f, 0x97, 0xc0], "seta al"); @@ -16924,9 +16924,9 @@ fn test_real_mode() {      test_display(&[0x67, 0xff, 0xe0], "jmp ax");      test_display(&[0x68, 0x7f, 0x63], "push 0x637f");      test_display(&[0x6b, 0x43, 0x6f, 0x6d], "imul ax, word [bp + di + 0x6f], 0x6d"); -    test_display(&[0x72, 0x5a], "jb 0x5a"); -    test_display(&[0x73, 0x31], "jnb 0x31"); -    test_display(&[0x74, 0x47], "jz 0x47"); +    test_display(&[0x72, 0x5a], "jb $+0x5a"); +    test_display(&[0x73, 0x31], "jnb $+0x31"); +    test_display(&[0x74, 0x47], "jz $+0x47");      test_display(&[0x81, 0xec, 0x10, 0x03], "sub sp, 0x310");      test_display(&[0x66, 0x81, 0xec, 0x10, 0x03, 0x00, 0x00], "sub esp, 0x310");      test_display(&[0x83, 0xf8, 0xff], "cmp ax, -0x1"); @@ -17752,10 +17752,11 @@ fn test_real_mode() {      test_display(&[0xdf, 0xe0], "fnstsw ax");      test_display(&[0xdf, 0xeb], "fucomip st(0), st(3)");      test_display(&[0xdf, 0xf3], "fcomip st(0), st(3)"); -    test_display(&[0xe0, 0x12], "loopnz 0x12"); -    test_display(&[0xe1, 0x12], "loopz 0x12"); -    test_display(&[0xe2, 0x12], "loop 0x12"); -    test_display(&[0xe3, 0x12], "jcxz 0x12"); +    test_display(&[0xe0, 0x12], "loopnz $+0x12"); +    test_display(&[0xe1, 0x12], "loopz $+0x12"); +    test_display(&[0xe2, 0x12], "loop $+0x12"); +    test_display(&[0xe3, 0x12], "jcxz $+0x12"); +    test_display(&[0xe3, 0xf0], "jcxz $+-0x10");      test_display(&[0xe4, 0x99], "in al, 0x99");      test_display(&[0xe5, 0x99], "in ax, 0x99");      test_display(&[0xe6, 0x99], "out 0x99, al");  | 
