* 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.
This commit is contained in:
DJ Delorie 2001-03-13 04:43:40 +00:00
parent 4b694d15d1
commit cd6ec716b6
2 changed files with 43 additions and 5 deletions

View file

@ -1,3 +1,9 @@
2001-03-12 DJ Delorie <dj@redhat.com>
* 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.
2001-03-12 Stefan Geuken <mail@stefan-geuken.de>
* binary.c (bfd_external_binary_architecture): Declare.

View file

@ -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);