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