* elf32-m68hc11.c (m68hc11_elf_relax_delete_bytes): Also adjust
[external/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 "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          TRUE),                 /* 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          TRUE),                 /* 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          0xffffff,              /* src_mask */
251          0xffffff,              /* 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 \f
449 /* 68HC11 Linker Relaxation.  */
450
451 struct m68hc11_direct_relax
452 {
453   const char *name;
454   unsigned char code;
455   unsigned char direct_code;
456 } m68hc11_direct_relax_table[] = {
457   { "adca", 0xB9, 0x99 },
458   { "adcb", 0xF9, 0xD9 },
459   { "adda", 0xBB, 0x9B },
460   { "addb", 0xFB, 0xDB },
461   { "addd", 0xF3, 0xD3 },
462   { "anda", 0xB4, 0x94 },
463   { "andb", 0xF4, 0xD4 },
464   { "cmpa", 0xB1, 0x91 },
465   { "cmpb", 0xF1, 0xD1 },
466   { "cpd",  0xB3, 0x93 },
467   { "cpxy", 0xBC, 0x9C },
468 /* { "cpy",  0xBC, 0x9C }, */
469   { "eora", 0xB8, 0x98 },
470   { "eorb", 0xF8, 0xD8 },
471   { "jsr",  0xBD, 0x9D },
472   { "ldaa", 0xB6, 0x96 },
473   { "ldab", 0xF6, 0xD6 },
474   { "ldd",  0xFC, 0xDC },
475   { "lds",  0xBE, 0x9E },
476   { "ldxy", 0xFE, 0xDE },
477   /*  { "ldy",  0xFE, 0xDE },*/
478   { "oraa", 0xBA, 0x9A },
479   { "orab", 0xFA, 0xDA },
480   { "sbca", 0xB2, 0x92 },
481   { "sbcb", 0xF2, 0xD2 },
482   { "staa", 0xB7, 0x97 },
483   { "stab", 0xF7, 0xD7 },
484   { "std",  0xFD, 0xDD },
485   { "sts",  0xBF, 0x9F },
486   { "stxy", 0xFF, 0xDF },
487   /*  { "sty",  0xFF, 0xDF },*/
488   { "suba", 0xB0, 0x90 },
489   { "subb", 0xF0, 0xD0 },
490   { "subd", 0xB3, 0x93 },
491   { 0, 0, 0 }
492 };
493
494 static struct m68hc11_direct_relax *
495 find_relaxable_insn (unsigned char code)
496 {
497   int i;
498
499   for (i = 0; m68hc11_direct_relax_table[i].name; i++)
500     if (m68hc11_direct_relax_table[i].code == code)
501       return &m68hc11_direct_relax_table[i];
502
503   return 0;
504 }
505
506 static int
507 compare_reloc (e1, e2)
508      const void *e1;
509      const void *e2;
510 {
511   const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
512   const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
513
514   if (i1->r_offset == i2->r_offset)
515     return 0;
516   else
517     return i1->r_offset < i2->r_offset ? -1 : 1;
518 }
519
520 #define M6811_OP_LDX_IMMEDIATE (0xCE)
521
522 static void
523 m68hc11_relax_group (abfd, sec, contents, value, offset, end_group)
524      bfd *abfd;
525      asection *sec;
526      bfd_byte *contents;
527      unsigned value;
528      unsigned long offset;
529      unsigned long end_group;
530 {
531   unsigned char code;
532   unsigned long start_offset;
533   unsigned long ldx_offset = offset;
534   unsigned long ldx_size;
535   int can_delete_ldx;
536   int relax_ldy = 0;
537
538   /* First instruction of the relax group must be a
539      LDX #value or LDY #value.  If this is not the case,
540      ignore the relax group.  */
541   code = bfd_get_8 (abfd, contents + offset);
542   if (code == 0x18)
543     {
544       relax_ldy++;
545       offset++;
546       code = bfd_get_8 (abfd, contents + offset);
547     }
548   ldx_size = offset - ldx_offset + 3;
549   offset += 3;
550   if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
551     return;
552
553
554   /* We can remove the LDX/LDY only when all bset/brclr instructions
555      of the relax group have been converted to use direct addressing
556      mode.  */
557   can_delete_ldx = 1;
558   while (offset < end_group)
559     {
560       unsigned isize;
561       unsigned new_value;
562       int bset_use_y;
563
564       bset_use_y = 0;
565       start_offset = offset;
566       code = bfd_get_8 (abfd, contents + offset);
567       if (code == 0x18)
568         {
569           bset_use_y++;
570           offset++;
571           code = bfd_get_8 (abfd, contents + offset);
572         }
573
574       /* Check the instruction and translate to use direct addressing mode.  */
575       switch (code)
576         {
577           /* bset */
578         case 0x1C:
579           code = 0x14;
580           isize = 3;
581           break;
582
583           /* brclr */
584         case 0x1F:
585           code = 0x13;
586           isize = 4;
587           break;
588
589           /* brset */
590         case 0x1E:
591           code = 0x12;
592           isize = 4;
593           break;
594
595           /* bclr */
596         case 0x1D:
597           code = 0x15;
598           isize = 3;
599           break;
600
601           /* This instruction is not recognized and we are not
602              at end of the relax group.  Ignore and don't remove
603              the first LDX (we don't know what it is used for...).  */
604         default:
605           return;
606         }
607       new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
608       new_value += value;
609       if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
610         {
611           bfd_put_8 (abfd, code, contents + offset);
612           bfd_put_8 (abfd, new_value, contents + offset + 1);
613           if (start_offset != offset)
614             {
615               m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
616                                               offset - start_offset);
617               end_group--;
618             }
619         }
620       else
621         {
622           can_delete_ldx = 0;
623         }
624       offset = start_offset + isize;
625     }
626   if (can_delete_ldx)
627     {
628       /* Remove the move instruction (3 or 4 bytes win).  */
629       m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
630     }
631 }
632
633 /* This function handles relaxing for the 68HC11.
634
635
636         and somewhat more difficult to support.  */
637
638 static bfd_boolean
639 m68hc11_elf_relax_section (abfd, sec, link_info, again)
640      bfd *abfd;
641      asection *sec;
642      struct bfd_link_info *link_info;
643      bfd_boolean *again;
644 {
645   Elf_Internal_Shdr *symtab_hdr;
646   Elf_Internal_Shdr *shndx_hdr;
647   Elf_Internal_Rela *internal_relocs;
648   Elf_Internal_Rela *free_relocs = NULL;
649   Elf_Internal_Rela *irel, *irelend;
650   bfd_byte *contents = NULL;
651   bfd_byte *free_contents = NULL;
652   Elf32_External_Sym *free_extsyms = NULL;
653   Elf_Internal_Rela *prev_insn_branch = NULL;
654   Elf_Internal_Rela *prev_insn_group = NULL;
655   unsigned insn_group_value = 0;
656   Elf_Internal_Sym *isymbuf = NULL;
657
658   /* Assume nothing changes.  */
659   *again = FALSE;
660
661   /* We don't have to do anything for a relocateable link, if
662      this section does not have relocs, or if this is not a
663      code section.  */
664   if (link_info->relocateable
665       || (sec->flags & SEC_RELOC) == 0
666       || sec->reloc_count == 0
667       || (sec->flags & SEC_CODE) == 0)
668     return TRUE;
669
670   /* If this is the first time we have been called for this section,
671      initialize the cooked size.  */
672   if (sec->_cooked_size == 0)
673     sec->_cooked_size = sec->_raw_size;
674
675   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
676   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
677
678   /* Get a copy of the native relocations.  */
679   internal_relocs = (_bfd_elf32_link_read_relocs
680                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
681                       link_info->keep_memory));
682   if (internal_relocs == NULL)
683     goto error_return;
684   if (! link_info->keep_memory)
685     free_relocs = internal_relocs;
686
687   /* Checking for branch relaxation relies on the relocations to
688      be sorted on 'r_offset'.  This is not guaranteed so we must sort.  */
689   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
690          compare_reloc);
691
692   /* Walk through them looking for relaxing opportunities.  */
693   irelend = internal_relocs + sec->reloc_count;
694   for (irel = internal_relocs; irel < irelend; irel++)
695     {
696       bfd_vma symval;
697       bfd_vma value;
698       Elf_Internal_Sym *isym;
699       asection *sym_sec;
700       int is_far = 0;
701
702       /* If this isn't something that can be relaxed, then ignore
703          this reloc.  */
704       if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
705           && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
706           && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
707         {
708           prev_insn_branch = 0;
709           prev_insn_group = 0;
710           continue;
711         }
712
713       /* Get the section contents if we haven't done so already.  */
714       if (contents == NULL)
715         {
716           /* Get cached copy if it exists.  */
717           if (elf_section_data (sec)->this_hdr.contents != NULL)
718             contents = elf_section_data (sec)->this_hdr.contents;
719           else
720             {
721               /* Go get them off disk.  */
722               contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
723               if (contents == NULL)
724                 goto error_return;
725               free_contents = contents;
726
727               if (! bfd_get_section_contents (abfd, sec, contents,
728                                               (file_ptr) 0, sec->_raw_size))
729                 goto error_return;
730             }
731         }
732
733       /* Try to eliminate an unconditional 8 bit pc-relative branch
734          which immediately follows a conditional 8 bit pc-relative
735          branch around the unconditional branch.
736
737             original:           new:
738             bCC lab1            bCC' lab2
739             bra lab2
740            lab1:               lab1:
741
742          This happens when the bCC can't reach lab2 at assembly time,
743          but due to other relaxations it can reach at link time.  */
744       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
745         {
746           Elf_Internal_Rela *nrel;
747           unsigned char code;
748           unsigned char roffset;
749
750           prev_insn_branch = 0;
751           prev_insn_group = 0;
752
753           /* Do nothing if this reloc is the last byte in the section.  */
754           if (irel->r_offset + 2 >= sec->_cooked_size)
755             continue;
756
757           /* See if the next instruction is an unconditional pc-relative
758              branch, more often than not this test will fail, so we
759              test it first to speed things up.  */
760           code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
761           if (code != 0x7e)
762             continue;
763
764           /* Also make sure the next relocation applies to the next
765              instruction and that it's a pc-relative 8 bit branch.  */
766           nrel = irel + 1;
767           if (nrel == irelend
768               || irel->r_offset + 3 != nrel->r_offset
769               || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
770             continue;
771
772           /* Make sure our destination immediately follows the
773              unconditional branch.  */
774           roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
775           if (roffset != 3)
776             continue;
777
778           prev_insn_branch = irel;
779           prev_insn_group = 0;
780           continue;
781         }
782
783       /* Read this BFD's symbols if we haven't done so already.  */
784       if (isymbuf == NULL && symtab_hdr->sh_info != 0)
785         {
786           isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
787           if (isymbuf == NULL)
788             isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
789                                             symtab_hdr->sh_info, 0,
790                                             NULL, NULL, NULL);
791           if (isymbuf == NULL)
792             goto error_return;
793         }
794
795       /* Get the value of the symbol referred to by the reloc.  */
796       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
797         {
798           /* A local symbol.  */
799           isym = isymbuf + ELF32_R_SYM (irel->r_info);
800           is_far = isym->st_other & STO_M68HC12_FAR;
801           sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
802           symval = (isym->st_value
803                     + sym_sec->output_section->vma
804                     + sym_sec->output_offset);
805         }
806       else
807         {
808           unsigned long indx;
809           struct elf_link_hash_entry *h;
810
811           /* An external symbol.  */
812           indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
813           h = elf_sym_hashes (abfd)[indx];
814           BFD_ASSERT (h != NULL);
815           if (h->root.type != bfd_link_hash_defined
816               && h->root.type != bfd_link_hash_defweak)
817             {
818               /* This appears to be a reference to an undefined
819                  symbol.  Just ignore it--it will be caught by the
820                  regular reloc processing.  */
821               prev_insn_branch = 0;
822               prev_insn_group = 0;
823               continue;
824             }
825
826           is_far = h->other & STO_M68HC12_FAR;
827           isym = 0;
828           sym_sec = h->root.u.def.section;
829           symval = (h->root.u.def.value
830                     + sym_sec->output_section->vma
831                     + sym_sec->output_offset);
832         }
833
834       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
835         {
836           prev_insn_branch = 0;
837           prev_insn_group = 0;
838
839           /* Do nothing if this reloc is the last byte in the section.  */
840           if (irel->r_offset == sec->_cooked_size)
841             continue;
842
843           prev_insn_group = irel;
844           insn_group_value = isym->st_value;
845           continue;
846         }
847
848       /* When we relax some bytes, the size of our section changes.
849          This affects the layout of next input sections that go in our
850          output section.  When the symbol is part of another section that
851          will go in the same output section as the current one, it's
852          final address may now be incorrect (too far).  We must let the
853          linker re-compute all section offsets before processing this
854          reloc.  Code example:
855
856                                 Initial             Final
857          .sect .text            section size = 6    section size = 4
858          jmp foo
859          jmp bar
860          .sect .text.foo_bar    output_offset = 6   output_offset = 4
861          foo: rts
862          bar: rts
863
864          If we process the reloc now, the jmp bar is replaced by a
865          relative branch to the initial bar address (output_offset 6).  */
866       if (*again && sym_sec != sec
867           && sym_sec->output_section == sec->output_section)
868         {
869           prev_insn_group = 0;
870           prev_insn_branch = 0;
871           continue;
872         }
873
874       value = symval;
875       /* Try to turn a far branch to a near branch.  */
876       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
877           && prev_insn_branch)
878         {
879           bfd_vma offset;
880           unsigned char code;
881
882           offset = value - (prev_insn_branch->r_offset
883                             + sec->output_section->vma
884                             + sec->output_offset + 2);
885
886           /* If the offset is still out of -128..+127 range,
887              leave that far branch unchanged.  */
888           if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
889             {
890               prev_insn_branch = 0;
891               continue;
892             }
893
894           /* Shrink the branch.  */
895           code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
896           if (code == 0x7e)
897             {
898               code = 0x20;
899               bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
900               bfd_put_8 (abfd, 0xff,
901                          contents + prev_insn_branch->r_offset + 1);
902               irel->r_offset = prev_insn_branch->r_offset + 1;
903               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
904                                            R_M68HC11_PCREL_8);
905               m68hc11_elf_relax_delete_bytes (abfd, sec,
906                                               irel->r_offset + 1, 1);
907             }
908           else
909             {
910               code ^= 0x1;
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, 3);
919             }
920           prev_insn_branch = 0;
921           *again = TRUE;
922         }
923
924       /* Try to turn a 16 bit address into a 8 bit page0 address.  */
925       else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
926                && (value & 0xff00) == 0)
927         {
928           unsigned char code;
929           unsigned short offset;
930           struct m68hc11_direct_relax *rinfo;
931
932           prev_insn_branch = 0;
933           offset = bfd_get_16 (abfd, contents + irel->r_offset);
934           offset += value;
935           if ((offset & 0xff00) != 0)
936             {
937               prev_insn_group = 0;
938               continue;
939             }
940
941           if (prev_insn_group)
942             {
943               unsigned long old_sec_size = sec->_cooked_size;
944
945               /* Note that we've changed the reldection contents, etc.  */
946               elf_section_data (sec)->relocs = internal_relocs;
947               free_relocs = NULL;
948
949               elf_section_data (sec)->this_hdr.contents = contents;
950               free_contents = NULL;
951
952               symtab_hdr->contents = (bfd_byte *) isymbuf;
953               free_extsyms = NULL;
954
955               m68hc11_relax_group (abfd, sec, contents, offset,
956                                    prev_insn_group->r_offset,
957                                    insn_group_value);
958               irel = prev_insn_group;
959               prev_insn_group = 0;
960               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
961                                            R_M68HC11_NONE);
962               if (sec->_cooked_size != old_sec_size)
963                 *again = TRUE;
964               continue;
965             }
966
967           /* Get the opcode.  */
968           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
969           rinfo = find_relaxable_insn (code);
970           if (rinfo == 0)
971             {
972               prev_insn_group = 0;
973               continue;
974             }
975
976           /* Note that we've changed the reldection contents, etc.  */
977           elf_section_data (sec)->relocs = internal_relocs;
978           free_relocs = NULL;
979
980           elf_section_data (sec)->this_hdr.contents = contents;
981           free_contents = NULL;
982
983           symtab_hdr->contents = (bfd_byte *) isymbuf;
984           free_extsyms = NULL;
985
986           /* Fix the opcode.  */
987           /* printf ("A relaxable case : 0x%02x (%s)\n",
988              code, rinfo->name); */
989           bfd_put_8 (abfd, rinfo->direct_code,
990                      contents + irel->r_offset - 1);
991
992           /* Delete one byte of data (upper byte of address).  */
993           m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
994
995           /* Fix the relocation's type.  */
996           irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
997                                        R_M68HC11_8);
998
999           /* That will change things, so, we should relax again.  */
1000           *again = TRUE;
1001         }
1002       else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
1003         {
1004           unsigned char code;
1005           bfd_vma offset;
1006
1007           prev_insn_branch = 0;
1008           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1009           if (code == 0x7e || code == 0xbd)
1010             {
1011               offset = value - (irel->r_offset
1012                                 + sec->output_section->vma
1013                                 + sec->output_offset + 1);
1014               offset += bfd_get_16 (abfd, contents + irel->r_offset);
1015
1016               /* If the offset is still out of -128..+127 range,
1017                  leave that far branch unchanged.  */
1018               if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
1019                 {
1020
1021                   /* Note that we've changed the reldection contents, etc.  */
1022                   elf_section_data (sec)->relocs = internal_relocs;
1023                   free_relocs = NULL;
1024
1025                   elf_section_data (sec)->this_hdr.contents = contents;
1026                   free_contents = NULL;
1027
1028                   symtab_hdr->contents = (bfd_byte *) isymbuf;
1029                   free_extsyms = NULL;
1030
1031                   /* Shrink the branch.  */
1032                   code = (code == 0x7e) ? 0x20 : 0x8d;
1033                   bfd_put_8 (abfd, code,
1034                              contents + irel->r_offset - 1);
1035                   bfd_put_8 (abfd, 0xff,
1036                              contents + irel->r_offset);
1037                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1038                                                R_M68HC11_PCREL_8);
1039                   m68hc11_elf_relax_delete_bytes (abfd, sec,
1040                                                   irel->r_offset + 1, 1);
1041                   /* That will change things, so, we should relax again.  */
1042                   *again = TRUE;
1043                 }
1044             }
1045         }
1046       prev_insn_branch = 0;
1047     }
1048
1049   if (free_relocs != NULL)
1050     {
1051       free (free_relocs);
1052       free_relocs = NULL;
1053     }
1054
1055   if (free_contents != NULL)
1056     {
1057       if (! link_info->keep_memory)
1058         free (free_contents);
1059       else
1060         {
1061           /* Cache the section contents for elf_link_input_bfd.  */
1062           elf_section_data (sec)->this_hdr.contents = contents;
1063         }
1064       free_contents = NULL;
1065     }
1066
1067   if (free_extsyms != NULL)
1068     {
1069       if (! link_info->keep_memory)
1070         free (free_extsyms);
1071       else
1072         {
1073           /* Cache the symbols for elf_link_input_bfd.  */
1074           symtab_hdr->contents = (unsigned char *) isymbuf;
1075         }
1076       free_extsyms = NULL;
1077     }
1078
1079   return TRUE;
1080
1081  error_return:
1082   if (free_relocs != NULL)
1083     free (free_relocs);
1084   if (free_contents != NULL)
1085     free (free_contents);
1086   if (free_extsyms != NULL)
1087     free (free_extsyms);
1088   return FALSE;
1089 }
1090
1091 /* Delete some bytes from a section while relaxing.  */
1092
1093 static void
1094 m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
1095      bfd *abfd;
1096      asection *sec;
1097      bfd_vma addr;
1098      int count;
1099 {
1100   Elf_Internal_Shdr *symtab_hdr;
1101   unsigned int sec_shndx;
1102   bfd_byte *contents;
1103   Elf_Internal_Rela *irel, *irelend;
1104   bfd_vma toaddr;
1105   Elf_Internal_Sym *isymbuf, *isym, *isymend;
1106   struct elf_link_hash_entry **sym_hashes;
1107   struct elf_link_hash_entry **end_hashes;
1108   unsigned int symcount;
1109
1110   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1111   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1112
1113   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1114
1115   contents = elf_section_data (sec)->this_hdr.contents;
1116
1117   toaddr = sec->_cooked_size;
1118
1119   irel = elf_section_data (sec)->relocs;
1120   irelend = irel + sec->reloc_count;
1121
1122   /* Actually delete the bytes.  */
1123   memmove (contents + addr, contents + addr + count,
1124            (size_t) (toaddr - addr - count));
1125
1126   sec->_cooked_size -= count;
1127
1128   /* Adjust all the relocs.  */
1129   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1130     {
1131       unsigned char code;
1132       unsigned char offset;
1133       unsigned short raddr;
1134       unsigned long old_offset;
1135       int branch_pos;
1136
1137       old_offset = irel->r_offset;
1138
1139       /* See if this reloc was for the bytes we have deleted, in which
1140          case we no longer care about it.  Don't delete relocs which
1141          represent addresses, though.  */
1142       if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
1143           && irel->r_offset >= addr && irel->r_offset < addr + count)
1144         irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1145                                      R_M68HC11_NONE);
1146
1147       if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
1148         continue;
1149
1150       /* Get the new reloc address.  */
1151       if ((irel->r_offset > addr
1152            && irel->r_offset < toaddr))
1153         irel->r_offset -= count;
1154
1155       /* If this is a PC relative reloc, see if the range it covers
1156          includes the bytes we have deleted.  */
1157       switch (ELF32_R_TYPE (irel->r_info))
1158         {
1159         default:
1160           break;
1161
1162         case R_M68HC11_RL_JUMP:
1163           code = bfd_get_8 (abfd, contents + irel->r_offset);
1164           switch (code)
1165             {
1166               /* jsr and jmp instruction are also marked with RL_JUMP
1167                  relocs but no adjustment must be made.  */
1168             case 0x7e:
1169             case 0x9d:
1170             case 0xbd:
1171               continue;
1172
1173             case 0x12:
1174             case 0x13:
1175               branch_pos = 3;
1176               raddr = 4;
1177
1178               /* Special case when we translate a brclr N,y into brclr *<addr>
1179                  In this case, the 0x18 page2 prefix is removed.
1180                  The reloc offset is not modified but the instruction
1181                  size is reduced by 1.  */
1182               if (old_offset == addr)
1183                 raddr++;
1184               break;
1185
1186             case 0x1e:
1187             case 0x1f:
1188               branch_pos = 3;
1189               raddr = 4;
1190               break;
1191
1192             case 0x18:
1193               branch_pos = 4;
1194               raddr = 5;
1195               break;
1196
1197             default:
1198               branch_pos = 1;
1199               raddr = 2;
1200               break;
1201             }
1202           offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
1203           raddr += old_offset;
1204           raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
1205           if (irel->r_offset < addr && raddr > addr)
1206             {
1207               offset -= count;
1208               bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1209             }
1210           else if (irel->r_offset >= addr && raddr <= addr)
1211             {
1212               offset += count;
1213               bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1214             }
1215           else
1216             {
1217               /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1218                 irel->r_offset, addr);*/
1219             }
1220
1221           break;
1222         }
1223     }
1224
1225   /* Adjust the local symbols defined in this section.  */
1226   isymend = isymbuf + symtab_hdr->sh_info;
1227   for (isym = isymbuf; isym < isymend; isym++)
1228     {
1229       if (isym->st_shndx == sec_shndx
1230           && isym->st_value > addr
1231           && isym->st_value <= toaddr)
1232         isym->st_value -= count;
1233     }
1234
1235   /* Now adjust the global symbols defined in this section.  */
1236   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1237               - symtab_hdr->sh_info);
1238   sym_hashes = elf_sym_hashes (abfd);
1239   end_hashes = sym_hashes + symcount;
1240   for (; sym_hashes < end_hashes; sym_hashes++)
1241     {
1242       struct elf_link_hash_entry *sym_hash = *sym_hashes;
1243       if ((sym_hash->root.type == bfd_link_hash_defined
1244            || sym_hash->root.type == bfd_link_hash_defweak)
1245           && sym_hash->root.u.def.section == sec
1246           && sym_hash->root.u.def.value > addr
1247           && sym_hash->root.u.def.value <= toaddr)
1248         {
1249           sym_hash->root.u.def.value -= count;
1250         }
1251     }
1252 }
1253
1254 /* Look through the relocs for a section during the first phase.
1255    Since we don't do .gots or .plts, we just need to consider the
1256    virtual table relocs for gc.  */
1257
1258 static bfd_boolean
1259 elf32_m68hc11_check_relocs (abfd, info, sec, relocs)
1260      bfd * abfd;
1261      struct bfd_link_info * info;
1262      asection * sec;
1263      const Elf_Internal_Rela * relocs;
1264 {
1265   Elf_Internal_Shdr *           symtab_hdr;
1266   struct elf_link_hash_entry ** sym_hashes;
1267   struct elf_link_hash_entry ** sym_hashes_end;
1268   const Elf_Internal_Rela *     rel;
1269   const Elf_Internal_Rela *     rel_end;
1270
1271   if (info->relocateable)
1272     return TRUE;
1273
1274   symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1275   sym_hashes = elf_sym_hashes (abfd);
1276   sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1277   if (!elf_bad_symtab (abfd))
1278     sym_hashes_end -= symtab_hdr->sh_info;
1279
1280   rel_end = relocs + sec->reloc_count;
1281
1282   for (rel = relocs; rel < rel_end; rel++)
1283     {
1284       struct elf_link_hash_entry * h;
1285       unsigned long r_symndx;
1286
1287       r_symndx = ELF32_R_SYM (rel->r_info);
1288
1289       if (r_symndx < symtab_hdr->sh_info)
1290         h = NULL;
1291       else
1292         h = sym_hashes [r_symndx - symtab_hdr->sh_info];
1293
1294       switch (ELF32_R_TYPE (rel->r_info))
1295         {
1296         /* This relocation describes the C++ object vtable hierarchy.
1297            Reconstruct it for later use during GC.  */
1298         case R_M68HC11_GNU_VTINHERIT:
1299           if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1300             return FALSE;
1301           break;
1302
1303         /* This relocation describes which C++ vtable entries are actually
1304            used.  Record for later use during GC.  */
1305         case R_M68HC11_GNU_VTENTRY:
1306           if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1307             return FALSE;
1308           break;
1309         }
1310     }
1311
1312   return TRUE;
1313 }
1314
1315 /* Relocate a 68hc11/68hc12 ELF section.  */
1316 static bfd_boolean
1317 elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section,
1318                                 contents, relocs, local_syms, local_sections)
1319      bfd *output_bfd ATTRIBUTE_UNUSED;
1320      struct bfd_link_info *info;
1321      bfd *input_bfd;
1322      asection *input_section;
1323      bfd_byte *contents;
1324      Elf_Internal_Rela *relocs;
1325      Elf_Internal_Sym *local_syms;
1326      asection **local_sections;
1327 {
1328   Elf_Internal_Shdr *symtab_hdr;
1329   struct elf_link_hash_entry **sym_hashes;
1330   Elf_Internal_Rela *rel, *relend;
1331   const char *name;
1332
1333   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1334   sym_hashes = elf_sym_hashes (input_bfd);
1335
1336   rel = relocs;
1337   relend = relocs + input_section->reloc_count;
1338   for (; rel < relend; rel++)
1339     {
1340       int r_type;
1341       reloc_howto_type *howto;
1342       unsigned long r_symndx;
1343       Elf_Internal_Sym *sym;
1344       asection *sec;
1345       struct elf_link_hash_entry *h;
1346       bfd_vma relocation;
1347       bfd_reloc_status_type r;
1348
1349       r_symndx = ELF32_R_SYM (rel->r_info);
1350       r_type = ELF32_R_TYPE (rel->r_info);
1351
1352       if (r_type == R_M68HC11_GNU_VTENTRY
1353           || r_type == R_M68HC11_GNU_VTINHERIT )
1354         continue;
1355
1356       howto = elf_m68hc11_howto_table + r_type;
1357
1358       if (info->relocateable)
1359         {
1360           /* This is a relocateable link.  We don't have to change
1361              anything, unless the reloc is against a section symbol,
1362              in which case we have to adjust according to where the
1363              section symbol winds up in the output section.  */
1364           if (r_symndx < symtab_hdr->sh_info)
1365             {
1366               sym = local_syms + r_symndx;
1367               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1368                 {
1369                   sec = local_sections[r_symndx];
1370                   rel->r_addend += sec->output_offset + sym->st_value;
1371                 }
1372             }
1373
1374           continue;
1375         }
1376
1377       /* This is a final link.  */
1378       h = NULL;
1379       sym = NULL;
1380       sec = NULL;
1381       if (r_symndx < symtab_hdr->sh_info)
1382         {
1383           sym = local_syms + r_symndx;
1384           sec = local_sections[r_symndx];
1385           relocation = (sec->output_section->vma
1386                         + sec->output_offset
1387                         + sym->st_value);
1388         }
1389       else
1390         {
1391           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1392           while (h->root.type == bfd_link_hash_indirect
1393                  || h->root.type == bfd_link_hash_warning)
1394             h = (struct elf_link_hash_entry *) h->root.u.i.link;
1395           if (h->root.type == bfd_link_hash_defined
1396               || h->root.type == bfd_link_hash_defweak)
1397             {
1398               sec = h->root.u.def.section;
1399               relocation = (h->root.u.def.value
1400                             + sec->output_section->vma
1401                             + sec->output_offset);
1402             }
1403           else if (h->root.type == bfd_link_hash_undefweak)
1404             relocation = 0;
1405           else
1406             {
1407               if (!((*info->callbacks->undefined_symbol)
1408                     (info, h->root.root.string, input_bfd,
1409                      input_section, rel->r_offset, TRUE)))
1410                 return FALSE;
1411               relocation = 0;
1412             }
1413         }
1414
1415       if (h != NULL)
1416         name = h->root.root.string;
1417       else
1418         {
1419           name = (bfd_elf_string_from_elf_section
1420                   (input_bfd, symtab_hdr->sh_link, sym->st_name));
1421           if (name == NULL || *name == '\0')
1422             name = bfd_section_name (input_bfd, sec);
1423         }
1424
1425       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1426                                     contents, rel->r_offset,
1427                                     relocation, rel->r_addend);
1428
1429       if (r != bfd_reloc_ok)
1430         {
1431           const char * msg = (const char *) 0;
1432
1433           switch (r)
1434             {
1435             case bfd_reloc_overflow:
1436               if (!((*info->callbacks->reloc_overflow)
1437                     (info, name, howto->name, (bfd_vma) 0,
1438                      input_bfd, input_section, rel->r_offset)))
1439                 return FALSE;
1440               break;
1441
1442             case bfd_reloc_undefined:
1443               if (!((*info->callbacks->undefined_symbol)
1444                     (info, name, input_bfd, input_section,
1445                      rel->r_offset, TRUE)))
1446                 return FALSE;
1447               break;
1448
1449             case bfd_reloc_outofrange:
1450               msg = _ ("internal error: out of range error");
1451               goto common_error;
1452
1453             case bfd_reloc_notsupported:
1454               msg = _ ("internal error: unsupported relocation error");
1455               goto common_error;
1456
1457             case bfd_reloc_dangerous:
1458               msg = _ ("internal error: dangerous error");
1459               goto common_error;
1460
1461             default:
1462               msg = _ ("internal error: unknown error");
1463               /* fall through */
1464
1465             common_error:
1466               if (!((*info->callbacks->warning)
1467                     (info, msg, name, input_bfd, input_section,
1468                      rel->r_offset)))
1469                 return FALSE;
1470               break;
1471             }
1472         }
1473     }
1474
1475   return TRUE;
1476 }
1477
1478
1479 \f
1480 /* Set and control ELF flags in ELF header.  */
1481
1482 bfd_boolean
1483 _bfd_m68hc11_elf_set_private_flags (abfd, flags)
1484      bfd *abfd;
1485      flagword flags;
1486 {
1487   BFD_ASSERT (!elf_flags_init (abfd)
1488               || elf_elfheader (abfd)->e_flags == flags);
1489
1490   elf_elfheader (abfd)->e_flags = flags;
1491   elf_flags_init (abfd) = TRUE;
1492   return TRUE;
1493 }
1494
1495 /* Merge backend specific data from an object file to the output
1496    object file when linking.  */
1497
1498 bfd_boolean
1499 _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
1500      bfd *ibfd;
1501      bfd *obfd;
1502 {
1503   flagword old_flags;
1504   flagword new_flags;
1505   bfd_boolean ok = TRUE;
1506
1507   /* Check if we have the same endianess */
1508   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1509     return FALSE;
1510
1511   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1512       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1513     return TRUE;
1514
1515   new_flags = elf_elfheader (ibfd)->e_flags;
1516   elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1517   old_flags = elf_elfheader (obfd)->e_flags;
1518
1519   if (! elf_flags_init (obfd))
1520     {
1521       elf_flags_init (obfd) = TRUE;
1522       elf_elfheader (obfd)->e_flags = new_flags;
1523       elf_elfheader (obfd)->e_ident[EI_CLASS]
1524         = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1525
1526       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1527           && bfd_get_arch_info (obfd)->the_default)
1528         {
1529           if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1530                                    bfd_get_mach (ibfd)))
1531             return FALSE;
1532         }
1533
1534       return TRUE;
1535     }
1536
1537   /* Check ABI compatibility.  */
1538   if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1539     {
1540       (*_bfd_error_handler)
1541         (_("%s: linking files compiled for 16-bit integers (-mshort) "
1542            "and others for 32-bit integers"),
1543          bfd_archive_filename (ibfd));
1544       ok = FALSE;
1545     }
1546   if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1547     {
1548       (*_bfd_error_handler)
1549         (_("%s: linking files compiled for 32-bit double (-fshort-double) "
1550            "and others for 64-bit double"),
1551          bfd_archive_filename (ibfd));
1552       ok = FALSE;
1553     }
1554   new_flags &= ~EF_M68HC11_ABI;
1555   old_flags &= ~EF_M68HC11_ABI;
1556
1557   /* Warn about any other mismatches */
1558   if (new_flags != old_flags)
1559     {
1560       (*_bfd_error_handler)
1561         (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1562          bfd_archive_filename (ibfd), (unsigned long) new_flags,
1563          (unsigned long) old_flags);
1564       ok = FALSE;
1565     }
1566
1567   if (! ok)
1568     {
1569       bfd_set_error (bfd_error_bad_value);
1570       return FALSE;
1571     }
1572
1573   return TRUE;
1574 }
1575
1576 bfd_boolean
1577 _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
1578      bfd *abfd;
1579      PTR ptr;
1580 {
1581   FILE *file = (FILE *) ptr;
1582
1583   BFD_ASSERT (abfd != NULL && ptr != NULL);
1584
1585   /* Print normal ELF private data.  */
1586   _bfd_elf_print_private_bfd_data (abfd, ptr);
1587
1588   /* xgettext:c-format */
1589   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1590
1591   if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1592     fprintf (file, _("[abi=32-bit int,"));
1593   else
1594     fprintf (file, _("[abi=16-bit int,"));
1595
1596   if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1597     fprintf (file, _(" 64-bit double]"));
1598   else
1599     fprintf (file, _(" 32-bit double]"));
1600
1601   if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1602     fprintf (file, _(" [memory=bank-model]"));
1603   else
1604     fprintf (file, _(" [memory=flat]"));
1605
1606   fputc ('\n', file);
1607
1608   return TRUE;
1609 }
1610
1611 /* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
1612    The Motorola spec says to use a different Elf machine code.  */
1613 #define ELF_ARCH                bfd_arch_m68hc11
1614 #define ELF_MACHINE_CODE        EM_68HC11
1615 #define ELF_MAXPAGESIZE         0x1000
1616
1617 #define TARGET_BIG_SYM          bfd_elf32_m68hc11_vec
1618 #define TARGET_BIG_NAME         "elf32-m68hc11"
1619
1620 #define elf_info_to_howto       0
1621 #define elf_info_to_howto_rel   m68hc11_info_to_howto_rel
1622 #define bfd_elf32_bfd_relax_section  m68hc11_elf_relax_section
1623 #define elf_backend_gc_mark_hook     elf32_m68hc11_gc_mark_hook
1624 #define elf_backend_gc_sweep_hook    elf32_m68hc11_gc_sweep_hook
1625 #define elf_backend_check_relocs     elf32_m68hc11_check_relocs
1626 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
1627 #define elf_backend_object_p    0
1628 #define elf_backend_final_write_processing      0
1629 #define elf_backend_can_gc_sections             1
1630 #define bfd_elf32_bfd_merge_private_bfd_data \
1631                                         _bfd_m68hc11_elf_merge_private_bfd_data
1632 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
1633 #define bfd_elf32_bfd_print_private_bfd_data \
1634                                         _bfd_m68hc11_elf_print_private_bfd_data
1635
1636 #include "elf32-target.h"