2005-06-20 H.J. Lu <hongjiu.lu@intel.com>
[external/binutils.git] / bfd / elf32-avr.c
1 /* AVR-specific support for 32-bit ELF
2    Copyright 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4    Contributed by Denis Chertykov <denisc@overta.ru>
5
6    This file is part of BFD, the Binary File Descriptor library.
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/avr.h"
27
28 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
29   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
30 static void avr_info_to_howto_rela
31   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
32 static asection *elf32_avr_gc_mark_hook
33   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
34            struct elf_link_hash_entry *, Elf_Internal_Sym *));
35 static bfd_boolean elf32_avr_gc_sweep_hook
36   PARAMS ((bfd *, struct bfd_link_info *, asection *,
37            const Elf_Internal_Rela *));
38 static bfd_boolean elf32_avr_check_relocs
39   PARAMS ((bfd *, struct bfd_link_info *, asection *,
40            const Elf_Internal_Rela *));
41 static bfd_reloc_status_type avr_final_link_relocate
42   PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
43            Elf_Internal_Rela *, bfd_vma));
44 static bfd_boolean elf32_avr_relocate_section
45   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
46            Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
47 static void bfd_elf_avr_final_write_processing PARAMS ((bfd *, bfd_boolean));
48 static bfd_boolean elf32_avr_object_p PARAMS ((bfd *));
49
50 static reloc_howto_type elf_avr_howto_table[] =
51 {
52   HOWTO (R_AVR_NONE,            /* type */
53          0,                     /* rightshift */
54          2,                     /* size (0 = byte, 1 = short, 2 = long) */
55          32,                    /* bitsize */
56          FALSE,                 /* pc_relative */
57          0,                     /* bitpos */
58          complain_overflow_bitfield, /* complain_on_overflow */
59          bfd_elf_generic_reloc, /* special_function */
60          "R_AVR_NONE",          /* name */
61          FALSE,                 /* partial_inplace */
62          0,                     /* src_mask */
63          0,                     /* dst_mask */
64          FALSE),                /* pcrel_offset */
65
66   HOWTO (R_AVR_32,              /* type */
67          0,                     /* rightshift */
68          2,                     /* size (0 = byte, 1 = short, 2 = long) */
69          32,                    /* bitsize */
70          FALSE,                 /* pc_relative */
71          0,                     /* bitpos */
72          complain_overflow_bitfield, /* complain_on_overflow */
73          bfd_elf_generic_reloc, /* special_function */
74          "R_AVR_32",            /* name */
75          FALSE,                 /* partial_inplace */
76          0xffffffff,            /* src_mask */
77          0xffffffff,            /* dst_mask */
78          FALSE),                /* pcrel_offset */
79
80   /* A 7 bit PC relative relocation.  */
81   HOWTO (R_AVR_7_PCREL,         /* type */
82          1,                     /* rightshift */
83          1,                     /* size (0 = byte, 1 = short, 2 = long) */
84          7,                     /* bitsize */
85          TRUE,                  /* pc_relative */
86          3,                     /* bitpos */
87          complain_overflow_bitfield, /* complain_on_overflow */
88          bfd_elf_generic_reloc, /* special_function */
89          "R_AVR_7_PCREL",       /* name */
90          FALSE,                 /* partial_inplace */
91          0xffff,                /* src_mask */
92          0xffff,                /* dst_mask */
93          TRUE),                 /* pcrel_offset */
94
95   /* A 13 bit PC relative relocation.  */
96   HOWTO (R_AVR_13_PCREL,        /* type */
97          1,                     /* rightshift */
98          1,                     /* size (0 = byte, 1 = short, 2 = long) */
99          13,                    /* bitsize */
100          TRUE,                  /* pc_relative */
101          0,                     /* bitpos */
102          complain_overflow_bitfield, /* complain_on_overflow */
103          bfd_elf_generic_reloc, /* special_function */
104          "R_AVR_13_PCREL",      /* name */
105          FALSE,                 /* partial_inplace */
106          0xfff,                 /* src_mask */
107          0xfff,                 /* dst_mask */
108          TRUE),                 /* pcrel_offset */
109
110   /* A 16 bit absolute relocation.  */
111   HOWTO (R_AVR_16,              /* type */
112          0,                     /* rightshift */
113          1,                     /* size (0 = byte, 1 = short, 2 = long) */
114          16,                    /* bitsize */
115          FALSE,                 /* pc_relative */
116          0,                     /* bitpos */
117          complain_overflow_dont, /* complain_on_overflow */
118          bfd_elf_generic_reloc, /* special_function */
119          "R_AVR_16",            /* name */
120          FALSE,                 /* partial_inplace */
121          0xffff,                /* src_mask */
122          0xffff,                /* dst_mask */
123          FALSE),                /* pcrel_offset */
124
125   /* A 16 bit absolute relocation for command address.  */
126   HOWTO (R_AVR_16_PM,           /* type */
127          1,                     /* rightshift */
128          1,                     /* size (0 = byte, 1 = short, 2 = long) */
129          16,                    /* bitsize */
130          FALSE,                 /* pc_relative */
131          0,                     /* bitpos */
132          complain_overflow_bitfield, /* complain_on_overflow */
133          bfd_elf_generic_reloc, /* special_function */
134          "R_AVR_16_PM",         /* name */
135          FALSE,                 /* partial_inplace */
136          0xffff,                /* src_mask */
137          0xffff,                /* dst_mask */
138          FALSE),                /* pcrel_offset */
139   /* A low 8 bit absolute relocation of 16 bit address.
140      For LDI command.  */
141   HOWTO (R_AVR_LO8_LDI,         /* type */
142          0,                     /* rightshift */
143          1,                     /* size (0 = byte, 1 = short, 2 = long) */
144          8,                     /* bitsize */
145          FALSE,                 /* pc_relative */
146          0,                     /* bitpos */
147          complain_overflow_dont, /* complain_on_overflow */
148          bfd_elf_generic_reloc, /* special_function */
149          "R_AVR_LO8_LDI",       /* name */
150          FALSE,                 /* partial_inplace */
151          0xffff,                /* src_mask */
152          0xffff,                /* dst_mask */
153          FALSE),                /* pcrel_offset */
154   /* A high 8 bit absolute relocation of 16 bit address.
155      For LDI command.  */
156   HOWTO (R_AVR_HI8_LDI,         /* type */
157          8,                     /* rightshift */
158          1,                     /* size (0 = byte, 1 = short, 2 = long) */
159          8,                     /* bitsize */
160          FALSE,                 /* pc_relative */
161          0,                     /* bitpos */
162          complain_overflow_dont, /* complain_on_overflow */
163          bfd_elf_generic_reloc, /* special_function */
164          "R_AVR_HI8_LDI",       /* name */
165          FALSE,                 /* partial_inplace */
166          0xffff,                /* src_mask */
167          0xffff,                /* dst_mask */
168          FALSE),                /* pcrel_offset */
169   /* A high 6 bit absolute relocation of 22 bit address.
170      For LDI command.  */
171   HOWTO (R_AVR_HH8_LDI,         /* type */
172          16,                    /* rightshift */
173          1,                     /* size (0 = byte, 1 = short, 2 = long) */
174          8,                     /* bitsize */
175          FALSE,                 /* pc_relative */
176          0,                     /* bitpos */
177          complain_overflow_dont, /* complain_on_overflow */
178          bfd_elf_generic_reloc, /* special_function */
179          "R_AVR_HH8_LDI",       /* name */
180          FALSE,                 /* partial_inplace */
181          0xffff,                /* src_mask */
182          0xffff,                /* dst_mask */
183          FALSE),                /* pcrel_offset */
184   /* A negative low 8 bit absolute relocation of 16 bit address.
185      For LDI command.  */
186   HOWTO (R_AVR_LO8_LDI_NEG,     /* type */
187          0,                     /* rightshift */
188          1,                     /* size (0 = byte, 1 = short, 2 = long) */
189          8,                     /* bitsize */
190          FALSE,                 /* pc_relative */
191          0,                     /* bitpos */
192          complain_overflow_dont, /* complain_on_overflow */
193          bfd_elf_generic_reloc, /* special_function */
194          "R_AVR_LO8_LDI_NEG",   /* name */
195          FALSE,                 /* partial_inplace */
196          0xffff,                /* src_mask */
197          0xffff,                /* dst_mask */
198          FALSE),                /* pcrel_offset */
199   /* A hegative high 8 bit absolute relocation of 16 bit address.
200      For LDI command.  */
201   HOWTO (R_AVR_HI8_LDI_NEG,     /* type */
202          8,                     /* rightshift */
203          1,                     /* size (0 = byte, 1 = short, 2 = long) */
204          8,                     /* bitsize */
205          FALSE,                 /* pc_relative */
206          0,                     /* bitpos */
207          complain_overflow_dont, /* complain_on_overflow */
208          bfd_elf_generic_reloc, /* special_function */
209          "R_AVR_HI8_LDI_NEG",   /* name */
210          FALSE,                 /* partial_inplace */
211          0xffff,                /* src_mask */
212          0xffff,                /* dst_mask */
213          FALSE),                /* pcrel_offset */
214   /* A hegative high 6 bit absolute relocation of 22 bit address.
215      For LDI command.  */
216   HOWTO (R_AVR_HH8_LDI_NEG,     /* type */
217          16,                    /* rightshift */
218          1,                     /* size (0 = byte, 1 = short, 2 = long) */
219          8,                     /* bitsize */
220          FALSE,                 /* pc_relative */
221          0,                     /* bitpos */
222          complain_overflow_dont, /* complain_on_overflow */
223          bfd_elf_generic_reloc, /* special_function */
224          "R_AVR_HH8_LDI_NEG",   /* name */
225          FALSE,                 /* partial_inplace */
226          0xffff,                /* src_mask */
227          0xffff,                /* dst_mask */
228          FALSE),                /* pcrel_offset */
229   /* A low 8 bit absolute relocation of 24 bit program memory address.
230      For LDI command.  */
231   HOWTO (R_AVR_LO8_LDI_PM,      /* type */
232          1,                     /* rightshift */
233          1,                     /* size (0 = byte, 1 = short, 2 = long) */
234          8,                     /* bitsize */
235          FALSE,                 /* pc_relative */
236          0,                     /* bitpos */
237          complain_overflow_dont, /* complain_on_overflow */
238          bfd_elf_generic_reloc, /* special_function */
239          "R_AVR_LO8_LDI_PM",    /* name */
240          FALSE,                 /* partial_inplace */
241          0xffff,                /* src_mask */
242          0xffff,                /* dst_mask */
243          FALSE),                /* pcrel_offset */
244   /* A high 8 bit absolute relocation of 16 bit program memory address.
245      For LDI command.  */
246   HOWTO (R_AVR_HI8_LDI_PM,      /* type */
247          9,                     /* rightshift */
248          1,                     /* size (0 = byte, 1 = short, 2 = long) */
249          8,                     /* bitsize */
250          FALSE,                 /* pc_relative */
251          0,                     /* bitpos */
252          complain_overflow_dont, /* complain_on_overflow */
253          bfd_elf_generic_reloc, /* special_function */
254          "R_AVR_HI8_LDI_PM",    /* name */
255          FALSE,                 /* partial_inplace */
256          0xffff,                /* src_mask */
257          0xffff,                /* dst_mask */
258          FALSE),                /* pcrel_offset */
259   /* A high 8 bit absolute relocation of 24 bit program memory address.
260      For LDI command.  */
261   HOWTO (R_AVR_HH8_LDI_PM,      /* type */
262          17,                    /* rightshift */
263          1,                     /* size (0 = byte, 1 = short, 2 = long) */
264          8,                     /* bitsize */
265          FALSE,                 /* pc_relative */
266          0,                     /* bitpos */
267          complain_overflow_dont, /* complain_on_overflow */
268          bfd_elf_generic_reloc, /* special_function */
269          "R_AVR_HH8_LDI_PM",    /* name */
270          FALSE,                 /* partial_inplace */
271          0xffff,                /* src_mask */
272          0xffff,                /* dst_mask */
273          FALSE),                /* pcrel_offset */
274   /* A low 8 bit absolute relocation of a negative 24 bit
275      program memory address.  For LDI command.  */
276   HOWTO (R_AVR_LO8_LDI_PM_NEG,  /* type */
277          1,                     /* rightshift */
278          1,                     /* size (0 = byte, 1 = short, 2 = long) */
279          8,                     /* bitsize */
280          FALSE,                 /* pc_relative */
281          0,                     /* bitpos */
282          complain_overflow_dont, /* complain_on_overflow */
283          bfd_elf_generic_reloc, /* special_function */
284          "R_AVR_LO8_LDI_PM_NEG", /* name */
285          FALSE,                 /* partial_inplace */
286          0xffff,                /* src_mask */
287          0xffff,                /* dst_mask */
288          FALSE),                /* pcrel_offset */
289   /* A high 8 bit absolute relocation of a negative 16 bit
290      program memory address.  For LDI command.  */
291   HOWTO (R_AVR_HI8_LDI_PM_NEG,  /* type */
292          9,                     /* rightshift */
293          1,                     /* size (0 = byte, 1 = short, 2 = long) */
294          8,                     /* bitsize */
295          FALSE,                 /* pc_relative */
296          0,                     /* bitpos */
297          complain_overflow_dont, /* complain_on_overflow */
298          bfd_elf_generic_reloc, /* special_function */
299          "R_AVR_HI8_LDI_PM_NEG", /* name */
300          FALSE,                 /* partial_inplace */
301          0xffff,                /* src_mask */
302          0xffff,                /* dst_mask */
303          FALSE),                /* pcrel_offset */
304   /* A high 8 bit absolute relocation of a negative 24 bit
305      program memory address.  For LDI command.  */
306   HOWTO (R_AVR_HH8_LDI_PM_NEG,  /* type */
307          17,                    /* rightshift */
308          1,                     /* size (0 = byte, 1 = short, 2 = long) */
309          8,                     /* bitsize */
310          FALSE,                 /* pc_relative */
311          0,                     /* bitpos */
312          complain_overflow_dont, /* complain_on_overflow */
313          bfd_elf_generic_reloc, /* special_function */
314          "R_AVR_HH8_LDI_PM_NEG", /* name */
315          FALSE,                 /* partial_inplace */
316          0xffff,                /* src_mask */
317          0xffff,                /* dst_mask */
318          FALSE),                /* pcrel_offset */
319   /* Relocation for CALL command in ATmega.  */
320   HOWTO (R_AVR_CALL,            /* type */
321          1,                     /* rightshift */
322          2,                     /* size (0 = byte, 1 = short, 2 = long) */
323          23,                    /* bitsize */
324          FALSE,                 /* pc_relative */
325          0,                     /* bitpos */
326          complain_overflow_dont,/* complain_on_overflow */
327          bfd_elf_generic_reloc, /* special_function */
328          "R_AVR_CALL",          /* name */
329          FALSE,                 /* partial_inplace */
330          0xffffffff,            /* src_mask */
331          0xffffffff,            /* dst_mask */
332          FALSE),                        /* pcrel_offset */
333   /* A 16 bit absolute relocation of 16 bit address.
334      For LDI command.  */
335   HOWTO (R_AVR_LDI,             /* type */
336          0,                     /* rightshift */
337          1,                     /* size (0 = byte, 1 = short, 2 = long) */
338          16,                    /* bitsize */
339          FALSE,                 /* pc_relative */
340          0,                     /* bitpos */
341          complain_overflow_dont,/* complain_on_overflow */
342          bfd_elf_generic_reloc, /* special_function */
343          "R_AVR_LDI",           /* name */
344          FALSE,                 /* partial_inplace */
345          0xffff,                /* src_mask */
346          0xffff,                /* dst_mask */
347          FALSE),                /* pcrel_offset */
348   /* A 6 bit absolute relocation of 6 bit offset.
349      For ldd/sdd command.  */
350   HOWTO (R_AVR_6,               /* type */
351          0,                     /* rightshift */
352          0,                     /* size (0 = byte, 1 = short, 2 = long) */
353          6,                     /* bitsize */
354          FALSE,                 /* pc_relative */
355          0,                     /* bitpos */
356          complain_overflow_dont,/* complain_on_overflow */
357          bfd_elf_generic_reloc, /* special_function */
358          "R_AVR_6",             /* name */
359          FALSE,                 /* partial_inplace */
360          0xffff,                /* src_mask */
361          0xffff,                /* dst_mask */
362          FALSE),                /* pcrel_offset */
363   /* A 6 bit absolute relocation of 6 bit offset.
364      For sbiw/adiw command.  */
365   HOWTO (R_AVR_6_ADIW,          /* type */
366          0,                     /* rightshift */
367          0,                     /* size (0 = byte, 1 = short, 2 = long) */
368          6,                     /* bitsize */
369          FALSE,                 /* pc_relative */
370          0,                     /* bitpos */
371          complain_overflow_dont,/* complain_on_overflow */
372          bfd_elf_generic_reloc, /* special_function */
373          "R_AVR_6_ADIW",        /* name */
374          FALSE,                 /* partial_inplace */
375          0xffff,                /* src_mask */
376          0xffff,                /* dst_mask */
377          FALSE)                 /* pcrel_offset */
378 };
379
380 /* Map BFD reloc types to AVR ELF reloc types.  */
381
382 struct avr_reloc_map
383 {
384   bfd_reloc_code_real_type bfd_reloc_val;
385   unsigned int elf_reloc_val;
386 };
387
388  static const struct avr_reloc_map avr_reloc_map[] =
389 {
390   { BFD_RELOC_NONE,                 R_AVR_NONE },
391   { BFD_RELOC_32,                   R_AVR_32 },
392   { BFD_RELOC_AVR_7_PCREL,          R_AVR_7_PCREL },
393   { BFD_RELOC_AVR_13_PCREL,         R_AVR_13_PCREL },
394   { BFD_RELOC_16,                   R_AVR_16 },
395   { BFD_RELOC_AVR_16_PM,            R_AVR_16_PM },
396   { BFD_RELOC_AVR_LO8_LDI,          R_AVR_LO8_LDI},
397   { BFD_RELOC_AVR_HI8_LDI,          R_AVR_HI8_LDI },
398   { BFD_RELOC_AVR_HH8_LDI,          R_AVR_HH8_LDI },
399   { BFD_RELOC_AVR_LO8_LDI_NEG,      R_AVR_LO8_LDI_NEG },
400   { BFD_RELOC_AVR_HI8_LDI_NEG,      R_AVR_HI8_LDI_NEG },
401   { BFD_RELOC_AVR_HH8_LDI_NEG,      R_AVR_HH8_LDI_NEG },
402   { BFD_RELOC_AVR_LO8_LDI_PM,       R_AVR_LO8_LDI_PM },
403   { BFD_RELOC_AVR_HI8_LDI_PM,       R_AVR_HI8_LDI_PM },
404   { BFD_RELOC_AVR_HH8_LDI_PM,       R_AVR_HH8_LDI_PM },
405   { BFD_RELOC_AVR_LO8_LDI_PM_NEG,   R_AVR_LO8_LDI_PM_NEG },
406   { BFD_RELOC_AVR_HI8_LDI_PM_NEG,   R_AVR_HI8_LDI_PM_NEG },
407   { BFD_RELOC_AVR_HH8_LDI_PM_NEG,   R_AVR_HH8_LDI_PM_NEG },
408   { BFD_RELOC_AVR_CALL,             R_AVR_CALL },
409   { BFD_RELOC_AVR_LDI,              R_AVR_LDI  },
410   { BFD_RELOC_AVR_6,                R_AVR_6    },
411   { BFD_RELOC_AVR_6_ADIW,           R_AVR_6_ADIW }
412 };
413
414 static reloc_howto_type *
415 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
416      bfd *abfd ATTRIBUTE_UNUSED;
417      bfd_reloc_code_real_type code;
418 {
419   unsigned int i;
420
421   for (i = 0;
422        i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);
423        i++)
424     {
425       if (avr_reloc_map[i].bfd_reloc_val == code)
426         return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];
427     }
428
429   return NULL;
430 }
431
432 /* Set the howto pointer for an AVR ELF reloc.  */
433
434 static void
435 avr_info_to_howto_rela (abfd, cache_ptr, dst)
436      bfd *abfd ATTRIBUTE_UNUSED;
437      arelent *cache_ptr;
438      Elf_Internal_Rela *dst;
439 {
440   unsigned int r_type;
441
442   r_type = ELF32_R_TYPE (dst->r_info);
443   BFD_ASSERT (r_type < (unsigned int) R_AVR_max);
444   cache_ptr->howto = &elf_avr_howto_table[r_type];
445 }
446
447 static asection *
448 elf32_avr_gc_mark_hook (sec, info, rel, h, sym)
449      asection *sec;
450      struct bfd_link_info *info ATTRIBUTE_UNUSED;
451      Elf_Internal_Rela *rel;
452      struct elf_link_hash_entry *h;
453      Elf_Internal_Sym *sym;
454 {
455   if (h != NULL)
456     {
457       switch (ELF32_R_TYPE (rel->r_info))
458         {
459         default:
460           switch (h->root.type)
461             {
462             case bfd_link_hash_defined:
463             case bfd_link_hash_defweak:
464               return h->root.u.def.section;
465
466             case bfd_link_hash_common:
467               return h->root.u.c.p->section;
468
469             default:
470               break;
471             }
472         }
473     }
474   else
475     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
476
477   return NULL;
478 }
479
480 static bfd_boolean
481 elf32_avr_gc_sweep_hook (abfd, info, sec, relocs)
482      bfd *abfd ATTRIBUTE_UNUSED;
483      struct bfd_link_info *info ATTRIBUTE_UNUSED;
484      asection *sec ATTRIBUTE_UNUSED;
485      const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
486 {
487   /* We don't use got and plt entries for avr.  */
488   return TRUE;
489 }
490
491 /* Look through the relocs for a section during the first phase.
492    Since we don't do .gots or .plts, we just need to consider the
493    virtual table relocs for gc.  */
494
495 static bfd_boolean
496 elf32_avr_check_relocs (abfd, info, sec, relocs)
497      bfd *abfd;
498      struct bfd_link_info *info;
499      asection *sec;
500      const Elf_Internal_Rela *relocs;
501 {
502   Elf_Internal_Shdr *symtab_hdr;
503   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
504   const Elf_Internal_Rela *rel;
505   const Elf_Internal_Rela *rel_end;
506
507   if (info->relocatable)
508     return TRUE;
509
510   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
511   sym_hashes = elf_sym_hashes (abfd);
512   sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
513   if (!elf_bad_symtab (abfd))
514     sym_hashes_end -= symtab_hdr->sh_info;
515
516   rel_end = relocs + sec->reloc_count;
517   for (rel = relocs; rel < rel_end; rel++)
518     {
519       struct elf_link_hash_entry *h;
520       unsigned long r_symndx;
521
522       r_symndx = ELF32_R_SYM (rel->r_info);
523       if (r_symndx < symtab_hdr->sh_info)
524         h = NULL;
525       else
526         {
527           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
528           while (h->root.type == bfd_link_hash_indirect
529                  || h->root.type == bfd_link_hash_warning)
530             h = (struct elf_link_hash_entry *) h->root.u.i.link;
531         }
532     }
533
534   return TRUE;
535 }
536
537 /* Perform a single relocation.  By default we use the standard BFD
538    routines, but a few relocs, we have to do them ourselves.  */
539
540 static bfd_reloc_status_type
541 avr_final_link_relocate (howto, input_bfd, input_section,
542                          contents, rel, relocation)
543      reloc_howto_type *  howto;
544      bfd *               input_bfd;
545      asection *          input_section;
546      bfd_byte *          contents;
547      Elf_Internal_Rela * rel;
548      bfd_vma             relocation;
549 {
550   bfd_reloc_status_type r = bfd_reloc_ok;
551   bfd_vma               x;
552   bfd_signed_vma        srel;
553
554   switch (howto->type)
555     {
556     case R_AVR_7_PCREL:
557       contents += rel->r_offset;
558       srel = (bfd_signed_vma) relocation;
559       srel += rel->r_addend;
560       srel -= rel->r_offset;
561       srel -= 2;        /* Branch instructions add 2 to the PC...  */
562       srel -= (input_section->output_section->vma +
563                input_section->output_offset);
564
565       if (srel & 1)
566         return bfd_reloc_outofrange;
567       if (srel > ((1 << 7) - 1) || (srel < - (1 << 7)))
568         return bfd_reloc_overflow;
569       x = bfd_get_16 (input_bfd, contents);
570       x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);
571       bfd_put_16 (input_bfd, x, contents);
572       break;
573
574     case R_AVR_13_PCREL:
575       contents   += rel->r_offset;
576       srel = (bfd_signed_vma) relocation;
577       srel += rel->r_addend;
578       srel -= rel->r_offset;
579       srel -= 2;        /* Branch instructions add 2 to the PC...  */
580       srel -= (input_section->output_section->vma +
581                input_section->output_offset);
582
583       if (srel & 1)
584         return bfd_reloc_outofrange;
585
586       /* AVR addresses commands as words.  */
587       srel >>= 1;
588
589       /* Check for overflow.  */
590       if (srel < -2048 || srel > 2047)
591         {
592           /* Apply WRAPAROUND if possible.  */
593           switch (bfd_get_mach (input_bfd))
594             {
595             case bfd_mach_avr2:
596             case bfd_mach_avr4:
597               break;
598
599             default:
600               return bfd_reloc_overflow;
601             }
602         }
603
604       x = bfd_get_16 (input_bfd, contents);
605       x = (x & 0xf000) | (srel & 0xfff);
606       bfd_put_16 (input_bfd, x, contents);
607       break;
608
609     case R_AVR_LO8_LDI:
610       contents += rel->r_offset;
611       srel = (bfd_signed_vma) relocation + rel->r_addend;
612       x = bfd_get_16 (input_bfd, contents);
613       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
614       bfd_put_16 (input_bfd, x, contents);
615       break;
616
617     case R_AVR_LDI:
618       contents += rel->r_offset;
619       srel = (bfd_signed_vma) relocation + rel->r_addend;
620       if ((srel & 0xffff) > 255)
621         /* Remove offset for data/eeprom section.  */
622         return bfd_reloc_overflow;
623       x = bfd_get_16 (input_bfd, contents);
624       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
625       bfd_put_16 (input_bfd, x, contents);
626       break;
627
628     case R_AVR_6:
629       contents += rel->r_offset;
630       srel = (bfd_signed_vma) relocation + rel->r_addend;
631       if (((srel & 0xffff) > 63) || (srel < 0))
632         /* Remove offset for data/eeprom section.  */
633         return bfd_reloc_overflow;
634       x = bfd_get_16 (input_bfd, contents);
635       x = (x & 0xd3f8) | ((srel & 7) | ((srel & (3 << 3)) << 7) | ((srel & (1 << 5)) << 8));
636       bfd_put_16 (input_bfd, x, contents);
637       break;
638
639     case R_AVR_6_ADIW:
640       contents += rel->r_offset;
641       srel = (bfd_signed_vma) relocation + rel->r_addend;
642       if (((srel & 0xffff) > 63) || (srel < 0))
643         /* Remove offset for data/eeprom section.  */
644         return bfd_reloc_overflow;
645       x = bfd_get_16 (input_bfd, contents);
646       x = (x & 0xff30) | (srel & 0xf) | ((srel & 0x30) << 2); 
647       bfd_put_16 (input_bfd, x, contents);
648       break;
649
650     case R_AVR_HI8_LDI:
651       contents += rel->r_offset;
652       srel = (bfd_signed_vma) relocation + rel->r_addend;
653       srel = (srel >> 8) & 0xff;
654       x = bfd_get_16 (input_bfd, contents);
655       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
656       bfd_put_16 (input_bfd, x, contents);
657       break;
658
659     case R_AVR_HH8_LDI:
660       contents += rel->r_offset;
661       srel = (bfd_signed_vma) relocation + rel->r_addend;
662       srel = (srel >> 16) & 0xff;
663       x = bfd_get_16 (input_bfd, contents);
664       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
665       bfd_put_16 (input_bfd, x, contents);
666       break;
667
668     case R_AVR_LO8_LDI_NEG:
669       contents += rel->r_offset;
670       srel = (bfd_signed_vma) relocation + rel->r_addend;
671       srel = -srel;
672       x = bfd_get_16 (input_bfd, contents);
673       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
674       bfd_put_16 (input_bfd, x, contents);
675       break;
676
677     case R_AVR_HI8_LDI_NEG:
678       contents += rel->r_offset;
679       srel = (bfd_signed_vma) relocation + rel->r_addend;
680       srel = -srel;
681       srel = (srel >> 8) & 0xff;
682       x = bfd_get_16 (input_bfd, contents);
683       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
684       bfd_put_16 (input_bfd, x, contents);
685       break;
686
687     case R_AVR_HH8_LDI_NEG:
688       contents += rel->r_offset;
689       srel = (bfd_signed_vma) relocation + rel->r_addend;
690       srel = -srel;
691       srel = (srel >> 16) & 0xff;
692       x = bfd_get_16 (input_bfd, contents);
693       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
694       bfd_put_16 (input_bfd, x, contents);
695       break;
696
697     case R_AVR_LO8_LDI_PM:
698       contents += rel->r_offset;
699       srel = (bfd_signed_vma) relocation + rel->r_addend;
700       if (srel & 1)
701         return bfd_reloc_outofrange;
702       srel = srel >> 1;
703       x = bfd_get_16 (input_bfd, contents);
704       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
705       bfd_put_16 (input_bfd, x, contents);
706       break;
707
708     case R_AVR_HI8_LDI_PM:
709       contents += rel->r_offset;
710       srel = (bfd_signed_vma) relocation + rel->r_addend;
711       if (srel & 1)
712         return bfd_reloc_outofrange;
713       srel = srel >> 1;
714       srel = (srel >> 8) & 0xff;
715       x = bfd_get_16 (input_bfd, contents);
716       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
717       bfd_put_16 (input_bfd, x, contents);
718       break;
719
720     case R_AVR_HH8_LDI_PM:
721       contents += rel->r_offset;
722       srel = (bfd_signed_vma) relocation + rel->r_addend;
723       if (srel & 1)
724         return bfd_reloc_outofrange;
725       srel = srel >> 1;
726       srel = (srel >> 16) & 0xff;
727       x = bfd_get_16 (input_bfd, contents);
728       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
729       bfd_put_16 (input_bfd, x, contents);
730       break;
731
732     case R_AVR_LO8_LDI_PM_NEG:
733       contents += rel->r_offset;
734       srel = (bfd_signed_vma) relocation + rel->r_addend;
735       srel = -srel;
736       if (srel & 1)
737         return bfd_reloc_outofrange;
738       srel = srel >> 1;
739       x = bfd_get_16 (input_bfd, contents);
740       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
741       bfd_put_16 (input_bfd, x, contents);
742       break;
743
744     case R_AVR_HI8_LDI_PM_NEG:
745       contents += rel->r_offset;
746       srel = (bfd_signed_vma) relocation + rel->r_addend;
747       srel = -srel;
748       if (srel & 1)
749         return bfd_reloc_outofrange;
750       srel = srel >> 1;
751       srel = (srel >> 8) & 0xff;
752       x = bfd_get_16 (input_bfd, contents);
753       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
754       bfd_put_16 (input_bfd, x, contents);
755       break;
756
757     case R_AVR_HH8_LDI_PM_NEG:
758       contents += rel->r_offset;
759       srel = (bfd_signed_vma) relocation + rel->r_addend;
760       srel = -srel;
761       if (srel & 1)
762         return bfd_reloc_outofrange;
763       srel = srel >> 1;
764       srel = (srel >> 16) & 0xff;
765       x = bfd_get_16 (input_bfd, contents);
766       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
767       bfd_put_16 (input_bfd, x, contents);
768       break;
769
770     case R_AVR_CALL:
771       contents += rel->r_offset;
772       srel = (bfd_signed_vma) relocation + rel->r_addend;
773       if (srel & 1)
774         return bfd_reloc_outofrange;
775       srel = srel >> 1;
776       x = bfd_get_16 (input_bfd, contents);
777       x |= ((srel & 0x10000) | ((srel << 3) & 0x1f00000)) >> 16;
778       bfd_put_16 (input_bfd, x, contents);
779       bfd_put_16 (input_bfd, (bfd_vma) srel & 0xffff, contents+2);
780       break;
781
782     default:
783       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
784                                     contents, rel->r_offset,
785                                     relocation, rel->r_addend);
786     }
787
788   return r;
789 }
790
791 /* Relocate an AVR ELF section.  */
792 static bfd_boolean
793 elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section,
794                             contents, relocs, local_syms, local_sections)
795      bfd *output_bfd ATTRIBUTE_UNUSED;
796      struct bfd_link_info *info;
797      bfd *input_bfd;
798      asection *input_section;
799      bfd_byte *contents;
800      Elf_Internal_Rela *relocs;
801      Elf_Internal_Sym *local_syms;
802      asection **local_sections;
803 {
804   Elf_Internal_Shdr *           symtab_hdr;
805   struct elf_link_hash_entry ** sym_hashes;
806   Elf_Internal_Rela *           rel;
807   Elf_Internal_Rela *           relend;
808
809   if (info->relocatable)
810     return TRUE;
811
812   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
813   sym_hashes = elf_sym_hashes (input_bfd);
814   relend     = relocs + input_section->reloc_count;
815
816   for (rel = relocs; rel < relend; rel ++)
817     {
818       reloc_howto_type *           howto;
819       unsigned long                r_symndx;
820       Elf_Internal_Sym *           sym;
821       asection *                   sec;
822       struct elf_link_hash_entry * h;
823       bfd_vma                      relocation;
824       bfd_reloc_status_type        r;
825       const char *                 name;
826       int                          r_type;
827
828       /* This is a final link.  */
829       r_type = ELF32_R_TYPE (rel->r_info);
830       r_symndx = ELF32_R_SYM (rel->r_info);
831       howto  = elf_avr_howto_table + ELF32_R_TYPE (rel->r_info);
832       h      = NULL;
833       sym    = NULL;
834       sec    = NULL;
835
836       if (r_symndx < symtab_hdr->sh_info)
837         {
838           sym = local_syms + r_symndx;
839           sec = local_sections [r_symndx];
840           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
841
842           name = bfd_elf_string_from_elf_section
843             (input_bfd, symtab_hdr->sh_link, sym->st_name);
844           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
845         }
846       else
847         {
848           bfd_boolean unresolved_reloc, warned;
849
850           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
851                                    r_symndx, symtab_hdr, sym_hashes,
852                                    h, sec, relocation,
853                                    unresolved_reloc, warned);
854
855           name = h->root.root.string;
856         }
857
858       r = avr_final_link_relocate (howto, input_bfd, input_section,
859                                    contents, rel, relocation);
860
861       if (r != bfd_reloc_ok)
862         {
863           const char * msg = (const char *) NULL;
864
865           switch (r)
866             {
867             case bfd_reloc_overflow:
868               r = info->callbacks->reloc_overflow
869                 (info, (h ? &h->root : NULL),
870                  name, howto->name, (bfd_vma) 0,
871                  input_bfd, input_section, rel->r_offset);
872               break;
873
874             case bfd_reloc_undefined:
875               r = info->callbacks->undefined_symbol
876                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
877               break;
878
879             case bfd_reloc_outofrange:
880               msg = _("internal error: out of range error");
881               break;
882
883             case bfd_reloc_notsupported:
884               msg = _("internal error: unsupported relocation error");
885               break;
886
887             case bfd_reloc_dangerous:
888               msg = _("internal error: dangerous relocation");
889               break;
890
891             default:
892               msg = _("internal error: unknown error");
893               break;
894             }
895
896           if (msg)
897             r = info->callbacks->warning
898               (info, msg, name, input_bfd, input_section, rel->r_offset);
899
900           if (! r)
901             return FALSE;
902         }
903     }
904
905   return TRUE;
906 }
907
908 /* The final processing done just before writing out a AVR ELF object
909    file.  This gets the AVR architecture right based on the machine
910    number.  */
911
912 static void
913 bfd_elf_avr_final_write_processing (abfd, linker)
914      bfd *abfd;
915      bfd_boolean linker ATTRIBUTE_UNUSED;
916 {
917   unsigned long val;
918
919   switch (bfd_get_mach (abfd))
920     {
921     default:
922     case bfd_mach_avr2:
923       val = E_AVR_MACH_AVR2;
924       break;
925
926     case bfd_mach_avr1:
927       val = E_AVR_MACH_AVR1;
928       break;
929
930     case bfd_mach_avr3:
931       val = E_AVR_MACH_AVR3;
932       break;
933
934     case bfd_mach_avr4:
935       val = E_AVR_MACH_AVR4;
936       break;
937
938     case bfd_mach_avr5:
939       val = E_AVR_MACH_AVR5;
940       break;
941     }
942
943   elf_elfheader (abfd)->e_machine = EM_AVR;
944   elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
945   elf_elfheader (abfd)->e_flags |= val;
946 }
947
948 /* Set the right machine number.  */
949
950 static bfd_boolean
951 elf32_avr_object_p (abfd)
952      bfd *abfd;
953 {
954   unsigned int e_set = bfd_mach_avr2;
955   if (elf_elfheader (abfd)->e_machine == EM_AVR
956       || elf_elfheader (abfd)->e_machine == EM_AVR_OLD)
957     {
958       int e_mach = elf_elfheader (abfd)->e_flags & EF_AVR_MACH;
959       switch (e_mach)
960         {
961         default:
962         case E_AVR_MACH_AVR2:
963           e_set = bfd_mach_avr2;
964           break;
965
966         case E_AVR_MACH_AVR1:
967           e_set = bfd_mach_avr1;
968           break;
969
970         case E_AVR_MACH_AVR3:
971           e_set = bfd_mach_avr3;
972           break;
973
974         case E_AVR_MACH_AVR4:
975           e_set = bfd_mach_avr4;
976           break;
977
978         case E_AVR_MACH_AVR5:
979           e_set = bfd_mach_avr5;
980           break;
981         }
982     }
983   return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
984                                     e_set);
985 }
986
987 #define ELF_ARCH                bfd_arch_avr
988 #define ELF_MACHINE_CODE        EM_AVR
989 #define ELF_MACHINE_ALT1        EM_AVR_OLD
990 #define ELF_MAXPAGESIZE         1
991
992 #define TARGET_LITTLE_SYM       bfd_elf32_avr_vec
993 #define TARGET_LITTLE_NAME      "elf32-avr"
994
995 #define elf_info_to_howto                    avr_info_to_howto_rela
996 #define elf_info_to_howto_rel                NULL
997 #define elf_backend_relocate_section         elf32_avr_relocate_section
998 #define elf_backend_gc_mark_hook             elf32_avr_gc_mark_hook
999 #define elf_backend_gc_sweep_hook            elf32_avr_gc_sweep_hook
1000 #define elf_backend_check_relocs             elf32_avr_check_relocs
1001 #define elf_backend_can_gc_sections          1
1002 #define elf_backend_rela_normal              1
1003 #define elf_backend_final_write_processing \
1004                                         bfd_elf_avr_final_write_processing
1005 #define elf_backend_object_p            elf32_avr_object_p
1006
1007 #include "elf32-target.h"