This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Fix MIPS16 section-relative addressing
- From: Thiemo Seufer <ths at networkno dot de>
- To: binutils at sourceware dot org
- Date: Thu, 20 Jul 2006 17:45:53 +0100
- Subject: [PATCH] Fix MIPS16 section-relative addressing
Hello All,
I applied the appended patch, it fixes section the relative addressing
done by MIPS16 jumps.
Thiemo
2006-07-20 Thiemo Seufer <ths@mips.com>
[ bfd/ChangeLog ]
* elf32-mips.c (mips16_jump_reloc): Remove function.
(elf_mips16_howto_table_rel): Use _bfd_mips_elf_generic_reloc
instead of mips16_jump_reloc.
* elf64_mips.c, wlfn32-mips.c (mips16_jump_reloc): Remove function.
(elf_mips16_howto_table_rel, elf_mips16_howto_table_rela): Use
_bfd_mips_elf_generic_reloc instead of mips16_jump_reloc.
[ gas/ChangeLog ]
* config/tc-mips.c (mips_fix_adjustable): Handle BFD_RELOC_MIPS16_JMP.
(tc_gen_reloc): Handle mips16 jumps to section symbol offsets.
[ ld/testsuite/ChangeLog ]
* ld-mips-elf/mips16-call-global-1.s,
ld-mips-elf/mips16-call-global-2.s,
ld-mips-elf/mips16-call-global-3.s, ld-mips-elf/mips16-call-global.d:
Test linking of external mips16 jumps.
* ld-mips-elf/mips-elf.exp: Run new test.
Index: bfd/elf32-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-mips.c,v
retrieving revision 1.189
diff -u -p -r1.189 elf32-mips.c
--- bfd/elf32-mips.c 12 Jun 2006 11:35:43 -0000 1.189
+++ bfd/elf32-mips.c 20 Jul 2006 12:35:59 -0000
@@ -68,8 +68,6 @@ static bfd_boolean mips_elf32_object_p
(bfd *);
static bfd_boolean mips_elf_is_local_label_name
(bfd *, const char *);
-static bfd_reloc_status_type mips16_jump_reloc
- (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type mips16_gprel_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type mips_elf_final_gp
@@ -734,7 +732,7 @@ static reloc_howto_type elf_mips16_howto
/* This needs complex overflow
detection, because the upper four
bits must match the PC. */
- mips16_jump_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_26", /* name */
TRUE, /* partial_inplace */
0x3ffffff, /* src_mask */
@@ -1112,36 +1110,6 @@ mips32_64bit_reloc (bfd *abfd, arelent *
return r;
}
-/* Handle a mips16 jump. */
-
-static bfd_reloc_status_type
-mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
- asymbol *symbol, void *data ATTRIBUTE_UNUSED,
- asection *input_section, bfd *output_bfd,
- char **error_message ATTRIBUTE_UNUSED)
-{
- if (output_bfd != NULL
- && (symbol->flags & BSF_SECTION_SYM) == 0
- && reloc_entry->addend == 0)
- {
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- /* FIXME. */
- {
- static bfd_boolean warned;
-
- if (! warned)
- (*_bfd_error_handler)
- (_("Linking mips16 objects into %s format is not supported"),
- bfd_get_target (input_section->output_section->owner));
- warned = TRUE;
- }
-
- return bfd_reloc_undefined;
-}
-
/* Handle a mips16 GP relative reloc. */
static bfd_reloc_status_type
Index: bfd/elf64-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mips.c,v
retrieving revision 1.74
diff -u -p -r1.74 elf64-mips.c
--- bfd/elf64-mips.c 12 Jun 2006 11:35:43 -0000 1.74
+++ bfd/elf64-mips.c 20 Jul 2006 12:35:59 -0000
@@ -112,8 +112,6 @@ static bfd_reloc_status_type mips_elf64_
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type mips_elf64_shift6_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips16_jump_reloc
- (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type mips16_gprel_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_boolean mips_elf64_assign_gp
@@ -1438,7 +1436,7 @@ static reloc_howto_type mips16_elf64_how
/* This needs complex overflow
detection, because the upper four
bits must match the PC. */
- mips16_jump_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_26", /* name */
TRUE, /* partial_inplace */
0x3ffffff, /* src_mask */
@@ -1510,7 +1508,7 @@ static reloc_howto_type mips16_elf64_how
/* This needs complex overflow
detection, because the upper four
bits must match the PC. */
- mips16_jump_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_26", /* name */
FALSE, /* partial_inplace */
0x3ffffff, /* src_mask */
@@ -2044,37 +2042,6 @@ mips_elf64_shift6_reloc (bfd *abfd, arel
error_message);
}
-/* Handle a mips16 jump. */
-
-static bfd_reloc_status_type
-mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
- asymbol *symbol, void *data ATTRIBUTE_UNUSED,
- asection *input_section, bfd *output_bfd,
- char **error_message ATTRIBUTE_UNUSED)
-{
- if (output_bfd != NULL
- && (symbol->flags & BSF_SECTION_SYM) == 0
- && (! reloc_entry->howto->partial_inplace
- || reloc_entry->addend == 0))
- {
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- /* FIXME. */
- {
- static bfd_boolean warned;
-
- if (! warned)
- (*_bfd_error_handler)
- (_("Linking mips16 objects into %s format is not supported"),
- bfd_get_target (input_section->output_section->owner));
- warned = TRUE;
- }
-
- return bfd_reloc_undefined;
-}
-
/* Handle a mips16 GP relative reloc. */
static bfd_reloc_status_type
Index: bfd/elfn32-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfn32-mips.c,v
retrieving revision 1.32
diff -u -p -r1.32 elfn32-mips.c
--- bfd/elfn32-mips.c 12 Jun 2006 11:35:43 -0000 1.32
+++ bfd/elfn32-mips.c 20 Jul 2006 12:35:59 -0000
@@ -61,8 +61,6 @@ static bfd_reloc_status_type gprel32_wit
(bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
static bfd_reloc_status_type mips_elf_shift6_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips16_jump_reloc
- (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type mips16_gprel_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
@@ -1444,7 +1442,7 @@ static reloc_howto_type elf_mips16_howto
/* This needs complex overflow
detection, because the upper four
bits must match the PC. */
- mips16_jump_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_26", /* name */
TRUE, /* partial_inplace */
0x3ffffff, /* src_mask */
@@ -1516,7 +1514,7 @@ static reloc_howto_type elf_mips16_howto
/* This needs complex overflow
detection, because the upper four
bits must match the PC. */
- mips16_jump_reloc, /* special_function */
+ _bfd_mips_elf_generic_reloc, /* special_function */
"R_MIPS16_26", /* name */
FALSE, /* partial_inplace */
0x3ffffff, /* src_mask */
@@ -1901,28 +1899,6 @@ mips_elf_shift6_reloc (bfd *abfd, arelen
error_message);
}
-/* Handle a mips16 jump. */
-
-static bfd_reloc_status_type
-mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED,
- arelent *reloc_entry ATTRIBUTE_UNUSED,
- asymbol *symbol ATTRIBUTE_UNUSED,
- void *data ATTRIBUTE_UNUSED,
- asection *input_section, bfd *output_bfd ATTRIBUTE_UNUSED,
- char **error_message ATTRIBUTE_UNUSED)
-{
- static bfd_boolean warned = FALSE;
-
- /* FIXME. */
- if (! warned)
- (*_bfd_error_handler)
- (_("Linking mips16 objects into %s format is not supported"),
- bfd_get_target (input_section->output_section->owner));
- warned = TRUE;
-
- return bfd_reloc_undefined;
-}
-
/* Handle a mips16 GP relative reloc. */
static bfd_reloc_status_type
Index: gas/config/tc-mips.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mips.c,v
retrieving revision 1.349
diff -u -p -r1.349 tc-mips.c
--- gas/config/tc-mips.c 17 Jul 2006 10:40:11 -0000 1.349
+++ gas/config/tc-mips.c 20 Jul 2006 12:36:01 -0000
@@ -13498,11 +13498,6 @@ md_estimate_size_before_relax (fragS *fr
int
mips_fix_adjustable (fixS *fixp)
{
- /* Don't adjust MIPS16 jump relocations, so we don't have to worry
- about the format of the offset in the .o file. */
- if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
- return 0;
-
if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
|| fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
return 0;
@@ -13578,6 +13573,10 @@ tc_gen_reloc (asection *section ATTRIBUT
else
reloc->addend = fixp->fx_addnumber;
+ /* Handle relocs adjusted against a section symbol. */
+ if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
+ reloc->addend += fixp->fx_offset;
+
/* Since the old MIPS ELF ABI uses Rel instead of Rela, encode the vtable
entry to be used in the relocation's section offset. */
if (! HAVE_NEWABI && fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mips-elf/mips-elf.exp,v
retrieving revision 1.36
diff -u -p -r1.36 mips-elf.exp
--- ld/testsuite/ld-mips-elf/mips-elf.exp 11 Jun 2006 08:33:27 -0000 1.36
+++ ld/testsuite/ld-mips-elf/mips-elf.exp 20 Jul 2006 12:36:02 -0000
@@ -243,3 +243,12 @@ if {[istarget mips*-*-linux*]} {
run_ld_link_tests $mips_tls_tests
}
+set mips16_call_global_test {
+ {"Global calls from mips16"
+ ""
+ "-mips32r2" {mips16-call-global-1.s mips16-call-global-2.s mips16-call-global-3.s}
+ {{objdump -dr mips16-call-global.d}}
+ "mips16-call-global"}
+}
+
+run_ld_link_tests $mips16_call_global_test
Index: ld/testsuite/ld-mips-elf/mips16-call-global-1.s
===================================================================
RCS file: ld/testsuite/ld-mips-elf/mips16-call-global-1.s
diff -N ld/testsuite/ld-mips-elf/mips16-call-global-1.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/mips16-call-global-1.s 20 Jul 2006 12:36:02 -0000
@@ -0,0 +1,12 @@
+ .set mips16
+
+ .globl __start
+ .ent __start
+__start:
+ .frame $sp,24,$31
+ save 24,$31
+ jal x+8
+ jal y+8
+ restore 24,$31
+ j $31
+ .end __start
Index: ld/testsuite/ld-mips-elf/mips16-call-global-2.s
===================================================================
RCS file: ld/testsuite/ld-mips-elf/mips16-call-global-2.s
diff -N ld/testsuite/ld-mips-elf/mips16-call-global-2.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/mips16-call-global-2.s 20 Jul 2006 12:36:02 -0000
@@ -0,0 +1,8 @@
+ .set mips16
+
+ .globl x
+ .ent x
+ .type x,@function
+x:
+ jr $31
+ .end x
Index: ld/testsuite/ld-mips-elf/mips16-call-global-3.s
===================================================================
RCS file: ld/testsuite/ld-mips-elf/mips16-call-global-3.s
diff -N ld/testsuite/ld-mips-elf/mips16-call-global-3.s
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/mips16-call-global-3.s 20 Jul 2006 12:36:02 -0000
@@ -0,0 +1,6 @@
+ .globl y
+ .ent y
+ .type y,@function
+y:
+ jr $31
+ .end y
Index: ld/testsuite/ld-mips-elf/mips16-call-global.d
===================================================================
RCS file: ld/testsuite/ld-mips-elf/mips16-call-global.d
diff -N ld/testsuite/ld-mips-elf/mips16-call-global.d
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/mips16-call-global.d 20 Jul 2006 12:36:02 -0000
@@ -0,0 +1,37 @@
+#as: -mips32r2
+#source: mips16-call-global-1.S mips16-call-global-2.S mips16-call-global-3.S
+
+.*: file format elf.*mips
+
+Disassembly of section .text:
+
+00400090 <__start>:
+ 400090: 64c3 save 24,ra
+ 400092: 1a00 002e jal 4000b8 <x\+0x8>
+ 400096: 6500 nop
+ 400098: 1e00 0032 jalx 4000c8 <y\+0x8>
+ 40009c: 6500 nop
+ 40009e: 6443 restore 24,ra
+ 4000a0: e8a0 jrc ra
+ 4000a2: 6500 nop
+ 4000a4: 6500 nop
+ 4000a6: 6500 nop
+ 4000a8: 6500 nop
+ 4000aa: 6500 nop
+ 4000ac: 6500 nop
+ 4000ae: 6500 nop
+
+004000b0 <x>:
+ 4000b0: e8a0 jrc ra
+ 4000b2: 6500 nop
+ 4000b4: 6500 nop
+ 4000b6: 6500 nop
+ 4000b8: 6500 nop
+ 4000ba: 6500 nop
+ 4000bc: 6500 nop
+ 4000be: 6500 nop
+
+004000c0 <y>:
+ 4000c0: 03e00008 jr ra
+ 4000c4: 00000000 nop
+ \.\.\.