aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-sh.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2001-03-13 04:43:40 +0000
committerDJ Delorie <dj@redhat.com>2001-03-13 04:43:40 +0000
commitcd6ec716b66f84c5d885bf261a5d6c0495bc8098 (patch)
treee0c53c6fe79e22283f9d74847e58c7e797f5f4f4 /bfd/elf32-sh.c
parent4b694d15d15745cce40fadfe9dc81953027402a3 (diff)
downloadgdb-cd6ec716b66f84c5d885bf261a5d6c0495bc8098.zip
gdb-cd6ec716b66f84c5d885bf261a5d6c0495bc8098.tar.gz
gdb-cd6ec716b66f84c5d885bf261a5d6c0495bc8098.tar.bz2
* elf32-sh.c (sh_elf_relocate_section): Only relocation
R_SH_DIR8WP* relocs if they're against external symbols, else they're just for relaxing. Validate the reloc values.
Diffstat (limited to 'bfd/elf32-sh.c')
-rw-r--r--bfd/elf32-sh.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 0e6be9b..6d7bc2e 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -3029,14 +3029,46 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
break;
case R_SH_IND12W:
+ relocation -= 4;
+ goto final_link_relocate;
+
case R_SH_DIR8WPN:
case R_SH_DIR8WPZ:
case R_SH_DIR8WPL:
- /* These should normally be handled by the assembler, but at
- least IND12W is generated by ourselves, so we must deal
- with it. */
- relocation -= 4;
- goto final_link_relocate;
+ /* If the reloc is against the start of this section, then
+ the assembler has already taken care of it and the reloc
+ is here only to assist in relaxing. If the reloc is not
+ against the start of this section, then it's against an
+ external symbol and we must deal with it ourselves. */
+ if (input_section->output_section->vma + input_section->output_offset
+ != relocation)
+ {
+ int disp = (relocation
+ - input_section->output_section->vma
+ - input_section->output_offset
+ - rel->r_offset);
+ int mask = 0;
+ switch (r_type)
+ {
+ case R_SH_DIR8WPN:
+ case R_SH_DIR8WPZ: mask = 1; break;
+ case R_SH_DIR8WPL: mask = 3; break;
+ default: mask = 0; break;
+ }
+ if (disp & mask)
+ {
+ ((*_bfd_error_handler)
+ (_("%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
+ bfd_get_filename (input_section->owner),
+ (unsigned long) rel->r_offset));
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ relocation -= 4;
+ goto final_link_relocate;
+ }
+ r = bfd_reloc_ok;
+ break;
default:
bfd_set_error (bfd_error_bad_value);