This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

2.10.91: The target of MIPS jump instructions is handled wrong


Hi,

 Another patch that did not went in...  From the original mail:

 I've noticed we handle MIPS jump instructions wrong.  These instructions
make 28 least significant bits of the PC change while 4 most significant
bits remain intact.  But we incorrectly assume these four bits are those
of the jump instruction, while they are really the ones of the instruction
in the delay slot, i.e. the following one.

 Here is a patch that fixes all places I could find including comments.

bfd/ChangeLog:

2001-01-18  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

	* elf32-mips.c (elf_mips_howto_table): Fix the comment on
	the R_MIPS_26 relocation.
	(mips_elf_calculate_relocation): Use (p + 4) instead of p for
	the R_MIPS_26 relocation.
	(mips_elf_perform_relocation): Fix the comment on the R_MIPS16_26
	relocation.
	* elf64-mips.c (mips_elf64_howto_table_rel): Fix the comment on
	the R_MIPS_26 relocation.
	(mips_elf64_howto_table_rela): Likewise.

opcodes/ChangeLog:

2001-01-18  Maciej W. Rozycki  <macro@ds2.pg.gda.pl>

        * mips-dis.c (print_insn_arg): Use top four bits of the address of
	the following instruction not of the jump itself for the jump
	target.
	(print_mips16_insn_arg): Likewise.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

binutils-2.10.91-20010116-mips-j.patch
diff -up --recursive --new-file binutils.macro/bfd/elf32-mips.c binutils/bfd/elf32-mips.c
--- binutils.macro/bfd/elf32-mips.c	Wed Dec 13 04:26:02 2000
+++ binutils/bfd/elf32-mips.c	Thu Jan 18 22:33:35 2001
@@ -531,7 +531,7 @@ static reloc_howto_type elf_mips_howto_t
 	 complain_overflow_dont, /* complain_on_overflow */
 	 			/* This needs complex overflow
 				   detection, because the upper four
-				   bits must match the PC.  */
+				   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_MIPS_26",		/* name */
 	 true,			/* partial_inplace */
@@ -6320,14 +6320,14 @@ mips_elf_calculate_relocation (abfd,
       break;
 
     case R_MIPS16_26:
-      /* The calculation for R_MIPS_26 is just the same as for an
+      /* The calculation for R_MIPS16_26 is just the same as for an
 	 R_MIPS_26.  It's only the storage of the relocated field into
 	 the output file that's different.  That's handled in
 	 mips_elf_perform_relocation.  So, we just fall through to the
 	 R_MIPS_26 case here.  */
     case R_MIPS_26:
       if (local_p)
-	value = (((addend << 2) | (p & 0xf0000000)) + symbol) >> 2;
+	value = (((addend << 2) | ((p + 4) & 0xf0000000)) + symbol) >> 2;
       else
 	value = (mips_elf_sign_extend (addend << 2, 28) + symbol) >> 2;
       value &= howto->dst_mask;
@@ -6620,9 +6620,9 @@ mips_elf_perform_relocation (info, howto
 	 ((sub1 << 16) | sub2)).
 
 	 When producing a relocateable object file, the calculation is
-	 (((A < 2) | (P & 0xf0000000) + S) >> 2)
+	 (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
 	 When producing a fully linked file, the calculation is
-	 let R = (((A < 2) | (P & 0xf0000000) + S) >> 2)
+	 let R = (((A < 2) | ((P + 4) & 0xf0000000) + S) >> 2)
 	 ((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff)  */
 
       if (!info->relocateable)
diff -up --recursive --new-file binutils.macro/bfd/elf64-mips.c binutils/bfd/elf64-mips.c
--- binutils.macro/bfd/elf64-mips.c	Sat Dec  9 04:26:17 2000
+++ binutils/bfd/elf64-mips.c	Thu Jan 18 22:33:35 2001
@@ -161,7 +161,7 @@ static reloc_howto_type mips_elf64_howto
 	 complain_overflow_dont, /* complain_on_overflow */
 	 			/* This needs complex overflow
 				   detection, because the upper four
-				   bits must match the PC.  */
+				   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_MIPS_26",		/* name */
 	 true,			/* partial_inplace */
@@ -714,7 +714,7 @@ static reloc_howto_type mips_elf64_howto
 	 complain_overflow_dont, /* complain_on_overflow */
 	 			/* This needs complex overflow
 				   detection, because the upper four
-				   bits must match the PC.  */
+				   bits must match the PC + 4.  */
 	 bfd_elf_generic_reloc,	/* special_function */
 	 "R_MIPS_26",		/* name */
 	 true,			/* partial_inplace */
diff -up --recursive --new-file binutils.macro/opcodes/mips-dis.c binutils/opcodes/mips-dis.c
--- binutils.macro/opcodes/mips-dis.c	Sat Dec  2 04:25:52 2000
+++ binutils/opcodes/mips-dis.c	Thu Jan 18 22:34:34 2001
@@ -137,7 +137,7 @@ print_insn_arg (d, l, pc, info)
 
     case 'a':
       (*info->print_address_func)
-	(((pc & ~ (bfd_vma) 0x0fffffff)
+	((((pc + 4) & ~ (bfd_vma) 0x0fffffff)
 	  | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)),
 	 info);
       break;
@@ -1038,9 +1038,9 @@ print_mips16_insn_arg (type, op, l, use_
       if (! use_extend)
 	extend = 0;
       l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
-      (*info->print_address_func) ((memaddr & 0xf0000000) | l, info);
+      (*info->print_address_func) (((memaddr + 4) & 0xf0000000) | l, info);
       info->insn_type = dis_jsr;
-      info->target = (memaddr & 0xf0000000) | l;
+      info->target = ((memaddr + 4) & 0xf0000000) | l;
       info->branch_delay_insns = 1;
       break;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]