X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-avr.c;h=9b0e8b53bfa750e1e3e336c6382d4858f4b40e91;hb=5a84f3e0d225c671f13d8571f035283012dc6448;hp=7649d456157a5dda2550dcbb1e1cc1172d909bb0;hpb=59c2e50f2900f1256ee5b00551afd084a68a900b;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 7649d45615..9b0e8b53bf 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1,22 +1,23 @@ /* AVR-specific support for 32-bit ELF - Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002, 2003, 2004 + Free Software Foundation, Inc. Contributed by Denis Chertykov -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" @@ -322,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 */ }; @@ -359,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 * @@ -560,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; @@ -735,7 +817,7 @@ elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section, struct elf_link_hash_entry * h; bfd_vma relocation; bfd_reloc_status_type r; - const char * name = NULL; + const char * name; int r_type; /* This is a final link. */ @@ -760,9 +842,12 @@ elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section, { bfd_boolean unresolved_reloc, warned; - RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, - relocation, sec, unresolved_reloc, - info, warned); + RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, + r_symndx, symtab_hdr, sym_hashes, + h, sec, relocation, + unresolved_reloc, warned); + + name = h->root.root.string; } r = avr_final_link_relocate (howto, input_bfd, input_section, @@ -776,7 +861,8 @@ elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section, { case bfd_reloc_overflow: r = info->callbacks->reloc_overflow - (info, name, howto->name, (bfd_vma) 0, + (info, (h ? &h->root : NULL), + name, howto->name, (bfd_vma) 0, input_bfd, input_section, rel->r_offset); break;