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