]> git.pld-linux.org Git - packages/crossavr-binutils.git/blob - crossavr-binutils-atmega256x.patch
- outdated
[packages/crossavr-binutils.git] / crossavr-binutils-atmega256x.patch
1 diff -Nur bfd/archures.c bfd/archures.c
2 --- bfd/archures.c      2006-03-06 14:42:03.000000000 +0100
3 +++ bfd/archures.c      2006-08-28 20:01:10.714097550 +0200
4 @@ -334,6 +334,7 @@
5  .#define bfd_mach_avr3         3
6  .#define bfd_mach_avr4         4
7  .#define bfd_mach_avr5         5
8 +.#define bfd_mach_avr6         6
9  .  bfd_arch_bfin,        {* ADI Blackfin *}
10  .#define bfd_mach_bfin          1
11  .  bfd_arch_cr16c,       {* National Semiconductor CompactRISC. *}
12 diff -Nur bfd/bfd-in2.h bfd/bfd-in2.h
13 --- bfd/bfd-in2.h       2006-03-26 01:38:42.000000000 +0100
14 +++ bfd/bfd-in2.h       2006-08-28 20:01:10.743095447 +0200
15 @@ -1931,6 +1931,7 @@
16  #define bfd_mach_avr3          3
17  #define bfd_mach_avr4          4
18  #define bfd_mach_avr5          5
19 +#define bfd_mach_avr6          6
20    bfd_arch_bfin,        /* ADI Blackfin */
21  #define bfd_mach_bfin          1
22    bfd_arch_cr16c,       /* National Semiconductor CompactRISC. */
23 @@ -3539,10 +3540,22 @@
24  command address) into 8 bit immediate value of LDI insn.  */
25    BFD_RELOC_AVR_LO8_LDI_PM,
26  
27 +/* This is a 16 bit reloc for the AVR that stores 8 bit value
28 +(command address) into 8 bit immediate value of LDI insn. If the address
29 +is beyond the 128k boundary, the linker inserts a jump stub for this reloc
30 +in the lower 128k.  */
31 +  BFD_RELOC_AVR_LO8_LDI_GS,
32 +
33  /* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
34  of command address) into 8 bit immediate value of LDI insn.  */
35    BFD_RELOC_AVR_HI8_LDI_PM,
36  
37 +/* This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
38 +of command address) into 8 bit immediate value of LDI insn.  If the address
39 +is beyond the 128k boundary, the linker inserts a jump stub for this reloc
40 +below 128k.  */
41 +  BFD_RELOC_AVR_HI8_LDI_GS,
42 +
43  /* This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
44  of command address) into 8 bit immediate value of LDI insn.  */
45    BFD_RELOC_AVR_HH8_LDI_PM,
46 diff -Nur bfd/cpu-avr.c bfd/cpu-avr.c
47 --- bfd/cpu-avr.c       2006-03-03 16:54:23.000000000 +0100
48 +++ bfd/cpu-avr.c       2006-08-28 20:01:10.771093417 +0200
49 @@ -82,7 +82,10 @@
50    N (16, bfd_mach_avr4, "avr:4", FALSE, & arch_info_struct[4]),
51  
52    /* ATmega161, ATmega163, ATmega32, AT94K.  */
53 -  N (22, bfd_mach_avr5, "avr:5", FALSE, NULL)
54 +  N (22, bfd_mach_avr5, "avr:5", FALSE, & arch_info_struct[5]),
55 +
56 +  /* ATmega256x.  */
57 +  N (22, bfd_mach_avr6, "avr:6", FALSE, NULL)
58  };
59  
60  const bfd_arch_info_type bfd_avr_arch =
61 diff -Nur bfd/elf32-avr.c bfd/elf32-avr.c
62 --- bfd/elf32-avr.c     2006-03-03 16:54:23.000000000 +0100
63 +++ bfd/elf32-avr.c     2006-08-28 20:18:20.796399347 +0200
64 @@ -25,6 +25,92 @@
65  #include "libbfd.h"
66  #include "elf-bfd.h"
67  #include "elf/avr.h"
68 +#include "elf32-avr.h"
69 +
70 +/* Enable debugging printout at stdout with this variable.  */
71 +static bfd_boolean debug_relax = FALSE;
72 +
73 +/* Enable debugging printout at stdout with this variable.  */
74 +static bfd_boolean debug_stubs = FALSE;
75 +
76 +/* Hash table initialization and handling.  Code is taken from the hppa port
77 +   and adapted to the needs of AVR.  */
78 +
79 +/* We use two hash tables to hold information for linking avr objects.
80 +
81 +   The first is the elf32_avr_link_hash_tablse which is derived from the
82 +   stanard ELF linker hash table.  We use this as a place to attach the other
83 +   hash table and some static information.
84 +
85 +   The second is the stub hash table which is derived from the base BFD
86 +   hash table.  The stub hash table holds the information on the linker
87 +   stubs.  */
88 +
89 +struct elf32_avr_stub_hash_entry
90 +{
91 +  /* Base hash table entry structure.  */
92 +  struct bfd_hash_entry bh_root;
93 +
94 +  /* Offset within stub_sec of the beginning of this stub.  */
95 +  bfd_vma stub_offset;
96 +
97 +  /* Given the symbol's value and its section we can determine its final
98 +     value when building the stubs (so the stub knows where to jump).  */
99 +  bfd_vma target_value;
100 +
101 +  /* This way we could mark stubs to be no longer necessary.  */
102 +  bfd_boolean is_actually_needed;
103 +};
104 +
105 +struct elf32_avr_link_hash_table
106 +{
107 +  /* The main hash table.  */
108 +  struct elf_link_hash_table etab;
109 +
110 +  /* The stub hash table.  */
111 +  struct bfd_hash_table bstab;
112 +
113 +  bfd_boolean no_stubs;
114 +
115 +  /* Linker stub bfd.  */
116 +  bfd *stub_bfd;
117 +
118 +  /* The stub section.  */
119 +  asection *stub_sec;
120 +
121 +  /* Usually 0, unless we are generating code for a bootloader.  Will
122 +     be initialized by elf32_avr_size_stubs to the vma offset of the
123 +     output section associated with the stub section.  */
124 +  bfd_vma vector_base;
125 +
126 +  /* Assorted information used by elf32_avr_size_stubs.  */
127 +  unsigned int        bfd_count;
128 +  int                 top_index;
129 +  asection **         input_list;
130 +  Elf_Internal_Sym ** all_local_syms;
131 +
132 +  /* Tables for mapping vma beyond the 128k boundary to the address of the
133 +     corresponding stub.  (AMT)
134 +     "amt_max_entry_cnt" reflects the number of entries that memory is allocated
135 +     for in the "amt_stub_offsets" and "amt_destination_addr" arrays.
136 +     "amt_entry_cnt" informs how many of these entries actually contain
137 +     useful data.  */
138 +  unsigned int amt_entry_cnt;
139 +  unsigned int amt_max_entry_cnt;
140 +  bfd_vma *    amt_stub_offsets;
141 +  bfd_vma *    amt_destination_addr;
142 +};
143 +
144 +/* Various hash macros and functions.  */
145 +#define avr_link_hash_table(p) \
146 +  ((struct elf32_avr_link_hash_table *) ((p)->hash))
147 +
148 +#define avr_stub_hash_entry(ent) \
149 +  ((struct elf32_avr_stub_hash_entry *)(ent))
150 +
151 +#define avr_stub_hash_lookup(table, string, create, copy) \
152 +  ((struct elf32_avr_stub_hash_entry *) \
153 +   bfd_hash_lookup ((table), (string), (create), (copy)))
154  
155  static reloc_howto_type elf_avr_howto_table[] =
156  {
157 @@ -101,7 +187,8 @@
158          0xffff,                /* dst_mask */
159          FALSE),                /* pcrel_offset */
160  
161 -  /* A 16 bit absolute relocation for command address.  */
162 +  /* A 16 bit absolute relocation for command address
163 +     Will be changed when linker stubs are needed.  */
164    HOWTO (R_AVR_16_PM,          /* type */
165          1,                     /* rightshift */
166          1,                     /* size (0 = byte, 1 = short, 2 = long) */
167 @@ -207,7 +294,7 @@
168          0xffff,                /* dst_mask */
169          FALSE),                /* pcrel_offset */
170    /* A low 8 bit absolute relocation of 24 bit program memory address.
171 -     For LDI command.  */
172 +     For LDI command.  Will not be changed when linker stubs are needed. */
173    HOWTO (R_AVR_LO8_LDI_PM,     /* type */
174          1,                     /* rightshift */
175          1,                     /* size (0 = byte, 1 = short, 2 = long) */
176 @@ -221,8 +308,8 @@
177          0xffff,                /* src_mask */
178          0xffff,                /* dst_mask */
179          FALSE),                /* pcrel_offset */
180 -  /* A high 8 bit absolute relocation of 16 bit program memory address.
181 -     For LDI command.  */
182 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
183 +     For LDI command.  Will not be changed when linker stubs are needed. */
184    HOWTO (R_AVR_HI8_LDI_PM,     /* type */
185          9,                     /* rightshift */
186          1,                     /* size (0 = byte, 1 = short, 2 = long) */
187 @@ -236,8 +323,8 @@
188          0xffff,                /* src_mask */
189          0xffff,                /* dst_mask */
190          FALSE),                /* pcrel_offset */
191 -  /* A high 8 bit absolute relocation of 24 bit program memory address.
192 -     For LDI command.  */
193 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
194 +     For LDI command.  Will not be changed when linker stubs are needed. */
195    HOWTO (R_AVR_HH8_LDI_PM,     /* type */
196          17,                    /* rightshift */
197          1,                     /* size (0 = byte, 1 = short, 2 = long) */
198 @@ -251,8 +338,8 @@
199          0xffff,                /* src_mask */
200          0xffff,                /* dst_mask */
201          FALSE),                /* pcrel_offset */
202 -  /* A low 8 bit absolute relocation of a negative 24 bit
203 -     program memory address.  For LDI command.  */
204 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
205 +     For LDI command.  Will not be changed when linker stubs are needed. */
206    HOWTO (R_AVR_LO8_LDI_PM_NEG, /* type */
207          1,                     /* rightshift */
208          1,                     /* size (0 = byte, 1 = short, 2 = long) */
209 @@ -266,8 +353,8 @@
210          0xffff,                /* src_mask */
211          0xffff,                /* dst_mask */
212          FALSE),                /* pcrel_offset */
213 -  /* A high 8 bit absolute relocation of a negative 16 bit
214 -     program memory address.  For LDI command.  */
215 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
216 +     For LDI command.  Will not be changed when linker stubs are needed. */
217    HOWTO (R_AVR_HI8_LDI_PM_NEG, /* type */
218          9,                     /* rightshift */
219          1,                     /* size (0 = byte, 1 = short, 2 = long) */
220 @@ -281,8 +368,8 @@
221          0xffff,                /* src_mask */
222          0xffff,                /* dst_mask */
223          FALSE),                /* pcrel_offset */
224 -  /* A high 8 bit absolute relocation of a negative 24 bit
225 -     program memory address.  For LDI command.  */
226 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
227 +     For LDI command.  Will not be changed when linker stubs are needed. */
228    HOWTO (R_AVR_HH8_LDI_PM_NEG, /* type */
229          17,                    /* rightshift */
230          1,                     /* size (0 = byte, 1 = short, 2 = long) */
231 @@ -382,7 +469,37 @@
232          FALSE,                 /* partial_inplace */
233          0xffff,                /* src_mask */
234          0xffff,                /* dst_mask */
235 -        FALSE)                 /* pcrel_offset */
236 +        FALSE),                /* pcrel_offset */
237 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
238 +     For LDI command.  Will be changed when linker stubs are needed. */
239 +  HOWTO (R_AVR_LO8_LDI_GS,      /* type */
240 +         1,                     /* rightshift */
241 +         1,                     /* size (0 = byte, 1 = short, 2 = long) */
242 +         8,                     /* bitsize */
243 +         FALSE,                 /* pc_relative */
244 +         0,                     /* bitpos */
245 +         complain_overflow_dont, /* complain_on_overflow */
246 +         bfd_elf_generic_reloc, /* special_function */
247 +         "R_AVR_LO8_LDI_GS",    /* name */
248 +         FALSE,                 /* partial_inplace */
249 +         0xffff,                /* src_mask */
250 +         0xffff,                /* dst_mask */
251 +         FALSE),                /* pcrel_offset */
252 +  /* A low 8 bit absolute relocation of 24 bit program memory address.
253 +     For LDI command.  Will be changed when linker stubs are needed. */
254 +  HOWTO (R_AVR_HI8_LDI_GS,      /* type */
255 +         9,                     /* rightshift */
256 +         1,                     /* size (0 = byte, 1 = short, 2 = long) */
257 +         8,                     /* bitsize */
258 +         FALSE,                 /* pc_relative */
259 +         0,                     /* bitpos */
260 +         complain_overflow_dont, /* complain_on_overflow */
261 +         bfd_elf_generic_reloc, /* special_function */
262 +         "R_AVR_HI8_LDI_GS",    /* name */
263 +         FALSE,                 /* partial_inplace */
264 +         0xffff,                /* src_mask */
265 +         0xffff,                /* dst_mask */
266 +         FALSE)                 /* pcrel_offset */
267  };
268  
269  /* Map BFD reloc types to AVR ELF reloc types.  */
270 @@ -393,7 +510,7 @@
271    unsigned int elf_reloc_val;
272  };
273  
274 - static const struct avr_reloc_map avr_reloc_map[] =
275 +static const struct avr_reloc_map avr_reloc_map[] =
276  {
277    { BFD_RELOC_NONE,                 R_AVR_NONE },
278    { BFD_RELOC_32,                   R_AVR_32 },
279 @@ -410,7 +527,9 @@
280    { BFD_RELOC_AVR_HH8_LDI_NEG,      R_AVR_HH8_LDI_NEG },
281    { BFD_RELOC_AVR_MS8_LDI_NEG,      R_AVR_MS8_LDI_NEG },
282    { BFD_RELOC_AVR_LO8_LDI_PM,       R_AVR_LO8_LDI_PM },
283 +  { BFD_RELOC_AVR_LO8_LDI_GS,       R_AVR_LO8_LDI_GS },
284    { BFD_RELOC_AVR_HI8_LDI_PM,       R_AVR_HI8_LDI_PM },
285 +  { BFD_RELOC_AVR_HI8_LDI_GS,       R_AVR_HI8_LDI_GS },
286    { BFD_RELOC_AVR_HH8_LDI_PM,       R_AVR_HH8_LDI_PM },
287    { BFD_RELOC_AVR_LO8_LDI_PM_NEG,   R_AVR_LO8_LDI_PM_NEG },
288    { BFD_RELOC_AVR_HI8_LDI_PM_NEG,   R_AVR_HI8_LDI_PM_NEG },
289 @@ -429,8 +548,101 @@
290     that we will never suggest a wrap-around jump during relaxation.
291     The logic of the source code later on assumes that in
292     avr_pc_wrap_around one single bit is set.  */
293 +static bfd_vma avr_pc_wrap_around = 0x10000000;
294 +
295 +/* If this variable holds a value different from zero, the linker relaxation
296 +   machine will try to optimize call/ret sequences by a single jump
297 +   instruction. This option could be switched off by a linker switch.  */
298 +static int avr_replace_call_ret_sequences = 1;
299 +\f
300 +/* Initialize an entry in the stub hash table.  */
301 +
302 +static struct bfd_hash_entry *
303 +stub_hash_newfunc (struct bfd_hash_entry *entry,
304 +                   struct bfd_hash_table *table,
305 +                   const char *string)
306 +{
307 +  /* Allocate the structure if it has not already been allocated by a
308 +     subclass.  */
309 +  if (entry == NULL)
310 +    {
311 +      entry = bfd_hash_allocate (table,
312 +                                 sizeof (struct elf32_avr_stub_hash_entry));
313 +      if (entry == NULL)
314 +        return entry;
315 +    }
316 +
317 +  /* Call the allocation method of the superclass.  */
318 +  entry = bfd_hash_newfunc (entry, table, string);
319 +  if (entry != NULL)
320 +    {
321 +      struct elf32_avr_stub_hash_entry *hsh;
322  
323 -unsigned int avr_pc_wrap_around = 0x10000000;
324 +      /* Initialize the local fields.  */
325 +      hsh = avr_stub_hash_entry (entry);
326 +      hsh->stub_offset = 0;
327 +      hsh->target_value = 0;
328 +    }
329 +
330 +  return entry;
331 +}
332 +
333 +/* Create the derived linker hash table.  The AVR ELF port uses the derived
334 +   hash table to keep information specific to the AVR ELF linker (without
335 +   using static variables).  */
336 +
337 +static struct bfd_link_hash_table *
338 +elf32_avr_link_hash_table_create (bfd *abfd)
339 +{
340 +  struct elf32_avr_link_hash_table *htab;
341 +  bfd_size_type amt = sizeof (*htab);
342 +
343 +  htab = bfd_malloc (amt);
344 +  if (htab == NULL)
345 +    return NULL;
346 +
347 +  if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd,
348 +                                      _bfd_elf_link_hash_newfunc,
349 +                                      sizeof (struct elf_link_hash_entry)))
350 +    {
351 +      free (htab);
352 +      return NULL;
353 +    }
354 +
355 +  /* Init the stub hash table too.  */
356 +  if (!bfd_hash_table_init (&htab->bstab, stub_hash_newfunc,
357 +                            sizeof (struct elf32_avr_stub_hash_entry)))
358 +    return NULL;
359 +
360 +  htab->stub_bfd = NULL;
361 +  htab->stub_sec = NULL;
362 +
363 +  /* Initialize the address mapping table.  */
364 +  htab->amt_stub_offsets = NULL;
365 +  htab->amt_destination_addr = NULL;
366 +  htab->amt_entry_cnt = 0;
367 +  htab->amt_max_entry_cnt = 0;
368 +
369 +  return &htab->etab.root;
370 +}
371 +
372 +/* Free the derived linker hash table.  */
373 +
374 +static void
375 +elf32_avr_link_hash_table_free (struct bfd_link_hash_table *btab)
376 +{
377 +  struct elf32_avr_link_hash_table *htab
378 +    = (struct elf32_avr_link_hash_table *) btab;
379 +
380 +  /* Free the address mapping table.  */
381 +  if (htab->amt_stub_offsets != NULL)
382 +    free (htab->amt_stub_offsets);
383 +  if (htab->amt_destination_addr != NULL)
384 +    free (htab->amt_destination_addr);
385 +
386 +  bfd_hash_table_free (&htab->bstab);
387 +  _bfd_generic_link_hash_table_free (btab);
388 +}
389  
390  /* Calculates the effective distance of a pc relative jump/call.  */
391  static int
392 @@ -564,20 +776,57 @@
393    return TRUE;
394  }
395  
396 +static bfd_boolean
397 +avr_stub_is_required_for_16_bit_reloc (bfd_vma relocation)
398 +{
399 +  return (relocation >= 0x020000);
400 +}
401 +
402 +/* Returns the address of the corresponding stub if there is one.
403 +   Returns otherwise an address above 0x020000.  This function
404 +   could also be used, if there is no knowledge on the section where
405 +   the destination is found.  */
406 +
407 +static bfd_vma
408 +avr_get_stub_addr (bfd_vma srel,
409 +                   struct elf32_avr_link_hash_table *htab)
410 +{
411 +  unsigned int index;
412 +  bfd_vma stub_sec_addr =
413 +              (htab->stub_sec->output_section->vma +
414 +              htab->stub_sec->output_offset);
415 +
416 +  for (index = 0; index < htab->amt_max_entry_cnt; index ++)
417 +    if (htab->amt_destination_addr[index] == srel)
418 +      return htab->amt_stub_offsets[index] + stub_sec_addr;
419 +
420 +  /* Return an address that could not be reached by 16 bit relocs.  */
421 +  return 0x020000;
422 +}
423 +
424  /* Perform a single relocation.  By default we use the standard BFD
425     routines, but a few relocs, we have to do them ourselves.  */
426  
427  static bfd_reloc_status_type
428 -avr_final_link_relocate (reloc_howto_type *  howto,
429 -                        bfd *               input_bfd,
430 -                        asection *          input_section,
431 -                        bfd_byte *          contents,
432 -                        Elf_Internal_Rela * rel,
433 -                        bfd_vma             relocation)
434 +avr_final_link_relocate (reloc_howto_type *                 howto,
435 +                        bfd *                              input_bfd,
436 +                        asection *                         input_section,
437 +                        bfd_byte *                         contents,
438 +                        Elf_Internal_Rela *                rel,
439 +                         bfd_vma                            relocation,
440 +                         struct elf32_avr_link_hash_table * htab)
441  {
442    bfd_reloc_status_type r = bfd_reloc_ok;
443    bfd_vma               x;
444    bfd_signed_vma       srel;
445 +  bfd_signed_vma       reloc_addr;
446 +  bfd_boolean           use_stubs = FALSE;
447 +  /* Usually is 0, unless we are generating code for a bootloader.  */
448 +  bfd_signed_vma        base_addr = htab->vector_base;
449 +
450 +  /* Absolute addr of the reloc in the final excecutable.  */
451 +  reloc_addr = rel->r_offset + input_section->output_section->vma
452 +              + input_section->output_offset;
453  
454    switch (howto->type)
455      {
456 @@ -748,9 +997,31 @@
457        bfd_put_16 (input_bfd, x, contents);
458        break;
459  
460 +    case R_AVR_LO8_LDI_GS:
461 +      use_stubs = (!htab->no_stubs);
462 +      /* Fall through.  */
463      case R_AVR_LO8_LDI_PM:
464        contents += rel->r_offset;
465        srel = (bfd_signed_vma) relocation + rel->r_addend;
466 +
467 +      if (use_stubs
468 +          && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
469 +        {
470 +          bfd_vma old_srel = srel;
471 +
472 +          /* We need to use the address of the stub instead.  */
473 +          srel = avr_get_stub_addr (srel, htab);
474 +          if (debug_stubs)
475 +            printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
476 +                    "reloc at address 0x%x.\n",
477 +                    (unsigned int) srel,
478 +                    (unsigned int) old_srel,
479 +                    (unsigned int) reloc_addr);
480 +
481 +         if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
482 +           return bfd_reloc_outofrange;
483 +        }
484 +
485        if (srel & 1)
486         return bfd_reloc_outofrange;
487        srel = srel >> 1;
488 @@ -759,9 +1030,31 @@
489        bfd_put_16 (input_bfd, x, contents);
490        break;
491  
492 +    case R_AVR_HI8_LDI_GS:
493 +      use_stubs = (!htab->no_stubs);
494 +      /* Fall through.  */
495      case R_AVR_HI8_LDI_PM:
496        contents += rel->r_offset;
497        srel = (bfd_signed_vma) relocation + rel->r_addend;
498 +
499 +      if (use_stubs
500 +          && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
501 +        {
502 +          bfd_vma old_srel = srel;
503 +
504 +          /* We need to use the address of the stub instead.  */
505 +          srel = avr_get_stub_addr (srel, htab);
506 +          if (debug_stubs)
507 +            printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
508 +                    "reloc at address 0x%x.\n",
509 +                    (unsigned int) srel,
510 +                    (unsigned int) old_srel,
511 +                    (unsigned int) reloc_addr);
512 +
513 +         if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
514 +           return bfd_reloc_outofrange;
515 +        }
516 +
517        if (srel & 1)
518         return bfd_reloc_outofrange;
519        srel = srel >> 1;
520 @@ -833,6 +1126,35 @@
521        bfd_put_16 (input_bfd, (bfd_vma) srel & 0xffff, contents+2);
522        break;
523  
524 +    case R_AVR_16_PM:
525 +      use_stubs = (!htab->no_stubs);
526 +      contents += rel->r_offset;
527 +      srel = (bfd_signed_vma) relocation + rel->r_addend;
528 +
529 +      if (use_stubs
530 +          && avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
531 +        {
532 +          bfd_vma old_srel = srel;
533 +
534 +          /* We need to use the address of the stub instead.  */
535 +          srel = avr_get_stub_addr (srel,htab);
536 +          if (debug_stubs)
537 +            printf ("LD: Using jump stub (at 0x%x) with destination 0x%x for "
538 +                    "reloc at address 0x%x.\n",
539 +                    (unsigned int) srel,
540 +                    (unsigned int) old_srel,
541 +                    (unsigned int) reloc_addr);
542 +
543 +         if (avr_stub_is_required_for_16_bit_reloc (srel - base_addr))
544 +           return bfd_reloc_outofrange;
545 +        }
546 +
547 +      if (srel & 1)
548 +       return bfd_reloc_outofrange;
549 +      srel = srel >> 1;
550 +      bfd_put_16 (input_bfd, (bfd_vma) srel &0x00ffff, contents);
551 +      break;
552 +
553      default:
554        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
555                                     contents, rel->r_offset,
556 @@ -858,6 +1180,7 @@
557    struct elf_link_hash_entry ** sym_hashes;
558    Elf_Internal_Rela *           rel;
559    Elf_Internal_Rela *           relend;
560 +  struct elf32_avr_link_hash_table * htab = avr_link_hash_table (info);
561  
562    if (info->relocatable)
563      return TRUE;
564 @@ -909,7 +1232,7 @@
565         }
566  
567        r = avr_final_link_relocate (howto, input_bfd, input_section,
568 -                                  contents, rel, relocation);
569 +                                  contents, rel, relocation, htab);
570  
571        if (r != bfd_reloc_ok)
572         {
573 @@ -990,6 +1313,10 @@
574      case bfd_mach_avr5:
575        val = E_AVR_MACH_AVR5;
576        break;
577 +
578 +    case bfd_mach_avr6:
579 +      val = E_AVR_MACH_AVR6;
580 +      break;
581      }
582  
583    elf_elfheader (abfd)->e_machine = EM_AVR;
584 @@ -1032,6 +1359,10 @@
585         case E_AVR_MACH_AVR5:
586           e_set = bfd_mach_avr5;
587           break;
588 +
589 +       case E_AVR_MACH_AVR6:
590 +         e_set = bfd_mach_avr6;
591 +         break;
592         }
593      }
594    return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
595 @@ -1039,9 +1370,6 @@
596  }
597  
598  
599 -/* Enable debugging printout at stdout with a value of 1.  */
600 -#define DEBUG_RELAX 0
601 -
602  /* Delete some bytes from a section while changing the size of an instruction.
603     The parameter "addr" denotes the section-relative offset pointing just
604     behind the shrinked instruction. "addr+count" point at the first
605 @@ -1101,7 +1429,7 @@
606        if ((irel->r_offset > addr
607             && irel->r_offset < toaddr))
608          {
609 -          if (DEBUG_RELAX)
610 +          if (debug_relax)
611              printf ("Relocation at address 0x%x needs to be moved.\n"
612                      "Old section offset: 0x%x, New section offset: 0x%x \n",
613                      (unsigned int) old_reloc_address,
614 @@ -1148,7 +1476,7 @@
615                 symval += sym_sec->output_section->vma
616                           + sym_sec->output_offset;
617  
618 -               if (DEBUG_RELAX)
619 +               if (debug_relax)
620                  printf ("Checking if the relocation's "
621                          "addend needs corrections.\n"
622                          "Address of anchor symbol: 0x%x \n"
623 @@ -1163,7 +1491,7 @@
624                   {
625                     irel->r_addend -= count;
626  
627 -                   if (DEBUG_RELAX)
628 +                   if (debug_relax)
629                       printf ("Anchor symbol and relocation target bracket "
630                               "shrinked insn address.\n"
631                               "Need for new addend : 0x%x\n",
632 @@ -1238,7 +1566,7 @@
633     contains 4-byte jump instructions whose relative offset must not
634     be changed.  */
635  
636 -static  bfd_boolean
637 +static bfd_boolean
638  elf32_avr_relax_section (bfd *abfd,
639                          asection *sec,
640                           struct bfd_link_info *link_info,
641 @@ -1251,10 +1579,37 @@
642    Elf_Internal_Sym *isymbuf = NULL;
643    static asection *last_input_section = NULL;
644    static Elf_Internal_Rela *last_reloc = NULL;
645 +  struct elf32_avr_link_hash_table *htab;
646 +
647 +  htab = avr_link_hash_table (link_info);
648  
649    /* Assume nothing changes.  */
650    *again = FALSE;
651  
652 +  if ((!htab->no_stubs) && (sec == htab->stub_sec))
653 +    {
654 +      /* We are just relaxing the stub section.
655 +        Let's calculate the size needed again.  */
656 +      bfd_size_type last_estimated_stub_section_size = htab->stub_sec->size;
657 +
658 +      if (debug_relax)
659 +        printf ("Relaxing the stub section. Size prior to this pass: %i\n",
660 +                (int) last_estimated_stub_section_size);
661 +
662 +      elf32_avr_size_stubs (htab->stub_sec->output_section->owner,
663 +                            link_info, FALSE);
664 +
665 +      /* Check if the number of trampolines changed.  */
666 +      if (last_estimated_stub_section_size != htab->stub_sec->size)
667 +        *again = TRUE;
668 +
669 +      if (debug_relax)
670 +        printf ("Size of stub section after this pass: %i\n",
671 +                (int) htab->stub_sec->size);
672 +
673 +      return TRUE;
674 +    }
675 +
676    /* We don't have to do anything for a relocatable link, if
677       this section does not have relocs, or if this is not a
678       code section.  */
679 @@ -1421,7 +1776,7 @@
680                  unsigned char code_msb;
681                  unsigned char code_lsb;
682  
683 -                if (DEBUG_RELAX)
684 +                if (debug_relax)
685                    printf ("shrinking jump/call instruction at address 0x%x"
686                            " in section %s\n\n",
687                            (int) dot, sec->name);
688 @@ -1496,8 +1851,9 @@
689                     + sec->output_offset + irel->r_offset);
690  
691              /* Here we look for rcall/ret or call/ret sequences that could be
692 -               safely replaced by rjmp/ret or jmp/ret */
693 -            if (0xd0 == (code_msb & 0xf0))
694 +               safely replaced by rjmp/ret or jmp/ret.  */
695 +            if (((code_msb & 0xf0) == 0xd0)
696 +                && avr_replace_call_ret_sequences)
697                {
698                  /* This insn is a rcall.  */
699                  unsigned char next_insn_msb = 0;
700 @@ -1517,7 +1873,7 @@
701                         into a rjmp instruction.  */
702                      code_msb &= 0xef;
703                      bfd_put_8 (abfd, code_msb, contents + irel->r_offset + 1);
704 -                    if (DEBUG_RELAX)
705 +                    if (debug_relax)
706                        printf ("converted rcall/ret sequence at address 0x%x"
707                                " into rjmp/ret sequence. Section is %s\n\n",
708                                (int) dot, sec->name);
709 @@ -1526,7 +1882,8 @@
710                    }
711                }
712              else if ((0x94 == (code_msb & 0xfe))
713 -                      && (0x0e == (code_lsb & 0x0e)))
714 +                    && (0x0e == (code_lsb & 0x0e))
715 +                    && avr_replace_call_ret_sequences)
716                {
717                  /* This insn is a call.  */
718                  unsigned char next_insn_msb = 0;
719 @@ -1547,7 +1904,7 @@
720  
721                      code_lsb &= 0xfd;
722                      bfd_put_8 (abfd, code_lsb, contents + irel->r_offset);
723 -                    if (DEBUG_RELAX)
724 +                    if (debug_relax)
725                        printf ("converted call/ret sequence at address 0x%x"
726                                " into jmp/ret sequence. Section is %s\n\n",
727                                (int) dot, sec->name);
728 @@ -1590,10 +1947,10 @@
729  
730                      address_of_ret = dot + insn_size;
731  
732 -                    if (DEBUG_RELAX && (insn_size == 2))
733 +                    if (debug_relax && (insn_size == 2))
734                        printf ("found rjmp / ret sequence at address 0x%x\n",
735                                (int) dot);
736 -                    if (DEBUG_RELAX && (insn_size == 4))
737 +                    if (debug_relax && (insn_size == 4))
738                        printf ("found jmp / ret sequence at address 0x%x\n",
739                                (int) dot);
740  
741 @@ -1630,7 +1987,7 @@
742                            there_is_preceeding_non_skip_insn = 0;
743  
744                          if (there_is_preceeding_non_skip_insn == 0)
745 -                          if (DEBUG_RELAX)
746 +                          if (debug_relax)
747                              printf ("preceeding skip insn prevents deletion of"
748                                      " ret insn at addr 0x%x in section %s\n",
749                                      (int) dot + 2, sec->name);
750 @@ -1666,7 +2023,7 @@
751                                 && isym->st_shndx == sec_shndx)
752                               {
753                                 deleting_ret_is_safe = 0;
754 -                               if (DEBUG_RELAX)
755 +                               if (debug_relax)
756                                   printf ("local label prevents deletion of ret "
757                                           "insn at address 0x%x\n",
758                                           (int) dot + insn_size);
759 @@ -1695,7 +2052,7 @@
760                                    && sym_hash->root.u.def.value == section_offset_of_ret_insn)
761                                  {
762                                    deleting_ret_is_safe = 0;
763 -                                  if (DEBUG_RELAX)
764 +                                  if (debug_relax)
765                                      printf ("global label prevents deletion of "
766                                              "ret insn at address 0x%x\n",
767                                              (int) dot + insn_size);
768 @@ -1772,7 +2129,7 @@
769                                 if (address_of_ret == reloc_target)
770                                   {
771                                     deleting_ret_is_safe = 0;
772 -                                   if (DEBUG_RELAX)
773 +                                   if (debug_relax)
774                                       printf ("ret from "
775                                               "rjmp/jmp ret sequence at address"
776                                               " 0x%x could not be deleted. ret"
777 @@ -1784,7 +2141,7 @@
778  
779                           if (deleting_ret_is_safe)
780                             {
781 -                             if (DEBUG_RELAX)
782 +                             if (debug_relax)
783                                 printf ("unreachable ret instruction "
784                                         "at address 0x%x deleted.\n",
785                                         (int) dot + insn_size);
786 @@ -1952,6 +2309,614 @@
787  }
788  
789  
790 +/* Determines the hash entry name for a particular reloc. It consists of
791 +   the identifier of the symbol section and the added reloc addend and
792 +   symbol offset relative to the section the symbol is attached to.  */
793 +
794 +static char *
795 +avr_stub_name (const asection *symbol_section,
796 +               const bfd_vma symbol_offset,
797 +               const Elf_Internal_Rela *rela)
798 +{
799 +  char *stub_name;
800 +  bfd_size_type len;
801 +
802 +  len = 8 + 1 + 8 + 1 + 1;
803 +  stub_name = bfd_malloc (len);
804 +
805 +  sprintf (stub_name, "%08x+%08x",
806 +           symbol_section->id & 0xffffffff,
807 +           (unsigned int) ((rela->r_addend & 0xffffffff) + symbol_offset));
808 +
809 +  return stub_name;
810 +}
811 +
812 +
813 +/* Add a new stub entry to the stub hash.  Not all fields of the new
814 +   stub entry are initialised.  */
815 +
816 +static struct elf32_avr_stub_hash_entry *
817 +avr_add_stub (const char *stub_name,
818 +              struct elf32_avr_link_hash_table *htab)
819 +{
820 +  struct elf32_avr_stub_hash_entry *hsh;
821 +
822 +  /* Enter this entry into the linker stub hash table.  */
823 +  hsh = avr_stub_hash_lookup (&htab->bstab, stub_name, TRUE, FALSE);
824 +
825 +  if (hsh == NULL)
826 +    {
827 +      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
828 +                             NULL, stub_name);
829 +      return NULL;
830 +    }
831 +
832 +  hsh->stub_offset = 0;
833 +  return hsh;
834 +}
835 +
836 +/* We assume that there is already space allocated for the stub section
837 +   contents and that before building the stubs the section size is
838 +   initialized to 0.  We assume that within the stub hash table entry,
839 +   the absolute position of the jmp target has been written in the
840 +   target_value field.  We write here the offset of the generated jmp insn
841 +   relative to the trampoline section start to the stub_offset entry in
842 +   the stub hash table entry.  */
843 +
844 +static  bfd_boolean
845 +avr_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
846 +{
847 +  struct elf32_avr_stub_hash_entry *hsh;
848 +  struct bfd_link_info *info;
849 +  struct elf32_avr_link_hash_table *htab;
850 +  bfd *stub_bfd;
851 +  bfd_byte *loc;
852 +  bfd_vma target;
853 +  bfd_vma starget;
854 +
855 +  /* Basic opcode */
856 +  bfd_vma jmp_insn = 0x0000940c;
857 +
858 +  /* Massage our args to the form they really have.  */
859 +  hsh = avr_stub_hash_entry (bh);
860 +
861 +  if (!hsh->is_actually_needed)
862 +    return TRUE;
863 +
864 +  info = (struct bfd_link_info *) in_arg;
865 +
866 +  htab = avr_link_hash_table (info);
867 +
868 +  target = hsh->target_value;
869 +
870 +  /* Make a note of the offset within the stubs for this entry.  */
871 +  hsh->stub_offset = htab->stub_sec->size;
872 +  loc = htab->stub_sec->contents + hsh->stub_offset;
873 +
874 +  stub_bfd = htab->stub_sec->owner;
875 +
876 +  if (debug_stubs)
877 +    printf ("Building one Stub. Address: 0x%x, Offset: 0x%x\n",
878 +             (unsigned int) target,
879 +             (unsigned int) hsh->stub_offset);
880 +
881 +  /* We now have to add the information on the jump target to the bare
882 +     opcode bits already set in jmp_insn.  */
883 +
884 +  /* Check for the alignment of the address.  */
885 +  if (target & 1)
886 +     return FALSE;
887 +
888 +  starget = target >> 1;
889 +  jmp_insn |= ((starget & 0x10000) | ((starget << 3) & 0x1f00000)) >> 16;
890 +  bfd_put_16 (stub_bfd, jmp_insn, loc);
891 +  bfd_put_16 (stub_bfd, (bfd_vma) starget & 0xffff, loc + 2);
892 +
893 +  htab->stub_sec->size += 4;
894 +
895 +  /* Now add the entries in the address mapping table if there is still
896 +     space left.  */
897 +  {
898 +    unsigned int nr;
899 +
900 +    nr = htab->amt_entry_cnt + 1;
901 +    if (nr <= htab->amt_max_entry_cnt)
902 +      {
903 +        htab->amt_entry_cnt = nr;
904 +
905 +        htab->amt_stub_offsets[nr - 1] = hsh->stub_offset;
906 +        htab->amt_destination_addr[nr - 1] = target;
907 +      }
908 +  }
909 +
910 +  return TRUE;
911 +}
912 +
913 +static bfd_boolean
914 +avr_mark_stub_not_to_be_necessary (struct bfd_hash_entry *bh,
915 +                                   void *in_arg)
916 +{
917 +  struct elf32_avr_stub_hash_entry *hsh;
918 +  struct elf32_avr_link_hash_table *htab;
919 +
920 +  htab = in_arg;
921 +  hsh = avr_stub_hash_entry (bh);
922 +  hsh->is_actually_needed = FALSE;
923 +
924 +  return TRUE;
925 +}
926 +
927 +static bfd_boolean
928 +avr_size_one_stub (struct bfd_hash_entry *bh, void *in_arg)
929 +{
930 +  struct elf32_avr_stub_hash_entry *hsh;
931 +  struct elf32_avr_link_hash_table *htab;
932 +  int size;
933 +
934 +  /* Massage our args to the form they really have.  */
935 +  hsh = avr_stub_hash_entry (bh);
936 +  htab = in_arg;
937 +
938 +  if (hsh->is_actually_needed)
939 +    size = 4;
940 +  else
941 +    size = 0;
942 +
943 +  htab->stub_sec->size += size;
944 +  return TRUE;
945 +}
946 +
947 +void
948 +elf32_avr_setup_params (struct bfd_link_info *info,
949 +                        bfd *avr_stub_bfd,
950 +                        asection *avr_stub_section,
951 +                        bfd_boolean no_stubs,
952 +                        bfd_boolean deb_stubs,
953 +                        bfd_boolean deb_relax,
954 +                        bfd_vma pc_wrap_around,
955 +                        bfd_boolean call_ret_replacement)
956 +{
957 +  struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
958 +
959 +  htab->stub_sec = avr_stub_section;
960 +  htab->stub_bfd = avr_stub_bfd;
961 +  htab->no_stubs = no_stubs;
962 +
963 +  debug_relax = deb_relax;
964 +  debug_stubs = deb_stubs;
965 +  avr_pc_wrap_around = pc_wrap_around;
966 +  avr_replace_call_ret_sequences = call_ret_replacement;
967 +}
968 +
969 +
970 +/* Set up various things so that we can make a list of input sections
971 +   for each output section included in the link.  Returns -1 on error,
972 +   0 when no stubs will be needed, and 1 on success.  It also sets
973 +   information on the stubs bfd and the stub section in the info
974 +   struct.  */
975 +
976 +int
977 +elf32_avr_setup_section_lists (bfd *output_bfd,
978 +                               struct bfd_link_info *info)
979 +{
980 +  bfd *input_bfd;
981 +  unsigned int bfd_count;
982 +  int top_id, top_index;
983 +  asection *section;
984 +  asection **input_list, **list;
985 +  bfd_size_type amt;
986 +  struct elf32_avr_link_hash_table *htab = avr_link_hash_table(info);
987 +
988 +  if (htab->no_stubs)
989 +    return 0;
990 +
991 +  /* Count the number of input BFDs and find the top input section id.  */
992 +  for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
993 +       input_bfd != NULL;
994 +       input_bfd = input_bfd->link_next)
995 +    {
996 +      bfd_count += 1;
997 +      for (section = input_bfd->sections;
998 +           section != NULL;
999 +           section = section->next)
1000 +       if (top_id < section->id)
1001 +         top_id = section->id;
1002 +    }
1003 +
1004 +  htab->bfd_count = bfd_count;
1005 +
1006 +  /* We can't use output_bfd->section_count here to find the top output
1007 +     section index as some sections may have been removed, and
1008 +     strip_excluded_output_sections doesn't renumber the indices.  */
1009 +  for (section = output_bfd->sections, top_index = 0;
1010 +       section != NULL;
1011 +       section = section->next)
1012 +    if (top_index < section->index)
1013 +      top_index = section->index;
1014 +
1015 +  htab->top_index = top_index;
1016 +  amt = sizeof (asection *) * (top_index + 1);
1017 +  input_list = bfd_malloc (amt);
1018 +  htab->input_list = input_list;
1019 +  if (input_list == NULL)
1020 +    return -1;
1021 +
1022 +  /* For sections we aren't interested in, mark their entries with a
1023 +     value we can check later.  */
1024 +  list = input_list + top_index;
1025 +  do
1026 +    *list = bfd_abs_section_ptr;
1027 +  while (list-- != input_list);
1028 +
1029 +  for (section = output_bfd->sections;
1030 +       section != NULL;
1031 +       section = section->next)
1032 +    if ((section->flags & SEC_CODE) != 0)
1033 +      input_list[section->index] = NULL;
1034 +
1035 +  return 1;
1036 +}
1037 +
1038 +
1039 +/* Read in all local syms for all input bfds, and create hash entries
1040 +   for export stubs if we are building a multi-subspace shared lib.
1041 +   Returns -1 on error, 0 otherwise.  */
1042 +
1043 +static int
1044 +get_local_syms (bfd *input_bfd, struct bfd_link_info *info)
1045 +{
1046 +  unsigned int bfd_indx;
1047 +  Elf_Internal_Sym *local_syms, **all_local_syms;
1048 +  struct elf32_avr_link_hash_table *htab = avr_link_hash_table (info);
1049 +
1050 +  /* We want to read in symbol extension records only once.  To do this
1051 +     we need to read in the local symbols in parallel and save them for
1052 +     later use; so hold pointers to the local symbols in an array.  */
1053 +  bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count;
1054 +  all_local_syms = bfd_zmalloc (amt);
1055 +  htab->all_local_syms = all_local_syms;
1056 +  if (all_local_syms == NULL)
1057 +    return -1;
1058 +
1059 +  /* Walk over all the input BFDs, swapping in local symbols.
1060 +     If we are creating a shared library, create hash entries for the
1061 +     export stubs.  */
1062 +  for (bfd_indx = 0;
1063 +       input_bfd != NULL;
1064 +       input_bfd = input_bfd->link_next, bfd_indx++)
1065 +    {
1066 +      Elf_Internal_Shdr *symtab_hdr;
1067 +
1068 +      /* We'll need the symbol table in a second.  */
1069 +      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1070 +      if (symtab_hdr->sh_info == 0)
1071 +       continue;
1072 +
1073 +      /* We need an array of the local symbols attached to the input bfd.  */
1074 +      local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
1075 +      if (local_syms == NULL)
1076 +       {
1077 +         local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
1078 +                                            symtab_hdr->sh_info, 0,
1079 +                                            NULL, NULL, NULL);
1080 +         /* Cache them for elf_link_input_bfd.  */
1081 +         symtab_hdr->contents = (unsigned char *) local_syms;
1082 +       }
1083 +      if (local_syms == NULL)
1084 +       return -1;
1085 +
1086 +      all_local_syms[bfd_indx] = local_syms;
1087 +    }
1088 +
1089 +  return 0;
1090 +}
1091 +
1092 +#define ADD_DUMMY_STUBS_FOR_DEBUGGING 0
1093 +
1094 +bfd_boolean
1095 +elf32_avr_size_stubs (bfd *output_bfd,
1096 +                      struct bfd_link_info *info,
1097 +                      bfd_boolean is_prealloc_run)
1098 +{
1099 + struct elf32_avr_link_hash_table *htab;
1100 + int stub_changed = 0;
1101 +
1102 + htab = avr_link_hash_table (info);
1103 +
1104 + /* At this point we initialize htab->vector_base
1105 +    To the start of the text output section.  */
1106 + htab->vector_base = htab->stub_sec->output_section->vma;
1107 +
1108 + if (get_local_syms (info->input_bfds, info))
1109 +   {
1110 +     if (htab->all_local_syms)
1111 +       goto error_ret_free_local;
1112 +     return FALSE;
1113 +   }
1114 +
1115 +  if (ADD_DUMMY_STUBS_FOR_DEBUGGING)
1116 +    {
1117 +      struct elf32_avr_stub_hash_entry *test;
1118 +
1119 +      test = avr_add_stub ("Hugo",htab);
1120 +      test->target_value = 0x123456;
1121 +      test->stub_offset = 13;
1122 +
1123 +      test = avr_add_stub ("Hugo2",htab);
1124 +      test->target_value = 0x84210;
1125 +      test->stub_offset = 14;
1126 +    }
1127 +
1128 +  while (1)
1129 +    {
1130 +      bfd *input_bfd;
1131 +      unsigned int bfd_indx;
1132 +
1133 +      /* We will have to re-generate the stub hash table each time anything
1134 +         in memory has changed.  */
1135 +
1136 +      bfd_hash_traverse (&htab->bstab, avr_mark_stub_not_to_be_necessary, htab);
1137 +      for (input_bfd = info->input_bfds, bfd_indx = 0;
1138 +           input_bfd != NULL;
1139 +           input_bfd = input_bfd->link_next, bfd_indx++)
1140 +        {
1141 +          Elf_Internal_Shdr *symtab_hdr;
1142 +          asection *section;
1143 +          Elf_Internal_Sym *local_syms;
1144 +
1145 +          /* We'll need the symbol table in a second.  */
1146 +          symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1147 +          if (symtab_hdr->sh_info == 0)
1148 +            continue;
1149 +
1150 +          local_syms = htab->all_local_syms[bfd_indx];
1151 +
1152 +          /* Walk over each section attached to the input bfd.  */
1153 +          for (section = input_bfd->sections;
1154 +               section != NULL;
1155 +               section = section->next)
1156 +            {
1157 +              Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
1158 +
1159 +              /* If there aren't any relocs, then there's nothing more
1160 +                 to do.  */
1161 +              if ((section->flags & SEC_RELOC) == 0
1162 +                  || section->reloc_count == 0)
1163 +                continue;
1164 +
1165 +              /* If this section is a link-once section that will be
1166 +                 discarded, then don't create any stubs.  */
1167 +              if (section->output_section == NULL
1168 +                  || section->output_section->owner != output_bfd)
1169 +                continue;
1170 +
1171 +              /* Get the relocs.  */
1172 +              internal_relocs
1173 +                = _bfd_elf_link_read_relocs (input_bfd, section, NULL, NULL,
1174 +                                             info->keep_memory);
1175 +              if (internal_relocs == NULL)
1176 +                goto error_ret_free_local;
1177 +
1178 +              /* Now examine each relocation.  */
1179 +              irela = internal_relocs;
1180 +              irelaend = irela + section->reloc_count;
1181 +              for (; irela < irelaend; irela++)
1182 +                {
1183 +                  unsigned int r_type, r_indx;
1184 +                  struct elf32_avr_stub_hash_entry *hsh;
1185 +                  asection *sym_sec;
1186 +                  bfd_vma sym_value;
1187 +                  bfd_vma destination;
1188 +                  struct elf_link_hash_entry *hh;
1189 +                  char *stub_name;
1190 +
1191 +                  r_type = ELF32_R_TYPE (irela->r_info);
1192 +                  r_indx = ELF32_R_SYM (irela->r_info);
1193 +
1194 +                  /* Only look for 16 bit GS relocs. No other reloc will need a
1195 +                     stub.  */
1196 +                  if (!((r_type == R_AVR_16_PM)
1197 +                        || (r_type == R_AVR_LO8_LDI_GS)
1198 +                        || (r_type == R_AVR_HI8_LDI_GS)))
1199 +                    continue;
1200 +
1201 +                  /* Now determine the call target, its name, value,
1202 +                     section.  */
1203 +                  sym_sec = NULL;
1204 +                  sym_value = 0;
1205 +                  destination = 0;
1206 +                  hh = NULL;
1207 +                  if (r_indx < symtab_hdr->sh_info)
1208 +                    {
1209 +                      /* It's a local symbol.  */
1210 +                      Elf_Internal_Sym *sym;
1211 +                      Elf_Internal_Shdr *hdr;
1212 +
1213 +                      sym = local_syms + r_indx;
1214 +                      hdr = elf_elfsections (input_bfd)[sym->st_shndx];
1215 +                      sym_sec = hdr->bfd_section;
1216 +                      if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1217 +                        sym_value = sym->st_value;
1218 +                      destination = (sym_value + irela->r_addend
1219 +                                     + sym_sec->output_offset
1220 +                                     + sym_sec->output_section->vma);
1221 +                    }
1222 +                  else
1223 +                    {
1224 +                      /* It's an external symbol.  */
1225 +                      int e_indx;
1226 +
1227 +                      e_indx = r_indx - symtab_hdr->sh_info;
1228 +                      hh = elf_sym_hashes (input_bfd)[e_indx];
1229 +
1230 +                      while (hh->root.type == bfd_link_hash_indirect
1231 +                             || hh->root.type == bfd_link_hash_warning)
1232 +                        hh = (struct elf_link_hash_entry *)
1233 +                              (hh->root.u.i.link);
1234 +
1235 +                      if (hh->root.type == bfd_link_hash_defined
1236 +                          || hh->root.type == bfd_link_hash_defweak)
1237 +                        {
1238 +                          sym_sec = hh->root.u.def.section;
1239 +                          sym_value = hh->root.u.def.value;
1240 +                          if (sym_sec->output_section != NULL)
1241 +                          destination = (sym_value + irela->r_addend
1242 +                                         + sym_sec->output_offset
1243 +                                         + sym_sec->output_section->vma);
1244 +                        }
1245 +                      else if (hh->root.type == bfd_link_hash_undefweak)
1246 +                        {
1247 +                          if (! info->shared)
1248 +                            continue;
1249 +                        }
1250 +                      else if (hh->root.type == bfd_link_hash_undefined)
1251 +                        {
1252 +                          if (! (info->unresolved_syms_in_objects == RM_IGNORE
1253 +                                 && (ELF_ST_VISIBILITY (hh->other)
1254 +                                     == STV_DEFAULT)))
1255 +                             continue;
1256 +                        }
1257 +                      else
1258 +                        {
1259 +                          bfd_set_error (bfd_error_bad_value);
1260 +
1261 +                          error_ret_free_internal:
1262 +                          if (elf_section_data (section)->relocs == NULL)
1263 +                            free (internal_relocs);
1264 +                          goto error_ret_free_local;
1265 +                        }
1266 +                    }
1267 +
1268 +                  if (! avr_stub_is_required_for_16_bit_reloc
1269 +                     (destination - htab->vector_base))
1270 +                    {
1271 +                      if (!is_prealloc_run)
1272 +                       /* We are having a reloc that does't need a stub.  */
1273 +                       continue;
1274 +
1275 +                     /* We don't right now know if a stub will be needed.
1276 +                        Let's rather be on the safe side.  */
1277 +                    }
1278 +
1279 +                  /* Get the name of this stub.  */
1280 +                  stub_name = avr_stub_name (sym_sec, sym_value, irela);
1281 +
1282 +                  if (!stub_name)
1283 +                    goto error_ret_free_internal;
1284 +
1285 +
1286 +                  hsh = avr_stub_hash_lookup (&htab->bstab,
1287 +                                              stub_name,
1288 +                                              FALSE, FALSE);
1289 +                  if (hsh != NULL)
1290 +                    {
1291 +                      /* The proper stub has already been created.  Mark it
1292 +                         to be used and write the possibly changed destination
1293 +                         value.  */
1294 +                      hsh->is_actually_needed = TRUE;
1295 +                      hsh->target_value = destination;
1296 +                      free (stub_name);
1297 +                      continue;
1298 +                    }
1299 +
1300 +                  hsh = avr_add_stub (stub_name, htab);
1301 +                  if (hsh == NULL)
1302 +                    {
1303 +                      free (stub_name);
1304 +                      goto error_ret_free_internal;
1305 +                    }
1306 +
1307 +                  hsh->is_actually_needed = TRUE;
1308 +                  hsh->target_value = destination;
1309 +
1310 +                  if (debug_stubs)
1311 +                    printf ("Adding stub with destination 0x%x to the"
1312 +                            " hash table.\n", (unsigned int) destination);
1313 +                  if (debug_stubs)
1314 +                    printf ("(Pre-Alloc run: %i)\n", is_prealloc_run);
1315 +
1316 +                  stub_changed = TRUE;
1317 +                }
1318 +
1319 +              /* We're done with the internal relocs, free them.  */
1320 +              if (elf_section_data (section)->relocs == NULL)
1321 +                free (internal_relocs);
1322 +            }
1323 +        }
1324 +
1325 +      /* Re-Calculate the number of needed stubs.  */
1326 +      htab->stub_sec->size = 0;
1327 +      bfd_hash_traverse (&htab->bstab, avr_size_one_stub, htab);
1328 +
1329 +      if (!stub_changed)
1330 +        break;
1331 +
1332 +      stub_changed = FALSE;
1333 +    }
1334 +
1335 +  free (htab->all_local_syms);
1336 +  return TRUE;
1337 +
1338 + error_ret_free_local:
1339 +  free (htab->all_local_syms);
1340 +  return FALSE;
1341 +}
1342 +
1343 +
1344 +/* Build all the stubs associated with the current output file.  The
1345 +   stubs are kept in a hash table attached to the main linker hash
1346 +   table.  We also set up the .plt entries for statically linked PIC
1347 +   functions here.  This function is called via hppaelf_finish in the
1348 +   linker.  */
1349 +
1350 +bfd_boolean
1351 +elf32_avr_build_stubs (struct bfd_link_info *info)
1352 +{
1353 +  asection *stub_sec;
1354 +  struct bfd_hash_table *table;
1355 +  struct elf32_avr_link_hash_table *htab;
1356 +  bfd_size_type total_size = 0;
1357 +
1358 +  htab = avr_link_hash_table (info);
1359 +
1360 +  /* In case that there were several stub sections:  */
1361 +  for (stub_sec = htab->stub_bfd->sections;
1362 +       stub_sec != NULL;
1363 +       stub_sec = stub_sec->next)
1364 +    {
1365 +      bfd_size_type size;
1366 +
1367 +      /* Allocate memory to hold the linker stubs.  */
1368 +      size = stub_sec->size;
1369 +      total_size += size;
1370 +
1371 +      stub_sec->contents = bfd_zalloc (htab->stub_bfd, size);
1372 +      if (stub_sec->contents == NULL && size != 0)
1373 +       return FALSE;
1374 +      stub_sec->size = 0;
1375 +    }
1376 +
1377 +  /* Allocate memory for the adress mapping table.  */
1378 +  htab->amt_entry_cnt = 0;
1379 +  htab->amt_max_entry_cnt = total_size / 4;
1380 +  htab->amt_stub_offsets = bfd_malloc (sizeof (bfd_vma)
1381 +                                       * htab->amt_max_entry_cnt);
1382 +  htab->amt_destination_addr = bfd_malloc (sizeof (bfd_vma)
1383 +                                          * htab->amt_max_entry_cnt );
1384 +
1385 +  if (debug_stubs)
1386 +    printf ("Allocating %i entries in the AMT\n", htab->amt_max_entry_cnt);
1387 +
1388 +  /* Build the stubs as directed by the stub hash table.  */
1389 +  table = &htab->bstab;
1390 +  bfd_hash_traverse (table, avr_build_one_stub, info);
1391 +
1392 +  if (debug_stubs)
1393 +    printf ("Final Stub section Size: %i\n", (int) htab->stub_sec->size);
1394 +
1395 +  return TRUE;
1396 +}
1397 +
1398  #define ELF_ARCH               bfd_arch_avr
1399  #define ELF_MACHINE_CODE       EM_AVR
1400  #define ELF_MACHINE_ALT1       EM_AVR_OLD
1401 @@ -1960,6 +2925,9 @@
1402  #define TARGET_LITTLE_SYM       bfd_elf32_avr_vec
1403  #define TARGET_LITTLE_NAME     "elf32-avr"
1404  
1405 +#define bfd_elf32_bfd_link_hash_table_create elf32_avr_link_hash_table_create
1406 +#define bfd_elf32_bfd_link_hash_table_free   elf32_avr_link_hash_table_free
1407 +
1408  #define elf_info_to_howto                   avr_info_to_howto_rela
1409  #define elf_info_to_howto_rel               NULL
1410  #define elf_backend_relocate_section         elf32_avr_relocate_section
1411 diff -Nur bfd/elf32-avr.h bfd/elf32-avr.h
1412 --- bfd/elf32-avr.h     1970-01-01 01:00:00.000000000 +0100
1413 +++ bfd/elf32-avr.h     2006-08-28 20:01:10.805090951 +0200
1414 @@ -0,0 +1,38 @@
1415 +/* AVR-specific support for 32-bit ELF.
1416 +   Copyright 2006 Free Software Foundation, Inc.
1417 +
1418 +   Written by Bjoern Haase <bjoern.m.haase@web.de>
1419 +
1420 +   This file is part of BFD, the Binary File Descriptor library.
1421 +
1422 +   This program is free software; you can redistribute it and/or modify
1423 +   it under the terms of the GNU General Public License as published by
1424 +   the Free Software Foundation; either version 2 of the License, or
1425 +   (at your option) any later version.
1426 +
1427 +   This program is distributed in the hope that it will be useful,
1428 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
1429 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1430 +   GNU General Public License for more details.
1431 +
1432 +   You should have received a copy of the GNU General Public License
1433 +   along with this program; if not, write to the Free Software
1434 +   Foundation, Inc., 51 Franklin Street - Fifth Floor, 
1435 +   Boston, MA 02110-1301, USA.  */
1436 +
1437 +
1438 +/* These four functions will be called from the ld back-end.  */
1439 +
1440 +extern void
1441 +elf32_avr_setup_params (struct bfd_link_info *, bfd *, asection *,
1442 +                        bfd_boolean, bfd_boolean, bfd_boolean,
1443 +                        bfd_vma, bfd_boolean);
1444 +
1445 +extern int
1446 +elf32_avr_setup_section_lists (bfd *, struct bfd_link_info *);
1447 +
1448 +extern bfd_boolean
1449 +elf32_avr_size_stubs (bfd *, struct bfd_link_info *, bfd_boolean);
1450 +
1451 +extern bfd_boolean
1452 +elf32_avr_build_stubs (struct bfd_link_info *);
1453 diff -Nur bfd/libbfd.h bfd/libbfd.h
1454 --- bfd/libbfd.h        2006-03-26 01:38:42.000000000 +0100
1455 +++ bfd/libbfd.h        2006-08-28 20:02:16.912297073 +0200
1456 @@ -1509,7 +1509,9 @@
1457    "BFD_RELOC_AVR_HH8_LDI_NEG",
1458    "BFD_RELOC_AVR_MS8_LDI_NEG",
1459    "BFD_RELOC_AVR_LO8_LDI_PM",
1460 +  "BFD_RELOC_AVR_LO8_LDI_GS",
1461    "BFD_RELOC_AVR_HI8_LDI_PM",
1462 +  "BFD_RELOC_AVR_HI8_LDI_GS",
1463    "BFD_RELOC_AVR_HH8_LDI_PM",
1464    "BFD_RELOC_AVR_LO8_LDI_PM_NEG",
1465    "BFD_RELOC_AVR_HI8_LDI_PM_NEG",
1466 diff -Nur bfd/reloc.c bfd/reloc.c
1467 --- bfd/reloc.c 2006-03-26 01:38:42.000000000 +0100
1468 +++ bfd/reloc.c 2006-08-28 20:02:16.936295332 +0200
1469 @@ -3666,11 +3666,25 @@
1470    This is a 16 bit reloc for the AVR that stores 8 bit value (usually
1471    command address) into 8 bit immediate value of LDI insn.
1472  ENUM
1473 +  BFD_RELOC_AVR_LO8_LDI_GS
1474 +ENUMDOC
1475 +  This is a 16 bit reloc for the AVR that stores 8 bit value 
1476 +  (command address) into 8 bit immediate value of LDI insn. If the address
1477 +  is beyond the 128k boundary, the linker inserts a jump stub for this reloc
1478 +  in the lower 128k.
1479 +ENUM
1480    BFD_RELOC_AVR_HI8_LDI_PM
1481  ENUMDOC
1482    This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
1483    of command address) into 8 bit immediate value of LDI insn.
1484  ENUM
1485 +  BFD_RELOC_AVR_HI8_LDI_GS
1486 +ENUMDOC
1487 +  This is a 16 bit reloc for the AVR that stores 8 bit value (high 8 bit
1488 +  of command address) into 8 bit immediate value of LDI insn.  If the address
1489 +  is beyond the 128k boundary, the linker inserts a jump stub for this reloc
1490 +  below 128k.
1491 +ENUM
1492    BFD_RELOC_AVR_HH8_LDI_PM
1493  ENUMDOC
1494    This is a 16 bit reloc for the AVR that stores 8 bit value (most high 8 bit
1495 diff -Nur gas/config/tc-avr.c gas/config/tc-avr.c
1496 --- gas/config/tc-avr.c 2006-04-07 17:18:08.000000000 +0200
1497 +++ gas/config/tc-avr.c 2006-08-28 20:02:16.948294462 +0200
1498 @@ -63,89 +63,92 @@
1499  
1500  static struct mcu_type_s mcu_types[] =
1501  {
1502 -  {"avr1",      AVR_ISA_TINY1,    bfd_mach_avr1},
1503 -  {"avr2",      AVR_ISA_TINY2,    bfd_mach_avr2},
1504 -  {"avr3",      AVR_ISA_M103,     bfd_mach_avr3},
1505 -  {"avr4",      AVR_ISA_M8,       bfd_mach_avr4},
1506 -  {"avr5",      AVR_ISA_ALL,      bfd_mach_avr5},
1507 -  {"at90s1200", AVR_ISA_1200,     bfd_mach_avr1},
1508 -  {"attiny10",  AVR_ISA_TINY1,    bfd_mach_avr1}, /* XXX -> tn11 */
1509 -  {"attiny11",  AVR_ISA_TINY1,    bfd_mach_avr1},
1510 -  {"attiny12",  AVR_ISA_TINY1,    bfd_mach_avr1},
1511 -  {"attiny15",  AVR_ISA_TINY1,    bfd_mach_avr1},
1512 -  {"attiny28",  AVR_ISA_TINY1,    bfd_mach_avr1},
1513 -  {"at90s2313", AVR_ISA_2xxx,     bfd_mach_avr2},
1514 -  {"at90s2323", AVR_ISA_2xxx,     bfd_mach_avr2},
1515 -  {"at90s2333", AVR_ISA_2xxx,     bfd_mach_avr2}, /* XXX -> 4433 */
1516 -  {"at90s2343", AVR_ISA_2xxx,     bfd_mach_avr2},
1517 -  {"attiny22",  AVR_ISA_2xxx,     bfd_mach_avr2}, /* XXX -> 2343 */
1518 -  {"attiny26",  AVR_ISA_2xxx,     bfd_mach_avr2},
1519 -  {"at90s4433", AVR_ISA_2xxx,     bfd_mach_avr2},
1520 -  {"at90s4414", AVR_ISA_2xxx,     bfd_mach_avr2}, /* XXX -> 8515 */
1521 -  {"at90s4434", AVR_ISA_2xxx,     bfd_mach_avr2}, /* XXX -> 8535 */
1522 -  {"at90s8515", AVR_ISA_2xxx,     bfd_mach_avr2},
1523 -  {"at90s8535", AVR_ISA_2xxx,     bfd_mach_avr2},
1524 -  {"at90c8534", AVR_ISA_2xxx,     bfd_mach_avr2},
1525 -  {"at86rf401", AVR_ISA_2xxx,     bfd_mach_avr2},
1526 -  {"attiny13",  AVR_ISA_TINY2,    bfd_mach_avr2},
1527 -  {"attiny2313",AVR_ISA_TINY2,    bfd_mach_avr2},
1528 -  {"attiny261", AVR_ISA_TINY2,    bfd_mach_avr2},
1529 -  {"attiny461", AVR_ISA_TINY2,    bfd_mach_avr2},
1530 -  {"attiny861", AVR_ISA_TINY2,    bfd_mach_avr2},
1531 -  {"attiny24",  AVR_ISA_TINY2,    bfd_mach_avr2},
1532 -  {"attiny44",  AVR_ISA_TINY2,    bfd_mach_avr2},
1533 -  {"attiny84",  AVR_ISA_TINY2,    bfd_mach_avr2},
1534 -  {"attiny25",  AVR_ISA_TINY2,    bfd_mach_avr2},
1535 -  {"attiny45",  AVR_ISA_TINY2,    bfd_mach_avr2},
1536 -  {"attiny85",  AVR_ISA_TINY2,    bfd_mach_avr2},
1537 -  {"atmega603", AVR_ISA_M603,     bfd_mach_avr3}, /* XXX -> m103 */
1538 -  {"atmega103", AVR_ISA_M103,     bfd_mach_avr3},
1539 -  {"at43usb320",AVR_ISA_M103,     bfd_mach_avr3},
1540 -  {"at43usb355",AVR_ISA_M603,     bfd_mach_avr3},
1541 -  {"at76c711",  AVR_ISA_M603,     bfd_mach_avr3},
1542 -  {"atmega48",  AVR_ISA_PWMx,     bfd_mach_avr4},
1543 -  {"atmega8",   AVR_ISA_M8,       bfd_mach_avr4},
1544 -  {"atmega83",  AVR_ISA_M8,       bfd_mach_avr4}, /* XXX -> m8535 */
1545 -  {"atmega85",  AVR_ISA_M8,       bfd_mach_avr4}, /* XXX -> m8 */
1546 -  {"atmega88",  AVR_ISA_PWMx,     bfd_mach_avr4},
1547 -  {"atmega8515",AVR_ISA_M8,       bfd_mach_avr4},
1548 -  {"atmega8535",AVR_ISA_M8,       bfd_mach_avr4},
1549 -  {"at90pwm2",  AVR_ISA_PWMx,     bfd_mach_avr4},
1550 -  {"at90pwm3",  AVR_ISA_PWMx,     bfd_mach_avr4},
1551 -  {"atmega16",  AVR_ISA_M323,     bfd_mach_avr5},
1552 -  {"atmega161", AVR_ISA_M161,     bfd_mach_avr5},
1553 -  {"atmega162", AVR_ISA_M323,     bfd_mach_avr5},
1554 -  {"atmega163", AVR_ISA_M161,     bfd_mach_avr5},
1555 -  {"atmega164", AVR_ISA_M323,     bfd_mach_avr5},
1556 -  {"atmega165", AVR_ISA_M323,     bfd_mach_avr5},
1557 -  {"atmega168", AVR_ISA_M323,     bfd_mach_avr5},
1558 -  {"atmega169", AVR_ISA_M323,     bfd_mach_avr5},
1559 -  {"atmega32",  AVR_ISA_M323,     bfd_mach_avr5},
1560 -  {"atmega323", AVR_ISA_M323,     bfd_mach_avr5},
1561 -  {"atmega324", AVR_ISA_M323,     bfd_mach_avr5},
1562 -  {"atmega325", AVR_ISA_M323,     bfd_mach_avr5},
1563 -  {"atmega329", AVR_ISA_M323,     bfd_mach_avr5},
1564 -  {"atmega3250",AVR_ISA_M323,     bfd_mach_avr5},
1565 -  {"atmega3290",AVR_ISA_M323,     bfd_mach_avr5},
1566 -  {"atmega406", AVR_ISA_M323,     bfd_mach_avr5},
1567 -  {"atmega64",  AVR_ISA_M323,     bfd_mach_avr5},
1568 -  {"atmega640", AVR_ISA_M323,     bfd_mach_avr5},
1569 -  {"atmega644", AVR_ISA_M323,     bfd_mach_avr5},
1570 -  {"atmega128", AVR_ISA_M128,     bfd_mach_avr5},
1571 -  {"atmega1280",AVR_ISA_M128,     bfd_mach_avr5},
1572 -  {"atmega1281",AVR_ISA_M128,     bfd_mach_avr5},
1573 -  {"atmega645", AVR_ISA_M323,     bfd_mach_avr5},
1574 -  {"atmega649", AVR_ISA_M323,     bfd_mach_avr5},
1575 -  {"atmega6450",AVR_ISA_M323,     bfd_mach_avr5},
1576 -  {"atmega6490",AVR_ISA_M323,     bfd_mach_avr5},
1577 -  {"at90can32" ,AVR_ISA_M323,     bfd_mach_avr5},
1578 -  {"at90can64" ,AVR_ISA_M323,     bfd_mach_avr5},
1579 -  {"at90can128",AVR_ISA_M128,     bfd_mach_avr5},
1580 +  {"avr1",       AVR_ISA_TINY1,   bfd_mach_avr1},
1581 +  {"avr2",       AVR_ISA_TINY2,   bfd_mach_avr2},
1582 +  {"avr3",       AVR_ISA_M103,    bfd_mach_avr3},
1583 +  {"avr4",       AVR_ISA_M8,      bfd_mach_avr4},
1584 +  {"avr5",       AVR_ISA_ALL,     bfd_mach_avr5},
1585 +  {"avr6",       AVR_ISA_ALL,     bfd_mach_avr6},
1586 +  {"at90s1200",  AVR_ISA_1200,    bfd_mach_avr1},
1587 +  {"attiny10",   AVR_ISA_TINY1,   bfd_mach_avr1}, /* XXX -> tn11 */
1588 +  {"attiny11",   AVR_ISA_TINY1,   bfd_mach_avr1},
1589 +  {"attiny12",   AVR_ISA_TINY1,   bfd_mach_avr1},
1590 +  {"attiny15",   AVR_ISA_TINY1,   bfd_mach_avr1},
1591 +  {"attiny28",   AVR_ISA_TINY1,   bfd_mach_avr1},
1592 +  {"at90s2313",  AVR_ISA_2xxx,    bfd_mach_avr2},
1593 +  {"at90s2323",  AVR_ISA_2xxx,    bfd_mach_avr2},
1594 +  {"at90s2333",  AVR_ISA_2xxx,    bfd_mach_avr2}, /* XXX -> 4433 */
1595 +  {"at90s2343",  AVR_ISA_2xxx,    bfd_mach_avr2},
1596 +  {"attiny22",   AVR_ISA_2xxx,    bfd_mach_avr2}, /* XXX -> 2343 */
1597 +  {"attiny26",   AVR_ISA_2xxx,    bfd_mach_avr2},
1598 +  {"at90s4433",  AVR_ISA_2xxx,    bfd_mach_avr2},
1599 +  {"at90s4414",  AVR_ISA_2xxx,    bfd_mach_avr2}, /* XXX -> 8515 */
1600 +  {"at90s4434",  AVR_ISA_2xxx,    bfd_mach_avr2}, /* XXX -> 8535 */
1601 +  {"at90s8515",  AVR_ISA_2xxx,    bfd_mach_avr2},
1602 +  {"at90s8535",  AVR_ISA_2xxx,    bfd_mach_avr2},
1603 +  {"at90c8534",  AVR_ISA_2xxx,    bfd_mach_avr2},
1604 +  {"at86rf401",  AVR_ISA_2xxx,    bfd_mach_avr2},
1605 +  {"attiny13",   AVR_ISA_TINY2,   bfd_mach_avr2},
1606 +  {"attiny2313", AVR_ISA_TINY2,   bfd_mach_avr2},
1607 +  {"attiny261",  AVR_ISA_TINY2,   bfd_mach_avr2},
1608 +  {"attiny461",  AVR_ISA_TINY2,   bfd_mach_avr2},
1609 +  {"attiny861",  AVR_ISA_TINY2,   bfd_mach_avr2},
1610 +  {"attiny24",   AVR_ISA_TINY2,   bfd_mach_avr2},
1611 +  {"attiny44",   AVR_ISA_TINY2,   bfd_mach_avr2},
1612 +  {"attiny84",   AVR_ISA_TINY2,   bfd_mach_avr2},
1613 +  {"attiny25",   AVR_ISA_TINY2,   bfd_mach_avr2},
1614 +  {"attiny45",   AVR_ISA_TINY2,   bfd_mach_avr2},
1615 +  {"attiny85",   AVR_ISA_TINY2,   bfd_mach_avr2},
1616 +  {"atmega603",  AVR_ISA_M603,    bfd_mach_avr3}, /* XXX -> m103 */
1617 +  {"atmega103",  AVR_ISA_M103,    bfd_mach_avr3},
1618 +  {"at43usb320", AVR_ISA_M103,    bfd_mach_avr3},
1619 +  {"at43usb355", AVR_ISA_M603,    bfd_mach_avr3},
1620 +  {"at76c711",   AVR_ISA_M603,    bfd_mach_avr3},
1621 +  {"atmega48",   AVR_ISA_PWMx,    bfd_mach_avr4},
1622 +  {"atmega8",    AVR_ISA_M8,      bfd_mach_avr4},
1623 +  {"atmega83",   AVR_ISA_M8,      bfd_mach_avr4}, /* XXX -> m8535 */
1624 +  {"atmega85",   AVR_ISA_M8,      bfd_mach_avr4}, /* XXX -> m8 */
1625 +  {"atmega88",   AVR_ISA_PWMx,    bfd_mach_avr4},
1626 +  {"atmega8515", AVR_ISA_M8,      bfd_mach_avr4},
1627 +  {"atmega8535", AVR_ISA_M8,      bfd_mach_avr4},
1628 +  {"at90pwm2",   AVR_ISA_PWMx,    bfd_mach_avr4},
1629 +  {"at90pwm3",   AVR_ISA_PWMx,    bfd_mach_avr4},
1630 +  {"atmega16",   AVR_ISA_M323,    bfd_mach_avr5},
1631 +  {"atmega161",  AVR_ISA_M161,    bfd_mach_avr5},
1632 +  {"atmega162",  AVR_ISA_M323,    bfd_mach_avr5},
1633 +  {"atmega163",  AVR_ISA_M161,    bfd_mach_avr5},
1634 +  {"atmega164",  AVR_ISA_M323,    bfd_mach_avr5},
1635 +  {"atmega165",  AVR_ISA_M323,    bfd_mach_avr5},
1636 +  {"atmega168",  AVR_ISA_M323,    bfd_mach_avr5},
1637 +  {"atmega169",  AVR_ISA_M323,    bfd_mach_avr5},
1638 +  {"atmega32",   AVR_ISA_M323,    bfd_mach_avr5},
1639 +  {"atmega323",  AVR_ISA_M323,    bfd_mach_avr5},
1640 +  {"atmega324",  AVR_ISA_M323,    bfd_mach_avr5},
1641 +  {"atmega325",  AVR_ISA_M323,    bfd_mach_avr5},
1642 +  {"atmega329",  AVR_ISA_M323,    bfd_mach_avr5},
1643 +  {"atmega3250", AVR_ISA_M323,    bfd_mach_avr5},
1644 +  {"atmega3290", AVR_ISA_M323,    bfd_mach_avr5},
1645 +  {"atmega406",  AVR_ISA_M323,    bfd_mach_avr5},
1646 +  {"atmega64",   AVR_ISA_M323,    bfd_mach_avr5},
1647 +  {"atmega640",  AVR_ISA_M323,    bfd_mach_avr5},
1648 +  {"atmega644",  AVR_ISA_M323,    bfd_mach_avr5},
1649 +  {"atmega128",  AVR_ISA_M128,    bfd_mach_avr5},
1650 +  {"atmega1280", AVR_ISA_M128,    bfd_mach_avr5},
1651 +  {"atmega1281", AVR_ISA_M128,    bfd_mach_avr5},
1652 +  {"atmega645",  AVR_ISA_M323,    bfd_mach_avr5},
1653 +  {"atmega649",  AVR_ISA_M323,    bfd_mach_avr5},
1654 +  {"atmega6450", AVR_ISA_M323,    bfd_mach_avr5},
1655 +  {"atmega6490", AVR_ISA_M323,    bfd_mach_avr5},
1656 +  {"at90can32" , AVR_ISA_M323,    bfd_mach_avr5},
1657 +  {"at90can64" , AVR_ISA_M323,    bfd_mach_avr5},
1658 +  {"at90can128", AVR_ISA_M128,    bfd_mach_avr5},
1659    {"at90usb646", AVR_ISA_M323,    bfd_mach_avr5},
1660    {"at90usb647", AVR_ISA_M323,    bfd_mach_avr5},
1661    {"at90usb1286",AVR_ISA_M128,    bfd_mach_avr5},
1662    {"at90usb1287",AVR_ISA_M128,    bfd_mach_avr5},
1663 -  {"at94k",     AVR_ISA_94K,      bfd_mach_avr5},
1664 +  {"at94k",      AVR_ISA_94K,     bfd_mach_avr5},
1665 +  {"atmega2560", AVR_ISA_ALL,     bfd_mach_avr6},
1666 +  {"atmega2561", AVR_ISA_ALL,     bfd_mach_avr6},
1667    {NULL, 0, 0}
1668  };
1669  
1670 @@ -512,7 +515,7 @@
1671    if (exp->X_op == O_constant)
1672      {
1673        int x = exp->X_add_number;
1674 -      
1675 +
1676        if (x < -255 || x > 255)
1677         as_warn (_("constant out of 8-bit range: %d"), x);
1678      }
1679 @@ -544,6 +547,8 @@
1680    char *tmp;
1681    char op[8];
1682    int mod;
1683 +  int linker_stubs_should_be_generated = 0;
1684 +
1685    tmp = str;
1686  
1687    str = extract_word (str, op, sizeof (op));
1688 @@ -551,7 +556,7 @@
1689    if (op[0])
1690      {
1691        mod_index m;
1692 -      
1693 +
1694        m.ptr = hash_find (avr_mod_hash, op);
1695        mod = m.index;
1696  
1697 @@ -564,11 +569,14 @@
1698  
1699           if (*str == '(')
1700             {
1701 +             bfd_reloc_code_real_type  reloc_to_return;
1702               int neg_p = 0;
1703  
1704               ++str;
1705  
1706               if (strncmp ("pm(", str, 3) == 0
1707 +                  || strncmp ("gs(",str,3) == 0
1708 +                  || strncmp ("-(gs(",str,5) == 0
1709                   || strncmp ("-(pm(", str, 5) == 0)
1710                 {
1711                   if (HAVE_PM_P (mod))
1712 @@ -579,6 +587,9 @@
1713                   else
1714                     as_bad (_("illegal expression"));
1715  
1716 +                  if (str[0] == 'g' || str[2] == 'g')
1717 +                    linker_stubs_should_be_generated = 1;
1718 +
1719                   if (*str == '-')
1720                     {
1721                       neg_p = 1;
1722 @@ -610,7 +621,24 @@
1723                 }
1724               while (closes--);
1725  
1726 -             return neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod);
1727 +             reloc_to_return =
1728 +               neg_p ? EXP_MOD_NEG_RELOC (mod) : EXP_MOD_RELOC (mod);
1729 +             if (linker_stubs_should_be_generated)
1730 +               {
1731 +                 switch (reloc_to_return)
1732 +                   {
1733 +                   case BFD_RELOC_AVR_LO8_LDI_PM:
1734 +                     reloc_to_return = BFD_RELOC_AVR_LO8_LDI_GS;
1735 +                     break;
1736 +                   case BFD_RELOC_AVR_HI8_LDI_PM:
1737 +                     reloc_to_return = BFD_RELOC_AVR_HI8_LDI_GS;
1738 +                     break;
1739 +
1740 +                   default:
1741 +                     break; /* as_warn (_("expression dangerous with linker stubs")); *//* Bjoern agreed. :) */
1742 +                   }
1743 +               }
1744 +             return reloc_to_return;
1745             }
1746         }
1747      }
1748 @@ -1227,7 +1255,7 @@
1749            return NULL;
1750          }
1751  
1752 -      /* We are dealing with two symbols defined in the same section. 
1753 +      /* We are dealing with two symbols defined in the same section.
1754           Let us fix-up them here.  */
1755        value += S_GET_VALUE (fixp->fx_addsy);
1756        value -= S_GET_VALUE (fixp->fx_subsy);
1757 @@ -1310,7 +1338,8 @@
1758  static int exp_mod_pm = 0;
1759  
1760  /* Parse special CONS expression: pm (expression)
1761 -   which is used for addressing to a program memory.
1762 +   or alternatively: gs (expression).
1763 +   These are used for addressing program memory.
1764     Relocation: BFD_RELOC_AVR_16_PM.  */
1765  
1766  void
1767 @@ -1324,10 +1353,13 @@
1768  
1769    if (nbytes == 2)
1770      {
1771 -      char *pm_name = "pm";
1772 -      int len = strlen (pm_name);
1773 +      char *pm_name1 = "pm";
1774 +      char *pm_name2 = "gs";
1775 +      int len = strlen (pm_name1);
1776 +      /* len must be the same for both pm identifiers.  */
1777  
1778 -      if (strncasecmp (input_line_pointer, pm_name, len) == 0)
1779 +      if (strncasecmp (input_line_pointer, pm_name1, len) == 0
1780 +          || strncasecmp (input_line_pointer, pm_name2, len) == 0)
1781         {
1782           input_line_pointer = skip_space (input_line_pointer + len);
1783  
1784 diff -Nur gas/config/tc-avr.h gas/config/tc-avr.h
1785 --- gas/config/tc-avr.h 2006-05-17 18:04:30.000000000 +0200
1786 +++ gas/config/tc-avr.h 2006-08-28 20:02:16.952294172 +0200
1787 @@ -125,16 +125,21 @@
1788     We will need them in case that we want to do linker relaxation.
1789     We could in principle keep these fixups in gas when not relaxing.
1790     However, there is no serious performance penilty when making the linker
1791 -   make the fixup work.  */
1792 -#define TC_VALIDATE_FIX(FIXP,SEG,SKIP)                     \
1793 - if (   (FIXP->fx_r_type == BFD_RELOC_AVR_7_PCREL          \
1794 -      || FIXP->fx_r_type == BFD_RELOC_AVR_13_PCREL         \
1795 -      || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM       \
1796 -      || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM       \
1797 -      || FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM       \
1798 -      || FIXP->fx_r_type == BFD_RELOC_AVR_16_PM)           \
1799 -     && (FIXP->fx_addsy))                                  \
1800 -   {                                                       \
1801 -     goto SKIP;                                            \
1802 +   make the fixup work.  Check also that fx_addsy is not NULL, in order to make
1803 +   sure that the fixup refers to some sort of lable.  */
1804 +#define TC_VALIDATE_FIX(FIXP,SEG,SKIP)                       \
1805 +  if (   (FIXP->fx_r_type == BFD_RELOC_AVR_7_PCREL           \
1806 +       || FIXP->fx_r_type == BFD_RELOC_AVR_13_PCREL          \
1807 +       || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM        \
1808 +       || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_GS        \
1809 +       || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM        \
1810 +       || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_GS        \
1811 +       || FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM        \
1812 +       || FIXP->fx_r_type == BFD_RELOC_AVR_LO8_LDI_PM_NEG    \
1813 +       || FIXP->fx_r_type == BFD_RELOC_AVR_HI8_LDI_PM_NEG    \
1814 +       || FIXP->fx_r_type == BFD_RELOC_AVR_HH8_LDI_PM_NEG    \
1815 +       || FIXP->fx_r_type == BFD_RELOC_AVR_16_PM)            \
1816 +      && (FIXP->fx_addsy))                                  \
1817 +    {                                                        \
1818 +      goto SKIP;                                             \
1819     }
1820 -
1821 diff -Nur include/elf/avr.h include/elf/avr.h
1822 --- include/elf/avr.h   2006-03-03 16:25:30.000000000 +0100
1823 +++ include/elf/avr.h   2006-08-28 20:02:16.998290837 +0200
1824 @@ -1,5 +1,5 @@
1825  /* AVR ELF support for BFD.
1826 -   Copyright 1999, 2000, 2004 Free Software Foundation, Inc.
1827 +   Copyright 1999, 2000, 2004, 2006 Free Software Foundation, Inc.
1828     Contributed by Denis Chertykov <denisc@overta.ru>
1829  
1830     This file is part of BFD, the Binary File Descriptor library.
1831 @@ -35,6 +35,7 @@
1832  #define E_AVR_MACH_AVR3 3
1833  #define E_AVR_MACH_AVR4 4
1834  #define E_AVR_MACH_AVR5 5
1835 +#define E_AVR_MACH_AVR6 6 
1836  
1837  /* Relocations.  */
1838  START_RELOC_NUMBERS (elf_avr_reloc_type)
1839 @@ -62,6 +63,8 @@
1840       RELOC_NUMBER (R_AVR_6_ADIW,               21)
1841       RELOC_NUMBER (R_AVR_MS8_LDI,              22)
1842       RELOC_NUMBER (R_AVR_MS8_LDI_NEG,          23)
1843 +     RELOC_NUMBER (R_AVR_LO8_LDI_GS,          24)
1844 +     RELOC_NUMBER (R_AVR_HI8_LDI_GS,          25)
1845  END_RELOC_NUMBERS (R_AVR_max)
1846  
1847  #endif /* _ELF_AVR_H */
1848 diff -Nur include/elf/ChangeLog include/elf/ChangeLog
1849 --- include/elf/ChangeLog       2006-03-22 10:28:12.000000000 +0100
1850 +++ include/elf/ChangeLog       2006-08-28 20:02:17.001290619 +0200
1851 @@ -1,3 +1,7 @@
1852 +2006-05-24  Bjoern Haase  <bjoern.m.haase@web.de> 
1853 +       
1854 +       * avr.h: Add E_AVR_MACH_AVR6, R_AVR_LO8_LDI_GS and R_AVR_HI8_LDI_GS.
1855 +
1856  2006-03-22  Richard Sandiford  <richard@codesourcery.com>
1857             Daniel Jacobowitz  <dan@codesourcery.com>
1858             Phil Edwards  <phil@codesourcery.com>
1859 diff -Nur ld/configure.tgt ld/configure.tgt
1860 --- ld/configure.tgt    2006-04-05 14:41:57.000000000 +0200
1861 +++ ld/configure.tgt    2006-08-28 20:02:17.029288589 +0200
1862 @@ -81,7 +81,7 @@
1863  xscale-*-elf)          targ_emul=armelf
1864                         ;;
1865  avr-*-*)               targ_emul=avr2
1866 -                       targ_extra_emuls="avr1 avr3 avr4 avr5"
1867 +                       targ_extra_emuls="avr1 avr3 avr4 avr5 avr6"
1868                         ;;
1869  bfin-*-elf)            targ_emul=elf32bfin; targ_extra_emuls="elf32bfinfd" ;;
1870  bfin-*-uclinux*)       targ_emul=elf32bfin; targ_extra_emuls="elf32bfinfd" ;;
1871 diff -Nur ld/emulparams/avr1.sh ld/emulparams/avr1.sh
1872 --- ld/emulparams/avr1.sh       2002-05-16 21:51:08.000000000 +0200
1873 +++ ld/emulparams/avr1.sh       2006-08-28 20:02:17.031288444 +0200
1874 @@ -4,7 +4,8 @@
1875  OUTPUT_FORMAT="elf32-avr"
1876  MAXPAGESIZE=1
1877  EMBEDDED=yes
1878 -TEMPLATE_NAME=generic
1879 +TEMPLATE_NAME=elf32
1880  
1881  TEXT_LENGTH=8K
1882  DATA_LENGTH=0
1883 +EXTRA_EM_FILE=avrelf
1884 diff -Nur ld/emulparams/avr2.sh ld/emulparams/avr2.sh
1885 --- ld/emulparams/avr2.sh       2002-05-16 21:51:08.000000000 +0200
1886 +++ ld/emulparams/avr2.sh       2006-08-28 20:02:17.033288299 +0200
1887 @@ -4,7 +4,8 @@
1888  OUTPUT_FORMAT="elf32-avr"
1889  MAXPAGESIZE=1
1890  EMBEDDED=yes
1891 -TEMPLATE_NAME=generic
1892 +TEMPLATE_NAME=elf32
1893  
1894  TEXT_LENGTH=8K
1895  DATA_LENGTH=0xffa0
1896 +EXTRA_EM_FILE=avrelf
1897 diff -Nur ld/emulparams/avr3.sh ld/emulparams/avr3.sh
1898 --- ld/emulparams/avr3.sh       2002-05-16 21:51:08.000000000 +0200
1899 +++ ld/emulparams/avr3.sh       2006-08-28 20:02:17.036288081 +0200
1900 @@ -4,7 +4,8 @@
1901  OUTPUT_FORMAT="elf32-avr"
1902  MAXPAGESIZE=1
1903  EMBEDDED=yes
1904 -TEMPLATE_NAME=generic
1905 +TEMPLATE_NAME=elf32
1906  
1907  TEXT_LENGTH=128K
1908  DATA_LENGTH=0xffa0
1909 +EXTRA_EM_FILE=avrelf
1910 diff -Nur ld/emulparams/avr4.sh ld/emulparams/avr4.sh
1911 --- ld/emulparams/avr4.sh       2002-05-16 21:51:08.000000000 +0200
1912 +++ ld/emulparams/avr4.sh       2006-08-28 20:02:17.038287936 +0200
1913 @@ -4,7 +4,8 @@
1914  OUTPUT_FORMAT="elf32-avr"
1915  MAXPAGESIZE=1
1916  EMBEDDED=yes
1917 -TEMPLATE_NAME=generic
1918 +TEMPLATE_NAME=elf32
1919  
1920  TEXT_LENGTH=8K
1921  DATA_LENGTH=0xffa0
1922 +EXTRA_EM_FILE=avrelf
1923 diff -Nur ld/emulparams/avr5.sh ld/emulparams/avr5.sh
1924 --- ld/emulparams/avr5.sh       2002-05-16 21:51:08.000000000 +0200
1925 +++ ld/emulparams/avr5.sh       2006-08-28 20:02:17.040287791 +0200
1926 @@ -4,7 +4,8 @@
1927  OUTPUT_FORMAT="elf32-avr"
1928  MAXPAGESIZE=1
1929  EMBEDDED=yes
1930 -TEMPLATE_NAME=generic
1931 +TEMPLATE_NAME=elf32
1932  
1933  TEXT_LENGTH=128K
1934  DATA_LENGTH=0xffa0
1935 +EXTRA_EM_FILE=avrelf
1936 diff -Nur ld/emulparams/avr6.sh ld/emulparams/avr6.sh
1937 --- ld/emulparams/avr6.sh       1970-01-01 01:00:00.000000000 +0100
1938 +++ ld/emulparams/avr6.sh       2006-08-28 20:02:17.043287574 +0200
1939 @@ -0,0 +1,11 @@
1940 +ARCH=avr:6
1941 +MACHINE=
1942 +SCRIPT_NAME=avr
1943 +OUTPUT_FORMAT="elf32-avr"
1944 +MAXPAGESIZE=1
1945 +EMBEDDED=yes
1946 +TEMPLATE_NAME=elf32
1947 +
1948 +TEXT_LENGTH=1024K
1949 +DATA_LENGTH=0xffa0
1950 +EXTRA_EM_FILE=avrelf
1951 diff -Nur ld/emultempl/avrelf.em ld/emultempl/avrelf.em
1952 --- ld/emultempl/avrelf.em      1970-01-01 01:00:00.000000000 +0100
1953 +++ ld/emultempl/avrelf.em      2006-08-28 20:02:17.047287284 +0200
1954 @@ -0,0 +1,267 @@
1955 +# This shell script emits a C file. -*- C -*-
1956 +#   Copyright 2006
1957 +#   Free Software Foundation, Inc.
1958 +#
1959 +# This file is part of GLD, the Gnu Linker.
1960 +#
1961 +# This program is free software; you can redistribute it and/or modify
1962 +# it under the terms of the GNU General Public License as published by
1963 +# the Free Software Foundation; either version 2 of the License, or
1964 +# (at your option) any later version.
1965 +#
1966 +# This program is distributed in the hope that it will be useful,
1967 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1968 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1969 +# GNU General Public License for more details.
1970 +#
1971 +# You should have received a copy of the GNU General Public License
1972 +# along with this program; if not, write to the Free Software
1973 +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 
1974 +# MA 02110-1301 USA.
1975 +
1976 +# This file is sourced from elf32.em, and defines extra avr-elf
1977 +# specific routines.  It is used to generate the trampolines for the avr6
1978 +# family devices where one needs to address the issue that it is not possible
1979 +# to reach the whole program memory by using 16 bit pointers.
1980 +
1981 +cat >>e${EMULATION_NAME}.c <<EOF
1982 +
1983 +#include "elf32-avr.h"
1984 +#include "ldctor.h"
1985 +
1986 +/* The fake file and it's corresponding section meant to hold 
1987 +   the linker stubs if needed.  */
1988 +
1989 +static lang_input_statement_type *stub_file;
1990 +static asection *avr_stub_section;
1991 +
1992 +/* Variables set by the command-line parameters and transfered
1993 +   to the bfd without use of global shared variables.  */
1994 +
1995 +static bfd_boolean avr_no_stubs = FALSE;
1996 +static bfd_boolean avr_debug_relax = FALSE;
1997 +static bfd_boolean avr_debug_stubs = FALSE;
1998 +static bfd_boolean avr_replace_call_ret_sequences = TRUE;
1999 +static bfd_vma avr_pc_wrap_around = 0x10000000;
2000 +
2001 +/* Transfers information to the bfd frontend.  */
2002 +
2003 +static void
2004 +avr_elf_set_global_bfd_parameters (void)
2005 +{
2006 +  elf32_avr_setup_params (& link_info,
2007 +                          stub_file->the_bfd,
2008 +                          avr_stub_section,
2009 +                          avr_no_stubs,
2010 +                          avr_debug_stubs,
2011 +                          avr_debug_relax,
2012 +                          avr_pc_wrap_around,
2013 +                          avr_replace_call_ret_sequences);
2014 +}
2015 +
2016 +
2017 +/* Makes a conservative estimate of the trampoline section size that could
2018 +   be corrected later on.  */
2019 +
2020 +static void
2021 +avr_elf_${EMULATION_NAME}_before_allocation (void)
2022 +{
2023 +  int ret;
2024 +
2025 +  gld${EMULATION_NAME}_before_allocation ();
2026 +
2027 +  /* We only need stubs for the avr6 family.  */
2028 +  if (strcmp ("${EMULATION_NAME}","avr6"))
2029 +    avr_no_stubs = TRUE;
2030 +
2031 +  avr_elf_set_global_bfd_parameters ();
2032 +
2033 +  /* If generating a relocatable output file, then
2034 +     we don't  have to generate the trampolines.  */
2035 +  if (link_info.relocatable)
2036 +    avr_no_stubs = TRUE;
2037 +
2038 +  if (avr_no_stubs)
2039 +    return;
2040 +
2041 +  ret = elf32_avr_setup_section_lists (output_bfd, &link_info);
2042 +
2043 +  if (ret < 0)
2044 +    einfo ("%X%P: can not setup the input section list: %E\n");
2045 +
2046 +  if (ret <= 0)
2047 +    return;
2048 +
2049 +  /* Call into the BFD backend to do the real "stub"-work.  */
2050 +  if (! elf32_avr_size_stubs (output_bfd, &link_info, TRUE))
2051 +    einfo ("%X%P: can not size stub section: %E\n");
2052 +}
2053 +
2054 +/* This is called before the input files are opened.  We create a new
2055 +   fake input file to hold the stub section and generate the section itself.  */
2056 +
2057 +static void
2058 +avr_elf_create_output_section_statements (void)
2059 +{
2060 +  flagword flags;
2061 +
2062 +  stub_file = lang_add_input_file ("linker stubs",
2063 +                                   lang_input_file_is_fake_enum,
2064 +                                   NULL);
2065 +
2066 +  stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
2067 +  if (stub_file->the_bfd == NULL
2068 +      || !bfd_set_arch_mach (stub_file->the_bfd,
2069 +                             bfd_get_arch (output_bfd),
2070 +                             bfd_get_mach (output_bfd)))
2071 +    {
2072 +      einfo ("%X%P: can not create stub BFD %E\n");
2073 +      return;
2074 +    }
2075 +
2076 +  /* Now we add the stub section.  */
2077 +
2078 +  avr_stub_section = bfd_make_section_anyway (stub_file->the_bfd,
2079 +                                              ".trampolines");
2080 +  if (avr_stub_section == NULL)
2081 +    goto err_ret;
2082 +  
2083 +  flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
2084 +           | SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
2085 +  if (!bfd_set_section_flags (stub_file->the_bfd, avr_stub_section, flags))
2086 +    goto err_ret;
2087 +
2088 +  avr_stub_section->alignment_power = 1;
2089 +  
2090 +  ldlang_add_file (stub_file);
2091 +
2092 +  return;
2093 +
2094 +  err_ret:
2095 +   einfo ("%X%P: can not make stub section: %E\n");
2096 +   return;
2097 +}
2098 +
2099 +/* Re-calculates the size of the stubs so that we won't waste space.  */
2100 +
2101 +static void
2102 +avr_elf_finish (void)
2103 +{ 
2104 +  if (!avr_no_stubs)
2105 +    {
2106 +      /* Now build the linker stubs.  */
2107 +      if (stub_file->the_bfd->sections != NULL)
2108 +       {
2109 +         /* Call again the trampoline analyzer to initialize the trampoline
2110 +            stubs with the correct symbol addresses.  Since there could have
2111 +            been relaxation, the symbol addresses that were found during
2112 +            first call may no longer be correct.  */
2113 +         if (!elf32_avr_size_stubs (output_bfd, &link_info, FALSE))
2114 +           {
2115 +             einfo ("%X%P: can not size stub section: %E\n");
2116 +             return;
2117 +           }
2118 +
2119 +         if (!elf32_avr_build_stubs (&link_info))
2120 +           einfo ("%X%P: can not build stubs: %E\n");
2121 +       }
2122 +    }
2123 +
2124 +  gld${EMULATION_NAME}_finish ();
2125 +}
2126 +
2127 +
2128 +EOF
2129 +
2130 +
2131 +PARSE_AND_LIST_PROLOGUE='
2132 +
2133 +#define OPTION_NO_CALL_RET_REPLACEMENT 301
2134 +#define OPTION_PMEM_WRAP_AROUND        302
2135 +#define OPTION_NO_STUBS                303
2136 +#define OPTION_DEBUG_STUBS             304
2137 +#define OPTION_DEBUG_RELAX             305
2138 +'
2139 +
2140 +PARSE_AND_LIST_LONGOPTS='
2141 +  { "no-call-ret-replacement", no_argument, 
2142 +     NULL, OPTION_NO_CALL_RET_REPLACEMENT},
2143 +  { "pmem-wrap-around", required_argument, 
2144 +    NULL, OPTION_PMEM_WRAP_AROUND},
2145 +  { "no-stubs", no_argument, 
2146 +    NULL, OPTION_NO_STUBS},
2147 +  { "debug-stubs", no_argument, 
2148 +    NULL, OPTION_DEBUG_STUBS},
2149 +  { "debug-relax", no_argument, 
2150 +    NULL, OPTION_DEBUG_RELAX},
2151 +'
2152 +
2153 +PARSE_AND_LIST_OPTIONS='
2154 +  fprintf (file, _("     --pmem-wrap-around=<val> "
2155 +                           "Make the linker relaxation machine assume that a\n"
2156 +                   "                              "
2157 +                           "program counter wrap-around occures at address\n"
2158 +                   "                              "
2159 +                           "<val>. Supported values are 16k, 32k and 64k.\n"));
2160 +  fprintf (file, _("     --no-call-ret-replacement "
2161 +                           "The relaxation machine normally will\n"
2162 +                   "                               "
2163 +                           "substitute two immediately following call/ret\n"
2164 +                   "                               "
2165 +                           "instructions by a single jump instruction.\n"
2166 +                   "                               "
2167 +                           "This option disables this optimization.\n"));
2168 +  fprintf (file, _("     --no-stubs "
2169 +                           "If the linker detects to attempt to access\n"
2170 +                   "                               "
2171 +                           "an instruction beyond 128k by a reloc that\n"
2172 +                   "                               "
2173 +                           "is limited to 128k max, it inserts a jump\n"
2174 +                   "                               "
2175 +                           "stub. You can de-active this with this switch.\n"));
2176 +  fprintf (file, _("     --debug-stubs Used for debugging avr-ld.\n"));
2177 +  fprintf (file, _("     --debug-relax Used for debugging avr-ld.\n"));
2178 +'
2179 +
2180 +PARSE_AND_LIST_ARGS_CASES='
2181 +
2182 +    case OPTION_PMEM_WRAP_AROUND:
2183 +      { 
2184 +        /* This variable is defined in the bfd library.  */
2185 +        if ((!strcmp (optarg,"32k"))      || (!strcmp (optarg,"32K")))
2186 +          avr_pc_wrap_around = 32768;
2187 +        else if ((!strcmp (optarg,"16k")) || (!strcmp (optarg,"16K")))
2188 +          avr_pc_wrap_around = 16384;
2189 +        else if ((!strcmp (optarg,"64k")) || (!strcmp (optarg,"64K")))
2190 +          avr_pc_wrap_around = 0x10000;
2191 +        else
2192 +          return FALSE;
2193 +      }
2194 +      break;
2195 +
2196 +    case OPTION_DEBUG_STUBS:
2197 +      avr_debug_stubs = TRUE;
2198 +      break;
2199 +
2200 +    case OPTION_DEBUG_RELAX:
2201 +      avr_debug_relax = TRUE;
2202 +      break;
2203 +
2204 +    case OPTION_NO_STUBS:
2205 +      avr_no_stubs = TRUE;
2206 +      break;
2207 +
2208 +    case OPTION_NO_CALL_RET_REPLACEMENT:
2209 +      {
2210 +        /* This variable is defined in the bfd library.  */
2211 +        avr_replace_call_ret_sequences = FALSE;
2212 +      }
2213 +      break;
2214 +'
2215 +
2216 +#
2217 +# Put these extra avr-elf routines in ld_${EMULATION_NAME}_emulation
2218 +#
2219 +LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation
2220 +LDEMUL_FINISH=avr_elf_finish
2221 +LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements
2222 diff -Nur ld/Makefile.am ld/Makefile.am
2223 --- ld/Makefile.am      2006-06-03 06:45:50.000000000 +0200
2224 +++ ld/Makefile.am      2006-08-28 20:02:17.055286703 +0200
2225 @@ -133,6 +133,7 @@
2226         eavr3.o \
2227         eavr4.o \
2228         eavr5.o \
2229 +       eavr6.o \
2230         ecoff_i860.o \
2231         ecoff_sparc.o \
2232         ecrisaout.o \
2233 @@ -595,6 +596,10 @@
2234    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \
2235    ${GEN_DEPENDS}
2236         ${GENSCRIPTS} avr5 "$(tdir_avr2)"
2237 +eavr6.c: $(srcdir)/emulparams/avr6.sh \
2238 +  $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \
2239 +  ${GEN_DEPENDS}
2240 +       ${GENSCRIPTS} avr6 "$(tdir_avr2)"
2241  ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \
2242    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS}
2243         ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)"
2244 diff -Nur ld/Makefile.in ld/Makefile.in
2245 --- ld/Makefile.in      2006-06-03 06:45:50.000000000 +0200
2246 +++ ld/Makefile.in      2006-08-28 20:02:17.072285471 +0200
2247 @@ -357,6 +357,7 @@
2248         eavr3.o \
2249         eavr4.o \
2250         eavr5.o \
2251 +       eavr6.o \
2252         ecoff_i860.o \
2253         ecoff_sparc.o \
2254         ecrisaout.o \
2255 @@ -1406,6 +1407,10 @@
2256    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \
2257    ${GEN_DEPENDS}
2258         ${GENSCRIPTS} avr5 "$(tdir_avr2)"
2259 +eavr6.c: $(srcdir)/emulparams/avr6.sh \
2260 +  $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/avr.sc \
2261 +  ${GEN_DEPENDS}
2262 +       ${GENSCRIPTS} avr6 "$(tdir_avr2)"
2263  ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \
2264    $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS}
2265         ${GENSCRIPTS} coff_i860 "$(tdir_coff_i860)"
2266 diff -Nur ld/scripttempl/avr.sc ld/scripttempl/avr.sc
2267 --- ld/scripttempl/avr.sc       2006-03-03 16:25:31.000000000 +0100
2268 +++ ld/scripttempl/avr.sc       2006-08-28 20:02:17.078285036 +0200
2269 @@ -71,12 +71,32 @@
2270    .rel.plt     ${RELOCATING-0} : { *(.rel.plt)         }
2271    .rela.plt    ${RELOCATING-0} : { *(.rela.plt)                }
2272  
2273 -  /* Internal text space or external memory */
2274 +  /* Internal text space or external memory.  */
2275    .text :
2276    {
2277      *(.vectors)
2278      KEEP(*(.vectors))
2279  
2280 +    /* For data that needs to reside in the lower 64k of progmem.  */
2281 +    *(.progmem.gcc*)
2282 +    *(.progmem*)
2283 +    ${RELOCATING+. = ALIGN(2);}
2284 +
2285 +    ${CONSTRUCTING+ __trampolines_start = . ; }
2286 +    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
2287 +    *(.trampolines)
2288 +    *(.trampolines*)
2289 +    ${CONSTRUCTING+ __trampolines_end = . ; }
2290 +
2291 +    /* For future tablejump instruction arrays for 3 byte pc devices.
2292 +       We don't relax jump/call instructions within these sections.  */
2293 +    *(.jumptables) 
2294 +    *(.jumptables*) 
2295 +
2296 +    /* For code that needs to reside in the lower 128k progmem.  */
2297 +    *(.lowtext)
2298 +    *(.lowtext*)
2299 +
2300      ${CONSTRUCTING+ __ctors_start = . ; }
2301      ${CONSTRUCTING+ *(.ctors) }
2302      ${CONSTRUCTING+ __ctors_end = . ; }
2303 @@ -86,18 +106,8 @@
2304      KEEP(SORT(*)(.ctors))
2305      KEEP(SORT(*)(.dtors))
2306  
2307 -    /* For data that needs to reside in the lower 64k of progmem */
2308 -    *(.progmem.gcc*)
2309 -    *(.progmem*)
2310 -    ${RELOCATING+. = ALIGN(2);}
2311 -    
2312 -    /* for future tablejump instruction arrays for 3 byte pc devices */
2313 -    *(.jumptables) 
2314 -    *(.jumptables*) 
2315 -    /* for code that needs to reside in the lower 128k progmem */
2316 -    *(.lowtext)
2317 -    *(.lowtext*)  
2318 -
2319 +    /* From this point on, we don't bother about wether the insns are
2320 +       below or above the 16 bits boundary.  */
2321      *(.init0)  /* Start here after reset.  */
2322      KEEP (*(.init0))
2323      *(.init1)
This page took 0.530877 seconds and 3 git commands to generate.