diff options
-rw-r--r-- | bfd/ChangeLog | 6 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 43 |
2 files changed, 28 insertions, 21 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 15e54df..4bbb6c0 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2000-08-22 Alexandre Oliva <aoliva@redhat.com> + + * elf32-sh.c (sh_elf_relocate_section) [R_SH_IND12W, + R_SH_DIR8WPN, R_SH_DIR8WPZ, R_SH_DIR8WPL]: Handle them + explicitly. Improve validation of r_type. + 2000-08-21 H.J. Lu <hjl@gnu.org> * elf32-i386.c (elf_i386_size_dynamic_sections): Zero out the diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index f1e0027..9e2d823 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -1884,6 +1884,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, continue; if (r_type < 0 + || r_type >= R_SH_max || (r_type >= (int) R_SH_FIRST_INVALID_RELOC && r_type <= (int) R_SH_LAST_INVALID_RELOC)) { @@ -1891,14 +1892,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, return false; } - /* FIXME: This is certainly incorrect. However, it is how the - COFF linker works. */ - if (r_type != (int) R_SH_DIR32 - && r_type != (int) R_SH_IND12W - && r_type != (int) R_SH_LOOP_START - && r_type != (int) R_SH_LOOP_END) - continue; - howto = sh_elf_howto_table + r_type; /* This is a final link. */ @@ -1907,11 +1900,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, sec = NULL; if (r_symndx < symtab_hdr->sh_info) { - /* There is nothing to be done for an internal IND12W - relocation. FIXME: This is probably wrong, but it's how - the COFF relocations work. */ - if (r_type == (int) R_SH_IND12W) - continue; sym = local_syms + r_symndx; sec = local_sections[r_symndx]; relocation = (sec->output_section->vma @@ -1944,22 +1932,34 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, } } - /* FIXME: This is how the COFF relocations work. */ - if (r_type == (int) R_SH_IND12W) - relocation -= 4; - switch ((int)r_type) { - case (int)R_SH_DIR32: - addend = rel->r_addend; - /* Fall through. */ - default: + final_link_relocate: /* COFF relocs don't use the addend. The addend is used for R_SH_DIR32 to be compatible with other compilers. */ r = _bfd_final_link_relocate (howto, input_bfd, input_section, contents, rel->r_offset, relocation, addend); break; + + case R_SH_IND12W: + 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; + + default: + bfd_set_error (bfd_error_bad_value); + return false; + + case R_SH_DIR32: + addend = rel->r_addend; + goto final_link_relocate; + case R_SH_LOOP_START: { static bfd_vma start, end; @@ -1969,6 +1969,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section, r = sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, rel->r_offset, sec, start, end); break; + case R_SH_LOOP_END: end = (relocation + rel->r_addend - (sec->output_section->vma + sec->output_offset)); |