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