Update year range in copyright notice of binutils files
[external/binutils.git] / bfd / elf32-m68hc11.c
1 /* Motorola 68HC11-specific support for 32-bit ELF
2    Copyright (C) 1999-2018 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.  */
33 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
34   (bfd *, bfd_reloc_code_real_type);
35 static void m68hc11_info_to_howto_rel
36   (bfd *, arelent *, Elf_Internal_Rela *);
37
38 /* Trampoline generation.  */
39 static bfd_boolean m68hc11_elf_size_one_stub
40   (struct bfd_hash_entry *gen_entry, void *in_arg);
41 static bfd_boolean m68hc11_elf_build_one_stub
42   (struct bfd_hash_entry *gen_entry, void *in_arg);
43 static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create
44   (bfd* abfd);
45
46 /* Linker relaxation.  */
47 static bfd_boolean m68hc11_elf_relax_section
48   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
49 static void m68hc11_elf_relax_delete_bytes
50   (bfd *, asection *, bfd_vma, int);
51 static void m68hc11_relax_group
52   (bfd *, asection *, bfd_byte *, unsigned, unsigned long, unsigned long);
53 static int compare_reloc (const void *, const void *);
54
55 /* Use REL instead of RELA to save space */
56 #define USE_REL 1
57
58 /* The Motorola 68HC11 microcontroller only addresses 64Kb but we also
59    support a memory bank switching mechanism similar to 68HC12.
60    We must handle 8 and 16-bit relocations.  The 32-bit relocation
61    are used for debugging sections (DWARF2) to represent a virtual
62    address.
63    The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
64 static reloc_howto_type elf_m68hc11_howto_table[] = {
65   /* This reloc does nothing.  */
66   HOWTO (R_M68HC11_NONE,        /* type */
67          0,                     /* rightshift */
68          3,                     /* size (0 = byte, 1 = short, 2 = long) */
69          0,                     /* bitsize */
70          FALSE,                 /* pc_relative */
71          0,                     /* bitpos */
72          complain_overflow_dont,/* complain_on_overflow */
73          bfd_elf_generic_reloc, /* special_function */
74          "R_M68HC11_NONE",      /* name */
75          FALSE,                 /* partial_inplace */
76          0,                     /* src_mask */
77          0,                     /* dst_mask */
78          FALSE),                /* pcrel_offset */
79
80   /* A 8 bit absolute relocation */
81   HOWTO (R_M68HC11_8,           /* type */
82          0,                     /* rightshift */
83          0,                     /* size (0 = byte, 1 = short, 2 = long) */
84          8,                     /* bitsize */
85          FALSE,                 /* pc_relative */
86          0,                     /* bitpos */
87          complain_overflow_bitfield,    /* complain_on_overflow */
88          bfd_elf_generic_reloc, /* special_function */
89          "R_M68HC11_8",         /* name */
90          FALSE,                 /* partial_inplace */
91          0x00ff,                /* src_mask */
92          0x00ff,                /* dst_mask */
93          FALSE),                /* pcrel_offset */
94
95   /* A 8 bit absolute relocation (upper address) */
96   HOWTO (R_M68HC11_HI8,         /* type */
97          8,                     /* rightshift */
98          0,                     /* size (0 = byte, 1 = short, 2 = long) */
99          8,                     /* bitsize */
100          FALSE,                 /* pc_relative */
101          0,                     /* bitpos */
102          complain_overflow_bitfield,    /* complain_on_overflow */
103          bfd_elf_generic_reloc, /* special_function */
104          "R_M68HC11_HI8",       /* name */
105          FALSE,                 /* partial_inplace */
106          0x00ff,                /* src_mask */
107          0x00ff,                /* dst_mask */
108          FALSE),                /* pcrel_offset */
109
110   /* A 8 bit absolute relocation (upper address) */
111   HOWTO (R_M68HC11_LO8,         /* type */
112          0,                     /* rightshift */
113          0,                     /* size (0 = byte, 1 = short, 2 = long) */
114          8,                     /* bitsize */
115          FALSE,                 /* pc_relative */
116          0,                     /* bitpos */
117          complain_overflow_dont,        /* complain_on_overflow */
118          bfd_elf_generic_reloc, /* special_function */
119          "R_M68HC11_LO8",       /* name */
120          FALSE,                 /* partial_inplace */
121          0x00ff,                /* src_mask */
122          0x00ff,                /* dst_mask */
123          FALSE),                /* pcrel_offset */
124
125   /* A 8 bit PC-rel relocation */
126   HOWTO (R_M68HC11_PCREL_8,     /* type */
127          0,                     /* rightshift */
128          0,                     /* size (0 = byte, 1 = short, 2 = long) */
129          8,                     /* bitsize */
130          TRUE,                  /* pc_relative */
131          0,                     /* bitpos */
132          complain_overflow_bitfield,    /* complain_on_overflow */
133          bfd_elf_generic_reloc, /* special_function */
134          "R_M68HC11_PCREL_8",   /* name */
135          FALSE,                 /* partial_inplace */
136          0x00ff,                /* src_mask */
137          0x00ff,                /* dst_mask */
138          TRUE),                 /* pcrel_offset */
139
140   /* A 16 bit absolute relocation */
141   HOWTO (R_M68HC11_16,          /* type */
142          0,                     /* rightshift */
143          1,                     /* size (0 = byte, 1 = short, 2 = long) */
144          16,                    /* bitsize */
145          FALSE,                 /* pc_relative */
146          0,                     /* bitpos */
147          complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
148          bfd_elf_generic_reloc, /* special_function */
149          "R_M68HC11_16",        /* name */
150          FALSE,                 /* partial_inplace */
151          0xffff,                /* src_mask */
152          0xffff,                /* dst_mask */
153          FALSE),                /* pcrel_offset */
154
155   /* A 32 bit absolute relocation.  This one is never used for the
156      code relocation.  It's used by gas for -gstabs generation.  */
157   HOWTO (R_M68HC11_32,          /* type */
158          0,                     /* rightshift */
159          2,                     /* size (0 = byte, 1 = short, 2 = long) */
160          32,                    /* bitsize */
161          FALSE,                 /* pc_relative */
162          0,                     /* bitpos */
163          complain_overflow_bitfield,    /* complain_on_overflow */
164          bfd_elf_generic_reloc, /* special_function */
165          "R_M68HC11_32",        /* name */
166          FALSE,                 /* partial_inplace */
167          0xffffffff,            /* src_mask */
168          0xffffffff,            /* dst_mask */
169          FALSE),                /* pcrel_offset */
170
171   /* A 3 bit absolute relocation */
172   HOWTO (R_M68HC11_3B,          /* type */
173          0,                     /* rightshift */
174          0,                     /* size (0 = byte, 1 = short, 2 = long) */
175          3,                     /* bitsize */
176          FALSE,                 /* pc_relative */
177          0,                     /* bitpos */
178          complain_overflow_bitfield,    /* complain_on_overflow */
179          bfd_elf_generic_reloc, /* special_function */
180          "R_M68HC11_4B",        /* name */
181          FALSE,                 /* partial_inplace */
182          0x003,                 /* src_mask */
183          0x003,                 /* dst_mask */
184          FALSE),                /* pcrel_offset */
185
186   /* A 16 bit PC-rel relocation */
187   HOWTO (R_M68HC11_PCREL_16,    /* type */
188          0,                     /* rightshift */
189          1,                     /* size (0 = byte, 1 = short, 2 = long) */
190          16,                    /* bitsize */
191          TRUE,                  /* pc_relative */
192          0,                     /* bitpos */
193          complain_overflow_dont,        /* complain_on_overflow */
194          bfd_elf_generic_reloc, /* special_function */
195          "R_M68HC11_PCREL_16",  /* name */
196          FALSE,                 /* partial_inplace */
197          0xffff,                /* src_mask */
198          0xffff,                /* dst_mask */
199          TRUE),                 /* pcrel_offset */
200
201   /* GNU extension to record C++ vtable hierarchy */
202   HOWTO (R_M68HC11_GNU_VTINHERIT,       /* type */
203          0,                     /* rightshift */
204          1,                     /* size (0 = byte, 1 = short, 2 = long) */
205          0,                     /* bitsize */
206          FALSE,                 /* pc_relative */
207          0,                     /* bitpos */
208          complain_overflow_dont,        /* complain_on_overflow */
209          NULL,                  /* special_function */
210          "R_M68HC11_GNU_VTINHERIT",     /* name */
211          FALSE,                 /* partial_inplace */
212          0,                     /* src_mask */
213          0,                     /* dst_mask */
214          FALSE),                /* pcrel_offset */
215
216   /* GNU extension to record C++ vtable member usage */
217   HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
218          0,                     /* rightshift */
219          1,                     /* size (0 = byte, 1 = short, 2 = long) */
220          0,                     /* bitsize */
221          FALSE,                 /* pc_relative */
222          0,                     /* bitpos */
223          complain_overflow_dont,        /* complain_on_overflow */
224          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
225          "R_M68HC11_GNU_VTENTRY",       /* name */
226          FALSE,                 /* partial_inplace */
227          0,                     /* src_mask */
228          0,                     /* dst_mask */
229          FALSE),                /* pcrel_offset */
230
231   /* A 24 bit relocation */
232   HOWTO (R_M68HC11_24,          /* type */
233          0,                     /* rightshift */
234          1,                     /* size (0 = byte, 1 = short, 2 = long) */
235          24,                    /* bitsize */
236          FALSE,                 /* pc_relative */
237          0,                     /* bitpos */
238          complain_overflow_bitfield,    /* complain_on_overflow */
239          bfd_elf_generic_reloc, /* special_function */
240          "R_M68HC11_24",        /* name */
241          FALSE,                 /* partial_inplace */
242          0xffffff,              /* src_mask */
243          0xffffff,              /* dst_mask */
244          FALSE),                /* pcrel_offset */
245
246   /* A 16-bit low relocation */
247   HOWTO (R_M68HC11_LO16,        /* type */
248          0,                     /* rightshift */
249          1,                     /* size (0 = byte, 1 = short, 2 = long) */
250          16,                    /* bitsize */
251          FALSE,                 /* pc_relative */
252          0,                     /* bitpos */
253          complain_overflow_bitfield,    /* complain_on_overflow */
254          bfd_elf_generic_reloc, /* special_function */
255          "R_M68HC11_LO16",      /* name */
256          FALSE,                 /* partial_inplace */
257          0xffff,                /* src_mask */
258          0xffff,                /* dst_mask */
259          FALSE),                /* pcrel_offset */
260
261   /* A page relocation */
262   HOWTO (R_M68HC11_PAGE,        /* type */
263          0,                     /* rightshift */
264          0,                     /* size (0 = byte, 1 = short, 2 = long) */
265          8,                     /* bitsize */
266          FALSE,                 /* pc_relative */
267          0,                     /* bitpos */
268          complain_overflow_bitfield,    /* complain_on_overflow */
269          bfd_elf_generic_reloc, /* special_function */
270          "R_M68HC11_PAGE",      /* name */
271          FALSE,                 /* partial_inplace */
272          0x00ff,                /* src_mask */
273          0x00ff,                /* dst_mask */
274          FALSE),                /* pcrel_offset */
275
276   EMPTY_HOWTO (14),
277   EMPTY_HOWTO (15),
278   EMPTY_HOWTO (16),
279   EMPTY_HOWTO (17),
280   EMPTY_HOWTO (18),
281   EMPTY_HOWTO (19),
282
283   /* Mark beginning of a jump instruction (any form).  */
284   HOWTO (R_M68HC11_RL_JUMP,     /* type */
285          0,                     /* rightshift */
286          1,                     /* size (0 = byte, 1 = short, 2 = long) */
287          0,                     /* bitsize */
288          FALSE,                 /* pc_relative */
289          0,                     /* bitpos */
290          complain_overflow_dont,        /* complain_on_overflow */
291          m68hc11_elf_ignore_reloc,      /* special_function */
292          "R_M68HC11_RL_JUMP",   /* name */
293          TRUE,                  /* partial_inplace */
294          0,                     /* src_mask */
295          0,                     /* dst_mask */
296          TRUE),                 /* pcrel_offset */
297
298   /* Mark beginning of Gcc relaxation group instruction.  */
299   HOWTO (R_M68HC11_RL_GROUP,    /* type */
300          0,                     /* rightshift */
301          1,                     /* size (0 = byte, 1 = short, 2 = long) */
302          0,                     /* bitsize */
303          FALSE,                 /* pc_relative */
304          0,                     /* bitpos */
305          complain_overflow_dont,        /* complain_on_overflow */
306          m68hc11_elf_ignore_reloc,      /* special_function */
307          "R_M68HC11_RL_GROUP",  /* name */
308          TRUE,                  /* partial_inplace */
309          0,                     /* src_mask */
310          0,                     /* dst_mask */
311          TRUE),                 /* pcrel_offset */
312 };
313
314 /* Map BFD reloc types to M68HC11 ELF reloc types.  */
315
316 struct m68hc11_reloc_map
317 {
318   bfd_reloc_code_real_type bfd_reloc_val;
319   unsigned char elf_reloc_val;
320 };
321
322 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
323   {BFD_RELOC_NONE, R_M68HC11_NONE,},
324   {BFD_RELOC_8, R_M68HC11_8},
325   {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
326   {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
327   {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
328   {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
329   {BFD_RELOC_16, R_M68HC11_16},
330   {BFD_RELOC_32, R_M68HC11_32},
331   {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
332
333   {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
334   {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
335
336   {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
337   {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
338   {BFD_RELOC_M68HC11_24, R_M68HC11_24},
339
340   {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
341   {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
342 };
343
344 static reloc_howto_type *
345 bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
346                                  bfd_reloc_code_real_type code)
347 {
348   unsigned int i;
349
350   for (i = 0;
351        i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
352        i++)
353     {
354       if (m68hc11_reloc_map[i].bfd_reloc_val == code)
355         return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
356     }
357
358   return NULL;
359 }
360
361 static reloc_howto_type *
362 bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
363                                  const char *r_name)
364 {
365   unsigned int i;
366
367   for (i = 0;
368        i < (sizeof (elf_m68hc11_howto_table)
369             / sizeof (elf_m68hc11_howto_table[0]));
370        i++)
371     if (elf_m68hc11_howto_table[i].name != NULL
372         && strcasecmp (elf_m68hc11_howto_table[i].name, r_name) == 0)
373       return &elf_m68hc11_howto_table[i];
374
375   return NULL;
376 }
377
378 /* Set the howto pointer for an M68HC11 ELF reloc.  */
379
380 static void
381 m68hc11_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
382                            arelent *cache_ptr, Elf_Internal_Rela *dst)
383 {
384   unsigned int r_type;
385
386   r_type = ELF32_R_TYPE (dst->r_info);
387   if (r_type >= (unsigned int) R_M68HC11_max)
388     {
389       /* xgettext:c-format */
390       _bfd_error_handler (_("%B: invalid M68HC11 reloc number: %d"), abfd, r_type);
391       r_type = 0;
392     }
393   cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
394 }
395
396 \f
397 /* Far trampoline generation.  */
398
399 /* Build a 68HC11 trampoline stub.  */
400 static bfd_boolean
401 m68hc11_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
464 static bfd_boolean
465 m68hc11_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
479 static struct bfd_link_hash_table *
480 m68hc11_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 \f
495 /* 68HC11 Linker Relaxation.  */
496
497 struct 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
540 static struct m68hc11_direct_relax *
541 find_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
552 static int
553 compare_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
566 static void
567 m68hc11_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
678 static bfd_boolean
679 m68hc11_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
1118 static void
1119 m68hc11_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.  */
1282 static 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 \f
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"