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