* 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> 2001-03-12 Stefan Geuken <mail@stefan-geuken.de>
* binary.c (bfd_external_binary_architecture): Declare. * 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; break;
case R_SH_IND12W: case R_SH_IND12W:
relocation -= 4;
goto final_link_relocate;
case R_SH_DIR8WPN: case R_SH_DIR8WPN:
case R_SH_DIR8WPZ: case R_SH_DIR8WPZ:
case R_SH_DIR8WPL: case R_SH_DIR8WPL:
/* These should normally be handled by the assembler, but at /* If the reloc is against the start of this section, then
least IND12W is generated by ourselves, so we must deal the assembler has already taken care of it and the reloc
with it. */ 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; relocation -= 4;
goto final_link_relocate; goto final_link_relocate;
}
r = bfd_reloc_ok;
break;
default: default:
bfd_set_error (bfd_error_bad_value); bfd_set_error (bfd_error_bad_value);