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