* elf64-ppc.c (ppc64_elf_relocate_section): Do unaligned reloc
[binutils.git] / bfd / elf32-m68hc11.c
blob1b95105299db0ab4d7f39358e8c365324124ecb9
1 /* Motorola 68HC11-specific support for 32-bit ELF
2 Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Stephane Carrez (stcarrez@nerim.fr)
4 (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "bfdlink.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf32-m68hc1x.h"
28 #include "elf/m68hc11.h"
29 #include "opcode/m68hc11.h"
31 /* Relocation functions. */
32 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
33 PARAMS ((bfd *, bfd_reloc_code_real_type));
34 static void m68hc11_info_to_howto_rel
35 PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
37 /* Trampoline generation. */
38 static bfd_boolean m68hc11_elf_size_one_stub
39 PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
40 static bfd_boolean m68hc11_elf_build_one_stub
41 PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
42 static struct bfd_link_hash_table* m68hc11_elf_bfd_link_hash_table_create
43 PARAMS ((bfd* abfd));
45 /* Linker relaxation. */
46 static bfd_boolean m68hc11_elf_relax_section
47 PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
48 static void m68hc11_elf_relax_delete_bytes
49 PARAMS ((bfd *, asection *, bfd_vma, int));
50 static void m68hc11_relax_group
51 PARAMS ((bfd *, asection *, bfd_byte *, unsigned,
52 unsigned long, unsigned long));
53 static int compare_reloc PARAMS ((const void *, const void *));
55 /* Use REL instead of RELA to save space */
56 #define USE_REL 1
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 2, /* size (0 = byte, 1 = short, 2 = long) */
69 32, /* 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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
276 EMPTY_HOWTO (14),
277 EMPTY_HOWTO (15),
278 EMPTY_HOWTO (16),
279 EMPTY_HOWTO (17),
280 EMPTY_HOWTO (18),
281 EMPTY_HOWTO (19),
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 */
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 */
314 /* Map BFD reloc types to M68HC11 ELF reloc types. */
316 struct m68hc11_reloc_map
318 bfd_reloc_code_real_type bfd_reloc_val;
319 unsigned char elf_reloc_val;
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},
333 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
334 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
336 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
337 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
338 {BFD_RELOC_M68HC11_24, R_M68HC11_24},
340 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
341 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
344 static reloc_howto_type *
345 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
346 bfd *abfd ATTRIBUTE_UNUSED;
347 bfd_reloc_code_real_type code;
349 unsigned int i;
351 for (i = 0;
352 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
353 i++)
355 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
356 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
359 return NULL;
362 /* Set the howto pointer for an M68HC11 ELF reloc. */
364 static void
365 m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
366 bfd *abfd ATTRIBUTE_UNUSED;
367 arelent *cache_ptr;
368 Elf_Internal_Rela *dst;
370 unsigned int r_type;
372 r_type = ELF32_R_TYPE (dst->r_info);
373 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
374 cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
378 /* Far trampoline generation. */
380 /* Build a 68HC11 trampoline stub. */
381 static bfd_boolean
382 m68hc11_elf_build_one_stub (gen_entry, in_arg)
383 struct bfd_hash_entry *gen_entry;
384 PTR in_arg;
386 struct elf32_m68hc11_stub_hash_entry *stub_entry;
387 struct bfd_link_info *info;
388 struct m68hc11_elf_link_hash_table *htab;
389 asection *stub_sec;
390 bfd *stub_bfd;
391 bfd_byte *loc;
392 bfd_vma sym_value, phys_page, phys_addr;
394 /* Massage our args to the form they really have. */
395 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
396 info = (struct bfd_link_info *) in_arg;
398 htab = m68hc11_elf_hash_table (info);
400 stub_sec = stub_entry->stub_sec;
402 /* Make a note of the offset within the stubs for this entry. */
403 stub_entry->stub_offset = stub_sec->_raw_size;
404 stub_sec->_raw_size += 10;
405 loc = stub_sec->contents + stub_entry->stub_offset;
407 stub_bfd = stub_sec->owner;
409 /* Create the trampoline call stub:
411 pshb
412 ldab #%page(symbol)
413 ldy #%addr(symbol)
414 jmp __trampoline
417 sym_value = (stub_entry->target_value
418 + stub_entry->target_section->output_offset
419 + stub_entry->target_section->output_section->vma);
420 phys_addr = m68hc11_phys_addr (&htab->pinfo, sym_value);
421 phys_page = m68hc11_phys_page (&htab->pinfo, sym_value);
423 /* pshb; ldab #%page(sym) */
424 bfd_put_8 (stub_bfd, 0x37, loc);
425 bfd_put_8 (stub_bfd, 0xC6, loc + 1);
426 bfd_put_8 (stub_bfd, phys_page, loc + 2);
427 loc += 3;
429 /* ldy #%addr(sym) */
430 bfd_put_8 (stub_bfd, 0x18, loc);
431 bfd_put_8 (stub_bfd, 0xCE, loc + 1);
432 bfd_put_16 (stub_bfd, phys_addr, loc + 2);
433 loc += 4;
435 /* jmp __trampoline */
436 bfd_put_8 (stub_bfd, 0x7E, loc);
437 bfd_put_16 (stub_bfd, htab->pinfo.trampoline_addr, loc + 1);
439 return TRUE;
442 /* As above, but don't actually build the stub. Just bump offset so
443 we know stub section sizes. */
445 static bfd_boolean
446 m68hc11_elf_size_one_stub (gen_entry, in_arg)
447 struct bfd_hash_entry *gen_entry;
448 PTR in_arg ATTRIBUTE_UNUSED;
450 struct elf32_m68hc11_stub_hash_entry *stub_entry;
452 /* Massage our args to the form they really have. */
453 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
455 stub_entry->stub_sec->_raw_size += 10;
456 return TRUE;
459 /* Create a 68HC11 ELF linker hash table. */
461 static struct bfd_link_hash_table *
462 m68hc11_elf_bfd_link_hash_table_create (abfd)
463 bfd *abfd;
465 struct m68hc11_elf_link_hash_table *ret;
467 ret = m68hc11_elf_hash_table_create (abfd);
468 if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
469 return NULL;
471 ret->size_one_stub = m68hc11_elf_size_one_stub;
472 ret->build_one_stub = m68hc11_elf_build_one_stub;
474 return &ret->root.root;
478 /* 68HC11 Linker Relaxation. */
480 struct m68hc11_direct_relax
482 const char *name;
483 unsigned char code;
484 unsigned char direct_code;
485 } m68hc11_direct_relax_table[] = {
486 { "adca", 0xB9, 0x99 },
487 { "adcb", 0xF9, 0xD9 },
488 { "adda", 0xBB, 0x9B },
489 { "addb", 0xFB, 0xDB },
490 { "addd", 0xF3, 0xD3 },
491 { "anda", 0xB4, 0x94 },
492 { "andb", 0xF4, 0xD4 },
493 { "cmpa", 0xB1, 0x91 },
494 { "cmpb", 0xF1, 0xD1 },
495 { "cpd", 0xB3, 0x93 },
496 { "cpxy", 0xBC, 0x9C },
497 /* { "cpy", 0xBC, 0x9C }, */
498 { "eora", 0xB8, 0x98 },
499 { "eorb", 0xF8, 0xD8 },
500 { "jsr", 0xBD, 0x9D },
501 { "ldaa", 0xB6, 0x96 },
502 { "ldab", 0xF6, 0xD6 },
503 { "ldd", 0xFC, 0xDC },
504 { "lds", 0xBE, 0x9E },
505 { "ldxy", 0xFE, 0xDE },
506 /* { "ldy", 0xFE, 0xDE },*/
507 { "oraa", 0xBA, 0x9A },
508 { "orab", 0xFA, 0xDA },
509 { "sbca", 0xB2, 0x92 },
510 { "sbcb", 0xF2, 0xD2 },
511 { "staa", 0xB7, 0x97 },
512 { "stab", 0xF7, 0xD7 },
513 { "std", 0xFD, 0xDD },
514 { "sts", 0xBF, 0x9F },
515 { "stxy", 0xFF, 0xDF },
516 /* { "sty", 0xFF, 0xDF },*/
517 { "suba", 0xB0, 0x90 },
518 { "subb", 0xF0, 0xD0 },
519 { "subd", 0xB3, 0x93 },
520 { 0, 0, 0 }
523 static struct m68hc11_direct_relax *
524 find_relaxable_insn (unsigned char code)
526 int i;
528 for (i = 0; m68hc11_direct_relax_table[i].name; i++)
529 if (m68hc11_direct_relax_table[i].code == code)
530 return &m68hc11_direct_relax_table[i];
532 return 0;
535 static int
536 compare_reloc (e1, e2)
537 const void *e1;
538 const void *e2;
540 const Elf_Internal_Rela *i1 = (const Elf_Internal_Rela *) e1;
541 const Elf_Internal_Rela *i2 = (const Elf_Internal_Rela *) e2;
543 if (i1->r_offset == i2->r_offset)
544 return 0;
545 else
546 return i1->r_offset < i2->r_offset ? -1 : 1;
549 #define M6811_OP_LDX_IMMEDIATE (0xCE)
551 static void
552 m68hc11_relax_group (abfd, sec, contents, value, offset, end_group)
553 bfd *abfd;
554 asection *sec;
555 bfd_byte *contents;
556 unsigned value;
557 unsigned long offset;
558 unsigned long end_group;
560 unsigned char code;
561 unsigned long start_offset;
562 unsigned long ldx_offset = offset;
563 unsigned long ldx_size;
564 int can_delete_ldx;
565 int relax_ldy = 0;
567 /* First instruction of the relax group must be a
568 LDX #value or LDY #value. If this is not the case,
569 ignore the relax group. */
570 code = bfd_get_8 (abfd, contents + offset);
571 if (code == 0x18)
573 relax_ldy++;
574 offset++;
575 code = bfd_get_8 (abfd, contents + offset);
577 ldx_size = offset - ldx_offset + 3;
578 offset += 3;
579 if (code != M6811_OP_LDX_IMMEDIATE || offset >= end_group)
580 return;
583 /* We can remove the LDX/LDY only when all bset/brclr instructions
584 of the relax group have been converted to use direct addressing
585 mode. */
586 can_delete_ldx = 1;
587 while (offset < end_group)
589 unsigned isize;
590 unsigned new_value;
591 int bset_use_y;
593 bset_use_y = 0;
594 start_offset = offset;
595 code = bfd_get_8 (abfd, contents + offset);
596 if (code == 0x18)
598 bset_use_y++;
599 offset++;
600 code = bfd_get_8 (abfd, contents + offset);
603 /* Check the instruction and translate to use direct addressing mode. */
604 switch (code)
606 /* bset */
607 case 0x1C:
608 code = 0x14;
609 isize = 3;
610 break;
612 /* brclr */
613 case 0x1F:
614 code = 0x13;
615 isize = 4;
616 break;
618 /* brset */
619 case 0x1E:
620 code = 0x12;
621 isize = 4;
622 break;
624 /* bclr */
625 case 0x1D:
626 code = 0x15;
627 isize = 3;
628 break;
630 /* This instruction is not recognized and we are not
631 at end of the relax group. Ignore and don't remove
632 the first LDX (we don't know what it is used for...). */
633 default:
634 return;
636 new_value = (unsigned) bfd_get_8 (abfd, contents + offset + 1);
637 new_value += value;
638 if ((new_value & 0xff00) == 0 && bset_use_y == relax_ldy)
640 bfd_put_8 (abfd, code, contents + offset);
641 bfd_put_8 (abfd, new_value, contents + offset + 1);
642 if (start_offset != offset)
644 m68hc11_elf_relax_delete_bytes (abfd, sec, start_offset,
645 offset - start_offset);
646 end_group--;
649 else
651 can_delete_ldx = 0;
653 offset = start_offset + isize;
655 if (can_delete_ldx)
657 /* Remove the move instruction (3 or 4 bytes win). */
658 m68hc11_elf_relax_delete_bytes (abfd, sec, ldx_offset, ldx_size);
662 /* This function handles relaxing for the 68HC11.
665 and somewhat more difficult to support. */
667 static bfd_boolean
668 m68hc11_elf_relax_section (abfd, sec, link_info, again)
669 bfd *abfd;
670 asection *sec;
671 struct bfd_link_info *link_info;
672 bfd_boolean *again;
674 Elf_Internal_Shdr *symtab_hdr;
675 Elf_Internal_Shdr *shndx_hdr;
676 Elf_Internal_Rela *internal_relocs;
677 Elf_Internal_Rela *free_relocs = NULL;
678 Elf_Internal_Rela *irel, *irelend;
679 bfd_byte *contents = NULL;
680 bfd_byte *free_contents = NULL;
681 Elf32_External_Sym *free_extsyms = NULL;
682 Elf_Internal_Rela *prev_insn_branch = NULL;
683 Elf_Internal_Rela *prev_insn_group = NULL;
684 unsigned insn_group_value = 0;
685 Elf_Internal_Sym *isymbuf = NULL;
687 /* Assume nothing changes. */
688 *again = FALSE;
690 /* We don't have to do anything for a relocateable link, if
691 this section does not have relocs, or if this is not a
692 code section. */
693 if (link_info->relocateable
694 || (sec->flags & SEC_RELOC) == 0
695 || sec->reloc_count == 0
696 || (sec->flags & SEC_CODE) == 0)
697 return TRUE;
699 /* If this is the first time we have been called for this section,
700 initialize the cooked size. */
701 if (sec->_cooked_size == 0)
702 sec->_cooked_size = sec->_raw_size;
704 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
705 shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
707 /* Get a copy of the native relocations. */
708 internal_relocs = (_bfd_elf_link_read_relocs
709 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
710 link_info->keep_memory));
711 if (internal_relocs == NULL)
712 goto error_return;
713 if (! link_info->keep_memory)
714 free_relocs = internal_relocs;
716 /* Checking for branch relaxation relies on the relocations to
717 be sorted on 'r_offset'. This is not guaranteed so we must sort. */
718 qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
719 compare_reloc);
721 /* Walk through them looking for relaxing opportunities. */
722 irelend = internal_relocs + sec->reloc_count;
723 for (irel = internal_relocs; irel < irelend; irel++)
725 bfd_vma symval;
726 bfd_vma value;
727 Elf_Internal_Sym *isym;
728 asection *sym_sec;
729 int is_far = 0;
731 /* If this isn't something that can be relaxed, then ignore
732 this reloc. */
733 if (ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_16
734 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_JUMP
735 && ELF32_R_TYPE (irel->r_info) != (int) R_M68HC11_RL_GROUP)
737 prev_insn_branch = 0;
738 prev_insn_group = 0;
739 continue;
742 /* Get the section contents if we haven't done so already. */
743 if (contents == NULL)
745 /* Get cached copy if it exists. */
746 if (elf_section_data (sec)->this_hdr.contents != NULL)
747 contents = elf_section_data (sec)->this_hdr.contents;
748 else
750 /* Go get them off disk. */
751 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
752 if (contents == NULL)
753 goto error_return;
754 free_contents = contents;
756 if (! bfd_get_section_contents (abfd, sec, contents,
757 (file_ptr) 0, sec->_raw_size))
758 goto error_return;
762 /* Try to eliminate an unconditional 8 bit pc-relative branch
763 which immediately follows a conditional 8 bit pc-relative
764 branch around the unconditional branch.
766 original: new:
767 bCC lab1 bCC' lab2
768 bra lab2
769 lab1: lab1:
771 This happens when the bCC can't reach lab2 at assembly time,
772 but due to other relaxations it can reach at link time. */
773 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_JUMP)
775 Elf_Internal_Rela *nrel;
776 unsigned char code;
777 unsigned char roffset;
779 prev_insn_branch = 0;
780 prev_insn_group = 0;
782 /* Do nothing if this reloc is the last byte in the section. */
783 if (irel->r_offset + 2 >= sec->_cooked_size)
784 continue;
786 /* See if the next instruction is an unconditional pc-relative
787 branch, more often than not this test will fail, so we
788 test it first to speed things up. */
789 code = bfd_get_8 (abfd, contents + irel->r_offset + 2);
790 if (code != 0x7e)
791 continue;
793 /* Also make sure the next relocation applies to the next
794 instruction and that it's a pc-relative 8 bit branch. */
795 nrel = irel + 1;
796 if (nrel == irelend
797 || irel->r_offset + 3 != nrel->r_offset
798 || ELF32_R_TYPE (nrel->r_info) != (int) R_M68HC11_16)
799 continue;
801 /* Make sure our destination immediately follows the
802 unconditional branch. */
803 roffset = bfd_get_8 (abfd, contents + irel->r_offset + 1);
804 if (roffset != 3)
805 continue;
807 prev_insn_branch = irel;
808 prev_insn_group = 0;
809 continue;
812 /* Read this BFD's symbols if we haven't done so already. */
813 if (isymbuf == NULL && symtab_hdr->sh_info != 0)
815 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
816 if (isymbuf == NULL)
817 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
818 symtab_hdr->sh_info, 0,
819 NULL, NULL, NULL);
820 if (isymbuf == NULL)
821 goto error_return;
824 /* Get the value of the symbol referred to by the reloc. */
825 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
827 /* A local symbol. */
828 isym = isymbuf + ELF32_R_SYM (irel->r_info);
829 is_far = isym->st_other & STO_M68HC12_FAR;
830 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
831 symval = (isym->st_value
832 + sym_sec->output_section->vma
833 + sym_sec->output_offset);
835 else
837 unsigned long indx;
838 struct elf_link_hash_entry *h;
840 /* An external symbol. */
841 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
842 h = elf_sym_hashes (abfd)[indx];
843 BFD_ASSERT (h != NULL);
844 if (h->root.type != bfd_link_hash_defined
845 && h->root.type != bfd_link_hash_defweak)
847 /* This appears to be a reference to an undefined
848 symbol. Just ignore it--it will be caught by the
849 regular reloc processing. */
850 prev_insn_branch = 0;
851 prev_insn_group = 0;
852 continue;
855 is_far = h->other & STO_M68HC12_FAR;
856 isym = 0;
857 sym_sec = h->root.u.def.section;
858 symval = (h->root.u.def.value
859 + sym_sec->output_section->vma
860 + sym_sec->output_offset);
863 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_RL_GROUP)
865 prev_insn_branch = 0;
866 prev_insn_group = 0;
868 /* Do nothing if this reloc is the last byte in the section. */
869 if (irel->r_offset == sec->_cooked_size)
870 continue;
872 prev_insn_group = irel;
873 insn_group_value = isym->st_value;
874 continue;
877 /* When we relax some bytes, the size of our section changes.
878 This affects the layout of next input sections that go in our
879 output section. When the symbol is part of another section that
880 will go in the same output section as the current one, it's
881 final address may now be incorrect (too far). We must let the
882 linker re-compute all section offsets before processing this
883 reloc. Code example:
885 Initial Final
886 .sect .text section size = 6 section size = 4
887 jmp foo
888 jmp bar
889 .sect .text.foo_bar output_offset = 6 output_offset = 4
890 foo: rts
891 bar: rts
893 If we process the reloc now, the jmp bar is replaced by a
894 relative branch to the initial bar address (output_offset 6). */
895 if (*again && sym_sec != sec
896 && sym_sec->output_section == sec->output_section)
898 prev_insn_group = 0;
899 prev_insn_branch = 0;
900 continue;
903 value = symval;
904 /* Try to turn a far branch to a near branch. */
905 if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
906 && prev_insn_branch)
908 bfd_vma offset;
909 unsigned char code;
911 offset = value - (prev_insn_branch->r_offset
912 + sec->output_section->vma
913 + sec->output_offset + 2);
915 /* If the offset is still out of -128..+127 range,
916 leave that far branch unchanged. */
917 if ((offset & 0xff80) != 0 && (offset & 0xff80) != 0xff80)
919 prev_insn_branch = 0;
920 continue;
923 /* Shrink the branch. */
924 code = bfd_get_8 (abfd, contents + prev_insn_branch->r_offset);
925 if (code == 0x7e)
927 code = 0x20;
928 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
929 bfd_put_8 (abfd, 0xff,
930 contents + prev_insn_branch->r_offset + 1);
931 irel->r_offset = prev_insn_branch->r_offset + 1;
932 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
933 R_M68HC11_PCREL_8);
934 m68hc11_elf_relax_delete_bytes (abfd, sec,
935 irel->r_offset + 1, 1);
937 else
939 code ^= 0x1;
940 bfd_put_8 (abfd, code, contents + prev_insn_branch->r_offset);
941 bfd_put_8 (abfd, 0xff,
942 contents + prev_insn_branch->r_offset + 1);
943 irel->r_offset = prev_insn_branch->r_offset + 1;
944 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
945 R_M68HC11_PCREL_8);
946 m68hc11_elf_relax_delete_bytes (abfd, sec,
947 irel->r_offset + 1, 3);
949 prev_insn_branch = 0;
950 *again = TRUE;
953 /* Try to turn a 16 bit address into a 8 bit page0 address. */
954 else if (ELF32_R_TYPE (irel->r_info) == (int) R_M68HC11_16
955 && (value & 0xff00) == 0)
957 unsigned char code;
958 unsigned short offset;
959 struct m68hc11_direct_relax *rinfo;
961 prev_insn_branch = 0;
962 offset = bfd_get_16 (abfd, contents + irel->r_offset);
963 offset += value;
964 if ((offset & 0xff00) != 0)
966 prev_insn_group = 0;
967 continue;
970 if (prev_insn_group)
972 unsigned long old_sec_size = sec->_cooked_size;
974 /* Note that we've changed the reldection contents, etc. */
975 elf_section_data (sec)->relocs = internal_relocs;
976 free_relocs = NULL;
978 elf_section_data (sec)->this_hdr.contents = contents;
979 free_contents = NULL;
981 symtab_hdr->contents = (bfd_byte *) isymbuf;
982 free_extsyms = NULL;
984 m68hc11_relax_group (abfd, sec, contents, offset,
985 prev_insn_group->r_offset,
986 insn_group_value);
987 irel = prev_insn_group;
988 prev_insn_group = 0;
989 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
990 R_M68HC11_NONE);
991 if (sec->_cooked_size != old_sec_size)
992 *again = TRUE;
993 continue;
996 /* Get the opcode. */
997 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
998 rinfo = find_relaxable_insn (code);
999 if (rinfo == 0)
1001 prev_insn_group = 0;
1002 continue;
1005 /* Note that we've changed the reldection contents, etc. */
1006 elf_section_data (sec)->relocs = internal_relocs;
1007 free_relocs = NULL;
1009 elf_section_data (sec)->this_hdr.contents = contents;
1010 free_contents = NULL;
1012 symtab_hdr->contents = (bfd_byte *) isymbuf;
1013 free_extsyms = NULL;
1015 /* Fix the opcode. */
1016 /* printf ("A relaxable case : 0x%02x (%s)\n",
1017 code, rinfo->name); */
1018 bfd_put_8 (abfd, rinfo->direct_code,
1019 contents + irel->r_offset - 1);
1021 /* Delete one byte of data (upper byte of address). */
1022 m68hc11_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 1);
1024 /* Fix the relocation's type. */
1025 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1026 R_M68HC11_8);
1028 /* That will change things, so, we should relax again. */
1029 *again = TRUE;
1031 else if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_16 && !is_far)
1033 unsigned char code;
1034 bfd_vma offset;
1036 prev_insn_branch = 0;
1037 code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
1038 if (code == 0x7e || code == 0xbd)
1040 offset = value - (irel->r_offset
1041 + sec->output_section->vma
1042 + sec->output_offset + 1);
1043 offset += bfd_get_16 (abfd, contents + irel->r_offset);
1045 /* If the offset is still out of -128..+127 range,
1046 leave that far branch unchanged. */
1047 if ((offset & 0xff80) == 0 || (offset & 0xff80) == 0xff80)
1050 /* Note that we've changed the reldection contents, etc. */
1051 elf_section_data (sec)->relocs = internal_relocs;
1052 free_relocs = NULL;
1054 elf_section_data (sec)->this_hdr.contents = contents;
1055 free_contents = NULL;
1057 symtab_hdr->contents = (bfd_byte *) isymbuf;
1058 free_extsyms = NULL;
1060 /* Shrink the branch. */
1061 code = (code == 0x7e) ? 0x20 : 0x8d;
1062 bfd_put_8 (abfd, code,
1063 contents + irel->r_offset - 1);
1064 bfd_put_8 (abfd, 0xff,
1065 contents + irel->r_offset);
1066 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1067 R_M68HC11_PCREL_8);
1068 m68hc11_elf_relax_delete_bytes (abfd, sec,
1069 irel->r_offset + 1, 1);
1070 /* That will change things, so, we should relax again. */
1071 *again = TRUE;
1075 prev_insn_branch = 0;
1076 prev_insn_group = 0;
1079 if (free_relocs != NULL)
1081 free (free_relocs);
1082 free_relocs = NULL;
1085 if (free_contents != NULL)
1087 if (! link_info->keep_memory)
1088 free (free_contents);
1089 else
1091 /* Cache the section contents for elf_link_input_bfd. */
1092 elf_section_data (sec)->this_hdr.contents = contents;
1094 free_contents = NULL;
1097 if (free_extsyms != NULL)
1099 if (! link_info->keep_memory)
1100 free (free_extsyms);
1101 else
1103 /* Cache the symbols for elf_link_input_bfd. */
1104 symtab_hdr->contents = (unsigned char *) isymbuf;
1106 free_extsyms = NULL;
1109 return TRUE;
1111 error_return:
1112 if (free_relocs != NULL)
1113 free (free_relocs);
1114 if (free_contents != NULL)
1115 free (free_contents);
1116 if (free_extsyms != NULL)
1117 free (free_extsyms);
1118 return FALSE;
1121 /* Delete some bytes from a section while relaxing. */
1123 static void
1124 m68hc11_elf_relax_delete_bytes (abfd, sec, addr, count)
1125 bfd *abfd;
1126 asection *sec;
1127 bfd_vma addr;
1128 int count;
1130 Elf_Internal_Shdr *symtab_hdr;
1131 unsigned int sec_shndx;
1132 bfd_byte *contents;
1133 Elf_Internal_Rela *irel, *irelend;
1134 bfd_vma toaddr;
1135 Elf_Internal_Sym *isymbuf, *isym, *isymend;
1136 struct elf_link_hash_entry **sym_hashes;
1137 struct elf_link_hash_entry **end_hashes;
1138 unsigned int symcount;
1140 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1141 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1143 sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1145 contents = elf_section_data (sec)->this_hdr.contents;
1147 toaddr = sec->_cooked_size;
1149 irel = elf_section_data (sec)->relocs;
1150 irelend = irel + sec->reloc_count;
1152 /* Actually delete the bytes. */
1153 memmove (contents + addr, contents + addr + count,
1154 (size_t) (toaddr - addr - count));
1156 sec->_cooked_size -= count;
1158 /* Adjust all the relocs. */
1159 for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
1161 unsigned char code;
1162 unsigned char offset;
1163 unsigned short raddr;
1164 unsigned long old_offset;
1165 int branch_pos;
1167 old_offset = irel->r_offset;
1169 /* See if this reloc was for the bytes we have deleted, in which
1170 case we no longer care about it. Don't delete relocs which
1171 represent addresses, though. */
1172 if (ELF32_R_TYPE (irel->r_info) != R_M68HC11_RL_JUMP
1173 && irel->r_offset >= addr && irel->r_offset < addr + count)
1174 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1175 R_M68HC11_NONE);
1177 if (ELF32_R_TYPE (irel->r_info) == R_M68HC11_NONE)
1178 continue;
1180 /* Get the new reloc address. */
1181 if ((irel->r_offset > addr
1182 && irel->r_offset < toaddr))
1183 irel->r_offset -= count;
1185 /* If this is a PC relative reloc, see if the range it covers
1186 includes the bytes we have deleted. */
1187 switch (ELF32_R_TYPE (irel->r_info))
1189 default:
1190 break;
1192 case R_M68HC11_RL_JUMP:
1193 code = bfd_get_8 (abfd, contents + irel->r_offset);
1194 switch (code)
1196 /* jsr and jmp instruction are also marked with RL_JUMP
1197 relocs but no adjustment must be made. */
1198 case 0x7e:
1199 case 0x9d:
1200 case 0xbd:
1201 continue;
1203 case 0x12:
1204 case 0x13:
1205 branch_pos = 3;
1206 raddr = 4;
1208 /* Special case when we translate a brclr N,y into brclr *<addr>
1209 In this case, the 0x18 page2 prefix is removed.
1210 The reloc offset is not modified but the instruction
1211 size is reduced by 1. */
1212 if (old_offset == addr)
1213 raddr++;
1214 break;
1216 case 0x1e:
1217 case 0x1f:
1218 branch_pos = 3;
1219 raddr = 4;
1220 break;
1222 case 0x18:
1223 branch_pos = 4;
1224 raddr = 5;
1225 break;
1227 default:
1228 branch_pos = 1;
1229 raddr = 2;
1230 break;
1232 offset = bfd_get_8 (abfd, contents + irel->r_offset + branch_pos);
1233 raddr += old_offset;
1234 raddr += ((unsigned short) offset | ((offset & 0x80) ? 0xff00 : 0));
1235 if (irel->r_offset < addr && raddr > addr)
1237 offset -= count;
1238 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1240 else if (irel->r_offset >= addr && raddr <= addr)
1242 offset += count;
1243 bfd_put_8 (abfd, offset, contents + irel->r_offset + branch_pos);
1245 else
1247 /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1248 irel->r_offset, addr);*/
1251 break;
1255 /* Adjust the local symbols defined in this section. */
1256 isymend = isymbuf + symtab_hdr->sh_info;
1257 for (isym = isymbuf; isym < isymend; isym++)
1259 if (isym->st_shndx == sec_shndx
1260 && isym->st_value > addr
1261 && isym->st_value <= toaddr)
1262 isym->st_value -= count;
1265 /* Now adjust the global symbols defined in this section. */
1266 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
1267 - symtab_hdr->sh_info);
1268 sym_hashes = elf_sym_hashes (abfd);
1269 end_hashes = sym_hashes + symcount;
1270 for (; sym_hashes < end_hashes; sym_hashes++)
1272 struct elf_link_hash_entry *sym_hash = *sym_hashes;
1273 if ((sym_hash->root.type == bfd_link_hash_defined
1274 || sym_hash->root.type == bfd_link_hash_defweak)
1275 && sym_hash->root.u.def.section == sec
1276 && sym_hash->root.u.def.value > addr
1277 && sym_hash->root.u.def.value <= toaddr)
1279 sym_hash->root.u.def.value -= count;
1285 #define ELF_ARCH bfd_arch_m68hc11
1286 #define ELF_MACHINE_CODE EM_68HC11
1287 #define ELF_MAXPAGESIZE 0x1000
1289 #define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
1290 #define TARGET_BIG_NAME "elf32-m68hc11"
1292 #define elf_info_to_howto 0
1293 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
1294 #define bfd_elf32_bfd_relax_section m68hc11_elf_relax_section
1295 #define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
1296 #define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
1297 #define elf_backend_check_relocs elf32_m68hc11_check_relocs
1298 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
1299 #define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
1300 #define elf_backend_object_p 0
1301 #define elf_backend_final_write_processing 0
1302 #define elf_backend_can_gc_sections 1
1304 #define bfd_elf32_bfd_link_hash_table_create \
1305 m68hc11_elf_bfd_link_hash_table_create
1306 #define bfd_elf32_bfd_link_hash_table_free \
1307 m68hc11_elf_bfd_link_hash_table_free
1308 #define bfd_elf32_bfd_merge_private_bfd_data \
1309 _bfd_m68hc11_elf_merge_private_bfd_data
1310 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
1311 #define bfd_elf32_bfd_print_private_bfd_data \
1312 _bfd_m68hc11_elf_print_private_bfd_data
1314 #include "elf32-target.h"