1 /* AVR-specific support for 32-bit ELF
2 Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov <denisc@overta.ru>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
27 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
28 PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
29 static void avr_info_to_howto_rela
30 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
31 static asection *elf32_avr_gc_mark_hook
32 PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
33 struct elf_link_hash_entry *, Elf_Internal_Sym *));
34 static boolean elf32_avr_gc_sweep_hook
35 PARAMS ((bfd *, struct bfd_link_info *, asection *,
36 const Elf_Internal_Rela *));
37 static boolean elf32_avr_check_relocs
38 PARAMS ((bfd *, struct bfd_link_info *, asection *,
39 const Elf_Internal_Rela *));
40 static bfd_reloc_status_type avr_final_link_relocate
41 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
42 Elf_Internal_Rela *, bfd_vma));
43 static boolean elf32_avr_relocate_section
44 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
45 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
46 static void bfd_elf_avr_final_write_processing PARAMS ((bfd *, boolean));
47 static boolean elf32_avr_object_p PARAMS ((bfd *));
49 /* Use RELA instead of REL */
52 static reloc_howto_type elf_avr_howto_table[] =
54 HOWTO (R_AVR_NONE, /* type */
56 2, /* size (0 = byte, 1 = short, 2 = long) */
58 false, /* pc_relative */
60 complain_overflow_bitfield, /* complain_on_overflow */
61 bfd_elf_generic_reloc, /* special_function */
62 "R_AVR_NONE", /* name */
63 false, /* partial_inplace */
66 false), /* pcrel_offset */
68 HOWTO (R_AVR_32, /* type */
70 2, /* size (0 = byte, 1 = short, 2 = long) */
72 false, /* pc_relative */
74 complain_overflow_bitfield, /* complain_on_overflow */
75 bfd_elf_generic_reloc, /* special_function */
76 "R_AVR_32", /* name */
77 false, /* partial_inplace */
78 0xffffffff, /* src_mask */
79 0xffffffff, /* dst_mask */
80 false), /* pcrel_offset */
82 /* A 7 bit PC relative relocation. */
83 HOWTO (R_AVR_7_PCREL, /* type */
85 1, /* size (0 = byte, 1 = short, 2 = long) */
87 true, /* pc_relative */
89 complain_overflow_bitfield, /* complain_on_overflow */
90 bfd_elf_generic_reloc, /* special_function */
91 "R_AVR_7_PCREL", /* name */
92 false, /* partial_inplace */
93 0xffff, /* src_mask */
94 0xffff, /* dst_mask */
95 true), /* pcrel_offset */
97 /* A 13 bit PC relative relocation. */
98 HOWTO (R_AVR_13_PCREL, /* type */
100 1, /* size (0 = byte, 1 = short, 2 = long) */
102 true, /* pc_relative */
104 complain_overflow_bitfield, /* complain_on_overflow */
105 bfd_elf_generic_reloc, /* special_function */
106 "R_AVR_13_PCREL", /* name */
107 false, /* partial_inplace */
108 0xfff, /* src_mask */
109 0xfff, /* dst_mask */
110 true), /* pcrel_offset */
112 /* A 16 bit absolute relocation. */
113 HOWTO (R_AVR_16, /* type */
115 1, /* size (0 = byte, 1 = short, 2 = long) */
117 false, /* pc_relative */
119 complain_overflow_dont, /* complain_on_overflow */
120 bfd_elf_generic_reloc, /* special_function */
121 "R_AVR_16", /* name */
122 false, /* partial_inplace */
123 0xffff, /* src_mask */
124 0xffff, /* dst_mask */
125 false), /* pcrel_offset */
127 /* A 16 bit absolute relocation for command address. */
128 HOWTO (R_AVR_16_PM, /* type */
130 1, /* size (0 = byte, 1 = short, 2 = long) */
132 false, /* pc_relative */
134 complain_overflow_bitfield, /* complain_on_overflow */
135 bfd_elf_generic_reloc, /* special_function */
136 "R_AVR_16_PM", /* name */
137 false, /* partial_inplace */
138 0xffff, /* src_mask */
139 0xffff, /* dst_mask */
140 false), /* pcrel_offset */
141 /* A low 8 bit absolute relocation of 16 bit address.
143 HOWTO (R_AVR_LO8_LDI, /* type */
145 1, /* size (0 = byte, 1 = short, 2 = long) */
147 false, /* pc_relative */
149 complain_overflow_dont, /* complain_on_overflow */
150 bfd_elf_generic_reloc, /* special_function */
151 "R_AVR_LO8_LDI", /* name */
152 false, /* partial_inplace */
153 0xffff, /* src_mask */
154 0xffff, /* dst_mask */
155 false), /* pcrel_offset */
156 /* A high 8 bit absolute relocation of 16 bit address.
158 HOWTO (R_AVR_HI8_LDI, /* type */
160 1, /* size (0 = byte, 1 = short, 2 = long) */
162 false, /* pc_relative */
164 complain_overflow_dont, /* complain_on_overflow */
165 bfd_elf_generic_reloc, /* special_function */
166 "R_AVR_HI8_LDI", /* name */
167 false, /* partial_inplace */
168 0xffff, /* src_mask */
169 0xffff, /* dst_mask */
170 false), /* pcrel_offset */
171 /* A high 6 bit absolute relocation of 22 bit address.
173 HOWTO (R_AVR_HH8_LDI, /* type */
175 1, /* size (0 = byte, 1 = short, 2 = long) */
177 false, /* pc_relative */
179 complain_overflow_dont, /* complain_on_overflow */
180 bfd_elf_generic_reloc, /* special_function */
181 "R_AVR_HH8_LDI", /* name */
182 false, /* partial_inplace */
183 0xffff, /* src_mask */
184 0xffff, /* dst_mask */
185 false), /* pcrel_offset */
186 /* A negative low 8 bit absolute relocation of 16 bit address.
188 HOWTO (R_AVR_LO8_LDI_NEG, /* type */
190 1, /* size (0 = byte, 1 = short, 2 = long) */
192 false, /* pc_relative */
194 complain_overflow_dont, /* complain_on_overflow */
195 bfd_elf_generic_reloc, /* special_function */
196 "R_AVR_LO8_LDI_NEG", /* name */
197 false, /* partial_inplace */
198 0xffff, /* src_mask */
199 0xffff, /* dst_mask */
200 false), /* pcrel_offset */
201 /* A hegative high 8 bit absolute relocation of 16 bit address.
203 HOWTO (R_AVR_HI8_LDI_NEG, /* type */
205 1, /* size (0 = byte, 1 = short, 2 = long) */
207 false, /* pc_relative */
209 complain_overflow_dont, /* complain_on_overflow */
210 bfd_elf_generic_reloc, /* special_function */
211 "R_AVR_HI8_LDI_NEG", /* name */
212 false, /* partial_inplace */
213 0xffff, /* src_mask */
214 0xffff, /* dst_mask */
215 false), /* pcrel_offset */
216 /* A hegative high 6 bit absolute relocation of 22 bit address.
218 HOWTO (R_AVR_HH8_LDI_NEG, /* type */
220 1, /* size (0 = byte, 1 = short, 2 = long) */
222 false, /* pc_relative */
224 complain_overflow_dont, /* complain_on_overflow */
225 bfd_elf_generic_reloc, /* special_function */
226 "R_AVR_HH8_LDI_NEG", /* name */
227 false, /* partial_inplace */
228 0xffff, /* src_mask */
229 0xffff, /* dst_mask */
230 false), /* pcrel_offset */
231 /* A low 8 bit absolute relocation of 24 bit program memory address.
233 HOWTO (R_AVR_LO8_LDI_PM, /* type */
235 1, /* size (0 = byte, 1 = short, 2 = long) */
237 false, /* pc_relative */
239 complain_overflow_dont, /* complain_on_overflow */
240 bfd_elf_generic_reloc, /* special_function */
241 "R_AVR_LO8_LDI_PM", /* name */
242 false, /* partial_inplace */
243 0xffff, /* src_mask */
244 0xffff, /* dst_mask */
245 false), /* pcrel_offset */
246 /* A high 8 bit absolute relocation of 16 bit program memory address.
248 HOWTO (R_AVR_HI8_LDI_PM, /* type */
250 1, /* size (0 = byte, 1 = short, 2 = long) */
252 false, /* pc_relative */
254 complain_overflow_dont, /* complain_on_overflow */
255 bfd_elf_generic_reloc, /* special_function */
256 "R_AVR_HI8_LDI_PM", /* name */
257 false, /* partial_inplace */
258 0xffff, /* src_mask */
259 0xffff, /* dst_mask */
260 false), /* pcrel_offset */
261 /* A high 8 bit absolute relocation of 24 bit program memory address.
263 HOWTO (R_AVR_HH8_LDI_PM, /* type */
265 1, /* size (0 = byte, 1 = short, 2 = long) */
267 false, /* pc_relative */
269 complain_overflow_dont, /* complain_on_overflow */
270 bfd_elf_generic_reloc, /* special_function */
271 "R_AVR_HH8_LDI_PM", /* name */
272 false, /* partial_inplace */
273 0xffff, /* src_mask */
274 0xffff, /* dst_mask */
275 false), /* pcrel_offset */
276 /* A low 8 bit absolute relocation of a negative 24 bit
277 program memory address. For LDI command. */
278 HOWTO (R_AVR_LO8_LDI_PM_NEG, /* type */
280 1, /* size (0 = byte, 1 = short, 2 = long) */
282 false, /* pc_relative */
284 complain_overflow_dont, /* complain_on_overflow */
285 bfd_elf_generic_reloc, /* special_function */
286 "R_AVR_LO8_LDI_PM_NEG", /* name */
287 false, /* partial_inplace */
288 0xffff, /* src_mask */
289 0xffff, /* dst_mask */
290 false), /* pcrel_offset */
291 /* A high 8 bit absolute relocation of a negative 16 bit
292 program memory address. For LDI command. */
293 HOWTO (R_AVR_HI8_LDI_PM_NEG, /* type */
295 1, /* size (0 = byte, 1 = short, 2 = long) */
297 false, /* pc_relative */
299 complain_overflow_dont, /* complain_on_overflow */
300 bfd_elf_generic_reloc, /* special_function */
301 "R_AVR_HI8_LDI_PM_NEG", /* name */
302 false, /* partial_inplace */
303 0xffff, /* src_mask */
304 0xffff, /* dst_mask */
305 false), /* pcrel_offset */
306 /* A high 8 bit absolute relocation of a negative 24 bit
307 program memory address. For LDI command. */
308 HOWTO (R_AVR_HH8_LDI_PM_NEG, /* type */
310 1, /* size (0 = byte, 1 = short, 2 = long) */
312 false, /* pc_relative */
314 complain_overflow_dont, /* complain_on_overflow */
315 bfd_elf_generic_reloc, /* special_function */
316 "R_AVR_HH8_LDI_PM_NEG", /* name */
317 false, /* partial_inplace */
318 0xffff, /* src_mask */
319 0xffff, /* dst_mask */
320 false), /* pcrel_offset */
321 /* Relocation for CALL command in ATmega. */
322 HOWTO (R_AVR_CALL, /* type */
324 2, /* size (0 = byte, 1 = short, 2 = long) */
326 false, /* pc_relative */
328 complain_overflow_dont, /* complain_on_overflow */
329 bfd_elf_generic_reloc, /* special_function */
330 "R_AVR_CALL", /* name */
331 false, /* partial_inplace */
332 0xffffffff, /* src_mask */
333 0xffffffff, /* dst_mask */
334 false) /* pcrel_offset */
337 /* Map BFD reloc types to AVR ELF reloc types. */
341 bfd_reloc_code_real_type bfd_reloc_val;
342 unsigned int elf_reloc_val;
345 static const struct avr_reloc_map avr_reloc_map[] =
347 { BFD_RELOC_NONE, R_AVR_NONE },
348 { BFD_RELOC_32, R_AVR_32 },
349 { BFD_RELOC_AVR_7_PCREL, R_AVR_7_PCREL },
350 { BFD_RELOC_AVR_13_PCREL, R_AVR_13_PCREL },
351 { BFD_RELOC_16, R_AVR_16 },
352 { BFD_RELOC_AVR_16_PM, R_AVR_16_PM },
353 { BFD_RELOC_AVR_LO8_LDI, R_AVR_LO8_LDI},
354 { BFD_RELOC_AVR_HI8_LDI, R_AVR_HI8_LDI },
355 { BFD_RELOC_AVR_HH8_LDI, R_AVR_HH8_LDI },
356 { BFD_RELOC_AVR_LO8_LDI_NEG, R_AVR_LO8_LDI_NEG },
357 { BFD_RELOC_AVR_HI8_LDI_NEG, R_AVR_HI8_LDI_NEG },
358 { BFD_RELOC_AVR_HH8_LDI_NEG, R_AVR_HH8_LDI_NEG },
359 { BFD_RELOC_AVR_LO8_LDI_PM, R_AVR_LO8_LDI_PM },
360 { BFD_RELOC_AVR_HI8_LDI_PM, R_AVR_HI8_LDI_PM },
361 { BFD_RELOC_AVR_HH8_LDI_PM, R_AVR_HH8_LDI_PM },
362 { BFD_RELOC_AVR_LO8_LDI_PM_NEG, R_AVR_LO8_LDI_PM_NEG },
363 { BFD_RELOC_AVR_HI8_LDI_PM_NEG, R_AVR_HI8_LDI_PM_NEG },
364 { BFD_RELOC_AVR_HH8_LDI_PM_NEG, R_AVR_HH8_LDI_PM_NEG },
365 { BFD_RELOC_AVR_CALL, R_AVR_CALL }
368 static reloc_howto_type *
369 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
370 bfd *abfd ATTRIBUTE_UNUSED;
371 bfd_reloc_code_real_type code;
376 i < sizeof (avr_reloc_map) / sizeof (struct avr_reloc_map);
379 if (avr_reloc_map[i].bfd_reloc_val == code)
380 return &elf_avr_howto_table[avr_reloc_map[i].elf_reloc_val];
386 /* Set the howto pointer for an AVR ELF reloc. */
389 avr_info_to_howto_rela (abfd, cache_ptr, dst)
390 bfd *abfd ATTRIBUTE_UNUSED;
392 Elf32_Internal_Rela *dst;
396 r_type = ELF32_R_TYPE (dst->r_info);
397 BFD_ASSERT (r_type < (unsigned int) R_AVR_max);
398 cache_ptr->howto = &elf_avr_howto_table[r_type];
402 elf32_avr_gc_mark_hook (sec, info, rel, h, sym)
404 struct bfd_link_info *info ATTRIBUTE_UNUSED;
405 Elf_Internal_Rela *rel;
406 struct elf_link_hash_entry *h;
407 Elf_Internal_Sym *sym;
411 switch (ELF32_R_TYPE (rel->r_info))
414 switch (h->root.type)
416 case bfd_link_hash_defined:
417 case bfd_link_hash_defweak:
418 return h->root.u.def.section;
420 case bfd_link_hash_common:
421 return h->root.u.c.p->section;
429 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
435 elf32_avr_gc_sweep_hook (abfd, info, sec, relocs)
436 bfd *abfd ATTRIBUTE_UNUSED;
437 struct bfd_link_info *info ATTRIBUTE_UNUSED;
438 asection *sec ATTRIBUTE_UNUSED;
439 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
441 /* We don't use got and plt entries for avr. */
445 /* Look through the relocs for a section during the first phase.
446 Since we don't do .gots or .plts, we just need to consider the
447 virtual table relocs for gc. */
450 elf32_avr_check_relocs (abfd, info, sec, relocs)
452 struct bfd_link_info *info;
454 const Elf_Internal_Rela *relocs;
456 Elf_Internal_Shdr *symtab_hdr;
457 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
458 const Elf_Internal_Rela *rel;
459 const Elf_Internal_Rela *rel_end;
461 if (info->relocateable)
464 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
465 sym_hashes = elf_sym_hashes (abfd);
466 sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
467 if (!elf_bad_symtab (abfd))
468 sym_hashes_end -= symtab_hdr->sh_info;
470 rel_end = relocs + sec->reloc_count;
471 for (rel = relocs; rel < rel_end; rel++)
473 struct elf_link_hash_entry *h;
474 unsigned long r_symndx;
476 r_symndx = ELF32_R_SYM (rel->r_info);
477 if (r_symndx < symtab_hdr->sh_info)
480 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
486 /* Perform a single relocation. By default we use the standard BFD
487 routines, but a few relocs, we have to do them ourselves. */
489 static bfd_reloc_status_type
490 avr_final_link_relocate (howto, input_bfd, input_section,
491 contents, rel, relocation)
492 reloc_howto_type * howto;
494 asection * input_section;
496 Elf_Internal_Rela * rel;
499 bfd_reloc_status_type r = bfd_reloc_ok;
506 contents += rel->r_offset;
507 srel = (bfd_signed_vma) relocation;
508 srel += rel->r_addend;
509 srel -= rel->r_offset;
510 srel -= 2; /* Branch instructions add 2 to the PC... */
511 srel -= (input_section->output_section->vma +
512 input_section->output_offset);
515 return bfd_reloc_outofrange;
516 if (srel > ((1 << 7) - 1) || (srel < - (1 << 7)))
517 return bfd_reloc_overflow;
518 x = bfd_get_16 (input_bfd, contents);
519 x = (x & 0xfc07) | (((srel >> 1) << 3) & 0x3f8);
520 bfd_put_16 (input_bfd, x, contents);
524 contents += rel->r_offset;
525 srel = (bfd_signed_vma) relocation;
526 srel += rel->r_addend;
527 srel -= rel->r_offset;
528 srel -= 2; /* Branch instructions add 2 to the PC... */
529 srel -= (input_section->output_section->vma +
530 input_section->output_offset);
533 return bfd_reloc_outofrange;
535 /* AVR addresses commands as words. */
538 /* Check for overflow. */
539 if (srel < -2048 || srel > 2047)
541 /* Apply WRAPAROUND if possible. */
542 switch (bfd_get_mach (input_bfd))
549 return bfd_reloc_overflow;
553 x = bfd_get_16 (input_bfd, contents);
554 x = (x & 0xf000) | (srel & 0xfff);
555 bfd_put_16 (input_bfd, x, contents);
559 contents += rel->r_offset;
560 srel = (bfd_signed_vma) relocation + rel->r_addend;
561 x = bfd_get_16 (input_bfd, contents);
562 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
563 bfd_put_16 (input_bfd, x, contents);
567 contents += rel->r_offset;
568 srel = (bfd_signed_vma) relocation + rel->r_addend;
569 srel = (srel >> 8) & 0xff;
570 x = bfd_get_16 (input_bfd, contents);
571 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
572 bfd_put_16 (input_bfd, x, contents);
576 contents += rel->r_offset;
577 srel = (bfd_signed_vma) relocation + rel->r_addend;
578 srel = (srel >> 16) & 0xff;
579 x = bfd_get_16 (input_bfd, contents);
580 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
581 bfd_put_16 (input_bfd, x, contents);
584 case R_AVR_LO8_LDI_NEG:
585 contents += rel->r_offset;
586 srel = (bfd_signed_vma) relocation + rel->r_addend;
588 x = bfd_get_16 (input_bfd, contents);
589 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
590 bfd_put_16 (input_bfd, x, contents);
593 case R_AVR_HI8_LDI_NEG:
594 contents += rel->r_offset;
595 srel = (bfd_signed_vma) relocation + rel->r_addend;
597 srel = (srel >> 8) & 0xff;
598 x = bfd_get_16 (input_bfd, contents);
599 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
600 bfd_put_16 (input_bfd, x, contents);
603 case R_AVR_HH8_LDI_NEG:
604 contents += rel->r_offset;
605 srel = (bfd_signed_vma) relocation + rel->r_addend;
607 srel = (srel >> 16) & 0xff;
608 x = bfd_get_16 (input_bfd, contents);
609 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
610 bfd_put_16 (input_bfd, x, contents);
613 case R_AVR_LO8_LDI_PM:
614 contents += rel->r_offset;
615 srel = (bfd_signed_vma) relocation + rel->r_addend;
617 return bfd_reloc_outofrange;
619 x = bfd_get_16 (input_bfd, contents);
620 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
621 bfd_put_16 (input_bfd, x, contents);
624 case R_AVR_HI8_LDI_PM:
625 contents += rel->r_offset;
626 srel = (bfd_signed_vma) relocation + rel->r_addend;
628 return bfd_reloc_outofrange;
630 srel = (srel >> 8) & 0xff;
631 x = bfd_get_16 (input_bfd, contents);
632 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
633 bfd_put_16 (input_bfd, x, contents);
636 case R_AVR_HH8_LDI_PM:
637 contents += rel->r_offset;
638 srel = (bfd_signed_vma) relocation + rel->r_addend;
640 return bfd_reloc_outofrange;
642 srel = (srel >> 16) & 0xff;
643 x = bfd_get_16 (input_bfd, contents);
644 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
645 bfd_put_16 (input_bfd, x, contents);
648 case R_AVR_LO8_LDI_PM_NEG:
649 contents += rel->r_offset;
650 srel = (bfd_signed_vma) relocation + rel->r_addend;
653 return bfd_reloc_outofrange;
655 x = bfd_get_16 (input_bfd, contents);
656 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
657 bfd_put_16 (input_bfd, x, contents);
660 case R_AVR_HI8_LDI_PM_NEG:
661 contents += rel->r_offset;
662 srel = (bfd_signed_vma) relocation + rel->r_addend;
665 return bfd_reloc_outofrange;
667 srel = (srel >> 8) & 0xff;
668 x = bfd_get_16 (input_bfd, contents);
669 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
670 bfd_put_16 (input_bfd, x, contents);
673 case R_AVR_HH8_LDI_PM_NEG:
674 contents += rel->r_offset;
675 srel = (bfd_signed_vma) relocation + rel->r_addend;
678 return bfd_reloc_outofrange;
680 srel = (srel >> 16) & 0xff;
681 x = bfd_get_16 (input_bfd, contents);
682 x = (x & 0xf0f0) | (srel & 0xf) | ((srel << 4) & 0xf00);
683 bfd_put_16 (input_bfd, x, contents);
687 contents += rel->r_offset;
688 srel = (bfd_signed_vma) relocation + rel->r_addend;
690 return bfd_reloc_outofrange;
692 x = bfd_get_16 (input_bfd, contents);
693 x |= ((srel & 0x10000) | ((srel << 3) & 0x1f00000)) >> 16;
694 bfd_put_16 (input_bfd, x, contents);
695 bfd_put_16 (input_bfd, (bfd_vma) srel & 0xffff, contents+2);
699 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
700 contents, rel->r_offset,
701 relocation, rel->r_addend);
707 /* Relocate an AVR ELF section. */
709 elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section,
710 contents, relocs, local_syms, local_sections)
711 bfd *output_bfd ATTRIBUTE_UNUSED;
712 struct bfd_link_info *info;
714 asection *input_section;
716 Elf_Internal_Rela *relocs;
717 Elf_Internal_Sym *local_syms;
718 asection **local_sections;
720 Elf_Internal_Shdr * symtab_hdr;
721 struct elf_link_hash_entry ** sym_hashes;
722 Elf_Internal_Rela * rel;
723 Elf_Internal_Rela * relend;
725 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
726 sym_hashes = elf_sym_hashes (input_bfd);
727 relend = relocs + input_section->reloc_count;
729 for (rel = relocs; rel < relend; rel ++)
731 reloc_howto_type * howto;
732 unsigned long r_symndx;
733 Elf_Internal_Sym * sym;
735 struct elf_link_hash_entry * h;
737 bfd_reloc_status_type r;
738 const char * name = NULL;
741 r_type = ELF32_R_TYPE (rel->r_info);
742 r_symndx = ELF32_R_SYM (rel->r_info);
744 if (info->relocateable)
746 /* This is a relocateable link. We don't have to change
747 anything, unless the reloc is against a section symbol,
748 in which case we have to adjust according to where the
749 section symbol winds up in the output section. */
750 if (r_symndx < symtab_hdr->sh_info)
752 sym = local_syms + r_symndx;
754 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
756 sec = local_sections [r_symndx];
757 rel->r_addend += sec->output_offset + sym->st_value;
764 /* This is a final link. */
765 howto = elf_avr_howto_table + ELF32_R_TYPE (rel->r_info);
770 if (r_symndx < symtab_hdr->sh_info)
772 sym = local_syms + r_symndx;
773 sec = local_sections [r_symndx];
774 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);
776 name = bfd_elf_string_from_elf_section
777 (input_bfd, symtab_hdr->sh_link, sym->st_name);
778 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
782 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
784 while (h->root.type == bfd_link_hash_indirect
785 || h->root.type == bfd_link_hash_warning)
786 h = (struct elf_link_hash_entry *) h->root.u.i.link;
788 name = h->root.root.string;
790 if (h->root.type == bfd_link_hash_defined
791 || h->root.type == bfd_link_hash_defweak)
793 sec = h->root.u.def.section;
794 relocation = (h->root.u.def.value
795 + sec->output_section->vma
796 + sec->output_offset);
798 else if (h->root.type == bfd_link_hash_undefweak)
804 if (! ((*info->callbacks->undefined_symbol)
805 (info, h->root.root.string, input_bfd,
806 input_section, rel->r_offset, true)))
812 r = avr_final_link_relocate (howto, input_bfd, input_section,
813 contents, rel, relocation);
815 if (r != bfd_reloc_ok)
817 const char * msg = (const char *) NULL;
821 case bfd_reloc_overflow:
822 r = info->callbacks->reloc_overflow
823 (info, name, howto->name, (bfd_vma) 0,
824 input_bfd, input_section, rel->r_offset);
827 case bfd_reloc_undefined:
828 r = info->callbacks->undefined_symbol
829 (info, name, input_bfd, input_section, rel->r_offset, true);
832 case bfd_reloc_outofrange:
833 msg = _("internal error: out of range error");
836 case bfd_reloc_notsupported:
837 msg = _("internal error: unsupported relocation error");
840 case bfd_reloc_dangerous:
841 msg = _("internal error: dangerous relocation");
845 msg = _("internal error: unknown error");
850 r = info->callbacks->warning
851 (info, msg, name, input_bfd, input_section, rel->r_offset);
861 /* The final processing done just before writing out a AVR ELF object
862 file. This gets the AVR architecture right based on the machine
866 bfd_elf_avr_final_write_processing (abfd, linker)
868 boolean linker ATTRIBUTE_UNUSED;
872 switch (bfd_get_mach (abfd))
876 val = E_AVR_MACH_AVR2;
880 val = E_AVR_MACH_AVR1;
884 val = E_AVR_MACH_AVR3;
888 val = E_AVR_MACH_AVR4;
892 val = E_AVR_MACH_AVR5;
896 elf_elfheader (abfd)->e_machine = EM_AVR;
897 elf_elfheader (abfd)->e_flags &= ~ EF_AVR_MACH;
898 elf_elfheader (abfd)->e_flags |= val;
901 /* Set the right machine number. */
904 elf32_avr_object_p (abfd)
907 unsigned int e_set = bfd_mach_avr2;
908 if (elf_elfheader (abfd)->e_machine == EM_AVR
909 || elf_elfheader (abfd)->e_machine == EM_AVR_OLD)
911 int e_mach = elf_elfheader (abfd)->e_flags & EF_AVR_MACH;
915 case E_AVR_MACH_AVR2:
916 e_set = bfd_mach_avr2;
919 case E_AVR_MACH_AVR1:
920 e_set = bfd_mach_avr1;
923 case E_AVR_MACH_AVR3:
924 e_set = bfd_mach_avr3;
927 case E_AVR_MACH_AVR4:
928 e_set = bfd_mach_avr4;
931 case E_AVR_MACH_AVR5:
932 e_set = bfd_mach_avr5;
936 return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
940 #define ELF_ARCH bfd_arch_avr
941 #define ELF_MACHINE_CODE EM_AVR
942 #define ELF_MACHINE_ALT1 EM_AVR_OLD
943 #define ELF_MAXPAGESIZE 1
945 #define TARGET_LITTLE_SYM bfd_elf32_avr_vec
946 #define TARGET_LITTLE_NAME "elf32-avr"
948 #define elf_info_to_howto avr_info_to_howto_rela
949 #define elf_info_to_howto_rel NULL
950 #define elf_backend_relocate_section elf32_avr_relocate_section
951 #define elf_backend_gc_mark_hook elf32_avr_gc_mark_hook
952 #define elf_backend_gc_sweep_hook elf32_avr_gc_sweep_hook
953 #define elf_backend_check_relocs elf32_avr_check_relocs
954 #define elf_backend_can_gc_sections 1
955 #define elf_backend_final_write_processing \
956 bfd_elf_avr_final_write_processing
957 #define elf_backend_object_p elf32_avr_object_p
959 #include "elf32-target.h"