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