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. */
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
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 */
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
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 */
68 2, /* size (0 = byte, 1 = short, 2 = long) */
70 FALSE
, /* pc_relative */
72 complain_overflow_dont
,/* complain_on_overflow */
73 bfd_elf_generic_reloc
, /* special_function */
74 "R_M68HC11_NONE", /* name */
75 FALSE
, /* partial_inplace */
78 FALSE
), /* pcrel_offset */
80 /* A 8 bit absolute relocation */
81 HOWTO (R_M68HC11_8
, /* type */
83 0, /* size (0 = byte, 1 = short, 2 = long) */
85 FALSE
, /* pc_relative */
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 */
98 0, /* size (0 = byte, 1 = short, 2 = long) */
100 FALSE
, /* pc_relative */
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 */
113 0, /* size (0 = byte, 1 = short, 2 = long) */
115 FALSE
, /* pc_relative */
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 */
128 0, /* size (0 = byte, 1 = short, 2 = long) */
130 TRUE
, /* pc_relative */
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 */
143 1, /* size (0 = byte, 1 = short, 2 = long) */
145 FALSE
, /* pc_relative */
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 */
159 2, /* size (0 = byte, 1 = short, 2 = long) */
161 FALSE
, /* pc_relative */
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 */
174 0, /* size (0 = byte, 1 = short, 2 = long) */
176 FALSE
, /* pc_relative */
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 */
189 1, /* size (0 = byte, 1 = short, 2 = long) */
191 TRUE
, /* pc_relative */
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 */
204 1, /* size (0 = byte, 1 = short, 2 = long) */
206 FALSE
, /* pc_relative */
208 complain_overflow_dont
, /* complain_on_overflow */
209 NULL
, /* special_function */
210 "R_M68HC11_GNU_VTINHERIT", /* name */
211 FALSE
, /* partial_inplace */
214 FALSE
), /* pcrel_offset */
216 /* GNU extension to record C++ vtable member usage */
217 HOWTO (R_M68HC11_GNU_VTENTRY
, /* type */
219 1, /* size (0 = byte, 1 = short, 2 = long) */
221 FALSE
, /* pc_relative */
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 */
229 FALSE
), /* pcrel_offset */
231 /* A 24 bit relocation */
232 HOWTO (R_M68HC11_24
, /* type */
234 1, /* size (0 = byte, 1 = short, 2 = long) */
236 FALSE
, /* pc_relative */
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 */
249 1, /* size (0 = byte, 1 = short, 2 = long) */
251 FALSE
, /* pc_relative */
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 */
264 0, /* size (0 = byte, 1 = short, 2 = long) */
266 FALSE
, /* pc_relative */
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 */
283 /* Mark beginning of a jump instruction (any form). */
284 HOWTO (R_M68HC11_RL_JUMP
, /* type */
286 1, /* size (0 = byte, 1 = short, 2 = long) */
288 FALSE
, /* pc_relative */
290 complain_overflow_dont
, /* complain_on_overflow */
291 m68hc11_elf_ignore_reloc
, /* special_function */
292 "R_M68HC11_RL_JUMP", /* name */
293 TRUE
, /* partial_inplace */
296 TRUE
), /* pcrel_offset */
298 /* Mark beginning of Gcc relaxation group instruction. */
299 HOWTO (R_M68HC11_RL_GROUP
, /* type */
301 1, /* size (0 = byte, 1 = short, 2 = long) */
303 FALSE
, /* pc_relative */
305 complain_overflow_dont
, /* complain_on_overflow */
306 m68hc11_elf_ignore_reloc
, /* special_function */
307 "R_M68HC11_RL_GROUP", /* name */
308 TRUE
, /* partial_inplace */
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
;
352 i
< sizeof (m68hc11_reloc_map
) / sizeof (struct m68hc11_reloc_map
);
355 if (m68hc11_reloc_map
[i
].bfd_reloc_val
== code
)
356 return &elf_m68hc11_howto_table
[m68hc11_reloc_map
[i
].elf_reloc_val
];
362 /* Set the howto pointer for an M68HC11 ELF reloc. */
365 m68hc11_info_to_howto_rel (abfd
, cache_ptr
, dst
)
366 bfd
*abfd ATTRIBUTE_UNUSED
;
368 Elf_Internal_Rela
*dst
;
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. */
382 m68hc11_elf_build_one_stub (gen_entry
, in_arg
)
383 struct bfd_hash_entry
*gen_entry
;
386 struct elf32_m68hc11_stub_hash_entry
*stub_entry
;
387 struct bfd_link_info
*info
;
388 struct m68hc11_elf_link_hash_table
*htab
;
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:
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);
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);
435 /* jmp __trampoline */
436 bfd_put_8 (stub_bfd
, 0x7E, loc
);
437 bfd_put_16 (stub_bfd
, htab
->pinfo
.trampoline_addr
, loc
+ 1);
442 /* As above, but don't actually build the stub. Just bump offset so
443 we know stub section sizes. */
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;
459 /* Create a 68HC11 ELF linker hash table. */
461 static struct bfd_link_hash_table
*
462 m68hc11_elf_bfd_link_hash_table_create (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
)
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
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 },
523 static struct m68hc11_direct_relax
*
524 find_relaxable_insn (unsigned char code
)
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
];
536 compare_reloc (e1
, 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
)
546 return i1
->r_offset
< i2
->r_offset
? -1 : 1;
549 #define M6811_OP_LDX_IMMEDIATE (0xCE)
552 m68hc11_relax_group (abfd
, sec
, contents
, value
, offset
, end_group
)
557 unsigned long offset
;
558 unsigned long end_group
;
561 unsigned long start_offset
;
562 unsigned long ldx_offset
= offset
;
563 unsigned long ldx_size
;
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
);
575 code
= bfd_get_8 (abfd
, contents
+ offset
);
577 ldx_size
= offset
- ldx_offset
+ 3;
579 if (code
!= M6811_OP_LDX_IMMEDIATE
|| offset
>= end_group
)
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
587 while (offset
< end_group
)
594 start_offset
= offset
;
595 code
= bfd_get_8 (abfd
, contents
+ offset
);
600 code
= bfd_get_8 (abfd
, contents
+ offset
);
603 /* Check the instruction and translate to use direct addressing mode. */
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...). */
636 new_value
= (unsigned) bfd_get_8 (abfd
, contents
+ offset
+ 1);
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
);
653 offset
= start_offset
+ isize
;
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. */
668 m68hc11_elf_relax_section (abfd
, sec
, link_info
, again
)
671 struct bfd_link_info
*link_info
;
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. */
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
693 if (link_info
->relocateable
694 || (sec
->flags
& SEC_RELOC
) == 0
695 || sec
->reloc_count
== 0
696 || (sec
->flags
& SEC_CODE
) == 0)
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_elf32_link_read_relocs
709 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
710 link_info
->keep_memory
));
711 if (internal_relocs
== NULL
)
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
),
721 /* Walk through them looking for relaxing opportunities. */
722 irelend
= internal_relocs
+ sec
->reloc_count
;
723 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
727 Elf_Internal_Sym
*isym
;
731 /* If this isn't something that can be relaxed, then ignore
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;
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
;
750 /* Go get them off disk. */
751 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
752 if (contents
== NULL
)
754 free_contents
= contents
;
756 if (! bfd_get_section_contents (abfd
, sec
, contents
,
757 (file_ptr
) 0, sec
->_raw_size
))
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.
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
;
777 unsigned char roffset
;
779 prev_insn_branch
= 0;
782 /* Do nothing if this reloc is the last byte in the section. */
783 if (irel
->r_offset
+ 2 >= sec
->_cooked_size
)
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);
793 /* Also make sure the next relocation applies to the next
794 instruction and that it's a pc-relative 8 bit branch. */
797 || irel
->r_offset
+ 3 != nrel
->r_offset
798 || ELF32_R_TYPE (nrel
->r_info
) != (int) R_M68HC11_16
)
801 /* Make sure our destination immediately follows the
802 unconditional branch. */
803 roffset
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
+ 1);
807 prev_insn_branch
= irel
;
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
;
817 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
818 symtab_hdr
->sh_info
, 0,
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
);
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;
855 is_far
= h
->other
& STO_M68HC12_FAR
;
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;
868 /* Do nothing if this reloc is the last byte in the section. */
869 if (irel
->r_offset
== sec
->_cooked_size
)
872 prev_insn_group
= irel
;
873 insn_group_value
= isym
->st_value
;
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
886 .sect .text section size = 6 section size = 4
889 .sect .text.foo_bar output_offset = 6 output_offset = 4
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
)
899 prev_insn_branch
= 0;
904 /* Try to turn a far branch to a near branch. */
905 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_M68HC11_16
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;
923 /* Shrink the branch. */
924 code
= bfd_get_8 (abfd
, contents
+ prev_insn_branch
->r_offset
);
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
),
934 m68hc11_elf_relax_delete_bytes (abfd
, sec
,
935 irel
->r_offset
+ 1, 1);
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
),
946 m68hc11_elf_relax_delete_bytes (abfd
, sec
,
947 irel
->r_offset
+ 1, 3);
949 prev_insn_branch
= 0;
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)
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
);
964 if ((offset
& 0xff00) != 0)
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
;
978 elf_section_data (sec
)->this_hdr
.contents
= contents
;
979 free_contents
= NULL
;
981 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
984 m68hc11_relax_group (abfd
, sec
, contents
, offset
,
985 prev_insn_group
->r_offset
,
987 irel
= prev_insn_group
;
989 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
991 if (sec
->_cooked_size
!= old_sec_size
)
996 /* Get the opcode. */
997 code
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
- 1);
998 rinfo
= find_relaxable_insn (code
);
1001 prev_insn_group
= 0;
1005 /* Note that we've changed the reldection contents, etc. */
1006 elf_section_data (sec
)->relocs
= internal_relocs
;
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
),
1028 /* That will change things, so, we should relax again. */
1031 else if (ELF32_R_TYPE (irel
->r_info
) == R_M68HC11_16
&& !is_far
)
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
;
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
),
1068 m68hc11_elf_relax_delete_bytes (abfd
, sec
,
1069 irel
->r_offset
+ 1, 1);
1070 /* That will change things, so, we should relax again. */
1075 prev_insn_branch
= 0;
1076 prev_insn_group
= 0;
1079 if (free_relocs
!= NULL
)
1085 if (free_contents
!= NULL
)
1087 if (! link_info
->keep_memory
)
1088 free (free_contents
);
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
);
1103 /* Cache the symbols for elf_link_input_bfd. */
1104 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1106 free_extsyms
= NULL
;
1112 if (free_relocs
!= NULL
)
1114 if (free_contents
!= NULL
)
1115 free (free_contents
);
1116 if (free_extsyms
!= NULL
)
1117 free (free_extsyms
);
1121 /* Delete some bytes from a section while relaxing. */
1124 m68hc11_elf_relax_delete_bytes (abfd
, sec
, addr
, count
)
1130 Elf_Internal_Shdr
*symtab_hdr
;
1131 unsigned int sec_shndx
;
1133 Elf_Internal_Rela
*irel
, *irelend
;
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
++)
1162 unsigned char offset
;
1163 unsigned short raddr
;
1164 unsigned long old_offset
;
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
),
1177 if (ELF32_R_TYPE (irel
->r_info
) == R_M68HC11_NONE
)
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
))
1192 case R_M68HC11_RL_JUMP
:
1193 code
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
);
1196 /* jsr and jmp instruction are also marked with RL_JUMP
1197 relocs but no adjustment must be made. */
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
)
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
)
1238 bfd_put_8 (abfd
, offset
, contents
+ irel
->r_offset
+ branch_pos
);
1240 else if (irel
->r_offset
>= addr
&& raddr
<= addr
)
1243 bfd_put_8 (abfd
, offset
, contents
+ irel
->r_offset
+ branch_pos
);
1247 /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1248 irel->r_offset, addr);*/
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"