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