1 /* Motorola 68HC11-specific support for 32-bit ELF 2 Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 3 Contributed by Stephane Carrez (stcarrez@nerim.fr) 4 (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com)) 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 "bfdlink.h" 25 #include "libbfd.h" 26 #include "elf-bfd.h" 27 #include "elf32-m68hc1x.h" 28 #include "elf/m68hc11.h" 29 #include "opcode/m68hc11.h" 30 31 /* Relocation functions. */ 32 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup 33 (bfd *, bfd_reloc_code_real_type); 34 static void m68hc11_info_to_howto_rel 35 (bfd *, arelent *, Elf_Internal_Rela *); 36 37 /* Trampoline generation. */ 38 static bfd_boolean m68hc11_elf_size_one_stub 39 (struct bfd_hash_entry *gen_entry, void *in_arg); 40 static bfd_boolean m68hc11_elf_build_one_stub 41 (struct bfd_hash_entry *gen_entry, void *in_arg); 42 static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create 43 (bfd* abfd); 44 45 /* Linker relaxation. */ 46 static bfd_boolean m68hc11_elf_relax_section 47 (bfd *, asection *, struct bfd_link_info *, bfd_boolean *); 48 static void m68hc11_elf_relax_delete_bytes 49 (bfd *, asection *, bfd_vma, int); 50 static void m68hc11_relax_group 51 (bfd *, asection *, bfd_byte *, unsigned, unsigned long, unsigned long); 52 static int compare_reloc (const void *, const void *); 53 54 /* Use REL instead of RELA to save space */ 55 #define USE_REL 1 56 57 /* The Motorola 68HC11 microcontroller only addresses 64Kb but we also 58 support a memory bank switching mechanism similar to 68HC12. 59 We must handle 8 and 16-bit relocations. The 32-bit relocation 60 are used for debugging sections (DWARF2) to represent a virtual 61 address. 62 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */ 63 static reloc_howto_type elf_m68hc11_howto_table[] = { 64 /* This reloc does nothing. */ 65 HOWTO (R_M68HC11_NONE, /* type */ 66 0, /* rightshift */ 67 2, /* size (0 = byte, 1 = short, 2 = long) */ 68 32, /* bitsize */ 69 FALSE, /* pc_relative */ 70 0, /* bitpos */ 71 complain_overflow_dont,/* complain_on_overflow */ 72 bfd_elf_generic_reloc, /* special_function */ 73 "R_M68HC11_NONE", /* name */ 74 FALSE, /* partial_inplace */ 75 0, /* src_mask */ 76 0, /* dst_mask */ 77 FALSE), /* pcrel_offset */ 78 79 /* A 8 bit absolute relocation */ 80 HOWTO (R_M68HC11_8, /* type */ 81 0, /* rightshift */ 82 0, /* size (0 = byte, 1 = short, 2 = long) */ 83 8, /* bitsize */ 84 FALSE, /* pc_relative */ 85 0, /* bitpos */ 86 complain_overflow_bitfield, /* complain_on_overflow */ 87 bfd_elf_generic_reloc, /* special_function */ 88 "R_M68HC11_8", /* name */ 89 FALSE, /* partial_inplace */ 90 0x00ff, /* src_mask */ 91 0x00ff, /* dst_mask */ 92 FALSE), /* pcrel_offset */ 93 94 /* A 8 bit absolute relocation (upper address) */ 95 HOWTO (R_M68HC11_HI8, /* type */ 96 8, /* rightshift */ 97 0, /* size (0 = byte, 1 = short, 2 = long) */ 98 8, /* bitsize */ 99 FALSE, /* pc_relative */ 100 0, /* bitpos */ 101 complain_overflow_bitfield, /* complain_on_overflow */ 102 bfd_elf_generic_reloc, /* special_function */ 103 "R_M68HC11_HI8", /* name */ 104 FALSE, /* partial_inplace */ 105 0x00ff, /* src_mask */ 106 0x00ff, /* dst_mask */ 107 FALSE), /* pcrel_offset */ 108 109 /* A 8 bit absolute relocation (upper address) */ 110 HOWTO (R_M68HC11_LO8, /* type */ 111 0, /* rightshift */ 112 0, /* size (0 = byte, 1 = short, 2 = long) */ 113 8, /* bitsize */ 114 FALSE, /* pc_relative */ 115 0, /* bitpos */ 116 complain_overflow_dont, /* complain_on_overflow */ 117 bfd_elf_generic_reloc, /* special_function */ 118 "R_M68HC11_LO8", /* name */ 119 FALSE, /* partial_inplace */ 120 0x00ff, /* src_mask */ 121 0x00ff, /* dst_mask */ 122 FALSE), /* pcrel_offset */ 123 124 /* A 8 bit PC-rel relocation */ 125 HOWTO (R_M68HC11_PCREL_8, /* type */ 126 0, /* rightshift */ 127 0, /* size (0 = byte, 1 = short, 2 = long) */ 128 8, /* bitsize */ 129 TRUE, /* pc_relative */ 130 0, /* bitpos */ 131 complain_overflow_bitfield, /* complain_on_overflow */ 132 bfd_elf_generic_reloc, /* special_function */ 133 "R_M68HC11_PCREL_8", /* name */ 134 FALSE, /* partial_inplace */ 135 0x00ff, /* src_mask */ 136 0x00ff, /* dst_mask */ 137 TRUE), /* pcrel_offset */ 138 139 /* A 16 bit absolute relocation */ 140 HOWTO (R_M68HC11_16, /* type */ 141 0, /* rightshift */ 142 1, /* size (0 = byte, 1 = short, 2 = long) */ 143 16, /* bitsize */ 144 FALSE, /* pc_relative */ 145 0, /* bitpos */ 146 complain_overflow_dont /*bitfield */ , /* complain_on_overflow */ 147 bfd_elf_generic_reloc, /* special_function */ 148 "R_M68HC11_16", /* name */ 149 FALSE, /* partial_inplace */ 150 0xffff, /* src_mask */ 151 0xffff, /* dst_mask */ 152 FALSE), /* pcrel_offset */ 153 154 /* A 32 bit absolute relocation. This one is never used for the 155 code relocation. It's used by gas for -gstabs generation. */ 156 HOWTO (R_M68HC11_32, /* type */ 157 0, /* rightshift */ 158 2, /* size (0 = byte, 1 = short, 2 = long) */ 159 32, /* bitsize */ 160 FALSE, /* pc_relative */ 161 0, /* bitpos */ 162 complain_overflow_bitfield, /* complain_on_overflow */ 163 bfd_elf_generic_reloc, /* special_function */ 164 "R_M68HC11_32", /* name */ 165 FALSE, /* partial_inplace */ 166 0xffffffff, /* src_mask */ 167 0xffffffff, /* dst_mask */ 168 FALSE), /* pcrel_offset */ 169 170 /* A 3 bit absolute relocation */ 171 HOWTO (R_M68HC11_3B, /* type */ 172 0, /* rightshift */ 173 0, /* size (0 = byte, 1 = short, 2 = long) */ 174 3, /* bitsize */ 175 FALSE, /* pc_relative */ 176 0, /* bitpos */ 177 complain_overflow_bitfield, /* complain_on_overflow */ 178 bfd_elf_generic_reloc, /* special_function */ 179 "R_M68HC11_4B", /* name */ 180 FALSE, /* partial_inplace */ 181 0x003, /* src_mask */ 182 0x003, /* dst_mask */ 183 FALSE), /* pcrel_offset */ 184 185 /* A 16 bit PC-rel relocation */ 186 HOWTO (R_M68HC11_PCREL_16, /* type */ 187 0, /* rightshift */ 188 1, /* size (0 = byte, 1 = short, 2 = long) */ 189 16, /* bitsize */ 190 TRUE, /* pc_relative */ 191 0, /* bitpos */ 192 complain_overflow_dont, /* complain_on_overflow */ 193 bfd_elf_generic_reloc, /* special_function */ 194 "R_M68HC11_PCREL_16", /* name */ 195 FALSE, /* partial_inplace */ 196 0xffff, /* src_mask */ 197 0xffff, /* dst_mask */ 198 TRUE), /* pcrel_offset */ 199 200 /* GNU extension to record C++ vtable hierarchy */ 201 HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */ 202 0, /* rightshift */ 203 1, /* size (0 = byte, 1 = short, 2 = long) */ 204 0, /* bitsize */ 205 FALSE, /* pc_relative */ 206 0, /* bitpos */ 207 complain_overflow_dont, /* complain_on_overflow */ 208 NULL, /* special_function */ 209 "R_M68HC11_GNU_VTINHERIT", /* name */ 210 FALSE, /* partial_inplace */ 211 0, /* src_mask */ 212 0, /* dst_mask */ 213 FALSE), /* pcrel_offset */ 214 215 /* GNU extension to record C++ vtable member usage */ 216 HOWTO (R_M68HC11_GNU_VTENTRY, /* type */ 217 0, /* rightshift */ 218 1, /* size (0 = byte, 1 = short, 2 = long) */ 219 0, /* bitsize */ 220 FALSE, /* pc_relative */ 221 0, /* bitpos */ 222 complain_overflow_dont, /* complain_on_overflow */ 223 _bfd_elf_rel_vtable_reloc_fn, /* special_function */ 224 "R_M68HC11_GNU_VTENTRY", /* name */ 225 FALSE, /* partial_inplace */ 226 0, /* src_mask */ 227 0, /* dst_mask */ 228 FALSE), /* pcrel_offset */ 229 230 /* A 24 bit relocation */ 231 HOWTO (R_M68HC11_24, /* type */ 232 0, /* rightshift */ 233 1, /* size (0 = byte, 1 = short, 2 = long) */ 234 24, /* bitsize */ 235 FALSE, /* pc_relative */ 236 0, /* bitpos */ 237 complain_overflow_bitfield, /* complain_on_overflow */ 238 bfd_elf_generic_reloc, /* special_function */ 239 "R_M68HC11_24", /* name */ 240 FALSE, /* partial_inplace */ 241 0xffffff, /* src_mask */ 242 0xffffff, /* dst_mask */ 243 FALSE), /* pcrel_offset */ 244 245 /* A 16-bit low relocation */ 246 HOWTO (R_M68HC11_LO16, /* type */ 247 0, /* rightshift */ 248 1, /* size (0 = byte, 1 = short, 2 = long) */ 249 16, /* bitsize */ 250 FALSE, /* pc_relative */ 251 0, /* bitpos */ 252 complain_overflow_bitfield, /* complain_on_overflow */ 253 bfd_elf_generic_reloc, /* special_function */ 254 "R_M68HC11_LO16", /* name */ 255 FALSE, /* partial_inplace */ 256 0xffff, /* src_mask */ 257 0xffff, /* dst_mask */ 258 FALSE), /* pcrel_offset */ 259 260 /* A page relocation */ 261 HOWTO (R_M68HC11_PAGE, /* type */ 262 0, /* rightshift */ 263 0, /* size (0 = byte, 1 = short, 2 = long) */ 264 8, /* bitsize */ 265 FALSE, /* pc_relative */ 266 0, /* bitpos */ 267 complain_overflow_bitfield, /* complain_on_overflow */ 268 bfd_elf_generic_reloc, /* special_function */ 269 "R_M68HC11_PAGE", /* name */ 270 FALSE, /* partial_inplace */ 271 0x00ff, /* src_mask */ 272 0x00ff, /* dst_mask */ 273 FALSE), /* pcrel_offset */ 274 275 EMPTY_HOWTO (14), 276 EMPTY_HOWTO (15), 277 EMPTY_HOWTO (16), 278 EMPTY_HOWTO (17), 279 EMPTY_HOWTO (18), 280 EMPTY_HOWTO (19), 281 282 /* Mark beginning of a jump instruction (any form). */ 283 HOWTO (R_M68HC11_RL_JUMP, /* type */ 284 0, /* rightshift */ 285 1, /* size (0 = byte, 1 = short, 2 = long) */ 286 0, /* bitsize */ 287 FALSE, /* pc_relative */ 288 0, /* bitpos */ 289 complain_overflow_dont, /* complain_on_overflow */ 290 m68hc11_elf_ignore_reloc, /* special_function */ 291 "R_M68HC11_RL_JUMP", /* name */ 292 TRUE, /* partial_inplace */ 293 0, /* src_mask */ 294 0, /* dst_mask */ 295 TRUE), /* pcrel_offset */ 296 297 /* Mark beginning of Gcc relaxation group instruction. */ 298 HOWTO (R_M68HC11_RL_GROUP, /* type */ 299 0, /* rightshift */ 300 1, /* size (0 = byte, 1 = short, 2 = long) */ 301 0, /* bitsize */ 302 FALSE, /* pc_relative */ 303 0, /* bitpos */ 304 complain_overflow_dont, /* complain_on_overflow */ 305 m68hc11_elf_ignore_reloc, /* special_function */ 306 "R_M68HC11_RL_GROUP", /* name */ 307 TRUE, /* partial_inplace */ 308 0, /* src_mask */ 309 0, /* dst_mask */ 310 TRUE), /* pcrel_offset */ 311 }; 312 313 /* Map BFD reloc types to M68HC11 ELF reloc types. */ 314 315 struct m68hc11_reloc_map 316 { 317 bfd_reloc_code_real_type bfd_reloc_val; 318 unsigned char elf_reloc_val; 319 }; 320 321 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = { 322 {BFD_RELOC_NONE, R_M68HC11_NONE,}, 323 {BFD_RELOC_8, R_M68HC11_8}, 324 {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8}, 325 {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8}, 326 {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8}, 327 {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16}, 328 {BFD_RELOC_16, R_M68HC11_16}, 329 {BFD_RELOC_32, R_M68HC11_32}, 330 {BFD_RELOC_M68HC11_3B, R_M68HC11_3B}, 331 332 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT}, 333 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY}, 334 335 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16}, 336 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE}, 337 {BFD_RELOC_M68HC11_24, R_M68HC11_24}, 338 339 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP}, 340 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP}, 341 }; 342 343 static reloc_howto_type * 344 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, 345 bfd_reloc_code_real_type code) 346 { 347 unsigned int i; 348 349 for (i = 0; 350 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map); 351 i++) 352 { 353 if (m68hc11_reloc_map[i].bfd_reloc_val == code) 354 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val]; 355 } 356 357 return NULL; 358 } 359 360 /* Set the howto pointer for an M68HC11 ELF reloc. */ 361 362 static void 363 m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, 364 arelent *cache_ptr, Elf_Internal_Rela *dst) 365 { 366 unsigned int r_type; 367 368 r_type = ELF32_R_TYPE (dst->r_info); 369 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max); 370 cache_ptr->howto = &elf_m68hc11_howto_table[r_type]; 371 } 372 373 374 /* Far trampoline generation. */ 375 376 /* Build a 68HC11 trampoline stub. */ 377 static bfd_boolean 378 m68hc11_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg) 379 { 380 struct elf32_m68hc11_stub_hash_entry *stub_entry; 381 struct bfd_link_info *info; 382 struct m68hc11_elf_link_hash_table *htab; 383 asection *stub_sec; 384 bfd *stub_bfd; 385 bfd_byte *loc; 386 bfd_vma sym_value, phys_page, phys_addr; 387 388 /* Massage our args to the form they really have. */ 389 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry; 390 info = (struct bfd_link_info *) in_arg; 391 392 htab = m68hc11_elf_hash_table (info); 393 394 stub_sec = stub_entry->stub_sec; 395 396 /* Make a note of the offset within the stubs for this entry. */ 397 stub_entry->stub_offset = stub_sec->_raw_size; 398 stub_sec->_raw_size += 10; 399 loc = stub_sec->contents + stub_entry->stub_offset; 400 401 stub_bfd = stub_sec->owner; 402 403 /* Create the trampoline call stub: 404 405 pshb 406 ldab #%page(symbol) 407 ldy #%addr(symbol) 408 jmp __trampoline 409 410 */ 411 sym_value = (stub_entry->target_value 412 + stub_entry->target_section->output_offset 413 + stub_entry->target_section->output_section->vma); 414 phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value); 415 phys_page = m68hc11_phys_page (&htab->pinfo, sym_value); 416 417 /* pshb; ldab #%page(sym) */ 418 bfd_put_8 (stub_bfd, 0x37, loc); 419 bfd_put_8 (stub_bfd, 0xC6, loc + 1); 420 bfd_put_8 (stub_bfd, phys_page, loc + 2); 421 loc += 3; 422 423 /* ldy #%addr(sym) */ 424 bfd_put_8 (stub_bfd, 0x18, loc); 425 bfd_put_8 (stub_bfd, 0xCE, loc + 1); 426 bfd_put_16 (stub_bfd, phys_addr, loc + 2); 427 loc += 4; 428 429 /* jmp __trampoline */ 430 bfd_put_8 (stub_bfd, 0x7E, loc); 431 bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1); 432 433 return TRUE; 434 } 435 436 /* As above, but don't actually build the stub. Just bump offset so 437 we know stub section sizes. */ 438 439 static bfd_boolean 440 m68hc11_elf_size_one_stub (struct bfd_hash_entry *gen_entry, 441 void *in_arg ATTRIBUTE_UNUSED) 442 { 443 struct elf32_m68hc11_stub_hash_entry *stub_entry; 444 445 /* Massage our args to the form they really have. */ 446 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry; 447 448 stub_entry->stub_sec->_raw_size += 10; 449 return TRUE; 450 } 451 452 /* Create a 68HC11 ELF linker hash table. */ 453 454 static struct bfd_link_hash_table * 455 m68hc11_elf_bfd_link_hash_table_create (bfd *abfd) 456 { 457 struct m68hc11_elf_link_hash_table *ret; 458 459 ret = m68hc11_elf_hash_table_create (abfd); 460 if (ret == (struct m68hc11_elf_link_hash_table *) NULL) 461 return NULL; 462 463 ret->size_one_stub = m68hc11_elf_size_one_stub; 464 ret->build_one_stub = m68hc11_elf_build_one_stub; 465 466 return &ret->root.root; 467 } 468 469 470 /* 68HC11 Linker Relaxation. */ 471 472 struct m68hc11_direct_relax 473 { 474 const char *name; 475 unsigned char code; 476 unsigned char direct_code; 477 } m68hc11_direct_relax_table[] = { 478 { "adca", 0xB9, 0x99 }, 479 { "adcb", 0xF9, 0xD9 }, 480 { "adda", 0xBB, 0x9B }, 481 { "addb", 0xFB, 0xDB }, 482 { "addd", 0xF3, 0xD3 }, 483 { "anda", 0xB4, 0x94 }, 484 { "andb", 0xF4, 0xD4 }, 485 { "cmpa", 0xB1, 0x91 }, 486 { "cmpb", 0xF1, 0xD1 }, 487 { "cpd", 0xB3, 0x93 }, 488 { "cpxy", 0xBC, 0x9C }, 489 /* { "cpy", 0xBC, 0x9C }, */ 490 { "eora", 0xB8, 0x98 }, 491 { "eorb", 0xF8, 0xD8 }, 492 { "jsr", 0xBD, 0x9D }, 493 { "ldaa", 0xB6, 0x96 }, 494 { "ldab", 0xF6, 0xD6 }, 495 { "ldd", 0xFC, 0xDC }, 496 { "lds", 0xBE, 0x9E }, 497 { "ldxy", 0xFE, 0xDE }, 498 /* { "ldy", 0xFE, 0xDE },*/ 499 { "oraa", 0xBA, 0x9A }, 500 { "orab", 0xFA, 0xDA }, 501 { "sbca", 0xB2, 0x92 }, 502 { "sbcb", 0xF2, 0xD2 }, 503 { "staa", 0xB7, 0x97 }, 504 { "stab", 0xF7, 0xD7 }, 505 { "std", 0xFD, 0xDD }, 506 { "sts", 0xBF, 0x9F }, 507 { "stxy", 0xFF, 0xDF }, 508 /* { "sty", 0xFF, 0xDF },*/ 509 { "suba", 0xB0, 0x90 }, 510 { "subb", 0xF0, 0xD0 }, 511 { "subd", 0xB3, 0x93 }, 512 { 0, 0, 0 } 513 }; 514 515 static struct m68hc11_direct_relax * 516 find_relaxable_insn (unsigned char code) 517 { 518 int i; 519 520 for (i = 0; m68hc11_direct_relax_table[i].name; i++) 521 if (m68hc11_direct_relax_table[i].code == code) 522 return &m68hc11_direct_relax_table[i]; 523 524 return 0; 525 } 526 527 static int 528 compare_reloc (const void *e1, const void *e2) 529 { 530 const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1; 531 const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2; 532 533 if (i1->r_offset == i2->r_offset) 534 return 0; 535 else 536 return i1->r_offset < i2->r_offset ? -1 : 1; 537 } 538 539 #define M6811_OP_LDX_IMMEDIATE (0xCE) 540 541 static void 542 m68hc11_relax_group (bfd *abfd, asection *sec, bfd_byte *contents, 543 unsigned value, unsigned long offset, 544 unsigned long end_group) 545 { 546 unsigned char code; 547 unsigned long start_offset; 548 unsigned long ldx_offset = offset; 549 unsigned long ldx_size; 550 int can_delete_ldx; 551 int relax_ldy = 0; 552 553 /* First instruction of the relax group must be a 554 LDX #value or LDY #value. If this is not the case, 555 ignore the relax group. */ 556 code = bfd_get_8 (abfd, contents + offset); 557 if (code == 0x18) 558 { 559 relax_ldy++; 560 offset++; 561 code = bfd_get_8 (abfd, contents + offset); 562 } 563 ldx_size = offset - ldx_offset + 3; 564 offset += 3; 565 if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group) 566 return; 567 568 569 /* We can remove the LDX/LDY only when all bset/brclr instructions 570 of the relax group have been converted to use direct addressing 571 mode. */ 572 can_delete_ldx = 1; 573 while (offset < end_group) 574 { 575 unsigned isize; 576 unsigned new_value; 577 int bset_use_y; 578 579 bset_use_y = 0; 580 start_offset = offset; 581 code = bfd_get_8 (abfd, contents + offset); 582 if (code == 0x18) 583 { 584 bset_use_y++; 585 offset++; 586 code = bfd_get_8 (abfd, contents + offset); 587 } 588 589 /* Check the instruction and translate to use direct addressing mode. */ 590 switch (code) 591 { 592 /* bset */ 593 case 0x1C: 594 code = 0x14; 595 isize = 3; 596 break; 597 598 /* brclr */ 599 case 0x1F: 600 code = 0x13; 601 isize = 4; 602 break; 603 604 /* brset */ 605 case 0x1E: 606 code = 0x12; 607 isize = 4; 608 break; 609 610 /* bclr */ 611 case 0x1D: 612 code = 0x15; 613 isize = 3; 614 break; 615 616 /* This instruction is not recognized and we are not 617 at end of the relax group. Ignore and don't remove 618 the first LDX (we don't know what it is used for...). */ 619 default: 620 return; 621 } 622 new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1); 623 new_value += value; 624 if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy) 625 { 626 bfd_put_8 (abfd, code, contents + offset); 627 bfd_put_8 (abfd, new_value, contents + offset + 1); 628 if (start_offset != offset) 629 { 630 m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset, 631 offset - start_offset); 632 end_group--; 633 } 634 } 635 else 636 { 637 can_delete_ldx = 0; 638 } 639 offset = start_offset + isize; 640 } 641 if (can_delete_ldx) 642 { 643 /* Remove the move instruction (3 or 4 bytes win). */ 644 m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size); 645 } 646 } 647 648 /* This function handles relaxing for the 68HC11. 649 650 651 and somewhat more difficult to support. */ 652 653 static bfd_boolean 654 m68hc11_elf_relax_section (bfd *abfd, asection *sec, 655 struct bfd_link_info *link_info, bfd_boolean *again) 656 { 657 Elf_Internal_Shdr *symtab_hdr; 658 Elf_Internal_Shdr *shndx_hdr; 659 Elf_Internal_Rela *internal_relocs; 660 Elf_Internal_Rela *free_relocs = NULL; 661 Elf_Internal_Rela *irel, *irelend; 662 bfd_byte *contents = NULL; 663 bfd_byte *free_contents = NULL; 664 Elf32_External_Sym *free_extsyms = NULL; 665 Elf_Internal_Rela *prev_insn_branch = NULL; 666 Elf_Internal_Rela *prev_insn_group = NULL; 667 unsigned insn_group_value = 0; 668 Elf_Internal_Sym *isymbuf = NULL; 669 670 /* Assume nothing changes. */ 671 *again = FALSE; 672 673 /* We don't have to do anything for a relocatable link, if 674 this section does not have relocs, or if this is not a 675 code section. */ 676 if (link_info->relocatable 677 || (sec->flags & SEC_RELOC) == 0 678 || sec->reloc_count == 0 679 || (sec->flags & SEC_CODE) == 0) 680 return TRUE; 681 682 /* If this is the first time we have been called for this section, 683 initialize the cooked size. */ 684 if (sec->_cooked_size == 0) 685 sec->_cooked_size = sec->_raw_size; 686 687 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 688 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; 689 690 /* Get a copy of the native relocations. */ 691 internal_relocs = (_bfd_elf_link_read_relocs 692 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, 693 link_info->keep_memory)); 694 if (internal_relocs == NULL) 695 goto error_return; 696 if (! link_info->keep_memory) 697 free_relocs = internal_relocs; 698 699 /* Checking for branch relaxation relies on the relocations to 700 be sorted on 'r_offset'. This is not guaranteed so we must sort. */ 701 qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela), 702 compare_reloc); 703 704 /* Walk through them looking for relaxing opportunities. */ 705 irelend = internal_relocs + sec->reloc_count; 706 for (irel = internal_relocs; irel < irelend; irel++) 707 { 708 bfd_vma symval; 709 bfd_vma value; 710 Elf_Internal_Sym *isym; 711 asection *sym_sec; 712 int is_far = 0; 713 714 /* If this isn't something that can be relaxed, then ignore 715 this reloc. */ 716 if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16 717 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP 718 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP) 719 { 720 prev_insn_branch = 0; 721 prev_insn_group = 0; 722 continue; 723 } 724 725 /* Get the section contents if we haven't done so already. */ 726 if (contents == NULL) 727 { 728 /* Get cached copy if it exists. */ 729 if (elf_section_data (sec)->this_hdr.contents != NULL) 730 contents = elf_section_data (sec)->this_hdr.contents; 731 else 732 { 733 /* Go get them off disk. */ 734 contents = (bfd_byte *) bfd_malloc (sec->_raw_size); 735 if (contents == NULL) 736 goto error_return; 737 free_contents = contents; 738 739 if (! bfd_get_section_contents (abfd, sec, contents, 740 (file_ptr) 0, sec->_raw_size)) 741 goto error_return; 742 } 743 } 744 745 /* Try to eliminate an unconditional 8 bit pc-relative branch 746 which immediately follows a conditional 8 bit pc-relative 747 branch around the unconditional branch. 748 749 original: new: 750 bCC lab1 bCC' lab2 751 bra lab2 752 lab1: lab1: 753 754 This happens when the bCC can't reach lab2 at assembly time, 755 but due to other relaxations it can reach at link time. */ 756 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP) 757 { 758 Elf_Internal_Rela *nrel; 759 unsigned char code; 760 unsigned char roffset; 761 762 prev_insn_branch = 0; 763 prev_insn_group = 0; 764 765 /* Do nothing if this reloc is the last byte in the section. */ 766 if (irel->r_offset + 2 >= sec->_cooked_size) 767 continue; 768 769 /* See if the next instruction is an unconditional pc-relative 770 branch, more often than not this test will fail, so we 771 test it first to speed things up. */ 772 code = bfd_get_8 (abfd, contents + irel->r_offset + 2); 773 if (code != 0x7e) 774 continue; 775 776 /* Also make sure the next relocation applies to the next 777 instruction and that it's a pc-relative 8 bit branch. */ 778 nrel = irel + 1; 779 if (nrel == irelend 780 || irel->r_offset + 3 != nrel->r_offset 781 || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16) 782 continue; 783 784 /* Make sure our destination immediately follows the 785 unconditional branch. */ 786 roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1); 787 if (roffset != 3) 788 continue; 789 790 prev_insn_branch = irel; 791 prev_insn_group = 0; 792 continue; 793 } 794 795 /* Read this BFD's symbols if we haven't done so already. */ 796 if (isymbuf == NULL && symtab_hdr->sh_info != 0) 797 { 798 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 799 if (isymbuf == NULL) 800 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, 801 symtab_hdr->sh_info, 0, 802 NULL, NULL, NULL); 803 if (isymbuf == NULL) 804 goto error_return; 805 } 806 807 /* Get the value of the symbol referred to by the reloc. */ 808 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info) 809 { 810 /* A local symbol. */ 811 isym = isymbuf + ELF32_R_SYM (irel->r_info); 812 is_far = isym->st_other & STO_M68HC12_FAR; 813 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx); 814 symval = (isym->st_value 815 + sym_sec->output_section->vma 816 + sym_sec->output_offset); 817 } 818 else 819 { 820 unsigned long indx; 821 struct elf_link_hash_entry *h; 822 823 /* An external symbol. */ 824 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info; 825 h = elf_sym_hashes (abfd)[indx]; 826 BFD_ASSERT (h != NULL); 827 if (h->root.type != bfd_link_hash_defined 828 && h->root.type != bfd_link_hash_defweak) 829 { 830 /* This appears to be a reference to an undefined 831 symbol. Just ignore it--it will be caught by the 832 regular reloc processing. */ 833 prev_insn_branch = 0; 834 prev_insn_group = 0; 835 continue; 836 } 837 838 is_far = h->other & STO_M68HC12_FAR; 839 isym = 0; 840 sym_sec = h->root.u.def.section; 841 symval = (h->root.u.def.value 842 + sym_sec->output_section->vma 843 + sym_sec->output_offset); 844 } 845 846 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP) 847 { 848 prev_insn_branch = 0; 849 prev_insn_group = 0; 850 851 /* Do nothing if this reloc is the last byte in the section. */ 852 if (irel->r_offset == sec->_cooked_size) 853 continue; 854 855 prev_insn_group = irel; 856 insn_group_value = isym->st_value; 857 continue; 858 } 859 860 /* When we relax some bytes, the size of our section changes. 861 This affects the layout of next input sections that go in our 862 output section. When the symbol is part of another section that 863 will go in the same output section as the current one, it's 864 final address may now be incorrect (too far). We must let the 865 linker re-compute all section offsets before processing this 866 reloc. Code example: 867 868 Initial Final 869 .sect .text section size = 6 section size = 4 870 jmp foo 871 jmp bar 872 .sect .text.foo_bar output_offset = 6 output_offset = 4 873 foo: rts 874 bar: rts 875 876 If we process the reloc now, the jmp bar is replaced by a 877 relative branch to the initial bar address (output_offset 6). */ 878 if (*again && sym_sec != sec 879 && sym_sec->output_section == sec->output_section) 880 { 881 prev_insn_group = 0; 882 prev_insn_branch = 0; 883 continue; 884 } 885 886 value = symval; 887 /* Try to turn a far branch to a near branch. */ 888 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16 889 && prev_insn_branch) 890 { 891 bfd_vma offset; 892 unsigned char code; 893 894 offset = value - (prev_insn_branch->r_offset 895 + sec->output_section->vma 896 + sec->output_offset + 2); 897 898 /* If the offset is still out of -128..+127 range, 899 leave that far branch unchanged. */ 900 if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80) 901 { 902 prev_insn_branch = 0; 903 continue; 904 } 905 906 /* Shrink the branch. */ 907 code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset); 908 if (code == 0x7e) 909 { 910 code = 0x20; 911 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset); 912 bfd_put_8 (abfd, 0xff, 913 contents + prev_insn_branch->r_offset + 1); 914 irel->r_offset = prev_insn_branch->r_offset + 1; 915 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 916 R_M68HC11_PCREL_8); 917 m68hc11_elf_relax_delete_bytes (abfd, sec, 918 irel->r_offset + 1, 1); 919 } 920 else 921 { 922 code ^= 0x1; 923 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset); 924 bfd_put_8 (abfd, 0xff, 925 contents + prev_insn_branch->r_offset + 1); 926 irel->r_offset = prev_insn_branch->r_offset + 1; 927 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 928 R_M68HC11_PCREL_8); 929 m68hc11_elf_relax_delete_bytes (abfd, sec, 930 irel->r_offset + 1, 3); 931 } 932 prev_insn_branch = 0; 933 *again = TRUE; 934 } 935 936 /* Try to turn a 16 bit address into a 8 bit page0 address. */ 937 else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16 938 && (value & 0xff00) == 0) 939 { 940 unsigned char code; 941 unsigned short offset; 942 struct m68hc11_direct_relax *rinfo; 943 944 prev_insn_branch = 0; 945 offset = bfd_get_16 (abfd, contents + irel->r_offset); 946 offset += value; 947 if ((offset & 0xff00) != 0) 948 { 949 prev_insn_group = 0; 950 continue; 951 } 952 953 if (prev_insn_group) 954 { 955 unsigned long old_sec_size = sec->_cooked_size; 956 957 /* Note that we've changed the relocation contents, etc. */ 958 elf_section_data (sec)->relocs = internal_relocs; 959 free_relocs = NULL; 960 961 elf_section_data (sec)->this_hdr.contents = contents; 962 free_contents = NULL; 963 964 symtab_hdr->contents = (bfd_byte *) isymbuf; 965 free_extsyms = NULL; 966 967 m68hc11_relax_group (abfd, sec, contents, offset, 968 prev_insn_group->r_offset, 969 insn_group_value); 970 irel = prev_insn_group; 971 prev_insn_group = 0; 972 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 973 R_M68HC11_NONE); 974 if (sec->_cooked_size != old_sec_size) 975 *again = TRUE; 976 continue; 977 } 978 979 /* Get the opcode. */ 980 code = bfd_get_8 (abfd, contents + irel->r_offset - 1); 981 rinfo = find_relaxable_insn (code); 982 if (rinfo == 0) 983 { 984 prev_insn_group = 0; 985 continue; 986 } 987 988 /* Note that we've changed the relocation contents, etc. */ 989 elf_section_data (sec)->relocs = internal_relocs; 990 free_relocs = NULL; 991 992 elf_section_data (sec)->this_hdr.contents = contents; 993 free_contents = NULL; 994 995 symtab_hdr->contents = (bfd_byte *) isymbuf; 996 free_extsyms = NULL; 997 998 /* Fix the opcode. */ 999 /* printf ("A relaxable case : 0x%02x (%s)\n", 1000 code, rinfo->name); */ 1001 bfd_put_8 (abfd, rinfo->direct_code, 1002 contents + irel->r_offset - 1); 1003 1004 /* Delete one byte of data (upper byte of address). */ 1005 m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1); 1006 1007 /* Fix the relocation's type. */ 1008 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1009 R_M68HC11_8); 1010 1011 /* That will change things, so, we should relax again. */ 1012 *again = TRUE; 1013 } 1014 else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far) 1015 { 1016 unsigned char code; 1017 bfd_vma offset; 1018 1019 prev_insn_branch = 0; 1020 code = bfd_get_8 (abfd, contents + irel->r_offset - 1); 1021 if (code == 0x7e || code == 0xbd) 1022 { 1023 offset = value - (irel->r_offset 1024 + sec->output_section->vma 1025 + sec->output_offset + 1); 1026 offset += bfd_get_16 (abfd, contents + irel->r_offset); 1027 1028 /* If the offset is still out of -128..+127 range, 1029 leave that far branch unchanged. */ 1030 if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80) 1031 { 1032 1033 /* Note that we've changed the relocation contents, etc. */ 1034 elf_section_data (sec)->relocs = internal_relocs; 1035 free_relocs = NULL; 1036 1037 elf_section_data (sec)->this_hdr.contents = contents; 1038 free_contents = NULL; 1039 1040 symtab_hdr->contents = (bfd_byte *) isymbuf; 1041 free_extsyms = NULL; 1042 1043 /* Shrink the branch. */ 1044 code = (code == 0x7e) ? 0x20 : 0x8d; 1045 bfd_put_8 (abfd, code, 1046 contents + irel->r_offset - 1); 1047 bfd_put_8 (abfd, 0xff, 1048 contents + irel->r_offset); 1049 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1050 R_M68HC11_PCREL_8); 1051 m68hc11_elf_relax_delete_bytes (abfd, sec, 1052 irel->r_offset + 1, 1); 1053 /* That will change things, so, we should relax again. */ 1054 *again = TRUE; 1055 } 1056 } 1057 } 1058 prev_insn_branch = 0; 1059 prev_insn_group = 0; 1060 } 1061 1062 if (free_relocs != NULL) 1063 { 1064 free (free_relocs); 1065 free_relocs = NULL; 1066 } 1067 1068 if (free_contents != NULL) 1069 { 1070 if (! link_info->keep_memory) 1071 free (free_contents); 1072 else 1073 { 1074 /* Cache the section contents for elf_link_input_bfd. */ 1075 elf_section_data (sec)->this_hdr.contents = contents; 1076 } 1077 free_contents = NULL; 1078 } 1079 1080 if (free_extsyms != NULL) 1081 { 1082 if (! link_info->keep_memory) 1083 free (free_extsyms); 1084 else 1085 { 1086 /* Cache the symbols for elf_link_input_bfd. */ 1087 symtab_hdr->contents = (unsigned char *) isymbuf; 1088 } 1089 free_extsyms = NULL; 1090 } 1091 1092 return TRUE; 1093 1094 error_return: 1095 if (free_relocs != NULL) 1096 free (free_relocs); 1097 if (free_contents != NULL) 1098 free (free_contents); 1099 if (free_extsyms != NULL) 1100 free (free_extsyms); 1101 return FALSE; 1102 } 1103 1104 /* Delete some bytes from a section while relaxing. */ 1105 1106 static void 1107 m68hc11_elf_relax_delete_bytes (bfd *abfd, asection *sec, 1108 bfd_vma addr, int count) 1109 { 1110 Elf_Internal_Shdr *symtab_hdr; 1111 unsigned int sec_shndx; 1112 bfd_byte *contents; 1113 Elf_Internal_Rela *irel, *irelend; 1114 bfd_vma toaddr; 1115 Elf_Internal_Sym *isymbuf, *isym, *isymend; 1116 struct elf_link_hash_entry **sym_hashes; 1117 struct elf_link_hash_entry **end_hashes; 1118 unsigned int symcount; 1119 1120 symtab_hdr = &elf_tdata (abfd)->symtab_hdr; 1121 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; 1122 1123 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); 1124 1125 contents = elf_section_data (sec)->this_hdr.contents; 1126 1127 toaddr = sec->_cooked_size; 1128 1129 irel = elf_section_data (sec)->relocs; 1130 irelend = irel + sec->reloc_count; 1131 1132 /* Actually delete the bytes. */ 1133 memmove (contents + addr, contents + addr + count, 1134 (size_t) (toaddr - addr - count)); 1135 1136 sec->_cooked_size -= count; 1137 1138 /* Adjust all the relocs. */ 1139 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++) 1140 { 1141 unsigned char code; 1142 unsigned char offset; 1143 unsigned short raddr; 1144 unsigned long old_offset; 1145 int branch_pos; 1146 1147 old_offset = irel->r_offset; 1148 1149 /* See if this reloc was for the bytes we have deleted, in which 1150 case we no longer care about it. Don't delete relocs which 1151 represent addresses, though. */ 1152 if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP 1153 && irel->r_offset >= addr && irel->r_offset < addr + count) 1154 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), 1155 R_M68HC11_NONE); 1156 1157 if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE) 1158 continue; 1159 1160 /* Get the new reloc address. */ 1161 if ((irel->r_offset > addr 1162 && irel->r_offset < toaddr)) 1163 irel->r_offset -= count; 1164 1165 /* If this is a PC relative reloc, see if the range it covers 1166 includes the bytes we have deleted. */ 1167 switch (ELF32_R_TYPE (irel->r_info)) 1168 { 1169 default: 1170 break; 1171 1172 case R_M68HC11_RL_JUMP: 1173 code = bfd_get_8 (abfd, contents + irel->r_offset); 1174 switch (code) 1175 { 1176 /* jsr and jmp instruction are also marked with RL_JUMP 1177 relocs but no adjustment must be made. */ 1178 case 0x7e: 1179 case 0x9d: 1180 case 0xbd: 1181 continue; 1182 1183 case 0x12: 1184 case 0x13: 1185 branch_pos = 3; 1186 raddr = 4; 1187 1188 /* Special case when we translate a brclr N,y into brclr *<addr> 1189 In this case, the 0x18 page2 prefix is removed. 1190 The reloc offset is not modified but the instruction 1191 size is reduced by 1. */ 1192 if (old_offset == addr) 1193 raddr++; 1194 break; 1195 1196 case 0x1e: 1197 case 0x1f: 1198 branch_pos = 3; 1199 raddr = 4; 1200 break; 1201 1202 case 0x18: 1203 branch_pos = 4; 1204 raddr = 5; 1205 break; 1206 1207 default: 1208 branch_pos = 1; 1209 raddr = 2; 1210 break; 1211 } 1212 offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos); 1213 raddr += old_offset; 1214 raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0)); 1215 if (irel->r_offset < addr && raddr > addr) 1216 { 1217 offset -= count; 1218 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos); 1219 } 1220 else if (irel->r_offset >= addr && raddr <= addr) 1221 { 1222 offset += count; 1223 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos); 1224 } 1225 else 1226 { 1227 /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr, 1228 irel->r_offset, addr);*/ 1229 } 1230 1231 break; 1232 } 1233 } 1234 1235 /* Adjust the local symbols defined in this section. */ 1236 isymend = isymbuf + symtab_hdr->sh_info; 1237 for (isym = isymbuf; isym < isymend; isym++) 1238 { 1239 if (isym->st_shndx == sec_shndx 1240 && isym->st_value > addr 1241 && isym->st_value <= toaddr) 1242 isym->st_value -= count; 1243 } 1244 1245 /* Now adjust the global symbols defined in this section. */ 1246 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym) 1247 - symtab_hdr->sh_info); 1248 sym_hashes = elf_sym_hashes (abfd); 1249 end_hashes = sym_hashes + symcount; 1250 for (; sym_hashes < end_hashes; sym_hashes++) 1251 { 1252 struct elf_link_hash_entry *sym_hash = *sym_hashes; 1253 if ((sym_hash->root.type == bfd_link_hash_defined 1254 || sym_hash->root.type == bfd_link_hash_defweak) 1255 && sym_hash->root.u.def.section == sec 1256 && sym_hash->root.u.def.value > addr 1257 && sym_hash->root.u.def.value <= toaddr) 1258 { 1259 sym_hash->root.u.def.value -= count; 1260 } 1261 } 1262 } 1263 1264 /* Specific sections: 1265 - The .page0 is a data section that is mapped in [0x0000..0x00FF]. 1266 Page0 accesses are faster on the M68HC11. Soft registers used by GCC-m6811 1267 are located in .page0. 1268 - The .vectors is the section that represents the interrupt 1269 vectors. */ 1270 static struct bfd_elf_special_section const elf32_m68hc11_special_sections[]= 1271 { 1272 { ".eeprom", 7, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 1273 { ".softregs", 9, 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, 1274 { ".page0", 6, 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, 1275 { ".vectors", 8, 0, SHT_PROGBITS, SHF_ALLOC }, 1276 { NULL, 0, 0, 0, 0 } 1277 }; 1278 1279 #define ELF_ARCH bfd_arch_m68hc11 1280 #define ELF_MACHINE_CODE EM_68HC11 1281 #define ELF_MAXPAGESIZE 0x1000 1282 1283 #define TARGET_BIG_SYM bfd_elf32_m68hc11_vec 1284 #define TARGET_BIG_NAME "elf32-m68hc11" 1285 1286 #define elf_info_to_howto 0 1287 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel 1288 #define bfd_elf32_bfd_relax_section m68hc11_elf_relax_section 1289 #define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook 1290 #define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook 1291 #define elf_backend_check_relocs elf32_m68hc11_check_relocs 1292 #define elf_backend_relocate_section elf32_m68hc11_relocate_section 1293 #define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook 1294 #define elf_backend_object_p 0 1295 #define elf_backend_final_write_processing 0 1296 #define elf_backend_can_gc_sections 1 1297 #define elf_backend_special_sections elf32_m68hc11_special_sections 1298 1299 #define bfd_elf32_bfd_link_hash_table_create \ 1300 m68hc11_elf_bfd_link_hash_table_create 1301 #define bfd_elf32_bfd_link_hash_table_free \ 1302 m68hc11_elf_bfd_link_hash_table_free 1303 #define bfd_elf32_bfd_merge_private_bfd_data \ 1304 _bfd_m68hc11_elf_merge_private_bfd_data 1305 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags 1306 #define bfd_elf32_bfd_print_private_bfd_data \ 1307 _bfd_m68hc11_elf_print_private_bfd_data 1308 1309 #include "elf32-target.h" 1310