diff options
author | Christian Groessler <chris@groessler.org> | 2003-08-31 18:22:06 +0000 |
---|---|---|
committer | Christian Groessler <chris@groessler.org> | 2003-08-31 18:22:06 +0000 |
commit | 1c0881ddd90f76eb7ececedfdcaa96f4c40e14d6 (patch) | |
tree | 297ab89dfb3772ee74ccc3e33f5726c365aef23d /bfd/elf32-i860.c | |
parent | 5bca7895b748abc3e01c88221778bda7e5ad3185 (diff) | |
download | fsf-binutils-gdb-1c0881ddd90f76eb7ececedfdcaa96f4c40e14d6.zip fsf-binutils-gdb-1c0881ddd90f76eb7ececedfdcaa96f4c40e14d6.tar.gz fsf-binutils-gdb-1c0881ddd90f76eb7ececedfdcaa96f4c40e14d6.tar.bz2 |
* elf32-i860.c (i860_howto_pc26_reloc): Finish relocation here
instead of returning bfd_reloc_continue.
Diffstat (limited to 'bfd/elf32-i860.c')
-rw-r--r-- | bfd/elf32-i860.c | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c index b523fb3..78e5a34 100644 --- a/bfd/elf32-i860.c +++ b/bfd/elf32-i860.c @@ -37,6 +37,10 @@ i860_howto_pc26_reloc (bfd *abfd ATTRIBUTE_UNUSED, bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED) { + bfd_vma insn; + bfd_vma relocation; + bfd_byte *addr; + if (output_bfd != NULL && (symbol->flags & BSF_SECTION_SYM) == 0 && (! reloc_entry->howto->partial_inplace @@ -46,8 +50,44 @@ i860_howto_pc26_reloc (bfd *abfd ATTRIBUTE_UNUSED, return bfd_reloc_ok; } - reloc_entry->addend -= 4; - return bfd_reloc_continue; + /* Used elf32-mips.c as an example. */ + if (bfd_is_und_section (symbol->section) + && output_bfd == (bfd *) NULL) + return bfd_reloc_undefined; + + if (bfd_is_com_section (symbol->section)) + relocation = 0; + else + relocation = symbol->value; + + relocation += symbol->section->output_section->vma; + relocation += symbol->section->output_offset; + relocation += reloc_entry->addend; + + if (reloc_entry->address > input_section->_cooked_size) + return bfd_reloc_outofrange; + + /* Adjust for PC-relative relocation. */ + relocation -= (input_section->output_section->vma + + input_section->output_offset + + reloc_entry->address + + 4); + + /* Check for target out of range. */ + if ((bfd_signed_vma)relocation > (0x3ffffff << 2) + || (bfd_signed_vma)relocation < (-0x4000000 << 2)) + return bfd_reloc_outofrange; + + addr = (bfd_byte *) data + reloc_entry->address; + insn = bfd_get_32 (abfd, addr); + + relocation >>= reloc_entry->howto->rightshift; + insn = (insn & ~reloc_entry->howto->dst_mask) + | (relocation & reloc_entry->howto->dst_mask); + + bfd_put_32 (abfd, (bfd_vma) insn, addr); + + return bfd_reloc_ok; } /* special_function for R_860_PC16 relocation. */ |