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