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