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