aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf32-mips.c34
-rw-r--r--bfd/elf64-mips.c37
-rw-r--r--bfd/elfn32-mips.c28
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-mips.c9
-rw-r--r--ld/testsuite/ChangeLog8
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp9
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-call-global-1.s12
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-call-global-2.s8
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-call-global-3.s6
-rw-r--r--ld/testsuite/ld-mips-elf/mips16-call-global.d37
12 files changed, 103 insertions, 99 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 55e6b54..2482506 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2006-07-20 Thiemo Seufer <ths@mips.com>
+
+ * 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.
+
2006-07-19 Alan Modra <amodra@bigpond.net.au>
* bfd-in.h (enum notice_asneeded_action): Define.
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index 5745df5..e86d955 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -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_table_rel[] =
/* 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 *reloc_entry,
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
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index ee5bce6..aa33cf7 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -112,8 +112,6 @@ static bfd_reloc_status_type mips_elf64_gprel32_reloc
(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_howto_table_rel[] =
/* 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_howto_table_rela[] =
/* 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, arelent *reloc_entry, asymbol *symbol,
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
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index 367bcf3..275e83c 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -61,8 +61,6 @@ static bfd_reloc_status_type gprel32_with_gp
(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_table_rel[] =
/* 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_table_rela[] =
/* 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, arelent *reloc_entry, asymbol *symbol,
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
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 999b795..dcb7a33 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2006-07-20 Thiemo Seufer <ths@mips.com>
+
+ * config/tc-mips.c (mips_fix_adjustable): Handle BFD_RELOC_MIPS16_JMP.
+ (tc_gen_reloc): Handle mips16 jumps to section symbol offsets.
+
2006-07-19 Paul Brook <paul@codesourcery.com>
* config/tc-arm.c (insns): Fix rbit Arm opcode.
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index abe4630..788a34b 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -13498,11 +13498,6 @@ md_estimate_size_before_relax (fragS *fragp, asection *segtype)
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 ATTRIBUTE_UNUSED, fixS *fixp)
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)
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index ad6b44c..395ae65 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2006-07-20 Thiemo Seufer <ths@mips.com>
+
+ * 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.
+
2006-07-19 Thiemo Seufer <ths@mips.com>
* ld-selective/selective.exp: Fix selective testcases for MIPS.
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index b5ddaef..aba416f 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-call-global-1.s b/ld/testsuite/ld-mips-elf/mips16-call-global-1.s
new file mode 100644
index 0000000..1e60bcc
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-call-global-1.s
@@ -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
diff --git a/ld/testsuite/ld-mips-elf/mips16-call-global-2.s b/ld/testsuite/ld-mips-elf/mips16-call-global-2.s
new file mode 100644
index 0000000..bae3195
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-call-global-2.s
@@ -0,0 +1,8 @@
+ .set mips16
+
+ .globl x
+ .ent x
+ .type x,@function
+x:
+ jr $31
+ .end x
diff --git a/ld/testsuite/ld-mips-elf/mips16-call-global-3.s b/ld/testsuite/ld-mips-elf/mips16-call-global-3.s
new file mode 100644
index 0000000..e776b3d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-call-global-3.s
@@ -0,0 +1,6 @@
+ .globl y
+ .ent y
+ .type y,@function
+y:
+ jr $31
+ .end y
diff --git a/ld/testsuite/ld-mips-elf/mips16-call-global.d b/ld/testsuite/ld-mips-elf/mips16-call-global.d
new file mode 100644
index 0000000..bd5095e
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/mips16-call-global.d
@@ -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
+ \.\.\.