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