s/boolean/bfd_boolean/ s/true/TRUE/ s/false/FALSE/. Simplify
[external/binutils.git] / bfd / elf32-m68hc11.c
1 /* Motorola 68HC11-specific support for 32-bit ELF
2    Copyright 1999, 2000, 2001, 2002 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 "elf/m68hc11.h"
28
29 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
30   PARAMS ((bfd *, bfd_reloc_code_real_type));
31 static void m68hc11_info_to_howto_rel
32   PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
33
34 static bfd_reloc_status_type m68hc11_elf_ignore_reloc
35   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
36
37 /* GC mark and sweep.  */
38 static asection *elf32_m68hc11_gc_mark_hook
39   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
40            struct elf_link_hash_entry *, Elf_Internal_Sym *));
41 static bfd_boolean elf32_m68hc11_gc_sweep_hook
42   PARAMS ((bfd *, struct bfd_link_info *, asection *,
43            const Elf_Internal_Rela *));
44 static bfd_boolean elf32_m68hc11_check_relocs
45   PARAMS ((bfd *, struct bfd_link_info *, asection *,
46            const Elf_Internal_Rela *));
47 static bfd_boolean elf32_m68hc11_relocate_section
48   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
49            Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
50 static bfd_boolean m68hc11_elf_relax_section
51   PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
52 static void m68hc11_elf_relax_delete_bytes
53   PARAMS ((bfd *, asection *, bfd_vma, int));
54 static void m68hc11_relax_group
55   PARAMS ((bfd *, asection *, bfd_byte *, unsigned,
56            unsigned long, unsigned long));
57 static int compare_reloc PARAMS ((const void *, const void *));
58
59
60 bfd_boolean _bfd_m68hc11_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
61 bfd_boolean _bfd_m68hc11_elf_set_private_flags PARAMS ((bfd *, flagword));
62 bfd_boolean _bfd_m68hc11_elf_print_private_bfd_data PARAMS ((bfd *, PTR));
63
64 /* Use REL instead of RELA to save space */
65 #define USE_REL 1
66
67 /* The Motorola 68HC11 microcontroler only addresses 64Kb.
68    We must handle 8 and 16-bit relocations.  The 32-bit relocation
69    is defined but not used except by gas when -gstabs is used (which
70    is wrong).
71    The 3-bit and 16-bit PC rel relocation is only used by 68HC12.  */
72 static reloc_howto_type elf_m68hc11_howto_table[] = {
73   /* This reloc does nothing.  */
74   HOWTO (R_M68HC11_NONE,        /* type */
75          0,                     /* rightshift */
76          2,                     /* size (0 = byte, 1 = short, 2 = long) */
77          32,                    /* bitsize */
78          FALSE,                 /* pc_relative */
79          0,                     /* bitpos */
80          complain_overflow_dont,/* complain_on_overflow */
81          bfd_elf_generic_reloc, /* special_function */
82          "R_M68HC11_NONE",      /* name */
83          FALSE,                 /* partial_inplace */
84          0,                     /* src_mask */
85          0,                     /* dst_mask */
86          FALSE),                /* pcrel_offset */
87
88   /* A 8 bit absolute relocation */
89   HOWTO (R_M68HC11_8,           /* type */
90          0,                     /* rightshift */
91          0,                     /* size (0 = byte, 1 = short, 2 = long) */
92          8,                     /* bitsize */
93          FALSE,                 /* pc_relative */
94          0,                     /* bitpos */
95          complain_overflow_bitfield,    /* complain_on_overflow */
96          bfd_elf_generic_reloc, /* special_function */
97          "R_M68HC11_8",         /* name */
98          FALSE,                 /* partial_inplace */
99          0x00ff,                /* src_mask */
100          0x00ff,                /* dst_mask */
101          FALSE),                /* pcrel_offset */
102
103   /* A 8 bit absolute relocation (upper address) */
104   HOWTO (R_M68HC11_HI8,         /* type */
105          8,                     /* rightshift */
106          0,                     /* size (0 = byte, 1 = short, 2 = long) */
107          8,                     /* bitsize */
108          FALSE,                 /* pc_relative */
109          0,                     /* bitpos */
110          complain_overflow_bitfield,    /* complain_on_overflow */
111          bfd_elf_generic_reloc, /* special_function */
112          "R_M68HC11_HI8",       /* name */
113          FALSE,                 /* partial_inplace */
114          0x00ff,                /* src_mask */
115          0x00ff,                /* dst_mask */
116          FALSE),                /* pcrel_offset */
117
118   /* A 8 bit absolute relocation (upper address) */
119   HOWTO (R_M68HC11_LO8,         /* type */
120          0,                     /* rightshift */
121          0,                     /* size (0 = byte, 1 = short, 2 = long) */
122          8,                     /* bitsize */
123          FALSE,                 /* pc_relative */
124          0,                     /* bitpos */
125          complain_overflow_dont,        /* complain_on_overflow */
126          bfd_elf_generic_reloc, /* special_function */
127          "R_M68HC11_LO8",       /* name */
128          FALSE,                 /* partial_inplace */
129          0x00ff,                /* src_mask */
130          0x00ff,                /* dst_mask */
131          FALSE),                /* pcrel_offset */
132
133   /* A 8 bit PC-rel relocation */
134   HOWTO (R_M68HC11_PCREL_8,     /* type */
135          0,                     /* rightshift */
136          0,                     /* size (0 = byte, 1 = short, 2 = long) */
137          8,                     /* bitsize */
138          TRUE,                  /* pc_relative */
139          0,                     /* bitpos */
140          complain_overflow_bitfield,    /* complain_on_overflow */
141          bfd_elf_generic_reloc, /* special_function */
142          "R_M68HC11_PCREL_8",   /* name */
143          FALSE,                 /* partial_inplace */
144          0x00ff,                /* src_mask */
145          0x00ff,                /* dst_mask */
146          FALSE),                /* pcrel_offset */
147
148   /* A 16 bit absolute relocation */
149   HOWTO (R_M68HC11_16,          /* type */
150          0,                     /* rightshift */
151          1,                     /* size (0 = byte, 1 = short, 2 = long) */
152          16,                    /* bitsize */
153          FALSE,                 /* pc_relative */
154          0,                     /* bitpos */
155          complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
156          bfd_elf_generic_reloc, /* special_function */
157          "R_M68HC11_16",        /* name */
158          FALSE,                 /* partial_inplace */
159          0xffff,                /* src_mask */
160          0xffff,                /* dst_mask */
161          FALSE),                /* pcrel_offset */
162
163   /* A 32 bit absolute relocation.  This one is never used for the
164      code relocation.  It's used by gas for -gstabs generation.  */
165   HOWTO (R_M68HC11_32,          /* type */
166          0,                     /* rightshift */
167          2,                     /* size (0 = byte, 1 = short, 2 = long) */
168          32,                    /* bitsize */
169          FALSE,                 /* pc_relative */
170          0,                     /* bitpos */
171          complain_overflow_bitfield,    /* complain_on_overflow */
172          bfd_elf_generic_reloc, /* special_function */
173          "R_M68HC11_32",        /* name */
174          FALSE,                 /* partial_inplace */
175          0xffffffff,            /* src_mask */
176          0xffffffff,            /* dst_mask */
177          FALSE),                /* pcrel_offset */
178
179   /* A 3 bit absolute relocation */
180   HOWTO (R_M68HC11_3B,          /* type */
181          0,                     /* rightshift */
182          0,                     /* size (0 = byte, 1 = short, 2 = long) */
183          3,                     /* bitsize */
184          FALSE,                 /* pc_relative */
185          0,                     /* bitpos */
186          complain_overflow_bitfield,    /* complain_on_overflow */
187          bfd_elf_generic_reloc, /* special_function */
188          "R_M68HC11_4B",        /* name */
189          FALSE,                 /* partial_inplace */
190          0x003,                 /* src_mask */
191          0x003,                 /* dst_mask */
192          FALSE),                /* pcrel_offset */
193
194   /* A 16 bit PC-rel relocation */
195   HOWTO (R_M68HC11_PCREL_16,    /* type */
196          0,                     /* rightshift */
197          1,                     /* size (0 = byte, 1 = short, 2 = long) */
198          16,                    /* bitsize */
199          TRUE,                  /* pc_relative */
200          0,                     /* bitpos */
201          complain_overflow_dont,        /* complain_on_overflow */
202          bfd_elf_generic_reloc, /* special_function */
203          "R_M68HC11_PCREL_16",  /* name */
204          FALSE,                 /* partial_inplace */
205          0xffff,                /* src_mask */
206          0xffff,                /* dst_mask */
207          FALSE),                /* pcrel_offset */
208
209   /* GNU extension to record C++ vtable hierarchy */
210   HOWTO (R_M68HC11_GNU_VTINHERIT,       /* type */
211          0,                     /* rightshift */
212          1,                     /* size (0 = byte, 1 = short, 2 = long) */
213          0,                     /* bitsize */
214          FALSE,                 /* pc_relative */
215          0,                     /* bitpos */
216          complain_overflow_dont,        /* complain_on_overflow */
217          NULL,                  /* special_function */
218          "R_M68HC11_GNU_VTINHERIT",     /* name */
219          FALSE,                 /* partial_inplace */
220          0,                     /* src_mask */
221          0,                     /* dst_mask */
222          FALSE),                /* pcrel_offset */
223
224   /* GNU extension to record C++ vtable member usage */
225   HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
226          0,                     /* rightshift */
227          1,                     /* size (0 = byte, 1 = short, 2 = long) */
228          0,                     /* bitsize */
229          FALSE,                 /* pc_relative */
230          0,                     /* bitpos */
231          complain_overflow_dont,        /* complain_on_overflow */
232          _bfd_elf_rel_vtable_reloc_fn,  /* special_function */
233          "R_M68HC11_GNU_VTENTRY",       /* name */
234          FALSE,                 /* partial_inplace */
235          0,                     /* src_mask */
236          0,                     /* dst_mask */
237          FALSE),                /* pcrel_offset */
238
239   /* A 24 bit relocation */
240   HOWTO (R_M68HC11_24,          /* type */
241          0,                     /* rightshift */
242          1,                     /* size (0 = byte, 1 = short, 2 = long) */
243          24,                    /* bitsize */
244          FALSE,                 /* pc_relative */
245          0,                     /* bitpos */
246          complain_overflow_bitfield,    /* complain_on_overflow */
247          bfd_elf_generic_reloc, /* special_function */
248          "R_M68HC11_24",        /* name */
249          FALSE,                 /* partial_inplace */
250          0xffff,                /* src_mask */
251          0xffff,                /* dst_mask */
252          FALSE),                /* pcrel_offset */
253
254   /* A 16-bit low relocation */
255   HOWTO (R_M68HC11_LO16,        /* type */
256          0,                     /* rightshift */
257          1,                     /* size (0 = byte, 1 = short, 2 = long) */
258          16,                    /* bitsize */
259          FALSE,                 /* pc_relative */
260          0,                     /* bitpos */
261          complain_overflow_bitfield,    /* complain_on_overflow */
262          bfd_elf_generic_reloc, /* special_function */
263          "R_M68HC11_LO16",      /* name */
264          FALSE,                 /* partial_inplace */
265          0xffff,                /* src_mask */
266          0xffff,                /* dst_mask */
267          FALSE),                /* pcrel_offset */
268
269   /* A page relocation */
270   HOWTO (R_M68HC11_PAGE,        /* type */
271          0,                     /* rightshift */
272          0,                     /* size (0 = byte, 1 = short, 2 = long) */
273          8,                     /* bitsize */
274          FALSE,                 /* pc_relative */
275          0,                     /* bitpos */
276          complain_overflow_bitfield,    /* complain_on_overflow */
277          bfd_elf_generic_reloc, /* special_function */
278          "R_M68HC11_PAGE",      /* name */
279          FALSE,                 /* partial_inplace */
280          0x00ff,                /* src_mask */
281          0x00ff,                /* dst_mask */
282          FALSE),                /* pcrel_offset */
283
284   EMPTY_HOWTO (14),
285   EMPTY_HOWTO (15),
286   EMPTY_HOWTO (16),
287   EMPTY_HOWTO (17),
288   EMPTY_HOWTO (18),
289   EMPTY_HOWTO (19),
290
291   /* Mark beginning of a jump instruction (any form).  */
292   HOWTO (R_M68HC11_RL_JUMP,     /* type */
293          0,                     /* rightshift */
294          1,                     /* size (0 = byte, 1 = short, 2 = long) */
295          0,                     /* bitsize */
296          FALSE,                 /* pc_relative */
297          0,                     /* bitpos */
298          complain_overflow_dont,        /* complain_on_overflow */
299          m68hc11_elf_ignore_reloc,      /* special_function */
300          "R_M68HC11_RL_JUMP",   /* name */
301          TRUE,                  /* partial_inplace */
302          0,                     /* src_mask */
303          0,                     /* dst_mask */
304          TRUE),                 /* pcrel_offset */
305
306   /* Mark beginning of Gcc relaxation group instruction.  */
307   HOWTO (R_M68HC11_RL_GROUP,    /* type */
308          0,                     /* rightshift */
309          1,                     /* size (0 = byte, 1 = short, 2 = long) */
310          0,                     /* bitsize */
311          FALSE,                 /* pc_relative */
312          0,                     /* bitpos */
313          complain_overflow_dont,        /* complain_on_overflow */
314          m68hc11_elf_ignore_reloc,      /* special_function */
315          "R_M68HC11_RL_GROUP",  /* name */
316          TRUE,                  /* partial_inplace */
317          0,                     /* src_mask */
318          0,                     /* dst_mask */
319          TRUE),                 /* pcrel_offset */
320 };
321
322 /* Map BFD reloc types to M68HC11 ELF reloc types.  */
323
324 struct m68hc11_reloc_map
325 {
326   bfd_reloc_code_real_type bfd_reloc_val;
327   unsigned char elf_reloc_val;
328 };
329
330 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
331   {BFD_RELOC_NONE, R_M68HC11_NONE,},
332   {BFD_RELOC_8, R_M68HC11_8},
333   {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
334   {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
335   {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
336   {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
337   {BFD_RELOC_16, R_M68HC11_16},
338   {BFD_RELOC_32, R_M68HC11_32},
339   {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
340
341   {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
342   {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
343
344   {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
345   {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
346   {BFD_RELOC_M68HC11_24, R_M68HC11_24},
347
348   {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
349   {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
350 };
351
352 static reloc_howto_type *
353 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
354      bfd *abfd ATTRIBUTE_UNUSED;
355      bfd_reloc_code_real_type code;
356 {
357   unsigned int i;
358
359   for (i = 0;
360        i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
361        i++)
362     {
363       if (m68hc11_reloc_map[i].bfd_reloc_val == code)
364         return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
365     }
366
367   return NULL;
368 }
369
370 /* This function is used for relocs which are only used for relaxing,
371    which the linker should otherwise ignore.  */
372
373 static bfd_reloc_status_type
374 m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
375                           output_bfd, error_message)
376      bfd *abfd ATTRIBUTE_UNUSED;
377      arelent *reloc_entry;
378      asymbol *symbol ATTRIBUTE_UNUSED;
379      PTR data ATTRIBUTE_UNUSED;
380      asection *input_section;
381      bfd *output_bfd;
382      char **error_message ATTRIBUTE_UNUSED;
383 {
384   if (output_bfd != NULL)
385     reloc_entry->address += input_section->output_offset;
386   return bfd_reloc_ok;
387 }
388
389 /* Set the howto pointer for an M68HC11 ELF reloc.  */
390
391 static void
392 m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
393      bfd *abfd ATTRIBUTE_UNUSED;
394      arelent *cache_ptr;
395      Elf_Internal_Rela *dst;
396 {
397   unsigned int r_type;
398
399   r_type = ELF32_R_TYPE (dst->r_info);
400   BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
401   cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
402 }
403
404 static asection *
405 elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
406      asection *sec;
407      struct bfd_link_info *info ATTRIBUTE_UNUSED;
408      Elf_Internal_Rela *rel;
409      struct elf_link_hash_entry *h;
410      Elf_Internal_Sym *sym;
411 {
412   if (h != NULL)
413     {
414       switch (ELF32_R_TYPE (rel->r_info))
415         {
416         default:
417           switch (h->root.type)
418             {
419             case bfd_link_hash_defined:
420             case bfd_link_hash_defweak:
421               return h->root.u.def.section;
422
423             case bfd_link_hash_common:
424               return h->root.u.c.p->section;
425
426             default:
427               break;
428             }
429         }
430     }
431   else
432     return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
433
434   return NULL;
435 }
436
437 static bfd_boolean
438 elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
439      bfd *abfd ATTRIBUTE_UNUSED;
440      struct bfd_link_info *info ATTRIBUTE_UNUSED;
441      asection *sec ATTRIBUTE_UNUSED;
442      const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
443 {
444   /* We don't use got and plt entries for 68hc11/68hc12.  */
445   return TRUE;
446 }
447
448 struct m68hc11_direct_relax
449 {
450   const char *name;
451   unsigned char code;
452   unsigned char direct_code;
453 } m68hc11_direct_relax_table[] = {
454   { "adca", 0xB9, 0x99 },
455   { "adcb", 0xF9, 0xD9 },
456   { "adda", 0xBB, 0x9B },
457   { "addb", 0xFB, 0xDB },
458   { "addd", 0xF3, 0xD3 },
459   { "anda", 0xB4, 0x94 },
460   { "andb", 0xF4, 0xD4 },
461   { "cmpa", 0xB1, 0x91 },
462   { "cmpb", 0xF1, 0xD1 },
463   { "cpd",  0xB3, 0x93 },
464   { "cpxy", 0xBC, 0x9C },
465 /* { "cpy",  0xBC, 0x9C }, */
466   { "eora", 0xB8, 0x98 },
467   { "eorb", 0xF8, 0xD8 },
468   { "jsr",  0xBD, 0x9D },
469   { "ldaa", 0xB6, 0x96 },
470   { "ldab", 0xF6, 0xD6 },
471   { "ldd",  0xFC, 0xDC },
472   { "lds",  0xBE, 0x9E },
473   { "ldxy", 0xFE, 0xDE },
474   /*  { "ldy",  0xFE, 0xDE },*/
475   { "oraa", 0xBA, 0x9A },
476   { "orab", 0xFA, 0xDA },
477   { "sbca", 0xB2, 0x92 },
478   { "sbcb", 0xF2, 0xD2 },
479   { "staa", 0xB7, 0x97 },
480   { "stab", 0xF7, 0xD7 },
481   { "std",  0xFD, 0xDD },
482   { "sts",  0xBF, 0x9F },
483   { "stxy", 0xFF, 0xDF },
484   /*  { "sty",  0xFF, 0xDF },*/
485   { "suba", 0xB0, 0x90 },
486   { "subb", 0xF0, 0xD0 },
487   { "subd", 0xB3, 0x93 },
488   { 0, 0, 0 }
489 };
490
491 static struct m68hc11_direct_relax *
492 find_relaxable_insn (unsigned char code)
493 {
494   int i;
495
496   for (i = 0; m68hc11_direct_relax_table[i].name; i++)
497     if (m68hc11_direct_relax_table[i].code == code)
498       return &m68hc11_direct_relax_table[i];
499
500   return 0;
501 }
502
503 static int
504 compare_reloc (e1, e2)
505      const void *e1;
506      const void *e2;
507 {
508   const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
509   const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
510
511   if (i1->r_offset == i2->r_offset)
512     return 0;
513   else
514     return i1->r_offset < i2->r_offset ? -1 : 1;
515 }
516
517 #define M6811_OP_LDX_IMMEDIATE (0xCE)
518
519 static void
520 m68hc11_relax_group (abfd, sec, contents, value, offset, end_group)
521      bfd *abfd;
522      asection *sec;
523      bfd_byte *contents;
524      unsigned value;
525      unsigned long offset;
526      unsigned long end_group;
527 {
528   unsigned char code;
529   unsigned long start_offset;
530   unsigned long ldx_offset = offset;
531   unsigned long ldx_size;
532   int can_delete_ldx;
533   int relax_ldy = 0;
534
535   /* First instruction of the relax group must be a
536      LDX #value or LDY #value.  If this is not the case,
537      ignore the relax group.  */
538   code = bfd_get_8 (abfd, contents + offset);
539   if (code == 0x18)
540     {
541       relax_ldy++;
542       offset++;
543       code = bfd_get_8 (abfd, contents + offset);
544     }
545   ldx_size = offset - ldx_offset + 3;
546   offset += 3;
547   if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
548     return;
549
550
551   /* We can remove the LDX/LDY only when all bset/brclr instructions
552      of the relax group have been converted to use direct addressing
553      mode.  */
554   can_delete_ldx = 1;
555   while (offset < end_group)
556     {
557       unsigned isize;
558       unsigned new_value;
559       int bset_use_y;
560
561       bset_use_y = 0;
562       start_offset = offset;
563       code = bfd_get_8 (abfd, contents + offset);
564       if (code == 0x18)
565         {
566           bset_use_y++;
567           offset++;
568           code = bfd_get_8 (abfd, contents + offset);
569         }
570
571       /* Check the instruction and translate to use direct addressing mode.  */
572       switch (code)
573         {
574           /* bset */
575         case 0x1C:
576           code = 0x14;
577           isize = 3;
578           break;
579
580           /* brclr */
581         case 0x1F:
582           code = 0x13;
583           isize = 4;
584           break;
585
586           /* brset */
587         case 0x1E:
588           code = 0x12;
589           isize = 4;
590           break;
591
592           /* bclr */
593         case 0x1D:
594           code = 0x15;
595           isize = 3;
596           break;
597
598           /* This instruction is not recognized and we are not
599              at end of the relax group.  Ignore and don't remove
600              the first LDX (we don't know what it is used for...).  */
601         default:
602           return;
603         }
604       new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
605       new_value += value;
606       if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
607         {
608           bfd_put_8 (abfd, code, contents + offset);
609           bfd_put_8 (abfd, new_value, contents + offset + 1);
610           if (start_offset != offset)
611             {
612               m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
613                                               offset - start_offset);
614               end_group--;
615             }
616         }
617       else
618         {
619           can_delete_ldx = 0;
620         }
621       offset = start_offset + isize;
622     }
623   if (can_delete_ldx)
624     {
625       /* Remove the move instruction (3 or 4 bytes win).  */
626       m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
627     }
628 }
629
630 /* This function handles relaxing for the 68HC11.
631
632
633         and somewhat more difficult to support.  */
634
635 static bfd_boolean
636 m68hc11_elf_relax_section (abfd, sec, link_info, again)
637      bfd *abfd;
638      asection *sec;
639      struct bfd_link_info *link_info;
640      bfd_boolean *again;
641 {
642   Elf_Internal_Shdr *symtab_hdr;
643   Elf_Internal_Shdr *shndx_hdr;
644   Elf_Internal_Rela *internal_relocs;
645   Elf_Internal_Rela *free_relocs = NULL;
646   Elf_Internal_Rela *irel, *irelend;
647   bfd_byte *contents = NULL;
648   bfd_byte *free_contents = NULL;
649   Elf32_External_Sym *free_extsyms = NULL;
650   Elf_Internal_Rela *prev_insn_branch = NULL;
651   Elf_Internal_Rela *prev_insn_group = NULL;
652   unsigned insn_group_value = 0;
653   Elf_Internal_Sym *isymbuf = NULL;
654
655   /* Assume nothing changes.  */
656   *again = FALSE;
657
658   /* We don't have to do anything for a relocateable link, if
659      this section does not have relocs, or if this is not a
660      code section.  */
661   if (link_info->relocateable
662       || (sec->flags & SEC_RELOC) == 0
663       || sec->reloc_count == 0
664       || (sec->flags & SEC_CODE) == 0)
665     return TRUE;
666
667   /* If this is the first time we have been called for this section,
668      initialize the cooked size.  */
669   if (sec->_cooked_size == 0)
670     sec->_cooked_size = sec->_raw_size;
671
672   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
673   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
674
675   /* Get a copy of the native relocations.  */
676   internal_relocs = (_bfd_elf32_link_read_relocs
677                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
678                       link_info->keep_memory));
679   if (internal_relocs == NULL)
680     goto error_return;
681   if (! link_info->keep_memory)
682     free_relocs = internal_relocs;
683
684   /* Checking for branch relaxation relies on the relocations to
685      be sorted on 'r_offset'.  This is not guaranteed so we must sort.  */
686   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
687          compare_reloc);
688
689   /* Walk through them looking for relaxing opportunities.  */
690   irelend = internal_relocs + sec->reloc_count;
691   for (irel = internal_relocs; irel < irelend; irel++)
692     {
693       bfd_vma symval;
694       bfd_vma value;
695       Elf_Internal_Sym *isym;
696       asection *sym_sec;
697
698       /* If this isn't something that can be relaxed, then ignore
699          this reloc.  */
700       if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
701           && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
702           && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
703         {
704           prev_insn_branch = 0;
705           prev_insn_group = 0;
706           continue;
707         }
708
709       /* Get the section contents if we haven't done so already.  */
710       if (contents == NULL)
711         {
712           /* Get cached copy if it exists.  */
713           if (elf_section_data (sec)->this_hdr.contents != NULL)
714             contents = elf_section_data (sec)->this_hdr.contents;
715           else
716             {
717               /* Go get them off disk.  */
718               contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
719               if (contents == NULL)
720                 goto error_return;
721               free_contents = contents;
722
723               if (! bfd_get_section_contents (abfd, sec, contents,
724                                               (file_ptr) 0, sec->_raw_size))
725                 goto error_return;
726             }
727         }
728
729       /* Try to eliminate an unconditional 8 bit pc-relative branch
730          which immediately follows a conditional 8 bit pc-relative
731          branch around the unconditional branch.
732
733             original:           new:
734             bCC lab1            bCC' lab2
735             bra lab2
736            lab1:               lab1:
737
738          This happens when the bCC can't reach lab2 at assembly time,
739          but due to other relaxations it can reach at link time.  */
740       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
741         {
742           Elf_Internal_Rela *nrel;
743           unsigned char code;
744           unsigned char roffset;
745
746           prev_insn_branch = 0;
747           prev_insn_group = 0;
748
749           /* Do nothing if this reloc is the last byte in the section.  */
750           if (irel->r_offset == sec->_cooked_size)
751             continue;
752
753           /* See if the next instruction is an unconditional pc-relative
754              branch, more often than not this test will fail, so we
755              test it first to speed things up.  */
756           code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
757           if (code != 0x7e)
758             continue;
759
760           /* Also make sure the next relocation applies to the next
761              instruction and that it's a pc-relative 8 bit branch.  */
762           nrel = irel + 1;
763           if (nrel == irelend
764               || irel->r_offset + 3 != nrel->r_offset
765               || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
766             continue;
767
768           /* Make sure our destination immediately follows the
769              unconditional branch.  */
770           roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
771           if (roffset != 3)
772             continue;
773
774           prev_insn_branch = irel;
775           prev_insn_group = 0;
776           continue;
777         }
778
779       /* Read this BFD's symbols if we haven't done so already.  */
780       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
781         {
782           isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
783           if (isymbuf == NULL)
784             isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
785                                             symtab_hdr->sh_info, 0,
786                                             NULL, NULL, NULL);
787           if (isymbuf == NULL)
788             goto error_return;
789         }
790
791       /* Get the value of the symbol referred to by the reloc.  */
792       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
793         {
794           /* A local symbol.  */
795           isym = isymbuf + ELF32_R_SYM (irel->r_info);
796           sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
797           symval = (isym->st_value
798                     + sym_sec->output_section->vma
799                     + sym_sec->output_offset);
800         }
801       else
802         {
803           unsigned long indx;
804           struct elf_link_hash_entry *h;
805
806           /* An external symbol.  */
807           indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
808           h = elf_sym_hashes (abfd)[indx];
809           BFD_ASSERT (h != NULL);
810           if (h->root.type != bfd_link_hash_defined
811               && h->root.type != bfd_link_hash_defweak)
812             {
813               /* This appears to be a reference to an undefined
814                  symbol.  Just ignore it--it will be caught by the
815                  regular reloc processing.  */
816               prev_insn_branch = 0;
817               prev_insn_group = 0;
818               continue;
819             }
820
821           isym = 0;
822           sym_sec = h->root.u.def.section;
823           symval = (h->root.u.def.value
824                     + sym_sec->output_section->vma
825                     + sym_sec->output_offset);
826         }
827
828       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
829         {
830           prev_insn_branch = 0;
831           prev_insn_group = 0;
832
833           /* Do nothing if this reloc is the last byte in the section.  */
834           if (irel->r_offset == sec->_cooked_size)
835             continue;
836
837           prev_insn_group = irel;
838           insn_group_value = isym->st_value;
839           continue;
840         }
841
842       /* When we relax some bytes, the size of our section changes.
843          This affects the layout of next input sections that go in our
844          output section.  When the symbol is part of another section that
845          will go in the same output section as the current one, it's
846          final address may now be incorrect (too far).  We must let the
847          linker re-compute all section offsets before processing this
848          reloc.  Code example:
849
850                                 Initial             Final
851          .sect .text            section size = 6    section size = 4
852          jmp foo
853          jmp bar
854          .sect .text.foo_bar    output_offset = 6   output_offset = 4
855          foo: rts
856          bar: rts
857
858          If we process the reloc now, the jmp bar is replaced by a
859          relative branch to the initial bar address (output_offset 6).  */
860       if (*again && sym_sec != sec
861           && sym_sec->output_section == sec->output_section)
862         {
863           prev_insn_group = 0;
864           prev_insn_branch = 0;
865           continue;
866         }
867
868       value = symval;
869       /* Try to turn a far branch to a near branch.  */
870       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
871           && prev_insn_branch)
872         {
873           bfd_vma offset;
874           unsigned char code;
875
876           offset = value - (prev_insn_branch->r_offset
877                             + sec->output_section->vma
878                             + sec->output_offset + 2);
879
880           /* If the offset is still out of -128..+127 range,
881              leave that far branch unchanged.  */
882           if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
883             {
884               prev_insn_branch = 0;
885               continue;
886             }
887
888           /* Shrink the branch.  */
889           code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
890           if (code == 0x7e)
891             {
892               code = 0x20;
893               bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
894               bfd_put_8 (abfd, offset,
895                          contents + prev_insn_branch->r_offset + 1);
896               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
897                                            R_M68HC11_NONE);
898               m68hc11_elf_relax_delete_bytes (abfd, sec,
899                                               irel->r_offset, 1);
900             }
901           else
902             {
903               code ^= 0x1;
904               bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
905               bfd_put_8 (abfd, offset,
906                          contents + prev_insn_branch->r_offset + 1);
907               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
908                                            R_M68HC11_NONE);
909               m68hc11_elf_relax_delete_bytes (abfd, sec,
910                                               irel->r_offset - 1, 3);
911             }
912           prev_insn_branch = 0;
913           *again = TRUE;
914         }
915
916       /* Try to turn a 16 bit address into a 8 bit page0 address.  */
917       else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
918                && (value & 0xff00) == 0)
919         {
920           unsigned char code;
921           unsigned short offset;
922           struct m68hc11_direct_relax *rinfo;
923
924           prev_insn_branch = 0;
925           offset = bfd_get_16 (abfd, contents + irel->r_offset);
926           offset += value;
927           if ((offset & 0xff00) != 0)
928             {
929               prev_insn_group = 0;
930               continue;
931             }
932
933           if (prev_insn_group)
934             {
935               unsigned long old_sec_size = sec->_cooked_size;
936
937               /* Note that we've changed the reldection contents, etc.  */
938               elf_section_data (sec)->relocs = internal_relocs;
939               free_relocs = NULL;
940
941               elf_section_data (sec)->this_hdr.contents = contents;
942               free_contents = NULL;
943
944               symtab_hdr->contents = (bfd_byte *) isymbuf;
945               free_extsyms = NULL;
946
947               m68hc11_relax_group (abfd, sec, contents, offset,
948                                    prev_insn_group->r_offset,
949                                    insn_group_value);
950               irel = prev_insn_group;
951               prev_insn_group = 0;
952               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
953                                            R_M68HC11_NONE);
954               if (sec->_cooked_size != old_sec_size)
955                 *again = TRUE;
956               continue;
957             }
958
959           /* Get the opcode.  */
960           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
961           rinfo = find_relaxable_insn (code);
962           if (rinfo == 0)
963             {
964               prev_insn_group = 0;
965               continue;
966             }
967
968           /* Note that we've changed the reldection contents, etc.  */
969           elf_section_data (sec)->relocs = internal_relocs;
970           free_relocs = NULL;
971
972           elf_section_data (sec)->this_hdr.contents = contents;
973           free_contents = NULL;
974
975           symtab_hdr->contents = (bfd_byte *) isymbuf;
976           free_extsyms = NULL;
977
978           /* Fix the opcode.  */
979           /* printf ("A relaxable case : 0x%02x (%s)\n",
980              code, rinfo->name); */
981           bfd_put_8 (abfd, rinfo->direct_code,
982                      contents + irel->r_offset - 1);
983
984           /* Delete one byte of data (upper byte of address).  */
985           m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
986
987           /* Fix the relocation's type.  */
988           irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
989                                        R_M68HC11_8);
990
991           /* That will change things, so, we should relax again.  */
992           *again = TRUE;
993         }
994       else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16)
995         {
996           unsigned char code;
997           bfd_vma offset;
998
999           prev_insn_branch = 0;
1000           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1001           if (code == 0x7e)
1002             {
1003               offset = value - (irel->r_offset
1004                                 + sec->output_section->vma
1005                                 + sec->output_offset + 1);
1006               offset += bfd_get_16 (abfd, contents + irel->r_offset);
1007
1008               /* If the offset is still out of -128..+127 range,
1009                  leave that far branch unchanged.  */
1010               if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
1011                 {
1012
1013                   /* Note that we've changed the reldection contents, etc.  */
1014                   elf_section_data (sec)->relocs = internal_relocs;
1015                   free_relocs = NULL;
1016
1017                   elf_section_data (sec)->this_hdr.contents = contents;
1018                   free_contents = NULL;
1019
1020                   symtab_hdr->contents = (bfd_byte *) isymbuf;
1021                   free_extsyms = NULL;
1022
1023                   /* Shrink the branch.  */
1024                   code = 0x20;
1025                   bfd_put_8 (abfd, code,
1026                              contents + irel->r_offset - 1);
1027                   bfd_put_8 (abfd, offset,
1028                              contents + irel->r_offset);
1029                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1030                                                R_M68HC11_NONE);
1031                   m68hc11_elf_relax_delete_bytes (abfd, sec,
1032                                                   irel->r_offset + 1, 1);
1033                   /* That will change things, so, we should relax again.  */
1034                   *again = TRUE;
1035                 }
1036             }
1037         }
1038       prev_insn_branch = 0;
1039     }
1040
1041   if (free_relocs != NULL)
1042     {
1043       free (free_relocs);
1044       free_relocs = NULL;
1045     }
1046
1047   if (free_contents != NULL)
1048     {
1049       if (! link_info->keep_memory)
1050         free (free_contents);
1051       else
1052         {
1053           /* Cache the section contents for elf_link_input_bfd.  */
1054           elf_section_data (sec)->this_hdr.contents = contents;
1055         }
1056       free_contents = NULL;
1057     }
1058
1059   if (free_extsyms != NULL)
1060     {
1061       if (! link_info->keep_memory)
1062         free (free_extsyms);
1063       else
1064         {
1065           /* Cache the symbols for elf_link_input_bfd.  */
1066           symtab_hdr->contents = (unsigned char *) isymbuf;
1067         }
1068       free_extsyms = NULL;
1069     }
1070
1071   return TRUE;
1072
1073  error_return:
1074   if (free_relocs != NULL)
1075     free (free_relocs);
1076   if (free_contents != NULL)
1077     free (free_contents);
1078   if (free_extsyms != NULL)
1079     free (free_extsyms);
1080   return FALSE;
1081 }
1082
1083 /* Delete some bytes from a section while relaxing.  */
1084
1085 static void
1086 m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
1087      bfd *abfd;
1088      asection *sec;
1089      bfd_vma addr;
1090      int count;
1091 {
1092   Elf_Internal_Shdr *symtab_hdr;
1093   unsigned int sec_shndx;
1094   bfd_byte *contents;
1095   Elf_Internal_Rela *irel, *irelend;
1096   bfd_vma toaddr;
1097   Elf_Internal_Sym *isymbuf, *isym, *isymend;
1098   struct elf_link_hash_entry **sym_hashes;
1099   struct elf_link_hash_entry **end_hashes;
1100   unsigned int symcount;
1101
1102   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1103   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1104
1105   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1106
1107   contents = elf_section_data (sec)->this_hdr.contents;
1108
1109   toaddr = sec->_cooked_size;
1110
1111   irel = elf_section_data (sec)->relocs;
1112   irelend = irel + sec->reloc_count;
1113
1114   /* Actually delete the bytes.  */
1115   memmove (contents + addr, contents + addr + count,
1116            (size_t) (toaddr - addr - count));
1117
1118   sec->_cooked_size -= count;
1119
1120   /* Adjust all the relocs.  */
1121   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1122     {
1123       unsigned char code;
1124       unsigned char offset;
1125       unsigned short raddr;
1126       unsigned long old_offset;
1127       int branch_pos;
1128
1129       old_offset = irel->r_offset;
1130
1131       /* See if this reloc was for the bytes we have deleted, in which
1132          case we no longer care about it.  Don't delete relocs which
1133          represent addresses, though.  */
1134       if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
1135           && irel->r_offset >= addr && irel->r_offset < addr + count)
1136         irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1137                                      R_M68HC11_NONE);
1138
1139       if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
1140         continue;
1141
1142       /* Get the new reloc address.  */
1143       if ((irel->r_offset > addr
1144            && irel->r_offset < toaddr))
1145         irel->r_offset -= count;
1146
1147       /* If this is a PC relative reloc, see if the range it covers
1148          includes the bytes we have deleted.  */
1149       switch (ELF32_R_TYPE (irel->r_info))
1150         {
1151         default:
1152           break;
1153
1154         case R_M68HC11_RL_JUMP:
1155           code = bfd_get_8 (abfd, contents + irel->r_offset);
1156           switch (code)
1157             {
1158               /* jsr and jmp instruction are also marked with RL_JUMP
1159                  relocs but no adjustment must be made.  */
1160             case 0x7e:
1161             case 0x9d:
1162             case 0xbd:
1163               continue;
1164
1165             case 0x12:
1166             case 0x13:
1167               branch_pos = 3;
1168               raddr = 4;
1169
1170               /* Special case when we translate a brclr N,y into brclr *<addr>
1171                  In this case, the 0x18 page2 prefix is removed.
1172                  The reloc offset is not modified but the instruction
1173                  size is reduced by 1.  */
1174               if (old_offset == addr)
1175                 raddr++;
1176               break;
1177
1178             case 0x1e:
1179             case 0x1f:
1180               branch_pos = 3;
1181               raddr = 4;
1182               break;
1183
1184             case 0x18:
1185               branch_pos = 4;
1186               raddr = 5;
1187               break;
1188
1189             default:
1190               branch_pos = 1;
1191               raddr = 2;
1192               break;
1193             }
1194           offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
1195           raddr += old_offset;
1196           raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
1197           if (irel->r_offset < addr && raddr >= addr)
1198             {
1199               offset -= count;
1200               bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1201             }
1202           else if (irel->r_offset >= addr && raddr <= addr)
1203             {
1204               offset += count;
1205               bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1206             }
1207           else
1208             {
1209               /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1210                 irel->r_offset, addr);*/
1211             }
1212
1213           break;
1214         }
1215     }
1216
1217   /* Adjust the local symbols defined in this section.  */
1218   isymend = isymbuf + symtab_hdr->sh_info;
1219   for (isym = isymbuf; isym < isymend; isym++)
1220     {
1221       if (isym->st_shndx == sec_shndx
1222           && isym->st_value > addr
1223           && isym->st_value < toaddr)
1224         isym->st_value -= count;
1225     }
1226
1227   /* Now adjust the global symbols defined in this section.  */
1228   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1229               - symtab_hdr->sh_info);
1230   sym_hashes = elf_sym_hashes (abfd);
1231   end_hashes = sym_hashes + symcount;
1232   for (; sym_hashes < end_hashes; sym_hashes++)
1233     {
1234       struct elf_link_hash_entry *sym_hash = *sym_hashes;
1235       if ((sym_hash->root.type == bfd_link_hash_defined
1236            || sym_hash->root.type == bfd_link_hash_defweak)
1237           && sym_hash->root.u.def.section == sec
1238           && sym_hash->root.u.def.value > addr
1239           && sym_hash->root.u.def.value < toaddr)
1240         {
1241           sym_hash->root.u.def.value -= count;
1242         }
1243     }
1244 }
1245
1246 /* Look through the relocs for a section during the first phase.
1247    Since we don't do .gots or .plts, we just need to consider the
1248    virtual table relocs for gc.  */
1249
1250 static bfd_boolean
1251 elf32_m68hc11_check_relocs (abfd, info, sec, relocs)
1252      bfd * abfd;
1253      struct bfd_link_info * info;
1254      asection * sec;
1255      const Elf_Internal_Rela * relocs;
1256 {
1257   Elf_Internal_Shdr *           symtab_hdr;
1258   struct elf_link_hash_entry ** sym_hashes;
1259   struct elf_link_hash_entry ** sym_hashes_end;
1260   const Elf_Internal_Rela *     rel;
1261   const Elf_Internal_Rela *     rel_end;
1262
1263   if (info->relocateable)
1264     return TRUE;
1265
1266   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1267   sym_hashes = elf_sym_hashes (abfd);
1268   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1269   if (!elf_bad_symtab (abfd))
1270     sym_hashes_end -= symtab_hdr->sh_info;
1271
1272   rel_end = relocs + sec->reloc_count;
1273
1274   for (rel = relocs; rel < rel_end; rel++)
1275     {
1276       struct elf_link_hash_entry * h;
1277       unsigned long r_symndx;
1278
1279       r_symndx = ELF32_R_SYM (rel->r_info);
1280
1281       if (r_symndx < symtab_hdr->sh_info)
1282         h = NULL;
1283       else
1284         h = sym_hashes [r_symndx - symtab_hdr->sh_info];
1285
1286       switch (ELF32_R_TYPE (rel->r_info))
1287         {
1288         /* This relocation describes the C++ object vtable hierarchy.
1289            Reconstruct it for later use during GC.  */
1290         case R_M68HC11_GNU_VTINHERIT:
1291           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1292             return FALSE;
1293           break;
1294
1295         /* This relocation describes which C++ vtable entries are actually
1296            used.  Record for later use during GC.  */
1297         case R_M68HC11_GNU_VTENTRY:
1298           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1299             return FALSE;
1300           break;
1301         }
1302     }
1303
1304   return TRUE;
1305 }
1306
1307 /* Relocate a 68hc11/68hc12 ELF section.  */
1308 static bfd_boolean
1309 elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section,
1310                                 contents, relocs, local_syms, local_sections)
1311      bfd *output_bfd ATTRIBUTE_UNUSED;
1312      struct bfd_link_info *info;
1313      bfd *input_bfd;
1314      asection *input_section;
1315      bfd_byte *contents;
1316      Elf_Internal_Rela *relocs;
1317      Elf_Internal_Sym *local_syms;
1318      asection **local_sections;
1319 {
1320   Elf_Internal_Shdr *symtab_hdr;
1321   struct elf_link_hash_entry **sym_hashes;
1322   Elf_Internal_Rela *rel, *relend;
1323   const char *name;
1324
1325   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1326   sym_hashes = elf_sym_hashes (input_bfd);
1327
1328   rel = relocs;
1329   relend = relocs + input_section->reloc_count;
1330   for (; rel < relend; rel++)
1331     {
1332       int r_type;
1333       reloc_howto_type *howto;
1334       unsigned long r_symndx;
1335       Elf_Internal_Sym *sym;
1336       asection *sec;
1337       struct elf_link_hash_entry *h;
1338       bfd_vma relocation;
1339       bfd_reloc_status_type r;
1340
1341       r_symndx = ELF32_R_SYM (rel->r_info);
1342       r_type = ELF32_R_TYPE (rel->r_info);
1343
1344       if (r_type == R_M68HC11_GNU_VTENTRY
1345           || r_type == R_M68HC11_GNU_VTINHERIT )
1346         continue;
1347
1348       howto = elf_m68hc11_howto_table + r_type;
1349
1350       if (info->relocateable)
1351         {
1352           /* This is a relocateable link.  We don't have to change
1353              anything, unless the reloc is against a section symbol,
1354              in which case we have to adjust according to where the
1355              section symbol winds up in the output section.  */
1356           if (r_symndx < symtab_hdr->sh_info)
1357             {
1358               sym = local_syms + r_symndx;
1359               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1360                 {
1361                   sec = local_sections[r_symndx];
1362                   rel->r_addend += sec->output_offset + sym->st_value;
1363                 }
1364             }
1365
1366           continue;
1367         }
1368
1369       /* This is a final link.  */
1370       h = NULL;
1371       sym = NULL;
1372       sec = NULL;
1373       if (r_symndx < symtab_hdr->sh_info)
1374         {
1375           sym = local_syms + r_symndx;
1376           sec = local_sections[r_symndx];
1377           relocation = (sec->output_section->vma
1378                         + sec->output_offset
1379                         + sym->st_value);
1380         }
1381       else
1382         {
1383           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1384           while (h->root.type == bfd_link_hash_indirect
1385                  || h->root.type == bfd_link_hash_warning)
1386             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1387           if (h->root.type == bfd_link_hash_defined
1388               || h->root.type == bfd_link_hash_defweak)
1389             {
1390               sec = h->root.u.def.section;
1391               relocation = (h->root.u.def.value
1392                             + sec->output_section->vma
1393                             + sec->output_offset);
1394             }
1395           else if (h->root.type == bfd_link_hash_undefweak)
1396             relocation = 0;
1397           else
1398             {
1399               if (!((*info->callbacks->undefined_symbol)
1400                     (info, h->root.root.string, input_bfd,
1401                      input_section, rel->r_offset, TRUE)))
1402                 return FALSE;
1403               relocation = 0;
1404             }
1405         }
1406
1407       if (h != NULL)
1408         name = h->root.root.string;
1409       else
1410         {
1411           name = (bfd_elf_string_from_elf_section
1412                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
1413           if (name == NULL || *name == '\0')
1414             name = bfd_section_name (input_bfd, sec);
1415         }
1416
1417       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1418                                     contents, rel->r_offset,
1419                                     relocation, rel->r_addend);
1420
1421       if (r != bfd_reloc_ok)
1422         {
1423           const char * msg = (const char *) 0;
1424
1425           switch (r)
1426             {
1427             case bfd_reloc_overflow:
1428               if (!((*info->callbacks->reloc_overflow)
1429                     (info, name, howto->name, (bfd_vma) 0,
1430                      input_bfd, input_section, rel->r_offset)))
1431                 return FALSE;
1432               break;
1433
1434             case bfd_reloc_undefined:
1435               if (!((*info->callbacks->undefined_symbol)
1436                     (info, name, input_bfd, input_section,
1437                      rel->r_offset, TRUE)))
1438                 return FALSE;
1439               break;
1440
1441             case bfd_reloc_outofrange:
1442               msg = _ ("internal error: out of range error");
1443               goto common_error;
1444
1445             case bfd_reloc_notsupported:
1446               msg = _ ("internal error: unsupported relocation error");
1447               goto common_error;
1448
1449             case bfd_reloc_dangerous:
1450               msg = _ ("internal error: dangerous error");
1451               goto common_error;
1452
1453             default:
1454               msg = _ ("internal error: unknown error");
1455               /* fall through */
1456
1457             common_error:
1458               if (!((*info->callbacks->warning)
1459                     (info, msg, name, input_bfd, input_section,
1460                      rel->r_offset)))
1461                 return FALSE;
1462               break;
1463             }
1464         }
1465     }
1466
1467   return TRUE;
1468 }
1469
1470
1471 \f
1472 /* Set and control ELF flags in ELF header.  */
1473
1474 bfd_boolean
1475 _bfd_m68hc11_elf_set_private_flags (abfd, flags)
1476      bfd *abfd;
1477      flagword flags;
1478 {
1479   BFD_ASSERT (!elf_flags_init (abfd)
1480               || elf_elfheader (abfd)->e_flags == flags);
1481
1482   elf_elfheader (abfd)->e_flags = flags;
1483   elf_flags_init (abfd) = TRUE;
1484   return TRUE;
1485 }
1486
1487 /* Merge backend specific data from an object file to the output
1488    object file when linking.  */
1489
1490 bfd_boolean
1491 _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
1492      bfd *ibfd;
1493      bfd *obfd;
1494 {
1495   flagword old_flags;
1496   flagword new_flags;
1497   bfd_boolean ok = TRUE;
1498
1499   /* Check if we have the same endianess */
1500   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1501     return FALSE;
1502
1503   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1504       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1505     return TRUE;
1506
1507   new_flags = elf_elfheader (ibfd)->e_flags;
1508   elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1509   old_flags = elf_elfheader (obfd)->e_flags;
1510
1511   if (! elf_flags_init (obfd))
1512     {
1513       elf_flags_init (obfd) = TRUE;
1514       elf_elfheader (obfd)->e_flags = new_flags;
1515       elf_elfheader (obfd)->e_ident[EI_CLASS]
1516         = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1517
1518       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1519           && bfd_get_arch_info (obfd)->the_default)
1520         {
1521           if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1522                                    bfd_get_mach (ibfd)))
1523             return FALSE;
1524         }
1525
1526       return TRUE;
1527     }
1528
1529   /* Check ABI compatibility.  */
1530   if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1531     {
1532       (*_bfd_error_handler)
1533         (_("%s: linking files compiled for 16-bit integers (-mshort) "
1534            "and others for 32-bit integers"),
1535          bfd_archive_filename (ibfd));
1536       ok = FALSE;
1537     }
1538   if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1539     {
1540       (*_bfd_error_handler)
1541         (_("%s: linking files compiled for 32-bit double (-fshort-double) "
1542            "and others for 64-bit double"),
1543          bfd_archive_filename (ibfd));
1544       ok = FALSE;
1545     }
1546   new_flags &= ~EF_M68HC11_ABI;
1547   old_flags &= ~EF_M68HC11_ABI;
1548
1549   /* Warn about any other mismatches */
1550   if (new_flags != old_flags)
1551     {
1552       (*_bfd_error_handler)
1553         (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1554          bfd_archive_filename (ibfd), (unsigned long) new_flags,
1555          (unsigned long) old_flags);
1556       ok = FALSE;
1557     }
1558
1559   if (! ok)
1560     {
1561       bfd_set_error (bfd_error_bad_value);
1562       return FALSE;
1563     }
1564
1565   return TRUE;
1566 }
1567
1568 bfd_boolean
1569 _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
1570      bfd *abfd;
1571      PTR ptr;
1572 {
1573   FILE *file = (FILE *) ptr;
1574
1575   BFD_ASSERT (abfd != NULL && ptr != NULL);
1576
1577   /* Print normal ELF private data.  */
1578   _bfd_elf_print_private_bfd_data (abfd, ptr);
1579
1580   /* xgettext:c-format */
1581   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1582
1583   if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1584     fprintf (file, _("[abi=32-bit int,"));
1585   else
1586     fprintf (file, _("[abi=16-bit int,"));
1587
1588   if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1589     fprintf (file, _(" 64-bit double]"));
1590   else
1591     fprintf (file, _(" 32-bit double]"));
1592
1593   if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1594     fprintf (file, _(" [memory=bank-model]"));
1595   else
1596     fprintf (file, _(" [memory=flat]"));
1597
1598   fputc ('\n', file);
1599
1600   return TRUE;
1601 }
1602
1603 /* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
1604    The Motorola spec says to use a different Elf machine code.  */
1605 #define ELF_ARCH                bfd_arch_m68hc11
1606 #define ELF_MACHINE_CODE        EM_68HC11
1607 #define ELF_MAXPAGESIZE         0x1000
1608
1609 #define TARGET_BIG_SYM          bfd_elf32_m68hc11_vec
1610 #define TARGET_BIG_NAME         "elf32-m68hc11"
1611
1612 #define elf_info_to_howto       0
1613 #define elf_info_to_howto_rel   m68hc11_info_to_howto_rel
1614 #define bfd_elf32_bfd_relax_section  m68hc11_elf_relax_section
1615 #define elf_backend_gc_mark_hook     elf32_m68hc11_gc_mark_hook
1616 #define elf_backend_gc_sweep_hook    elf32_m68hc11_gc_sweep_hook
1617 #define elf_backend_check_relocs     elf32_m68hc11_check_relocs
1618 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
1619 #define elf_backend_object_p    0
1620 #define elf_backend_final_write_processing      0
1621 #define elf_backend_can_gc_sections             1
1622 #define bfd_elf32_bfd_merge_private_bfd_data \
1623                                         _bfd_m68hc11_elf_merge_private_bfd_data
1624 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
1625 #define bfd_elf32_bfd_print_private_bfd_data \
1626                                         _bfd_m68hc11_elf_print_private_bfd_data
1627
1628 #include "elf32-target.h"