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 | |
parent | 76a56260628e949cd60b00f8035a53cbadca61ad (diff) | |
download | binutils-750bce0ee10ab816e29d8f01733ad000466181fb.zip binutils-750bce0ee10ab816e29d8f01733ad000466181fb.tar.gz binutils-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')
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 20 | ||||
-rw-r--r-- | bfd/elf32-avr.c | 109 |
3 files changed, 119 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index cfebc74..0524c5b 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2004-12-22 Klaus Rudolph <lts-rudolph@gmx.de> + + * reloc.c: Add new relocs R_AVR_LDI, R_AVR_6, R_AVR_6_ADIW. + * bfd-in2.h: Regenerate. + * elf32-avr.c (elf_avr_nowto_table): Add the new relocs. + (avr_reloc_map): Likewise. + (avr_final_link_relocate): Likewise. + 2004-12-22 Alan Modra <amodra@bigpond.net.au> * elflink.c (_bfd_elf_merge_symbol): Treat old definitions from diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 8f7a3d4..d6b6503 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1686,10 +1686,10 @@ enum bfd_architecture #define bfd_mach_sh_dsp 0x2d #define bfd_mach_sh2a 0x2a #define bfd_mach_sh2a_nofpu 0x2b -#define bfd_mach_sh2a_fake1 0x2a1 -#define bfd_mach_sh2a_fake2 0x2a2 -#define bfd_mach_sh2a_fake3 0x2a3 -#define bfd_mach_sh2a_fake4 0x2a4 +#define bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu 0x2a1 +#define bfd_mach_sh2a_nofpu_or_sh3_nommu 0x2a2 +#define bfd_mach_sh2a_or_sh4 0x2a3 +#define bfd_mach_sh2a_or_sh3e 0x2a4 #define bfd_mach_sh2e 0x2e #define bfd_mach_sh3 0x30 #define bfd_mach_sh3_nommu 0x31 @@ -3163,6 +3163,18 @@ value of SUBI insn. */ into 22 bits. */ BFD_RELOC_AVR_CALL, +/* This is a 16 bit reloc for the AVR that stores all needed bits +for absolute addressing with ldi with overflow check to linktime */ + BFD_RELOC_AVR_LDI, + +/* This is a 6 bit reloc for the AVR that stores offset for ldd/std +instructions */ + BFD_RELOC_AVR_6, + +/* This is a 6 bit reloc for the AVR that stores offset for adiw/sbiw +instructions */ + BFD_RELOC_AVR_6_ADIW, + /* Direct 12 bit. */ BFD_RELOC_390_12, 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; |