diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2007-02-05 18:22:49 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2007-02-05 18:22:49 +0000 |
commit | 65ca155d272d69a8dbd249c54bbb41ff672ea190 (patch) | |
tree | 8c209dbcc7049e1fbc25b4744e822fef4afcd511 /opcodes/i386-dis.c | |
parent | f1ab23406b16f148da6a95860e57cac688a2690c (diff) | |
download | gdb-65ca155d272d69a8dbd249c54bbb41ff672ea190.zip gdb-65ca155d272d69a8dbd249c54bbb41ff672ea190.tar.gz gdb-65ca155d272d69a8dbd249c54bbb41ff672ea190.tar.bz2 |
ld/testsuite/
2076-02-05 H.J. Lu <hongjiu.lu@intel.com>
* ld-i386/pcrel16.d: Undo the last change.
* ld-x86-64/pcrel16.d: Likewise.
opcodes/
2076-02-05 H.J. Lu <hongjiu.lu@intel.com>
* i386-dis.c (OP_J): Undo the last change. Properly handle 64K
wrap around within the same segment in 16bit mode.
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r-- | opcodes/i386-dis.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 5ecc143..509cc5d 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -4901,6 +4901,7 @@ OP_J (int bytemode, int sizeflag) { bfd_vma disp; bfd_vma mask = -1; + bfd_vma segment = 0; switch (bytemode) { @@ -4918,11 +4919,14 @@ OP_J (int bytemode, int sizeflag) disp = get16 (); if ((disp & 0x8000) != 0) disp -= 0x10000; - /* For some reason, a data16 prefix on a jump instruction - means that the pc is masked to 16 bits after the - displacement is added! */ - if ((prefixes & PREFIX_DATA) != 0) - mask = 0xffff; + /* In 16bit mode, address is wrapped around at 64k within + the same segment. Otherwise, a data16 prefix on a jump + instruction means that the pc is masked to 16 bits after + the displacement is added! */ + mask = 0xffff; + if ((prefixes & PREFIX_DATA) == 0) + segment = ((start_pc + codep - start_codep) + & ~((bfd_vma) 0xffff)); } used_prefixes |= (prefixes & PREFIX_DATA); break; @@ -4930,7 +4934,7 @@ OP_J (int bytemode, int sizeflag) oappend (INTERNAL_DISASSEMBLER_ERROR); return; } - disp = (start_pc + codep - start_codep + disp) & mask; + disp = ((start_pc + codep - start_codep + disp) & mask) | segment; set_op (disp, 0); print_operand_value (scratchbuf, 1, disp); oappend (scratchbuf); |