OSDN Git Service

Update the FSF address in the copyright/GPL notice
[pf3gnuchains/pf3gnuchains4x.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., 59 Temple Place - Suite 330, 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         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
527     }
528
529   return TRUE;
530 }
531
532 /* Perform a single relocation.  By default we use the standard BFD
533    routines, but a few relocs, we have to do them ourselves.  */
534
535 static bfd_reloc_status_type
536 avr_final_link_relocate (howto, input_bfd, input_section,
537                          contents, rel, relocation)
538      reloc_howto_type *  howto;
539      bfd *               input_bfd;
540      asection *          input_section;
541      bfd_byte *          contents;
542      Elf_Internal_Rela * rel;
543      bfd_vma             relocation;
544 {
545   bfd_reloc_status_type r = bfd_reloc_ok;
546   bfd_vma               x;
547   bfd_signed_vma        srel;
548
549   switch (howto->type)
550     {
551     case R_AVR_7_PCREL:
552       contents += rel->r_offset;
553       srel = (bfd_signed_vma) relocation;
554       srel += rel->r_addend;
555       srel -= rel->r_offset;
556       srel -= 2;        /* Branch instructions add 2 to the PC...  */
557       srel -= (input_section->output_section->vma +
558                input_section->output_offset);
559
560       if (srel & 1)
561         return bfd_reloc_outofrange;
562       if (srel > ((1 << 7) - 1) || (srel < - (1 << 7)))
563         return bfd_reloc_overflow;
564       x = bfd_get_16 (input_bfd, contents);
565       x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);
566       bfd_put_16 (input_bfd, x, contents);
567       break;
568
569     case R_AVR_13_PCREL:
570       contents   += rel->r_offset;
571       srel = (bfd_signed_vma) relocation;
572       srel += rel->r_addend;
573       srel -= rel->r_offset;
574       srel -= 2;        /* Branch instructions add 2 to the PC...  */
575       srel -= (input_section->output_section->vma +
576                input_section->output_offset);
577
578       if (srel & 1)
579         return bfd_reloc_outofrange;
580
581       /* AVR addresses commands as words.  */
582       srel >>= 1;
583
584       /* Check for overflow.  */
585       if (srel < -2048 || srel > 2047)
586         {
587           /* Apply WRAPAROUND if possible.  */
588           switch (bfd_get_mach (input_bfd))
589             {
590             case bfd_mach_avr2:
591             case bfd_mach_avr4:
592               break;
593
594             default:
595               return bfd_reloc_overflow;
596             }
597         }
598
599       x = bfd_get_16 (input_bfd, contents);
600       x = (x & 0xf000) | (srel & 0xfff);
601       bfd_put_16 (input_bfd, x, contents);
602       break;
603
604     case R_AVR_LO8_LDI:
605       contents += rel->r_offset;
606       srel = (bfd_signed_vma) relocation + rel->r_addend;
607       x = bfd_get_16 (input_bfd, contents);
608       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
609       bfd_put_16 (input_bfd, x, contents);
610       break;
611
612     case R_AVR_LDI:
613       contents += rel->r_offset;
614       srel = (bfd_signed_vma) relocation + rel->r_addend;
615       if ((srel & 0xffff) > 255)
616         /* Remove offset for data/eeprom section.  */
617         return bfd_reloc_overflow;
618       x = bfd_get_16 (input_bfd, contents);
619       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
620       bfd_put_16 (input_bfd, x, contents);
621       break;
622
623     case R_AVR_6:
624       contents += rel->r_offset;
625       srel = (bfd_signed_vma) relocation + rel->r_addend;
626       if (((srel & 0xffff) > 63) || (srel < 0))
627         /* Remove offset for data/eeprom section.  */
628         return bfd_reloc_overflow;
629       x = bfd_get_16 (input_bfd, contents);
630       x = (x & 0xd3f8) | ((srel & 7) | ((srel & (3 << 3)) << 7) | ((srel & (1 << 5)) << 8));
631       bfd_put_16 (input_bfd, x, contents);
632       break;
633
634     case R_AVR_6_ADIW:
635       contents += rel->r_offset;
636       srel = (bfd_signed_vma) relocation + rel->r_addend;
637       if (((srel & 0xffff) > 63) || (srel < 0))
638         /* Remove offset for data/eeprom section.  */
639         return bfd_reloc_overflow;
640       x = bfd_get_16 (input_bfd, contents);
641       x = (x & 0xff30) | (srel & 0xf) | ((srel & 0x30) << 2); 
642       bfd_put_16 (input_bfd, x, contents);
643       break;
644
645     case R_AVR_HI8_LDI:
646       contents += rel->r_offset;
647       srel = (bfd_signed_vma) relocation + rel->r_addend;
648       srel = (srel >> 8) & 0xff;
649       x = bfd_get_16 (input_bfd, contents);
650       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
651       bfd_put_16 (input_bfd, x, contents);
652       break;
653
654     case R_AVR_HH8_LDI:
655       contents += rel->r_offset;
656       srel = (bfd_signed_vma) relocation + rel->r_addend;
657       srel = (srel >> 16) & 0xff;
658       x = bfd_get_16 (input_bfd, contents);
659       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
660       bfd_put_16 (input_bfd, x, contents);
661       break;
662
663     case R_AVR_LO8_LDI_NEG:
664       contents += rel->r_offset;
665       srel = (bfd_signed_vma) relocation + rel->r_addend;
666       srel = -srel;
667       x = bfd_get_16 (input_bfd, contents);
668       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
669       bfd_put_16 (input_bfd, x, contents);
670       break;
671
672     case R_AVR_HI8_LDI_NEG:
673       contents += rel->r_offset;
674       srel = (bfd_signed_vma) relocation + rel->r_addend;
675       srel = -srel;
676       srel = (srel >> 8) & 0xff;
677       x = bfd_get_16 (input_bfd, contents);
678       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
679       bfd_put_16 (input_bfd, x, contents);
680       break;
681
682     case R_AVR_HH8_LDI_NEG:
683       contents += rel->r_offset;
684       srel = (bfd_signed_vma) relocation + rel->r_addend;
685       srel = -srel;
686       srel = (srel >> 16) & 0xff;
687       x = bfd_get_16 (input_bfd, contents);
688       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
689       bfd_put_16 (input_bfd, x, contents);
690       break;
691
692     case R_AVR_LO8_LDI_PM:
693       contents += rel->r_offset;
694       srel = (bfd_signed_vma) relocation + rel->r_addend;
695       if (srel & 1)
696         return bfd_reloc_outofrange;
697       srel = srel >> 1;
698       x = bfd_get_16 (input_bfd, contents);
699       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
700       bfd_put_16 (input_bfd, x, contents);
701       break;
702
703     case R_AVR_HI8_LDI_PM:
704       contents += rel->r_offset;
705       srel = (bfd_signed_vma) relocation + rel->r_addend;
706       if (srel & 1)
707         return bfd_reloc_outofrange;
708       srel = srel >> 1;
709       srel = (srel >> 8) & 0xff;
710       x = bfd_get_16 (input_bfd, contents);
711       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
712       bfd_put_16 (input_bfd, x, contents);
713       break;
714
715     case R_AVR_HH8_LDI_PM:
716       contents += rel->r_offset;
717       srel = (bfd_signed_vma) relocation + rel->r_addend;
718       if (srel & 1)
719         return bfd_reloc_outofrange;
720       srel = srel >> 1;
721       srel = (srel >> 16) & 0xff;
722       x = bfd_get_16 (input_bfd, contents);
723       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
724       bfd_put_16 (input_bfd, x, contents);
725       break;
726
727     case R_AVR_LO8_LDI_PM_NEG:
728       contents += rel->r_offset;
729       srel = (bfd_signed_vma) relocation + rel->r_addend;
730       srel = -srel;
731       if (srel & 1)
732         return bfd_reloc_outofrange;
733       srel = srel >> 1;
734       x = bfd_get_16 (input_bfd, contents);
735       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
736       bfd_put_16 (input_bfd, x, contents);
737       break;
738
739     case R_AVR_HI8_LDI_PM_NEG:
740       contents += rel->r_offset;
741       srel = (bfd_signed_vma) relocation + rel->r_addend;
742       srel = -srel;
743       if (srel & 1)
744         return bfd_reloc_outofrange;
745       srel = srel >> 1;
746       srel = (srel >> 8) & 0xff;
747       x = bfd_get_16 (input_bfd, contents);
748       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
749       bfd_put_16 (input_bfd, x, contents);
750       break;
751
752     case R_AVR_HH8_LDI_PM_NEG:
753       contents += rel->r_offset;
754       srel = (bfd_signed_vma) relocation + rel->r_addend;
755       srel = -srel;
756       if (srel & 1)
757         return bfd_reloc_outofrange;
758       srel = srel >> 1;
759       srel = (srel >> 16) & 0xff;
760       x = bfd_get_16 (input_bfd, contents);
761       x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
762       bfd_put_16 (input_bfd, x, contents);
763       break;
764
765     case R_AVR_CALL:
766       contents += rel->r_offset;
767       srel = (bfd_signed_vma) relocation + rel->r_addend;
768       if (srel & 1)
769         return bfd_reloc_outofrange;
770       srel = srel >> 1;
771       x = bfd_get_16 (input_bfd, contents);
772       x |= ((srel & 0x10000) | ((srel << 3) & 0x1f00000)) >> 16;
773       bfd_put_16 (input_bfd, x, contents);
774       bfd_put_16 (input_bfd, (bfd_vma) srel & 0xffff, contents+2);
775       break;
776
777     default:
778       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
779                                     contents, rel->r_offset,
780                                     relocation, rel->r_addend);
781     }
782
783   return r;
784 }
785
786 /* Relocate an AVR ELF section.  */
787 static bfd_boolean
788 elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section,
789                             contents, relocs, local_syms, local_sections)
790      bfd *output_bfd ATTRIBUTE_UNUSED;
791      struct bfd_link_info *info;
792      bfd *input_bfd;
793      asection *input_section;
794      bfd_byte *contents;
795      Elf_Internal_Rela *relocs;
796      Elf_Internal_Sym *local_syms;
797      asection **local_sections;
798 {
799   Elf_Internal_Shdr *           symtab_hdr;
800   struct elf_link_hash_entry ** sym_hashes;
801   Elf_Internal_Rela *           rel;
802   Elf_Internal_Rela *           relend;
803
804   if (info->relocatable)
805     return TRUE;
806
807   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
808   sym_hashes = elf_sym_hashes (input_bfd);
809   relend     = relocs + input_section->reloc_count;
810
811   for (rel = relocs; rel < relend; rel ++)
812     {
813       reloc_howto_type *           howto;
814       unsigned long                r_symndx;
815       Elf_Internal_Sym *           sym;
816       asection *                   sec;
817       struct elf_link_hash_entry * h;
818       bfd_vma                      relocation;
819       bfd_reloc_status_type        r;
820       const char *                 name;
821       int                          r_type;
822
823       /* This is a final link.  */
824       r_type = ELF32_R_TYPE (rel->r_info);
825       r_symndx = ELF32_R_SYM (rel->r_info);
826       howto  = elf_avr_howto_table + ELF32_R_TYPE (rel->r_info);
827       h      = NULL;
828       sym    = NULL;
829       sec    = NULL;
830
831       if (r_symndx < symtab_hdr->sh_info)
832         {
833           sym = local_syms + r_symndx;
834           sec = local_sections [r_symndx];
835           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
836
837           name = bfd_elf_string_from_elf_section
838             (input_bfd, symtab_hdr->sh_link, sym->st_name);
839           name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
840         }
841       else
842         {
843           bfd_boolean unresolved_reloc, warned;
844
845           RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
846                                    r_symndx, symtab_hdr, sym_hashes,
847                                    h, sec, relocation,
848                                    unresolved_reloc, warned);
849
850           name = h->root.root.string;
851         }
852
853       r = avr_final_link_relocate (howto, input_bfd, input_section,
854                                    contents, rel, relocation);
855
856       if (r != bfd_reloc_ok)
857         {
858           const char * msg = (const char *) NULL;
859
860           switch (r)
861             {
862             case bfd_reloc_overflow:
863               r = info->callbacks->reloc_overflow
864                 (info, (h ? &h->root : NULL),
865                  name, howto->name, (bfd_vma) 0,
866                  input_bfd, input_section, rel->r_offset);
867               break;
868
869             case bfd_reloc_undefined:
870               r = info->callbacks->undefined_symbol
871                 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
872               break;
873
874             case bfd_reloc_outofrange:
875               msg = _("internal error: out of range error");
876               break;
877
878             case bfd_reloc_notsupported:
879               msg = _("internal error: unsupported relocation error");
880               break;
881
882             case bfd_reloc_dangerous:
883               msg = _("internal error: dangerous relocation");
884               break;
885
886             default:
887               msg = _("internal error: unknown error");
888               break;
889             }
890
891           if (msg)
892             r = info->callbacks->warning
893               (info, msg, name, input_bfd, input_section, rel->r_offset);
894
895           if (! r)
896             return FALSE;
897         }
898     }
899
900   return TRUE;
901 }
902
903 /* The final processing done just before writing out a AVR ELF object
904    file.  This gets the AVR architecture right based on the machine
905    number.  */
906
907 static void
908 bfd_elf_avr_final_write_processing (abfd, linker)
909      bfd *abfd;
910      bfd_boolean linker ATTRIBUTE_UNUSED;
911 {
912   unsigned long val;
913
914   switch (bfd_get_mach (abfd))
915     {
916     default:
917     case bfd_mach_avr2:
918       val = E_AVR_MACH_AVR2;
919       break;
920
921     case bfd_mach_avr1:
922       val = E_AVR_MACH_AVR1;
923       break;
924
925     case bfd_mach_avr3:
926       val = E_AVR_MACH_AVR3;
927       break;
928
929     case bfd_mach_avr4:
930       val = E_AVR_MACH_AVR4;
931       break;
932
933     case bfd_mach_avr5:
934       val = E_AVR_MACH_AVR5;
935       break;
936     }
937
938   elf_elfheader (abfd)->e_machine = EM_AVR;
939   elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
940   elf_elfheader (abfd)->e_flags |= val;
941 }
942
943 /* Set the right machine number.  */
944
945 static bfd_boolean
946 elf32_avr_object_p (abfd)
947      bfd *abfd;
948 {
949   unsigned int e_set = bfd_mach_avr2;
950   if (elf_elfheader (abfd)->e_machine == EM_AVR
951       || elf_elfheader (abfd)->e_machine == EM_AVR_OLD)
952     {
953       int e_mach = elf_elfheader (abfd)->e_flags & EF_AVR_MACH;
954       switch (e_mach)
955         {
956         default:
957         case E_AVR_MACH_AVR2:
958           e_set = bfd_mach_avr2;
959           break;
960
961         case E_AVR_MACH_AVR1:
962           e_set = bfd_mach_avr1;
963           break;
964
965         case E_AVR_MACH_AVR3:
966           e_set = bfd_mach_avr3;
967           break;
968
969         case E_AVR_MACH_AVR4:
970           e_set = bfd_mach_avr4;
971           break;
972
973         case E_AVR_MACH_AVR5:
974           e_set = bfd_mach_avr5;
975           break;
976         }
977     }
978   return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
979                                     e_set);
980 }
981
982 #define ELF_ARCH                bfd_arch_avr
983 #define ELF_MACHINE_CODE        EM_AVR
984 #define ELF_MACHINE_ALT1        EM_AVR_OLD
985 #define ELF_MAXPAGESIZE         1
986
987 #define TARGET_LITTLE_SYM       bfd_elf32_avr_vec
988 #define TARGET_LITTLE_NAME      "elf32-avr"
989
990 #define elf_info_to_howto                    avr_info_to_howto_rela
991 #define elf_info_to_howto_rel                NULL
992 #define elf_backend_relocate_section         elf32_avr_relocate_section
993 #define elf_backend_gc_mark_hook             elf32_avr_gc_mark_hook
994 #define elf_backend_gc_sweep_hook            elf32_avr_gc_sweep_hook
995 #define elf_backend_check_relocs             elf32_avr_check_relocs
996 #define elf_backend_can_gc_sections          1
997 #define elf_backend_rela_normal              1
998 #define elf_backend_final_write_processing \
999                                         bfd_elf_avr_final_write_processing
1000 #define elf_backend_object_p            elf32_avr_object_p
1001
1002 #include "elf32-target.h"