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