diff options
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 17 | ||||
-rw-r--r-- | ld/ChangeLog | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/jal-global-overflow-0.d | 20 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/jal-global-overflow-1.d | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/jal-global-overflow.s | 37 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/jal-local-overflow-0.d | 6 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/jal-local-overflow-1.d | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/jal-local-overflow.s | 35 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/mips-elf.exp | 6 |
10 files changed, 146 insertions, 8 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4ce81a6..fa83823 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2016-05-28 Maciej W. Rozycki <macro@imgtec.com> + + * elfxx-mips.c (mips_elf_calculate_relocation): <R_MIPS16_26> + <R_MIPS_26, R_MICROMIPS_26_S1>: Drop the region bits of the + reloc location from calculation, treat the addend as signed with + local non-section symbols and enable overflow detection. + 2016-05-28 Alan Modra <amodra@gmail.com> * aoutx.h: Adjust linker callback calls throughout file, diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 5143fcb..d519090 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -5247,6 +5247,9 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, /* TRUE if the symbol referred to by this relocation is a local symbol. */ bfd_boolean local_p, was_local_p; + /* TRUE if the symbol referred to by this relocation is a section + symbol. */ + bfd_boolean section_p = FALSE; /* TRUE if the symbol referred to by this relocation is "_gp_disp". */ bfd_boolean gp_disp_p = FALSE; /* TRUE if the symbol referred to by this relocation is @@ -5302,12 +5305,12 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, sym = local_syms + r_symndx; sec = local_sections[r_symndx]; + section_p = ELF_ST_TYPE (sym->st_info) == STT_SECTION; + symbol = sec->output_section->vma + sec->output_offset; - if (ELF_ST_TYPE (sym->st_info) != STT_SECTION - || (sec->flags & SEC_MERGE)) + if (!section_p || (sec->flags & SEC_MERGE)) symbol += sym->st_value; - if ((sec->flags & SEC_MERGE) - && ELF_ST_TYPE (sym->st_info) == STT_SECTION) + if ((sec->flags & SEC_MERGE) && section_p) { addend = _bfd_elf_rel_local_sym (abfd, sym, &sec, addend); addend -= symbol; @@ -5773,9 +5776,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, /* Shift is 2, unusually, for microMIPS JALX. */ shift = (!*cross_mode_jump_p && r_type == R_MICROMIPS_26_S1) ? 1 : 2; - if (was_local_p) - value = addend | ((p + 4) & (0xfc000000 << shift)); - else if (howto->partial_inplace) + if (howto->partial_inplace && !section_p) value = _bfd_mips_elf_sign_extend (addend, 26 + shift); else value = addend; @@ -5787,7 +5788,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd, return bfd_reloc_outofrange; value >>= shift; - if (!was_local_p && h->root.root.type != bfd_link_hash_undefweak) + if (was_local_p || h->root.root.type != bfd_link_hash_undefweak) overflowed_p = (value >> 26) != ((p + 4) >> (26 + shift)); value &= howto->dst_mask; } diff --git a/ld/ChangeLog b/ld/ChangeLog index fde9553..13fb745 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2016-05-28 Maciej W. Rozycki <macro@imgtec.com> + + * testsuite/ld-mips-elf/jal-global-overflow-0.d: New test. + * testsuite/ld-mips-elf/jal-global-overflow-1.d: New test. + * testsuite/ld-mips-elf/jal-local-overflow-0.d: New test. + * testsuite/ld-mips-elf/jal-local-overflow-1.d: New test. + * testsuite/ld-mips-elf/jal-global-overflow.s: New test source. + * testsuite/ld-mips-elf/jal-local-overflow.s: New test source. + * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests. + 2016-05-28 Alan Modra <amodra@gmail.com> * ldmain.c (multiple_definition, multiple_common, add_to_set, diff --git a/ld/testsuite/ld-mips-elf/jal-global-overflow-0.d b/ld/testsuite/ld-mips-elf/jal-global-overflow-0.d new file mode 100644 index 0000000..f02bfea --- /dev/null +++ b/ld/testsuite/ld-mips-elf/jal-global-overflow-0.d @@ -0,0 +1,20 @@ +#name: MIPS JAL to global symbol overflow 0 +#source: jal-global-overflow.s +#as: -EB -32 +#ld: -EB -Ttext 0x20000000 -e 0x20000000 +#objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*mips.* + +Disassembly of section \.text: + \.\.\. +[0-9a-f]+ <[^>]*> 0c001000 jal 20004000 <bar> +[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero +[0-9a-f]+ <[^>]*> 0c000800 jal 20002000 <foo> +[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero + \.\.\. +[0-9a-f]+ <[^>]*> 0c000800 jal 20002000 <foo> +[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero +[0-9a-f]+ <[^>]*> 0c001000 jal 20004000 <bar> +[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero + \.\.\. diff --git a/ld/testsuite/ld-mips-elf/jal-global-overflow-1.d b/ld/testsuite/ld-mips-elf/jal-global-overflow-1.d new file mode 100644 index 0000000..da6e750 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/jal-global-overflow-1.d @@ -0,0 +1,8 @@ +#name: MIPS JAL to global symbol overflow 1 +#source: jal-global-overflow.s +#as: -EB -32 +#ld: -EB -Ttext 0x1fffd000 -e 0x1fffd000 +#error: \A[^\n]*: In function `foo':\n +#error: \(\.text\+0x2000\): relocation truncated to fit: R_MIPS_26 against `abar'\n +#error: [^\n]*: In function `bar':\n +#error: \(\.text\+0x4000\): relocation truncated to fit: R_MIPS_26 against `afoo'\Z diff --git a/ld/testsuite/ld-mips-elf/jal-global-overflow.s b/ld/testsuite/ld-mips-elf/jal-global-overflow.s new file mode 100644 index 0000000..a67d0bf --- /dev/null +++ b/ld/testsuite/ld-mips-elf/jal-global-overflow.s @@ -0,0 +1,37 @@ + .text + .set noreorder + .org 0x2000 + + .align 4 + .globl foo + .ent foo +foo: + jal abar - 8 + nor $0, $0 + + .globl afoo + .aent afoo +afoo: + jal afoo - 8 + nor $0, $0 + .end foo + + .org 0x4000 + + .align 4 + .globl bar + .ent bar +bar: + jal afoo - 8 + nor $0, $0 + + .globl abar + .aent abar +abar: + jal abar - 8 + nor $0, $0 + .end bar + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/ld/testsuite/ld-mips-elf/jal-local-overflow-0.d b/ld/testsuite/ld-mips-elf/jal-local-overflow-0.d new file mode 100644 index 0000000..592b2ae --- /dev/null +++ b/ld/testsuite/ld-mips-elf/jal-local-overflow-0.d @@ -0,0 +1,6 @@ +#name: MIPS JAL to local symbol overflow 0 +#source: jal-local-overflow.s +#as: -EB -32 +#ld: -EB -Ttext 0x20000000 -e 0x20000000 +#objdump: -dr --prefix-addresses --show-raw-insn +#dump: jal-global-overflow-0.d diff --git a/ld/testsuite/ld-mips-elf/jal-local-overflow-1.d b/ld/testsuite/ld-mips-elf/jal-local-overflow-1.d new file mode 100644 index 0000000..869df0e --- /dev/null +++ b/ld/testsuite/ld-mips-elf/jal-local-overflow-1.d @@ -0,0 +1,8 @@ +#name: MIPS JAL to local symbol overflow 1 +#source: jal-local-overflow.s +#as: -EB -32 +#ld: -EB -Ttext 0x1fffd000 -e 0x1fffd000 +#error: \A[^\n]*: In function `foo':\n +#error: \(\.text\+0x2000\): relocation truncated to fit: R_MIPS_26 against `.text'\n +#error: [^\n]*: In function `bar':\n +#error: \(\.text\+0x4000\): relocation truncated to fit: R_MIPS_26 against `.text'\Z diff --git a/ld/testsuite/ld-mips-elf/jal-local-overflow.s b/ld/testsuite/ld-mips-elf/jal-local-overflow.s new file mode 100644 index 0000000..9b22f67 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/jal-local-overflow.s @@ -0,0 +1,35 @@ + .text + .set noreorder + .org 0x2000 + + .align 4 + .globl foo + .ent foo +foo: + jal abar - 8 + nor $0, $0 + + .aent afoo +afoo: + jal afoo - 8 + nor $0, $0 + .end foo + + .org 0x4000 + + .align 4 + .globl bar + .ent bar +bar: + jal afoo - 8 + nor $0, $0 + + .aent abar +abar: + jal abar - 8 + nor $0, $0 + .end bar + +# Force some (non-delay-slot) zero bytes, to make 'objdump' print ... + .align 4, 0 + .space 16 diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index 3fa151a..f8c8b09 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -493,6 +493,12 @@ if {$linux_gnu} { run_dump_test "jaloverflow" run_dump_test "jaloverflow-2" + +run_dump_test "jal-global-overflow-0" [list [list ld $abi_ldflags(o32)]] +run_dump_test "jal-global-overflow-1" [list [list ld $abi_ldflags(o32)]] +run_dump_test "jal-local-overflow-0" [list [list ld $abi_ldflags(o32)]] +run_dump_test "jal-local-overflow-1" [list [list ld $abi_ldflags(o32)]] + run_dump_test "undefweak-overflow" [list [list as $abi_asflags(o32)] \ [list ld $abi_ldflags(o32)]] |