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