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