This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
R_MIPS_PC16 relocation handling, a proposal
- To: binutils at sourceware dot cygnus dot com
- Subject: R_MIPS_PC16 relocation handling, a proposal
- From: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- Date: Tue, 12 Oct 1999 18:41:07 +0200 (MET DST)
- Organization: Technical University of Gdansk
- Reply-To: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
Hi,
Guessing from MIPS ISA and ABI documents it seems there is no much use of
R_MIPS_PC16 relocations. On the other hand, the b* branch opcode family
uses a shifted by two bits 16-bit PC-relative field that is not handled by
any of MIPS relocations. I think the authors of ABI might just missed the
fact of the shift when documenting R_MIPS_PC16.
Anyway, I propose using R_MIPS_PC16 for BFD_RELOC_16_PCREL_S2 relocations
which would allow object modules to contain external references from b*
opcodes. As R_MIPS_PC16 is pretty unusable at the moment, nothing should
break. Otherwise, we might create a BFD-specific extension (just like
e.g. R_386_PC8 for i386).
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
Mon Oct 11 1999 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
* elf32-mips.c (elf_mips_howto_table): Fix rightshift
and pcrel_offset for R_MIPS_PC16.
(mips_reloc_map): Replace BFD_RELOC_16_PCREL with
BFD_RELOC_16_PCREL_S2.
(mips_elf_calculate_relocation): Handle R_MIPS_PC16
properly.
(mips_elf_perform_relocation): Fix typos in the comment.
* elf64-mips.c (mips_elf64_howto_table_rel): Fix
rightshift and pcrel_offset for R_MIPS_PC16.
(mips_elf64_howto_table_rela): Likewise.
(mips_reloc_map): Replace BFD_RELOC_16_PCREL with
BFD_RELOC_16_PCREL_S2.
diff -u --recursive --new-file binutils.macro/bfd/elf32-mips.c binutils/bfd/elf32-mips.c
--- binutils.macro/bfd/elf32-mips.c Mon Oct 4 16:31:22 1999
+++ binutils/bfd/elf32-mips.c Fri Oct 8 13:29:48 1999
@@ -601,7 +601,7 @@
/* 16 bit PC relative reference. */
HOWTO (R_MIPS_PC16, /* type */
- 0, /* rightshift */
+ 2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
true, /* pc_relative */
@@ -612,7 +612,7 @@
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ true), /* pcrel_offset */
/* 16 bit call through global offset table. */
HOWTO (R_MIPS_CALL16, /* type */
@@ -1829,7 +1829,7 @@
{ BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
{ BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
{ BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
- { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
+ { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
{ BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
{ BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
{ BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
@@ -6101,7 +6101,8 @@
break;
case R_MIPS_PC16:
- value = mips_elf_sign_extend (addend, 16) + symbol - p;
+ value = (bfd_signed_vma) (mips_elf_sign_extend (addend << 2, 18)
+ + symbol - p) >> 2;
overflowed_p = mips_elf_overflow_p (value, 16);
break;
@@ -6294,9 +6295,9 @@
((sub1 << 16) | sub2)).
When producing a relocateable object file, the calculation is
- (((A < 2) | (P & 0xf0000000) + S) >> 2)
+ (((A << 2) | (P & 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 & 0xf0000000) + S) >> 2)
((R & 0x1f0000) << 5) | ((R & 0x3e00000) >> 5) | (R & 0xffff) */
if (!info->relocateable)
diff -u --recursive --new-file binutils.macro/bfd/elf64-mips.c binutils/bfd/elf64-mips.c
--- binutils.macro/bfd/elf64-mips.c Tue Aug 10 13:16:42 1999
+++ binutils/bfd/elf64-mips.c Fri Oct 8 13:55:04 1999
@@ -246,7 +246,7 @@
/* 16 bit PC relative reference. */
HOWTO (R_MIPS_PC16, /* type */
- 0, /* rightshift */
+ 2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
true, /* pc_relative */
@@ -257,7 +257,7 @@
true, /* partial_inplace */
0xffff, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ true), /* pcrel_offset */
/* 16 bit call through global offset table. */
/* FIXME: This is not handled correctly. */
@@ -800,7 +800,7 @@
/* 16 bit PC relative reference. */
HOWTO (R_MIPS_PC16, /* type */
- 0, /* rightshift */
+ 2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
16, /* bitsize */
true, /* pc_relative */
@@ -811,7 +811,7 @@
true, /* partial_inplace */
0, /* src_mask */
0xffff, /* dst_mask */
- false), /* pcrel_offset */
+ true), /* pcrel_offset */
/* 16 bit call through global offset table. */
/* FIXME: This is not handled correctly. */
@@ -1372,7 +1372,7 @@
{ BFD_RELOC_MIPS_GPREL, R_MIPS_GPREL16 },
{ BFD_RELOC_MIPS_LITERAL, R_MIPS_LITERAL },
{ BFD_RELOC_MIPS_GOT16, R_MIPS_GOT16 },
- { BFD_RELOC_16_PCREL, R_MIPS_PC16 },
+ { BFD_RELOC_16_PCREL_S2, R_MIPS_PC16 },
{ BFD_RELOC_MIPS_CALL16, R_MIPS_CALL16 },
{ BFD_RELOC_MIPS_GPREL32, R_MIPS_GPREL32 },
{ BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },