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