/* Hitachi SH specific support for 32-bit ELF
- Copyright 1996, 97, 98, 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001
+ Free Software Foundation, Inc.
Contributed by Ian Lance Taylor, Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
return true;
}
-
\f
/* Relocate an SH ELF 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);