diff options
author | Nick Clifton <nickc@redhat.com> | 2004-12-22 14:25:42 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2004-12-22 14:25:42 +0000 |
commit | 750bce0ee10ab816e29d8f01733ad000466181fb (patch) | |
tree | 7b299de8a67aa64196ee9cbda3b524f9a4a89270 /bfd/elf32-avr.c | |
parent | 76a56260628e949cd60b00f8035a53cbadca61ad (diff) | |
download | gdb-750bce0ee10ab816e29d8f01733ad000466181fb.zip gdb-750bce0ee10ab816e29d8f01733ad000466181fb.tar.gz gdb-750bce0ee10ab816e29d8f01733ad000466181fb.tar.bz2 |
Add support for the new R_AVR_LDI, R_AVR_6 and R_AVR_6_ADIW relocs for the
LDI, ADIW/SBIW and LDD/STD instructions.
Diffstat (limited to 'bfd/elf32-avr.c')
-rw-r--r-- | bfd/elf32-avr.c | 109 |
1 files changed, 95 insertions, 14 deletions
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 1026bfb..9b0e8b5 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -3,21 +3,21 @@ Free Software Foundation, Inc. Contributed by Denis Chertykov <denisc@overta.ru> -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" @@ -323,12 +323,57 @@ static reloc_howto_type elf_avr_howto_table[] = 23, /* bitsize */ FALSE, /* pc_relative */ 0, /* bitpos */ - complain_overflow_dont, /* complain_on_overflow */ + complain_overflow_dont,/* complain_on_overflow */ bfd_elf_generic_reloc, /* special_function */ "R_AVR_CALL", /* name */ FALSE, /* partial_inplace */ 0xffffffff, /* src_mask */ 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* A 16 bit absolute relocation of 16 bit address. + For LDI command. */ + HOWTO (R_AVR_LDI, /* type */ + 0, /* rightshift */ + 1, /* size (0 = byte, 1 = short, 2 = long) */ + 16, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_AVR_LDI", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* A 6 bit absolute relocation of 6 bit offset. + For ldd/sdd command. */ + HOWTO (R_AVR_6, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 6, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_AVR_6", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ + FALSE), /* pcrel_offset */ + /* A 6 bit absolute relocation of 6 bit offset. + For sbiw/adiw command. */ + HOWTO (R_AVR_6_ADIW, /* type */ + 0, /* rightshift */ + 0, /* size (0 = byte, 1 = short, 2 = long) */ + 6, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_AVR_6_ADIW", /* name */ + FALSE, /* partial_inplace */ + 0xffff, /* src_mask */ + 0xffff, /* dst_mask */ FALSE) /* pcrel_offset */ }; @@ -360,7 +405,10 @@ struct avr_reloc_map { BFD_RELOC_AVR_LO8_LDI_PM_NEG, R_AVR_LO8_LDI_PM_NEG }, { BFD_RELOC_AVR_HI8_LDI_PM_NEG, R_AVR_HI8_LDI_PM_NEG }, { BFD_RELOC_AVR_HH8_LDI_PM_NEG, R_AVR_HH8_LDI_PM_NEG }, - { BFD_RELOC_AVR_CALL, R_AVR_CALL } + { BFD_RELOC_AVR_CALL, R_AVR_CALL }, + { BFD_RELOC_AVR_LDI, R_AVR_LDI }, + { BFD_RELOC_AVR_6, R_AVR_6 }, + { BFD_RELOC_AVR_6_ADIW, R_AVR_6_ADIW } }; static reloc_howto_type * @@ -561,6 +609,39 @@ avr_final_link_relocate (howto, input_bfd, input_section, bfd_put_16 (input_bfd, x, contents); break; + case R_AVR_LDI: + contents += rel->r_offset; + srel = (bfd_signed_vma) relocation + rel->r_addend; + if ((srel & 0xffff) > 255) + /* Remove offset for data/eeprom section. */ + return bfd_reloc_overflow; + x = bfd_get_16 (input_bfd, contents); + x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00); + bfd_put_16 (input_bfd, x, contents); + break; + + case R_AVR_6: + contents += rel->r_offset; + srel = (bfd_signed_vma) relocation + rel->r_addend; + if (((srel & 0xffff) > 63) || (srel < 0)) + /* Remove offset for data/eeprom section. */ + return bfd_reloc_overflow; + x = bfd_get_16 (input_bfd, contents); + x = (x & 0xd3f8) | ((srel & 7) | ((srel & (3 << 3)) << 7) | ((srel & (1 << 5)) << 8)); + bfd_put_16 (input_bfd, x, contents); + break; + + case R_AVR_6_ADIW: + contents += rel->r_offset; + srel = (bfd_signed_vma) relocation + rel->r_addend; + if (((srel & 0xffff) > 63) || (srel < 0)) + /* Remove offset for data/eeprom section. */ + return bfd_reloc_overflow; + x = bfd_get_16 (input_bfd, contents); + x = (x & 0xff30) | (srel & 0xf) | ((srel & 0x30) << 2); + bfd_put_16 (input_bfd, x, contents); + break; + case R_AVR_HI8_LDI: contents += rel->r_offset; srel = (bfd_signed_vma) relocation + rel->r_addend; |