Home | History | Annotate | Line # | Download | only in bfd
elf32-m68hc11.c revision 1.1.1.5.12.2
      1 /* Motorola 68HC11-specific support for 32-bit ELF
      2    Copyright (C) 1999-2018 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 bfd_boolean 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 	 3,			/* size (0 = byte, 1 = short, 2 = long) */
     69 	 0,			/* 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 bfd_boolean
    381 m68hc11_info_to_howto_rel (bfd *abfd,
    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   if (r_type >= (unsigned int) R_M68HC11_max)
    388     {
    389       /* xgettext:c-format */
    390       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
    391 			  abfd, r_type);
    392       bfd_set_error (bfd_error_bad_value);
    393       return FALSE;
    394     }
    395   cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
    396   return TRUE;
    397 }
    398 
    399 
    400 /* Far trampoline generation.  */
    402 
    403 /* Build a 68HC11 trampoline stub.  */
    404 static bfd_boolean
    405 m68hc11_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
    406 {
    407   struct elf32_m68hc11_stub_hash_entry *stub_entry;
    408   struct bfd_link_info *info;
    409   struct m68hc11_elf_link_hash_table *htab;
    410   asection *stub_sec;
    411   bfd *stub_bfd;
    412   bfd_byte *loc;
    413   bfd_vma sym_value, phys_page, phys_addr;
    414 
    415   /* Massage our args to the form they really have.  */
    416   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
    417   info = (struct bfd_link_info *) in_arg;
    418 
    419   htab = m68hc11_elf_hash_table (info);
    420   if (htab == NULL)
    421     return FALSE;
    422 
    423   stub_sec = stub_entry->stub_sec;
    424 
    425   /* Make a note of the offset within the stubs for this entry.  */
    426   stub_entry->stub_offset = stub_sec->size;
    427   stub_sec->size += 10;
    428   loc = stub_sec->contents + stub_entry->stub_offset;
    429 
    430   stub_bfd = stub_sec->owner;
    431 
    432   /* Create the trampoline call stub:
    433 
    434      pshb
    435      ldab #%page(symbol)
    436      ldy #%addr(symbol)
    437      jmp __trampoline
    438 
    439   */
    440   sym_value = (stub_entry->target_value
    441 	       + stub_entry->target_section->output_offset
    442 	       + stub_entry->target_section->output_section->vma);
    443   phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
    444   phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
    445 
    446   /* pshb; ldab #%page(sym) */
    447   bfd_put_8 (stub_bfd, 0x37, loc);
    448   bfd_put_8 (stub_bfd, 0xC6, loc + 1);
    449   bfd_put_8 (stub_bfd, phys_page, loc + 2);
    450   loc += 3;
    451 
    452   /* ldy #%addr(sym)  */
    453   bfd_put_8 (stub_bfd, 0x18, loc);
    454   bfd_put_8 (stub_bfd, 0xCE, loc + 1);
    455   bfd_put_16 (stub_bfd, phys_addr, loc + 2);
    456   loc += 4;
    457 
    458   /* jmp __trampoline  */
    459   bfd_put_8 (stub_bfd, 0x7E, loc);
    460   bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
    461 
    462   return TRUE;
    463 }
    464 
    465 /* As above, but don't actually build the stub.  Just bump offset so
    466    we know stub section sizes.  */
    467 
    468 static bfd_boolean
    469 m68hc11_elf_size_one_stub (struct bfd_hash_entry *gen_entry,
    470 			   void *in_arg ATTRIBUTE_UNUSED)
    471 {
    472   struct elf32_m68hc11_stub_hash_entry *stub_entry;
    473 
    474   /* Massage our args to the form they really have.  */
    475   stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
    476 
    477   stub_entry->stub_sec->size += 10;
    478   return TRUE;
    479 }
    480 
    481 /* Create a 68HC11 ELF linker hash table.  */
    482 
    483 static struct bfd_link_hash_table *
    484 m68hc11_elf_bfd_link_hash_table_create (bfd *abfd)
    485 {
    486   struct m68hc11_elf_link_hash_table *ret;
    487 
    488   ret = m68hc11_elf_hash_table_create (abfd);
    489   if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
    490     return NULL;
    491 
    492   ret->size_one_stub = m68hc11_elf_size_one_stub;
    493   ret->build_one_stub = m68hc11_elf_build_one_stub;
    494 
    495   return &ret->root.root;
    496 }
    497 
    498 
    499 /* 68HC11 Linker Relaxation.  */
    501 
    502 struct m68hc11_direct_relax
    503 {
    504   const char *name;
    505   unsigned char code;
    506   unsigned char direct_code;
    507 } m68hc11_direct_relax_table[] = {
    508   { "adca", 0xB9, 0x99 },
    509   { "adcb", 0xF9, 0xD9 },
    510   { "adda", 0xBB, 0x9B },
    511   { "addb", 0xFB, 0xDB },
    512   { "addd", 0xF3, 0xD3 },
    513   { "anda", 0xB4, 0x94 },
    514   { "andb", 0xF4, 0xD4 },
    515   { "cmpa", 0xB1, 0x91 },
    516   { "cmpb", 0xF1, 0xD1 },
    517   { "cpd",  0xB3, 0x93 },
    518   { "cpxy", 0xBC, 0x9C },
    519 /* { "cpy",  0xBC, 0x9C }, */
    520   { "eora", 0xB8, 0x98 },
    521   { "eorb", 0xF8, 0xD8 },
    522   { "jsr",  0xBD, 0x9D },
    523   { "ldaa", 0xB6, 0x96 },
    524   { "ldab", 0xF6, 0xD6 },
    525   { "ldd",  0xFC, 0xDC },
    526   { "lds",  0xBE, 0x9E },
    527   { "ldxy", 0xFE, 0xDE },
    528   /*  { "ldy",  0xFE, 0xDE },*/
    529   { "oraa", 0xBA, 0x9A },
    530   { "orab", 0xFA, 0xDA },
    531   { "sbca", 0xB2, 0x92 },
    532   { "sbcb", 0xF2, 0xD2 },
    533   { "staa", 0xB7, 0x97 },
    534   { "stab", 0xF7, 0xD7 },
    535   { "std",  0xFD, 0xDD },
    536   { "sts",  0xBF, 0x9F },
    537   { "stxy", 0xFF, 0xDF },
    538   /*  { "sty",  0xFF, 0xDF },*/
    539   { "suba", 0xB0, 0x90 },
    540   { "subb", 0xF0, 0xD0 },
    541   { "subd", 0xB3, 0x93 },
    542   { 0, 0, 0 }
    543 };
    544 
    545 static struct m68hc11_direct_relax *
    546 find_relaxable_insn (unsigned char code)
    547 {
    548   int i;
    549 
    550   for (i = 0; m68hc11_direct_relax_table[i].name; i++)
    551     if (m68hc11_direct_relax_table[i].code == code)
    552       return &m68hc11_direct_relax_table[i];
    553 
    554   return 0;
    555 }
    556 
    557 static int
    558 compare_reloc (const void *e1, const void *e2)
    559 {
    560   const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
    561   const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
    562 
    563   if (i1->r_offset == i2->r_offset)
    564     return 0;
    565   else
    566     return i1->r_offset < i2->r_offset ? -1 : 1;
    567 }
    568 
    569 #define M6811_OP_LDX_IMMEDIATE (0xCE)
    570 
    571 static void
    572 m68hc11_relax_group (bfd *abfd, asection *sec, bfd_byte *contents,
    573 		     unsigned value, unsigned long offset,
    574 		     unsigned long end_group)
    575 {
    576   unsigned char code;
    577   unsigned long start_offset;
    578   unsigned long ldx_offset = offset;
    579   unsigned long ldx_size;
    580   int can_delete_ldx;
    581   int relax_ldy = 0;
    582 
    583   /* First instruction of the relax group must be a
    584      LDX #value or LDY #value.  If this is not the case,
    585      ignore the relax group.  */
    586   code = bfd_get_8 (abfd, contents + offset);
    587   if (code == 0x18)
    588     {
    589       relax_ldy++;
    590       offset++;
    591       code = bfd_get_8 (abfd, contents + offset);
    592     }
    593   ldx_size = offset - ldx_offset + 3;
    594   offset += 3;
    595   if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
    596     return;
    597 
    598 
    599   /* We can remove the LDX/LDY only when all bset/brclr instructions
    600      of the relax group have been converted to use direct addressing
    601      mode.  */
    602   can_delete_ldx = 1;
    603   while (offset < end_group)
    604     {
    605       unsigned isize;
    606       unsigned new_value;
    607       int bset_use_y;
    608 
    609       bset_use_y = 0;
    610       start_offset = offset;
    611       code = bfd_get_8 (abfd, contents + offset);
    612       if (code == 0x18)
    613 	{
    614 	  bset_use_y++;
    615 	  offset++;
    616 	  code = bfd_get_8 (abfd, contents + offset);
    617 	}
    618 
    619       /* Check the instruction and translate to use direct addressing mode.  */
    620       switch (code)
    621 	{
    622 	  /* bset */
    623 	case 0x1C:
    624 	  code = 0x14;
    625 	  isize = 3;
    626 	  break;
    627 
    628 	  /* brclr */
    629 	case 0x1F:
    630 	  code = 0x13;
    631 	  isize = 4;
    632 	  break;
    633 
    634 	  /* brset */
    635 	case 0x1E:
    636 	  code = 0x12;
    637 	  isize = 4;
    638 	  break;
    639 
    640 	  /* bclr */
    641 	case 0x1D:
    642 	  code = 0x15;
    643 	  isize = 3;
    644 	  break;
    645 
    646 	  /* This instruction is not recognized and we are not
    647 	     at end of the relax group.  Ignore and don't remove
    648 	     the first LDX (we don't know what it is used for...).  */
    649 	default:
    650 	  return;
    651 	}
    652       new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
    653       new_value += value;
    654       if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
    655 	{
    656 	  bfd_put_8 (abfd, code, contents + offset);
    657 	  bfd_put_8 (abfd, new_value, contents + offset + 1);
    658 	  if (start_offset != offset)
    659 	    {
    660 	      m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
    661 					      offset - start_offset);
    662 	      end_group--;
    663 	    }
    664 	}
    665       else
    666 	{
    667 	  can_delete_ldx = 0;
    668 	}
    669       offset = start_offset + isize;
    670     }
    671   if (can_delete_ldx)
    672     {
    673       /* Remove the move instruction (3 or 4 bytes win).  */
    674       m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
    675     }
    676 }
    677 
    678 /* This function handles relaxing for the 68HC11.
    679 
    680 
    681 	and somewhat more difficult to support.  */
    682 
    683 static bfd_boolean
    684 m68hc11_elf_relax_section (bfd *abfd, asection *sec,
    685 			   struct bfd_link_info *link_info, bfd_boolean *again)
    686 {
    687   Elf_Internal_Shdr *symtab_hdr;
    688   Elf_Internal_Rela *internal_relocs;
    689   Elf_Internal_Rela *free_relocs = NULL;
    690   Elf_Internal_Rela *irel, *irelend;
    691   bfd_byte *contents = NULL;
    692   bfd_byte *free_contents = NULL;
    693   Elf32_External_Sym *free_extsyms = NULL;
    694   Elf_Internal_Rela *prev_insn_branch = NULL;
    695   Elf_Internal_Rela *prev_insn_group = NULL;
    696   unsigned insn_group_value = 0;
    697   Elf_Internal_Sym *isymbuf = NULL;
    698 
    699   /* Assume nothing changes.  */
    700   *again = FALSE;
    701 
    702   /* We don't have to do anything for a relocatable link, if
    703      this section does not have relocs, or if this is not a
    704      code section.  */
    705   if (bfd_link_relocatable (link_info)
    706       || (sec->flags & SEC_RELOC) == 0
    707       || sec->reloc_count == 0
    708       || (sec->flags & SEC_CODE) == 0)
    709     return TRUE;
    710 
    711   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    712 
    713   /* Get a copy of the native relocations.  */
    714   internal_relocs = (_bfd_elf_link_read_relocs
    715 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
    716 		      link_info->keep_memory));
    717   if (internal_relocs == NULL)
    718     goto error_return;
    719   if (! link_info->keep_memory)
    720     free_relocs = internal_relocs;
    721 
    722   /* Checking for branch relaxation relies on the relocations to
    723      be sorted on 'r_offset'.  This is not guaranteed so we must sort.  */
    724   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
    725 	 compare_reloc);
    726 
    727   /* Walk through them looking for relaxing opportunities.  */
    728   irelend = internal_relocs + sec->reloc_count;
    729   for (irel = internal_relocs; irel < irelend; irel++)
    730     {
    731       bfd_vma symval;
    732       bfd_vma value;
    733       Elf_Internal_Sym *isym;
    734       asection *sym_sec;
    735       int is_far = 0;
    736 
    737       /* If this isn't something that can be relaxed, then ignore
    738 	 this reloc.  */
    739       if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
    740 	  && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
    741 	  && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
    742 	{
    743 	  prev_insn_branch = 0;
    744 	  prev_insn_group = 0;
    745 	  continue;
    746 	}
    747 
    748       /* Get the section contents if we haven't done so already.  */
    749       if (contents == NULL)
    750 	{
    751 	  /* Get cached copy if it exists.  */
    752 	  if (elf_section_data (sec)->this_hdr.contents != NULL)
    753 	    contents = elf_section_data (sec)->this_hdr.contents;
    754 	  else
    755 	    {
    756 	      /* Go get them off disk.  */
    757 	      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
    758 		goto error_return;
    759 	    }
    760 	}
    761 
    762       /* Try to eliminate an unconditional 8 bit pc-relative branch
    763 	 which immediately follows a conditional 8 bit pc-relative
    764 	 branch around the unconditional branch.
    765 
    766 	    original:		new:
    767 	    bCC lab1		bCC' lab2
    768 	    bra lab2
    769 	   lab1:	       lab1:
    770 
    771 	 This happens when the bCC can't reach lab2 at assembly time,
    772 	 but due to other relaxations it can reach at link time.  */
    773       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
    774 	{
    775 	  Elf_Internal_Rela *nrel;
    776 	  unsigned char code;
    777 	  unsigned char roffset;
    778 
    779 	  prev_insn_branch = 0;
    780 	  prev_insn_group = 0;
    781 
    782 	  /* Do nothing if this reloc is the last byte in the section.  */
    783 	  if (irel->r_offset + 2 >= sec->size)
    784 	    continue;
    785 
    786 	  /* See if the next instruction is an unconditional pc-relative
    787 	     branch, more often than not this test will fail, so we
    788 	     test it first to speed things up.  */
    789 	  code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
    790 	  if (code != 0x7e)
    791 	    continue;
    792 
    793 	  /* Also make sure the next relocation applies to the next
    794 	     instruction and that it's a pc-relative 8 bit branch.  */
    795 	  nrel = irel + 1;
    796 	  if (nrel == irelend
    797 	      || irel->r_offset + 3 != nrel->r_offset
    798 	      || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
    799 	    continue;
    800 
    801 	  /* Make sure our destination immediately follows the
    802 	     unconditional branch.  */
    803 	  roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
    804 	  if (roffset != 3)
    805 	    continue;
    806 
    807 	  prev_insn_branch = irel;
    808 	  prev_insn_group = 0;
    809 	  continue;
    810 	}
    811 
    812       /* Read this BFD's symbols if we haven't done so already.  */
    813       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
    814 	{
    815 	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
    816 	  if (isymbuf == NULL)
    817 	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
    818 					    symtab_hdr->sh_info, 0,
    819 					    NULL, NULL, NULL);
    820 	  if (isymbuf == NULL)
    821 	    goto error_return;
    822 	}
    823 
    824       /* Get the value of the symbol referred to by the reloc.  */
    825       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    826 	{
    827 	  /* A local symbol.  */
    828 	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
    829 	  is_far = isym->st_other & STO_M68HC12_FAR;
    830 	  sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    831 	  symval = (isym->st_value
    832 		    + sym_sec->output_section->vma
    833 		    + sym_sec->output_offset);
    834 	}
    835       else
    836 	{
    837 	  unsigned long indx;
    838 	  struct elf_link_hash_entry *h;
    839 
    840 	  /* An external symbol.  */
    841 	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
    842 	  h = elf_sym_hashes (abfd)[indx];
    843 	  BFD_ASSERT (h != NULL);
    844 	  if (h->root.type != bfd_link_hash_defined
    845 	      && h->root.type != bfd_link_hash_defweak)
    846 	    {
    847 	      /* This appears to be a reference to an undefined
    848 		 symbol.  Just ignore it--it will be caught by the
    849 		 regular reloc processing.  */
    850 	      prev_insn_branch = 0;
    851 	      prev_insn_group = 0;
    852 	      continue;
    853 	    }
    854 
    855 	  is_far = h->other & STO_M68HC12_FAR;
    856 	  isym = 0;
    857 	  sym_sec = h->root.u.def.section;
    858 	  symval = (h->root.u.def.value
    859 		    + sym_sec->output_section->vma
    860 		    + sym_sec->output_offset);
    861 	}
    862 
    863       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
    864 	{
    865 	  prev_insn_branch = 0;
    866 	  prev_insn_group = 0;
    867 
    868 	  /* Do nothing if this reloc is the last byte in the section.  */
    869 	  if (irel->r_offset == sec->size)
    870 	    continue;
    871 
    872 	  prev_insn_group = irel;
    873 	  insn_group_value = isym->st_value;
    874 	  continue;
    875 	}
    876 
    877       /* When we relax some bytes, the size of our section changes.
    878 	 This affects the layout of next input sections that go in our
    879 	 output section.  When the symbol is part of another section that
    880 	 will go in the same output section as the current one, it's
    881 	 final address may now be incorrect (too far).  We must let the
    882 	 linker re-compute all section offsets before processing this
    883 	 reloc.  Code example:
    884 
    885 				Initial		    Final
    886 	 .sect .text		section size = 6    section size = 4
    887 	 jmp foo
    888 	 jmp bar
    889 	 .sect .text.foo_bar	output_offset = 6   output_offset = 4
    890 	 foo: rts
    891 	 bar: rts
    892 
    893 	 If we process the reloc now, the jmp bar is replaced by a
    894 	 relative branch to the initial bar address (output_offset 6).  */
    895       if (*again && sym_sec != sec
    896 	  && sym_sec->output_section == sec->output_section)
    897 	{
    898 	  prev_insn_group = 0;
    899 	  prev_insn_branch = 0;
    900 	  continue;
    901 	}
    902 
    903       value = symval;
    904       /* Try to turn a far branch to a near branch.  */
    905       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
    906 	  && prev_insn_branch)
    907 	{
    908 	  bfd_vma offset;
    909 	  unsigned char code;
    910 
    911 	  offset = value - (prev_insn_branch->r_offset
    912 			    + sec->output_section->vma
    913 			    + sec->output_offset + 2);
    914 
    915 	  /* If the offset is still out of -128..+127 range,
    916 	     leave that far branch unchanged.  */
    917 	  if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
    918 	    {
    919 	      prev_insn_branch = 0;
    920 	      continue;
    921 	    }
    922 
    923 	  /* Shrink the branch.  */
    924 	  code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
    925 	  if (code == 0x7e)
    926 	    {
    927 	      code = 0x20;
    928 	      bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
    929 	      bfd_put_8 (abfd, 0xff,
    930 			 contents + prev_insn_branch->r_offset + 1);
    931 	      irel->r_offset = prev_insn_branch->r_offset + 1;
    932 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
    933 					   R_M68HC11_PCREL_8);
    934 	      m68hc11_elf_relax_delete_bytes (abfd, sec,
    935 					      irel->r_offset + 1, 1);
    936 	    }
    937 	  else
    938 	    {
    939 	      code ^= 0x1;
    940 	      bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
    941 	      bfd_put_8 (abfd, 0xff,
    942 			 contents + prev_insn_branch->r_offset + 1);
    943 	      irel->r_offset = prev_insn_branch->r_offset + 1;
    944 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
    945 					   R_M68HC11_PCREL_8);
    946 	      m68hc11_elf_relax_delete_bytes (abfd, sec,
    947 					      irel->r_offset + 1, 3);
    948 	    }
    949 	  prev_insn_branch = 0;
    950 	  *again = TRUE;
    951 	}
    952 
    953       /* Try to turn a 16 bit address into a 8 bit page0 address.  */
    954       else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
    955 	       && (value & 0xff00) == 0)
    956 	{
    957 	  unsigned char code;
    958 	  unsigned short offset;
    959 	  struct m68hc11_direct_relax *rinfo;
    960 
    961 	  prev_insn_branch = 0;
    962 	  offset = bfd_get_16 (abfd, contents + irel->r_offset);
    963 	  offset += value;
    964 	  if ((offset & 0xff00) != 0)
    965 	    {
    966 	      prev_insn_group = 0;
    967 	      continue;
    968 	    }
    969 
    970 	  if (prev_insn_group)
    971 	    {
    972 	      unsigned long old_sec_size = sec->size;
    973 
    974 	      /* Note that we've changed the relocation contents, etc.  */
    975 	      elf_section_data (sec)->relocs = internal_relocs;
    976 	      free_relocs = NULL;
    977 
    978 	      elf_section_data (sec)->this_hdr.contents = contents;
    979 	      free_contents = NULL;
    980 
    981 	      symtab_hdr->contents = (bfd_byte *) isymbuf;
    982 	      free_extsyms = NULL;
    983 
    984 	      m68hc11_relax_group (abfd, sec, contents, offset,
    985 				   prev_insn_group->r_offset,
    986 				   insn_group_value);
    987 	      irel = prev_insn_group;
    988 	      prev_insn_group = 0;
    989 	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
    990 					   R_M68HC11_NONE);
    991 	      if (sec->size != old_sec_size)
    992 		*again = TRUE;
    993 	      continue;
    994 	    }
    995 
    996 	  /* Get the opcode.  */
    997 	  code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
    998 	  rinfo = find_relaxable_insn (code);
    999 	  if (rinfo == 0)
   1000 	    {
   1001 	      prev_insn_group = 0;
   1002 	      continue;
   1003 	    }
   1004 
   1005 	  /* Note that we've changed the relocation contents, etc.  */
   1006 	  elf_section_data (sec)->relocs = internal_relocs;
   1007 	  free_relocs = NULL;
   1008 
   1009 	  elf_section_data (sec)->this_hdr.contents = contents;
   1010 	  free_contents = NULL;
   1011 
   1012 	  symtab_hdr->contents = (bfd_byte *) isymbuf;
   1013 	  free_extsyms = NULL;
   1014 
   1015 	  /* Fix the opcode.  */
   1016 	  /* printf ("A relaxable case : 0x%02x (%s)\n",
   1017 	     code, rinfo->name); */
   1018 	  bfd_put_8 (abfd, rinfo->direct_code,
   1019 		     contents + irel->r_offset - 1);
   1020 
   1021 	  /* Delete one byte of data (upper byte of address).  */
   1022 	  m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
   1023 
   1024 	  /* Fix the relocation's type.  */
   1025 	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1026 				       R_M68HC11_8);
   1027 
   1028 	  /* That will change things, so, we should relax again.  */
   1029 	  *again = TRUE;
   1030 	}
   1031       else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
   1032 	{
   1033 	  unsigned char code;
   1034 	  bfd_vma offset;
   1035 
   1036 	  prev_insn_branch = 0;
   1037 	  code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
   1038 	  if (code == 0x7e || code == 0xbd)
   1039 	    {
   1040 	      offset = value - (irel->r_offset
   1041 				+ sec->output_section->vma
   1042 				+ sec->output_offset + 1);
   1043 	      offset += bfd_get_16 (abfd, contents + irel->r_offset);
   1044 
   1045 	      /* If the offset is still out of -128..+127 range,
   1046 		 leave that far branch unchanged.  */
   1047 	      if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
   1048 		{
   1049 
   1050 		  /* Note that we've changed the relocation contents, etc.  */
   1051 		  elf_section_data (sec)->relocs = internal_relocs;
   1052 		  free_relocs = NULL;
   1053 
   1054 		  elf_section_data (sec)->this_hdr.contents = contents;
   1055 		  free_contents = NULL;
   1056 
   1057 		  symtab_hdr->contents = (bfd_byte *) isymbuf;
   1058 		  free_extsyms = NULL;
   1059 
   1060 		  /* Shrink the branch.  */
   1061 		  code = (code == 0x7e) ? 0x20 : 0x8d;
   1062 		  bfd_put_8 (abfd, code,
   1063 			     contents + irel->r_offset - 1);
   1064 		  bfd_put_8 (abfd, 0xff,
   1065 			     contents + irel->r_offset);
   1066 		  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1067 					       R_M68HC11_PCREL_8);
   1068 		  m68hc11_elf_relax_delete_bytes (abfd, sec,
   1069 						  irel->r_offset + 1, 1);
   1070 		  /* That will change things, so, we should relax again.  */
   1071 		  *again = TRUE;
   1072 		}
   1073 	    }
   1074 	}
   1075       prev_insn_branch = 0;
   1076       prev_insn_group = 0;
   1077     }
   1078 
   1079   if (free_relocs != NULL)
   1080     {
   1081       free (free_relocs);
   1082       free_relocs = NULL;
   1083     }
   1084 
   1085   if (free_contents != NULL)
   1086     {
   1087       if (! link_info->keep_memory)
   1088 	free (free_contents);
   1089       else
   1090 	{
   1091 	  /* Cache the section contents for elf_link_input_bfd.  */
   1092 	  elf_section_data (sec)->this_hdr.contents = contents;
   1093 	}
   1094       free_contents = NULL;
   1095     }
   1096 
   1097   if (free_extsyms != NULL)
   1098     {
   1099       if (! link_info->keep_memory)
   1100 	free (free_extsyms);
   1101       else
   1102 	{
   1103 	  /* Cache the symbols for elf_link_input_bfd.  */
   1104 	  symtab_hdr->contents = (unsigned char *) isymbuf;
   1105 	}
   1106       free_extsyms = NULL;
   1107     }
   1108 
   1109   return TRUE;
   1110 
   1111  error_return:
   1112   if (free_relocs != NULL)
   1113     free (free_relocs);
   1114   if (free_contents != NULL)
   1115     free (free_contents);
   1116   if (free_extsyms != NULL)
   1117     free (free_extsyms);
   1118   return FALSE;
   1119 }
   1120 
   1121 /* Delete some bytes from a section while relaxing.  */
   1122 
   1123 static void
   1124 m68hc11_elf_relax_delete_bytes (bfd *abfd, asection *sec,
   1125 				bfd_vma addr, int count)
   1126 {
   1127   Elf_Internal_Shdr *symtab_hdr;
   1128   unsigned int sec_shndx;
   1129   bfd_byte *contents;
   1130   Elf_Internal_Rela *irel, *irelend;
   1131   bfd_vma toaddr;
   1132   Elf_Internal_Sym *isymbuf, *isym, *isymend;
   1133   struct elf_link_hash_entry **sym_hashes;
   1134   struct elf_link_hash_entry **end_hashes;
   1135   unsigned int symcount;
   1136 
   1137   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1138   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1139 
   1140   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
   1141 
   1142   contents = elf_section_data (sec)->this_hdr.contents;
   1143 
   1144   toaddr = sec->size;
   1145 
   1146   irel = elf_section_data (sec)->relocs;
   1147   irelend = irel + sec->reloc_count;
   1148 
   1149   /* Actually delete the bytes.  */
   1150   memmove (contents + addr, contents + addr + count,
   1151 	   (size_t) (toaddr - addr - count));
   1152 
   1153   sec->size -= count;
   1154 
   1155   /* Adjust all the relocs.  */
   1156   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
   1157     {
   1158       unsigned char code;
   1159       unsigned char offset;
   1160       unsigned short raddr;
   1161       unsigned long old_offset;
   1162       int branch_pos;
   1163 
   1164       old_offset = irel->r_offset;
   1165 
   1166       /* See if this reloc was for the bytes we have deleted, in which
   1167 	 case we no longer care about it.  Don't delete relocs which
   1168 	 represent addresses, though.  */
   1169       if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
   1170 	  && irel->r_offset >= addr && irel->r_offset < addr + count)
   1171 	irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
   1172 				     R_M68HC11_NONE);
   1173 
   1174       if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
   1175 	continue;
   1176 
   1177       /* Get the new reloc address.  */
   1178       if ((irel->r_offset > addr
   1179 	   && irel->r_offset < toaddr))
   1180 	irel->r_offset -= count;
   1181 
   1182       /* If this is a PC relative reloc, see if the range it covers
   1183 	 includes the bytes we have deleted.  */
   1184       switch (ELF32_R_TYPE (irel->r_info))
   1185 	{
   1186 	default:
   1187 	  break;
   1188 
   1189 	case R_M68HC11_RL_JUMP:
   1190 	  code = bfd_get_8 (abfd, contents + irel->r_offset);
   1191 	  switch (code)
   1192 	    {
   1193 	      /* jsr and jmp instruction are also marked with RL_JUMP
   1194 		 relocs but no adjustment must be made.  */
   1195 	    case 0x7e:
   1196 	    case 0x9d:
   1197 	    case 0xbd:
   1198 	      continue;
   1199 
   1200 	    case 0x12:
   1201 	    case 0x13:
   1202 	      branch_pos = 3;
   1203 	      raddr = 4;
   1204 
   1205 	      /* Special case when we translate a brclr N,y into brclr *<addr>
   1206 		 In this case, the 0x18 page2 prefix is removed.
   1207 		 The reloc offset is not modified but the instruction
   1208 		 size is reduced by 1.  */
   1209 	      if (old_offset == addr)
   1210 		raddr++;
   1211 	      break;
   1212 
   1213 	    case 0x1e:
   1214 	    case 0x1f:
   1215 	      branch_pos = 3;
   1216 	      raddr = 4;
   1217 	      break;
   1218 
   1219 	    case 0x18:
   1220 	      branch_pos = 4;
   1221 	      raddr = 5;
   1222 	      break;
   1223 
   1224 	    default:
   1225 	      branch_pos = 1;
   1226 	      raddr = 2;
   1227 	      break;
   1228 	    }
   1229 	  offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
   1230 	  raddr += old_offset;
   1231 	  raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
   1232 	  if (irel->r_offset < addr && raddr > addr)
   1233 	    {
   1234 	      offset -= count;
   1235 	      bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
   1236 	    }
   1237 	  else if (irel->r_offset >= addr && raddr <= addr)
   1238 	    {
   1239 	      offset += count;
   1240 	      bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
   1241 	    }
   1242 	  else
   1243 	    {
   1244 	      /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
   1245 		irel->r_offset, addr);*/
   1246 	    }
   1247 
   1248 	  break;
   1249 	}
   1250     }
   1251 
   1252   /* Adjust the local symbols defined in this section.  */
   1253   isymend = isymbuf + symtab_hdr->sh_info;
   1254   for (isym = isymbuf; isym < isymend; isym++)
   1255     {
   1256       if (isym->st_shndx == sec_shndx
   1257 	  && isym->st_value > addr
   1258 	  && isym->st_value <= toaddr)
   1259 	isym->st_value -= count;
   1260     }
   1261 
   1262   /* Now adjust the global symbols defined in this section.  */
   1263   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
   1264 	      - symtab_hdr->sh_info);
   1265   sym_hashes = elf_sym_hashes (abfd);
   1266   end_hashes = sym_hashes + symcount;
   1267   for (; sym_hashes < end_hashes; sym_hashes++)
   1268     {
   1269       struct elf_link_hash_entry *sym_hash = *sym_hashes;
   1270       if ((sym_hash->root.type == bfd_link_hash_defined
   1271 	   || sym_hash->root.type == bfd_link_hash_defweak)
   1272 	  && sym_hash->root.u.def.section == sec
   1273 	  && sym_hash->root.u.def.value > addr
   1274 	  && sym_hash->root.u.def.value <= toaddr)
   1275 	{
   1276 	  sym_hash->root.u.def.value -= count;
   1277 	}
   1278     }
   1279 }
   1280 
   1281 /* Specific sections:
   1282    - The .page0 is a data section that is mapped in [0x0000..0x00FF].
   1283      Page0 accesses are faster on the M68HC11. Soft registers used by GCC-m6811
   1284      are located in .page0.
   1285    - The .vectors is the section that represents the interrupt
   1286      vectors.  */
   1287 static const struct bfd_elf_special_section elf32_m68hc11_special_sections[] =
   1288 {
   1289   { STRING_COMMA_LEN (".eeprom"),   0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
   1290   { STRING_COMMA_LEN (".page0"),    0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
   1291   { STRING_COMMA_LEN (".softregs"), 0, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
   1292   { STRING_COMMA_LEN (".vectors"),  0, SHT_PROGBITS, SHF_ALLOC },
   1293   { NULL,			0,  0, 0,	     0 }
   1294 };
   1295 
   1296 #define ELF_ARCH		bfd_arch_m68hc11
   1298 #define ELF_TARGET_ID		M68HC11_ELF_DATA
   1299 #define ELF_MACHINE_CODE	EM_68HC11
   1300 #define ELF_MAXPAGESIZE		0x1000
   1301 
   1302 #define TARGET_BIG_SYM		m68hc11_elf32_vec
   1303 #define TARGET_BIG_NAME		"elf32-m68hc11"
   1304 
   1305 #define elf_info_to_howto	NULL
   1306 #define elf_info_to_howto_rel	m68hc11_info_to_howto_rel
   1307 #define bfd_elf32_bfd_relax_section  m68hc11_elf_relax_section
   1308 #define elf_backend_check_relocs     elf32_m68hc11_check_relocs
   1309 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
   1310 #define elf_backend_add_symbol_hook  elf32_m68hc11_add_symbol_hook
   1311 #define elf_backend_object_p	0
   1312 #define elf_backend_final_write_processing	0
   1313 #define elf_backend_can_gc_sections		1
   1314 #define elf_backend_special_sections  elf32_m68hc11_special_sections
   1315 #define elf_backend_merge_symbol_attribute elf32_m68hc11_merge_symbol_attribute
   1316 
   1317 #define bfd_elf32_bfd_link_hash_table_create \
   1318 				m68hc11_elf_bfd_link_hash_table_create
   1319 #define bfd_elf32_bfd_merge_private_bfd_data \
   1320 					_bfd_m68hc11_elf_merge_private_bfd_data
   1321 #define bfd_elf32_bfd_set_private_flags	_bfd_m68hc11_elf_set_private_flags
   1322 #define bfd_elf32_bfd_print_private_bfd_data \
   1323 					_bfd_m68hc11_elf_print_private_bfd_data
   1324 
   1325 #include "elf32-target.h"
   1326