This commit was generated by cvs2svn to track changes on a CVS vendor
[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 *, Elf32_Internal_Rel *));
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 boolean elf32_m68hc11_gc_sweep_hook
42   PARAMS ((bfd *, struct bfd_link_info *, asection *,
43            const Elf_Internal_Rela *));
44 static boolean elf32_m68hc11_check_relocs
45   PARAMS ((bfd *, struct bfd_link_info *, asection *,
46            const Elf_Internal_Rela *));
47 static 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 boolean m68hc11_elf_relax_section
51   PARAMS ((bfd *, asection *, struct bfd_link_info *, 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 boolean _bfd_m68hc11_elf_merge_private_bfd_data PARAMS ((bfd *, bfd *));
61 boolean _bfd_m68hc11_elf_set_private_flags PARAMS ((bfd *, flagword));
62 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
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      Elf32_Internal_Rel *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 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 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      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 *extsyms = NULL;
650   Elf32_External_Sym *free_extsyms = NULL;
651   Elf_Internal_Rela *prev_insn_branch = NULL;
652   Elf_Internal_Rela *prev_insn_group = NULL;
653   unsigned insn_group_value = 0;
654   Elf_External_Sym_Shndx *shndx_buf = NULL;
655
656   /* Assume nothing changes.  */
657   *again = false;
658
659   /* We don't have to do anything for a relocateable link, if
660      this section does not have relocs, or if this is not a
661      code section.  */
662   if (link_info->relocateable
663       || (sec->flags & SEC_RELOC) == 0
664       || sec->reloc_count == 0
665       || (sec->flags & SEC_CODE) == 0)
666     return true;
667
668   /* If this is the first time we have been called for this section,
669      initialize the cooked size.  */
670   if (sec->_cooked_size == 0)
671     sec->_cooked_size = sec->_raw_size;
672
673   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
674   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
675
676   /* Get a copy of the native relocations.  */
677   internal_relocs = (_bfd_elf32_link_read_relocs
678                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
679                       link_info->keep_memory));
680   if (internal_relocs == NULL)
681     goto error_return;
682   if (! link_info->keep_memory)
683     free_relocs = internal_relocs;
684
685   /* Checking for branch relaxation relies on the relocations to
686      be sorted on 'r_offset'.  This is not guaranteed so we must sort.  */
687   qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
688          compare_reloc);
689
690   /* Walk through them looking for relaxing opportunities.  */
691   irelend = internal_relocs + sec->reloc_count;
692   for (irel = internal_relocs; irel < irelend; irel++)
693     {
694       bfd_vma symval;
695       bfd_vma value;
696       Elf_Internal_Sym isym;
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 (extsyms == NULL)
781         {
782           /* Get cached copy if it exists.  */
783           if (symtab_hdr->contents != NULL)
784             extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
785           else
786             {
787               /* Go get them off disk.  */
788               bfd_size_type amt = symtab_hdr->sh_size;
789               extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
790               if (extsyms == NULL)
791                 goto error_return;
792               free_extsyms = extsyms;
793               if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
794                   || bfd_bread ((PTR) extsyms, amt, abfd) != amt)
795                 goto error_return;
796             }
797
798           if (shndx_hdr->sh_size != 0)
799             {
800               bfd_size_type amt;
801
802               amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
803               shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
804               if (shndx_buf == NULL)
805                 goto error_return;
806               if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
807                   || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
808                 goto error_return;
809               shndx_hdr->contents = (PTR) shndx_buf;
810             }
811         }
812
813       /* Get the value of the symbol referred to by the reloc.  */
814       if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
815         {
816           Elf32_External_Sym *esym;
817           Elf_External_Sym_Shndx *shndx;
818           asection *sym_sec;
819
820           /* A local symbol.  */
821           esym = extsyms + ELF32_R_SYM (irel->r_info);
822           shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (irel->r_info) : 0);
823           bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
824
825           sym_sec = bfd_section_from_elf_index (abfd, isym.st_shndx);
826           symval = (isym.st_value
827                     + sym_sec->output_section->vma
828                     + sym_sec->output_offset);
829         }
830       else
831         {
832           unsigned long indx;
833           struct elf_link_hash_entry *h;
834
835           /* An external symbol.  */
836           indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
837           h = elf_sym_hashes (abfd)[indx];
838           BFD_ASSERT (h != NULL);
839           if (h->root.type != bfd_link_hash_defined
840               && h->root.type != bfd_link_hash_defweak)
841             {
842               /* This appears to be a reference to an undefined
843                  symbol.  Just ignore it--it will be caught by the
844                  regular reloc processing.  */
845               prev_insn_branch = 0;
846               prev_insn_group = 0;
847               continue;
848             }
849
850           symval = (h->root.u.def.value
851                     + h->root.u.def.section->output_section->vma
852                     + h->root.u.def.section->output_offset);
853         }
854
855       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
856         {
857           prev_insn_branch = 0;
858           prev_insn_group = 0;
859           
860           /* Do nothing if this reloc is the last byte in the section.  */
861           if (irel->r_offset == sec->_cooked_size)
862             continue;
863
864           prev_insn_group = irel;
865           insn_group_value = isym.st_value;
866           continue;
867         }
868
869       value = symval;
870       /* Try to turn a far branch to a near branch.  */
871       if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
872           && prev_insn_branch)
873         {
874           bfd_vma offset;
875           unsigned char code;
876
877           offset = value - (prev_insn_branch->r_offset
878                             + sec->output_section->vma
879                             + sec->output_offset + 2);
880
881           /* If the offset is still out of -128..+127 range,
882              leave that far branch unchanged.  */
883           if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
884             {
885               prev_insn_branch = 0;
886               continue;
887             }
888
889           /* Shrink the branch.  */
890           code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
891           if (code == 0x7e)
892             {
893               code = 0x20;
894               bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
895               bfd_put_8 (abfd, offset,
896                          contents + prev_insn_branch->r_offset + 1);
897               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
898                                            R_M68HC11_NONE);
899               m68hc11_elf_relax_delete_bytes (abfd, sec,
900                                               irel->r_offset, 1);
901             }
902           else
903             {
904               code ^= 0x1;
905               bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
906               bfd_put_8 (abfd, offset,
907                          contents + prev_insn_branch->r_offset + 1);
908               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
909                                            R_M68HC11_NONE);
910               m68hc11_elf_relax_delete_bytes (abfd, sec,
911                                               irel->r_offset - 1, 3);
912             }
913           prev_insn_branch = 0;
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               /* Note that we've changed the reldection contents, etc.  */
936               elf_section_data (sec)->relocs = internal_relocs;
937               free_relocs = NULL;
938
939               elf_section_data (sec)->this_hdr.contents = contents;
940               free_contents = NULL;
941
942               symtab_hdr->contents = (bfd_byte *) extsyms;
943               free_extsyms = NULL;
944
945               m68hc11_relax_group (abfd, sec, contents, offset,
946                                    prev_insn_group->r_offset,
947                                    insn_group_value);
948               irel = prev_insn_group;
949               prev_insn_group = 0;
950               irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
951                                            R_M68HC11_NONE);
952               continue;
953             }
954           
955           /* Get the opcode.  */
956           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
957           rinfo = find_relaxable_insn (code);
958           if (rinfo == 0)
959             {
960               prev_insn_group = 0;
961               continue;
962             }
963
964           /* Note that we've changed the reldection contents, etc.  */
965           elf_section_data (sec)->relocs = internal_relocs;
966           free_relocs = NULL;
967
968           elf_section_data (sec)->this_hdr.contents = contents;
969           free_contents = NULL;
970
971           symtab_hdr->contents = (bfd_byte *) extsyms;
972           free_extsyms = NULL;
973
974           /* Fix the opcode.  */
975           /* printf ("A relaxable case : 0x%02x (%s)\n",
976              code, rinfo->name); */
977           bfd_put_8 (abfd, rinfo->direct_code,
978                      contents + irel->r_offset - 1);
979
980           /* Delete one byte of data (upper byte of address).  */
981           m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
982
983           /* Fix the relocation's type.  */
984           irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
985                                        R_M68HC11_8);
986
987           /* That will change things, so, we should relax again.
988              Note that this is not required, and it may be slow.  */
989           *again = true;
990         }
991       else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16)
992         {
993           unsigned char code;
994           bfd_vma offset;
995
996           prev_insn_branch = 0;
997           code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
998           if (code == 0x7e)
999             {
1000               offset = value - (irel->r_offset
1001                                 + sec->output_section->vma
1002                                 + sec->output_offset + 1);
1003               offset += bfd_get_16 (abfd, contents + irel->r_offset);
1004
1005               /* If the offset is still out of -128..+127 range,
1006                  leave that far branch unchanged.  */
1007               if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
1008                 {
1009
1010                   /* Note that we've changed the reldection contents, etc.  */
1011                   elf_section_data (sec)->relocs = internal_relocs;
1012                   free_relocs = NULL;
1013                   
1014                   elf_section_data (sec)->this_hdr.contents = contents;
1015                   free_contents = NULL;
1016                   
1017                   symtab_hdr->contents = (bfd_byte *) extsyms;
1018                   free_extsyms = NULL;
1019
1020                   /* Shrink the branch.  */
1021                   code = 0x20;
1022                   bfd_put_8 (abfd, code,
1023                              contents + irel->r_offset - 1);
1024                   bfd_put_8 (abfd, offset,
1025                              contents + irel->r_offset);
1026                   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1027                                                R_M68HC11_NONE);
1028                   m68hc11_elf_relax_delete_bytes (abfd, sec,
1029                                                   irel->r_offset + 1, 1);
1030                 }
1031             }
1032         }
1033       prev_insn_branch = 0;
1034     }
1035
1036   if (free_relocs != NULL)
1037     {
1038       free (free_relocs);
1039       free_relocs = NULL;
1040     }
1041
1042   if (free_contents != NULL)
1043     {
1044       if (! link_info->keep_memory)
1045         free (free_contents);
1046       else
1047         {
1048           /* Cache the section contents for elf_link_input_bfd.  */
1049           elf_section_data (sec)->this_hdr.contents = contents;
1050         }
1051       free_contents = NULL;
1052     }
1053
1054   if (free_extsyms != NULL)
1055     {
1056       if (! link_info->keep_memory)
1057         free (free_extsyms);
1058       else
1059         {
1060           /* Cache the symbols for elf_link_input_bfd.  */
1061           symtab_hdr->contents = (unsigned char *) extsyms;
1062         }
1063       free_extsyms = NULL;
1064     }
1065
1066   return true;
1067
1068  error_return:
1069   if (free_relocs != NULL)
1070     free (free_relocs);
1071   if (free_contents != NULL)
1072     free (free_contents);
1073   if (free_extsyms != NULL)
1074     free (free_extsyms);
1075   return false;
1076 }
1077
1078 /* Delete some bytes from a section while relaxing.  */
1079
1080 static void
1081 m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
1082      bfd *abfd;
1083      asection *sec;
1084      bfd_vma addr;
1085      int count;
1086 {
1087   Elf_Internal_Shdr *symtab_hdr;
1088   Elf_Internal_Shdr *shndx_hdr;
1089   Elf32_External_Sym *extsyms;
1090   unsigned int sec_shndx;
1091   Elf_External_Sym_Shndx *shndx;
1092   bfd_byte *contents;
1093   Elf_Internal_Rela *irel, *irelend;
1094   bfd_vma toaddr;
1095   Elf32_External_Sym *esym, *esymend;
1096   struct elf_link_hash_entry **sym_hashes;
1097   struct elf_link_hash_entry **end_hashes;
1098   unsigned int symcount;
1099
1100   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1101   extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
1102
1103   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1104
1105   contents = elf_section_data (sec)->this_hdr.contents;
1106
1107   toaddr = sec->_cooked_size;
1108
1109   irel = elf_section_data (sec)->relocs;
1110   irelend = irel + sec->reloc_count;
1111
1112   /* Actually delete the bytes.  */
1113   memmove (contents + addr, contents + addr + count,
1114            (size_t) (toaddr - addr - count));
1115   sec->_cooked_size -= count;
1116
1117   /* Adjust all the relocs.  */
1118   for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1119     {
1120       unsigned char code;
1121       unsigned char offset;
1122       unsigned short raddr;
1123       unsigned long old_offset;
1124       int branch_pos;
1125
1126       old_offset = irel->r_offset;
1127
1128       /* See if this reloc was for the bytes we have deleted, in which
1129          case we no longer care about it.  Don't delete relocs which
1130          represent addresses, though.  */
1131       if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
1132           && irel->r_offset >= addr && irel->r_offset < addr + count)
1133         irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1134                                      R_M68HC11_NONE);
1135
1136       if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
1137         continue;
1138
1139       /* Get the new reloc address.  */
1140       if ((irel->r_offset > addr
1141            && irel->r_offset < toaddr))
1142         irel->r_offset -= count;
1143
1144       /* If this is a PC relative reloc, see if the range it covers
1145          includes the bytes we have deleted.  */
1146       switch (ELF32_R_TYPE (irel->r_info))
1147         {
1148         default:
1149           break;
1150
1151         case R_M68HC11_RL_JUMP:
1152           code = bfd_get_8 (abfd, contents + irel->r_offset);
1153           switch (code)
1154             {
1155               /* jsr and jmp instruction are also marked with RL_JUMP
1156                  relocs but no adjustment must be made.  */
1157             case 0x7e:
1158             case 0x9d:
1159             case 0xbd:
1160               continue;
1161
1162             case 0x12:
1163             case 0x13:
1164               branch_pos = 3;
1165               raddr = 4;
1166
1167               /* Special case when we translate a brclr N,y into brclr *<addr>
1168                  In this case, the 0x18 page2 prefix is removed.
1169                  The reloc offset is not modified but the instruction
1170                  size is reduced by 1.  */
1171               if (old_offset == addr)
1172                 raddr++;
1173               break;
1174
1175             case 0x1e:
1176             case 0x1f:
1177               branch_pos = 3;
1178               raddr = 4;
1179               break;
1180
1181             case 0x18:
1182               branch_pos = 4;
1183               raddr = 5;
1184               break;
1185
1186             default:
1187               branch_pos = 1;
1188               raddr = 2;
1189               break;
1190             }
1191           offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
1192           raddr += old_offset;
1193           raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
1194           if (irel->r_offset < addr && raddr >= addr)
1195             {
1196               offset -= count;
1197               bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1198             }
1199           else if (irel->r_offset >= addr && raddr <= addr)
1200             {
1201               offset += count;
1202               bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1203             }
1204           else
1205             {
1206               /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1207                 irel->r_offset, addr);*/
1208             }
1209           
1210           break;
1211         }
1212     }
1213
1214   /* Adjust the local symbols defined in this section.  */
1215   shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
1216   shndx = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
1217   esym = extsyms;
1218   esymend = esym + symtab_hdr->sh_info;
1219   for (; esym < esymend; esym++, shndx = (shndx ? shndx + 1 : NULL))
1220     {
1221       Elf_Internal_Sym isym;
1222       Elf_External_Sym_Shndx dummy;
1223
1224       bfd_elf32_swap_symbol_in (abfd, esym, shndx, &isym);
1225
1226       if (isym.st_shndx == sec_shndx
1227           && isym.st_value > addr
1228           && isym.st_value < toaddr)
1229         {
1230           isym.st_value -= count;
1231           bfd_elf32_swap_symbol_out (abfd, &isym, esym, &dummy);
1232         }
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 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 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 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 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   boolean ok = true;
1506
1507   /* Check if we have the same endianess */
1508   if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
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 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"