OSDN Git Service

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