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 (bfd
*, bfd_reloc_code_real_type
);
34 static void m68hc11_info_to_howto_rel
35 (bfd
*, arelent
*, Elf_Internal_Rela
*);
37 /* Trampoline generation. */
38 static bfd_boolean m68hc11_elf_size_one_stub
39 (struct bfd_hash_entry
*gen_entry
, void *in_arg
);
40 static bfd_boolean m68hc11_elf_build_one_stub
41 (struct bfd_hash_entry
*gen_entry
, void *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 (bfd
*, asection
*, struct bfd_link_info
*, bfd_boolean
*);
48 static void m68hc11_elf_relax_delete_bytes
49 (bfd
*, asection
*, bfd_vma
, int);
50 static void m68hc11_relax_group
51 (bfd
*, asection
*, bfd_byte
*, unsigned, unsigned long, unsigned long);
52 static int compare_reloc (const void *, const void *);
54 /* Use REL instead of RELA to save space */
57 /* The Motorola 68HC11 microcontroller only addresses 64Kb but we also
58 support a memory bank switching mechanism similar to 68HC12.
59 We must handle 8 and 16-bit relocations. The 32-bit relocation
60 are used for debugging sections (DWARF2) to represent a virtual
62 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
63 static reloc_howto_type elf_m68hc11_howto_table
[] = {
64 /* This reloc does nothing. */
65 HOWTO (R_M68HC11_NONE
, /* type */
67 2, /* size (0 = byte, 1 = short, 2 = long) */
69 FALSE
, /* pc_relative */
71 complain_overflow_dont
,/* complain_on_overflow */
72 bfd_elf_generic_reloc
, /* special_function */
73 "R_M68HC11_NONE", /* name */
74 FALSE
, /* partial_inplace */
77 FALSE
), /* pcrel_offset */
79 /* A 8 bit absolute relocation */
80 HOWTO (R_M68HC11_8
, /* type */
82 0, /* size (0 = byte, 1 = short, 2 = long) */
84 FALSE
, /* pc_relative */
86 complain_overflow_bitfield
, /* complain_on_overflow */
87 bfd_elf_generic_reloc
, /* special_function */
88 "R_M68HC11_8", /* name */
89 FALSE
, /* partial_inplace */
90 0x00ff, /* src_mask */
91 0x00ff, /* dst_mask */
92 FALSE
), /* pcrel_offset */
94 /* A 8 bit absolute relocation (upper address) */
95 HOWTO (R_M68HC11_HI8
, /* type */
97 0, /* size (0 = byte, 1 = short, 2 = long) */
99 FALSE
, /* pc_relative */
101 complain_overflow_bitfield
, /* complain_on_overflow */
102 bfd_elf_generic_reloc
, /* special_function */
103 "R_M68HC11_HI8", /* name */
104 FALSE
, /* partial_inplace */
105 0x00ff, /* src_mask */
106 0x00ff, /* dst_mask */
107 FALSE
), /* pcrel_offset */
109 /* A 8 bit absolute relocation (upper address) */
110 HOWTO (R_M68HC11_LO8
, /* type */
112 0, /* size (0 = byte, 1 = short, 2 = long) */
114 FALSE
, /* pc_relative */
116 complain_overflow_dont
, /* complain_on_overflow */
117 bfd_elf_generic_reloc
, /* special_function */
118 "R_M68HC11_LO8", /* name */
119 FALSE
, /* partial_inplace */
120 0x00ff, /* src_mask */
121 0x00ff, /* dst_mask */
122 FALSE
), /* pcrel_offset */
124 /* A 8 bit PC-rel relocation */
125 HOWTO (R_M68HC11_PCREL_8
, /* type */
127 0, /* size (0 = byte, 1 = short, 2 = long) */
129 TRUE
, /* pc_relative */
131 complain_overflow_bitfield
, /* complain_on_overflow */
132 bfd_elf_generic_reloc
, /* special_function */
133 "R_M68HC11_PCREL_8", /* name */
134 FALSE
, /* partial_inplace */
135 0x00ff, /* src_mask */
136 0x00ff, /* dst_mask */
137 TRUE
), /* pcrel_offset */
139 /* A 16 bit absolute relocation */
140 HOWTO (R_M68HC11_16
, /* type */
142 1, /* size (0 = byte, 1 = short, 2 = long) */
144 FALSE
, /* pc_relative */
146 complain_overflow_dont
/*bitfield */ , /* complain_on_overflow */
147 bfd_elf_generic_reloc
, /* special_function */
148 "R_M68HC11_16", /* name */
149 FALSE
, /* partial_inplace */
150 0xffff, /* src_mask */
151 0xffff, /* dst_mask */
152 FALSE
), /* pcrel_offset */
154 /* A 32 bit absolute relocation. This one is never used for the
155 code relocation. It's used by gas for -gstabs generation. */
156 HOWTO (R_M68HC11_32
, /* type */
158 2, /* size (0 = byte, 1 = short, 2 = long) */
160 FALSE
, /* pc_relative */
162 complain_overflow_bitfield
, /* complain_on_overflow */
163 bfd_elf_generic_reloc
, /* special_function */
164 "R_M68HC11_32", /* name */
165 FALSE
, /* partial_inplace */
166 0xffffffff, /* src_mask */
167 0xffffffff, /* dst_mask */
168 FALSE
), /* pcrel_offset */
170 /* A 3 bit absolute relocation */
171 HOWTO (R_M68HC11_3B
, /* type */
173 0, /* size (0 = byte, 1 = short, 2 = long) */
175 FALSE
, /* pc_relative */
177 complain_overflow_bitfield
, /* complain_on_overflow */
178 bfd_elf_generic_reloc
, /* special_function */
179 "R_M68HC11_4B", /* name */
180 FALSE
, /* partial_inplace */
181 0x003, /* src_mask */
182 0x003, /* dst_mask */
183 FALSE
), /* pcrel_offset */
185 /* A 16 bit PC-rel relocation */
186 HOWTO (R_M68HC11_PCREL_16
, /* type */
188 1, /* size (0 = byte, 1 = short, 2 = long) */
190 TRUE
, /* pc_relative */
192 complain_overflow_dont
, /* complain_on_overflow */
193 bfd_elf_generic_reloc
, /* special_function */
194 "R_M68HC11_PCREL_16", /* name */
195 FALSE
, /* partial_inplace */
196 0xffff, /* src_mask */
197 0xffff, /* dst_mask */
198 TRUE
), /* pcrel_offset */
200 /* GNU extension to record C++ vtable hierarchy */
201 HOWTO (R_M68HC11_GNU_VTINHERIT
, /* type */
203 1, /* size (0 = byte, 1 = short, 2 = long) */
205 FALSE
, /* pc_relative */
207 complain_overflow_dont
, /* complain_on_overflow */
208 NULL
, /* special_function */
209 "R_M68HC11_GNU_VTINHERIT", /* name */
210 FALSE
, /* partial_inplace */
213 FALSE
), /* pcrel_offset */
215 /* GNU extension to record C++ vtable member usage */
216 HOWTO (R_M68HC11_GNU_VTENTRY
, /* type */
218 1, /* size (0 = byte, 1 = short, 2 = long) */
220 FALSE
, /* pc_relative */
222 complain_overflow_dont
, /* complain_on_overflow */
223 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
224 "R_M68HC11_GNU_VTENTRY", /* name */
225 FALSE
, /* partial_inplace */
228 FALSE
), /* pcrel_offset */
230 /* A 24 bit relocation */
231 HOWTO (R_M68HC11_24
, /* type */
233 1, /* size (0 = byte, 1 = short, 2 = long) */
235 FALSE
, /* pc_relative */
237 complain_overflow_bitfield
, /* complain_on_overflow */
238 bfd_elf_generic_reloc
, /* special_function */
239 "R_M68HC11_24", /* name */
240 FALSE
, /* partial_inplace */
241 0xffffff, /* src_mask */
242 0xffffff, /* dst_mask */
243 FALSE
), /* pcrel_offset */
245 /* A 16-bit low relocation */
246 HOWTO (R_M68HC11_LO16
, /* type */
248 1, /* size (0 = byte, 1 = short, 2 = long) */
250 FALSE
, /* pc_relative */
252 complain_overflow_bitfield
, /* complain_on_overflow */
253 bfd_elf_generic_reloc
, /* special_function */
254 "R_M68HC11_LO16", /* name */
255 FALSE
, /* partial_inplace */
256 0xffff, /* src_mask */
257 0xffff, /* dst_mask */
258 FALSE
), /* pcrel_offset */
260 /* A page relocation */
261 HOWTO (R_M68HC11_PAGE
, /* type */
263 0, /* size (0 = byte, 1 = short, 2 = long) */
265 FALSE
, /* pc_relative */
267 complain_overflow_bitfield
, /* complain_on_overflow */
268 bfd_elf_generic_reloc
, /* special_function */
269 "R_M68HC11_PAGE", /* name */
270 FALSE
, /* partial_inplace */
271 0x00ff, /* src_mask */
272 0x00ff, /* dst_mask */
273 FALSE
), /* pcrel_offset */
282 /* Mark beginning of a jump instruction (any form). */
283 HOWTO (R_M68HC11_RL_JUMP
, /* type */
285 1, /* size (0 = byte, 1 = short, 2 = long) */
287 FALSE
, /* pc_relative */
289 complain_overflow_dont
, /* complain_on_overflow */
290 m68hc11_elf_ignore_reloc
, /* special_function */
291 "R_M68HC11_RL_JUMP", /* name */
292 TRUE
, /* partial_inplace */
295 TRUE
), /* pcrel_offset */
297 /* Mark beginning of Gcc relaxation group instruction. */
298 HOWTO (R_M68HC11_RL_GROUP
, /* type */
300 1, /* size (0 = byte, 1 = short, 2 = long) */
302 FALSE
, /* pc_relative */
304 complain_overflow_dont
, /* complain_on_overflow */
305 m68hc11_elf_ignore_reloc
, /* special_function */
306 "R_M68HC11_RL_GROUP", /* name */
307 TRUE
, /* partial_inplace */
310 TRUE
), /* pcrel_offset */
313 /* Map BFD reloc types to M68HC11 ELF reloc types. */
315 struct m68hc11_reloc_map
317 bfd_reloc_code_real_type bfd_reloc_val
;
318 unsigned char elf_reloc_val
;
321 static const struct m68hc11_reloc_map m68hc11_reloc_map
[] = {
322 {BFD_RELOC_NONE
, R_M68HC11_NONE
,},
323 {BFD_RELOC_8
, R_M68HC11_8
},
324 {BFD_RELOC_M68HC11_HI8
, R_M68HC11_HI8
},
325 {BFD_RELOC_M68HC11_LO8
, R_M68HC11_LO8
},
326 {BFD_RELOC_8_PCREL
, R_M68HC11_PCREL_8
},
327 {BFD_RELOC_16_PCREL
, R_M68HC11_PCREL_16
},
328 {BFD_RELOC_16
, R_M68HC11_16
},
329 {BFD_RELOC_32
, R_M68HC11_32
},
330 {BFD_RELOC_M68HC11_3B
, R_M68HC11_3B
},
332 {BFD_RELOC_VTABLE_INHERIT
, R_M68HC11_GNU_VTINHERIT
},
333 {BFD_RELOC_VTABLE_ENTRY
, R_M68HC11_GNU_VTENTRY
},
335 {BFD_RELOC_M68HC11_LO16
, R_M68HC11_LO16
},
336 {BFD_RELOC_M68HC11_PAGE
, R_M68HC11_PAGE
},
337 {BFD_RELOC_M68HC11_24
, R_M68HC11_24
},
339 {BFD_RELOC_M68HC11_RL_JUMP
, R_M68HC11_RL_JUMP
},
340 {BFD_RELOC_M68HC11_RL_GROUP
, R_M68HC11_RL_GROUP
},
343 static reloc_howto_type
*
344 bfd_elf32_bfd_reloc_type_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
345 bfd_reloc_code_real_type code
)
350 i
< sizeof (m68hc11_reloc_map
) / sizeof (struct m68hc11_reloc_map
);
353 if (m68hc11_reloc_map
[i
].bfd_reloc_val
== code
)
354 return &elf_m68hc11_howto_table
[m68hc11_reloc_map
[i
].elf_reloc_val
];
360 /* Set the howto pointer for an M68HC11 ELF reloc. */
363 m68hc11_info_to_howto_rel (bfd
*abfd ATTRIBUTE_UNUSED
,
364 arelent
*cache_ptr
, Elf_Internal_Rela
*dst
)
368 r_type
= ELF32_R_TYPE (dst
->r_info
);
369 BFD_ASSERT (r_type
< (unsigned int) R_M68HC11_max
);
370 cache_ptr
->howto
= &elf_m68hc11_howto_table
[r_type
];
374 /* Far trampoline generation. */
376 /* Build a 68HC11 trampoline stub. */
378 m68hc11_elf_build_one_stub (struct bfd_hash_entry
*gen_entry
, void *in_arg
)
380 struct elf32_m68hc11_stub_hash_entry
*stub_entry
;
381 struct bfd_link_info
*info
;
382 struct m68hc11_elf_link_hash_table
*htab
;
386 bfd_vma sym_value
, phys_page
, phys_addr
;
388 /* Massage our args to the form they really have. */
389 stub_entry
= (struct elf32_m68hc11_stub_hash_entry
*) gen_entry
;
390 info
= (struct bfd_link_info
*) in_arg
;
392 htab
= m68hc11_elf_hash_table (info
);
394 stub_sec
= stub_entry
->stub_sec
;
396 /* Make a note of the offset within the stubs for this entry. */
397 stub_entry
->stub_offset
= stub_sec
->_raw_size
;
398 stub_sec
->_raw_size
+= 10;
399 loc
= stub_sec
->contents
+ stub_entry
->stub_offset
;
401 stub_bfd
= stub_sec
->owner
;
403 /* Create the trampoline call stub:
411 sym_value
= (stub_entry
->target_value
412 + stub_entry
->target_section
->output_offset
413 + stub_entry
->target_section
->output_section
->vma
);
414 phys_addr
= m68hc11_phys_addr (&htab
->pinfo
, sym_value
);
415 phys_page
= m68hc11_phys_page (&htab
->pinfo
, sym_value
);
417 /* pshb; ldab #%page(sym) */
418 bfd_put_8 (stub_bfd
, 0x37, loc
);
419 bfd_put_8 (stub_bfd
, 0xC6, loc
+ 1);
420 bfd_put_8 (stub_bfd
, phys_page
, loc
+ 2);
423 /* ldy #%addr(sym) */
424 bfd_put_8 (stub_bfd
, 0x18, loc
);
425 bfd_put_8 (stub_bfd
, 0xCE, loc
+ 1);
426 bfd_put_16 (stub_bfd
, phys_addr
, loc
+ 2);
429 /* jmp __trampoline */
430 bfd_put_8 (stub_bfd
, 0x7E, loc
);
431 bfd_put_16 (stub_bfd
, htab
->pinfo
.trampoline_addr
, loc
+ 1);
436 /* As above, but don't actually build the stub. Just bump offset so
437 we know stub section sizes. */
440 m68hc11_elf_size_one_stub (struct bfd_hash_entry
*gen_entry
,
441 void *in_arg ATTRIBUTE_UNUSED
)
443 struct elf32_m68hc11_stub_hash_entry
*stub_entry
;
445 /* Massage our args to the form they really have. */
446 stub_entry
= (struct elf32_m68hc11_stub_hash_entry
*) gen_entry
;
448 stub_entry
->stub_sec
->_raw_size
+= 10;
452 /* Create a 68HC11 ELF linker hash table. */
454 static struct bfd_link_hash_table
*
455 m68hc11_elf_bfd_link_hash_table_create (bfd
*abfd
)
457 struct m68hc11_elf_link_hash_table
*ret
;
459 ret
= m68hc11_elf_hash_table_create (abfd
);
460 if (ret
== (struct m68hc11_elf_link_hash_table
*) NULL
)
463 ret
->size_one_stub
= m68hc11_elf_size_one_stub
;
464 ret
->build_one_stub
= m68hc11_elf_build_one_stub
;
466 return &ret
->root
.root
;
470 /* 68HC11 Linker Relaxation. */
472 struct m68hc11_direct_relax
476 unsigned char direct_code
;
477 } m68hc11_direct_relax_table
[] = {
478 { "adca", 0xB9, 0x99 },
479 { "adcb", 0xF9, 0xD9 },
480 { "adda", 0xBB, 0x9B },
481 { "addb", 0xFB, 0xDB },
482 { "addd", 0xF3, 0xD3 },
483 { "anda", 0xB4, 0x94 },
484 { "andb", 0xF4, 0xD4 },
485 { "cmpa", 0xB1, 0x91 },
486 { "cmpb", 0xF1, 0xD1 },
487 { "cpd", 0xB3, 0x93 },
488 { "cpxy", 0xBC, 0x9C },
489 /* { "cpy", 0xBC, 0x9C }, */
490 { "eora", 0xB8, 0x98 },
491 { "eorb", 0xF8, 0xD8 },
492 { "jsr", 0xBD, 0x9D },
493 { "ldaa", 0xB6, 0x96 },
494 { "ldab", 0xF6, 0xD6 },
495 { "ldd", 0xFC, 0xDC },
496 { "lds", 0xBE, 0x9E },
497 { "ldxy", 0xFE, 0xDE },
498 /* { "ldy", 0xFE, 0xDE },*/
499 { "oraa", 0xBA, 0x9A },
500 { "orab", 0xFA, 0xDA },
501 { "sbca", 0xB2, 0x92 },
502 { "sbcb", 0xF2, 0xD2 },
503 { "staa", 0xB7, 0x97 },
504 { "stab", 0xF7, 0xD7 },
505 { "std", 0xFD, 0xDD },
506 { "sts", 0xBF, 0x9F },
507 { "stxy", 0xFF, 0xDF },
508 /* { "sty", 0xFF, 0xDF },*/
509 { "suba", 0xB0, 0x90 },
510 { "subb", 0xF0, 0xD0 },
511 { "subd", 0xB3, 0x93 },
515 static struct m68hc11_direct_relax
*
516 find_relaxable_insn (unsigned char code
)
520 for (i
= 0; m68hc11_direct_relax_table
[i
].name
; i
++)
521 if (m68hc11_direct_relax_table
[i
].code
== code
)
522 return &m68hc11_direct_relax_table
[i
];
528 compare_reloc (const void *e1
, const void *e2
)
530 const Elf_Internal_Rela
*i1
= (const Elf_Internal_Rela
*) e1
;
531 const Elf_Internal_Rela
*i2
= (const Elf_Internal_Rela
*) e2
;
533 if (i1
->r_offset
== i2
->r_offset
)
536 return i1
->r_offset
< i2
->r_offset
? -1 : 1;
539 #define M6811_OP_LDX_IMMEDIATE (0xCE)
542 m68hc11_relax_group (bfd
*abfd
, asection
*sec
, bfd_byte
*contents
,
543 unsigned value
, unsigned long offset
,
544 unsigned long end_group
)
547 unsigned long start_offset
;
548 unsigned long ldx_offset
= offset
;
549 unsigned long ldx_size
;
553 /* First instruction of the relax group must be a
554 LDX #value or LDY #value. If this is not the case,
555 ignore the relax group. */
556 code
= bfd_get_8 (abfd
, contents
+ offset
);
561 code
= bfd_get_8 (abfd
, contents
+ offset
);
563 ldx_size
= offset
- ldx_offset
+ 3;
565 if (code
!= M6811_OP_LDX_IMMEDIATE
|| offset
>= end_group
)
569 /* We can remove the LDX/LDY only when all bset/brclr instructions
570 of the relax group have been converted to use direct addressing
573 while (offset
< end_group
)
580 start_offset
= offset
;
581 code
= bfd_get_8 (abfd
, contents
+ offset
);
586 code
= bfd_get_8 (abfd
, contents
+ offset
);
589 /* Check the instruction and translate to use direct addressing mode. */
616 /* This instruction is not recognized and we are not
617 at end of the relax group. Ignore and don't remove
618 the first LDX (we don't know what it is used for...). */
622 new_value
= (unsigned) bfd_get_8 (abfd
, contents
+ offset
+ 1);
624 if ((new_value
& 0xff00) == 0 && bset_use_y
== relax_ldy
)
626 bfd_put_8 (abfd
, code
, contents
+ offset
);
627 bfd_put_8 (abfd
, new_value
, contents
+ offset
+ 1);
628 if (start_offset
!= offset
)
630 m68hc11_elf_relax_delete_bytes (abfd
, sec
, start_offset
,
631 offset
- start_offset
);
639 offset
= start_offset
+ isize
;
643 /* Remove the move instruction (3 or 4 bytes win). */
644 m68hc11_elf_relax_delete_bytes (abfd
, sec
, ldx_offset
, ldx_size
);
648 /* This function handles relaxing for the 68HC11.
651 and somewhat more difficult to support. */
654 m68hc11_elf_relax_section (bfd
*abfd
, asection
*sec
,
655 struct bfd_link_info
*link_info
, bfd_boolean
*again
)
657 Elf_Internal_Shdr
*symtab_hdr
;
658 Elf_Internal_Shdr
*shndx_hdr
;
659 Elf_Internal_Rela
*internal_relocs
;
660 Elf_Internal_Rela
*free_relocs
= NULL
;
661 Elf_Internal_Rela
*irel
, *irelend
;
662 bfd_byte
*contents
= NULL
;
663 bfd_byte
*free_contents
= NULL
;
664 Elf32_External_Sym
*free_extsyms
= NULL
;
665 Elf_Internal_Rela
*prev_insn_branch
= NULL
;
666 Elf_Internal_Rela
*prev_insn_group
= NULL
;
667 unsigned insn_group_value
= 0;
668 Elf_Internal_Sym
*isymbuf
= NULL
;
670 /* Assume nothing changes. */
673 /* We don't have to do anything for a relocatable link, if
674 this section does not have relocs, or if this is not a
676 if (link_info
->relocatable
677 || (sec
->flags
& SEC_RELOC
) == 0
678 || sec
->reloc_count
== 0
679 || (sec
->flags
& SEC_CODE
) == 0)
682 /* If this is the first time we have been called for this section,
683 initialize the cooked size. */
684 if (sec
->_cooked_size
== 0)
685 sec
->_cooked_size
= sec
->_raw_size
;
687 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
688 shndx_hdr
= &elf_tdata (abfd
)->symtab_shndx_hdr
;
690 /* Get a copy of the native relocations. */
691 internal_relocs
= (_bfd_elf_link_read_relocs
692 (abfd
, sec
, (PTR
) NULL
, (Elf_Internal_Rela
*) NULL
,
693 link_info
->keep_memory
));
694 if (internal_relocs
== NULL
)
696 if (! link_info
->keep_memory
)
697 free_relocs
= internal_relocs
;
699 /* Checking for branch relaxation relies on the relocations to
700 be sorted on 'r_offset'. This is not guaranteed so we must sort. */
701 qsort (internal_relocs
, sec
->reloc_count
, sizeof (Elf_Internal_Rela
),
704 /* Walk through them looking for relaxing opportunities. */
705 irelend
= internal_relocs
+ sec
->reloc_count
;
706 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
710 Elf_Internal_Sym
*isym
;
714 /* If this isn't something that can be relaxed, then ignore
716 if (ELF32_R_TYPE (irel
->r_info
) != (int) R_M68HC11_16
717 && ELF32_R_TYPE (irel
->r_info
) != (int) R_M68HC11_RL_JUMP
718 && ELF32_R_TYPE (irel
->r_info
) != (int) R_M68HC11_RL_GROUP
)
720 prev_insn_branch
= 0;
725 /* Get the section contents if we haven't done so already. */
726 if (contents
== NULL
)
728 /* Get cached copy if it exists. */
729 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
730 contents
= elf_section_data (sec
)->this_hdr
.contents
;
733 /* Go get them off disk. */
734 contents
= (bfd_byte
*) bfd_malloc (sec
->_raw_size
);
735 if (contents
== NULL
)
737 free_contents
= contents
;
739 if (! bfd_get_section_contents (abfd
, sec
, contents
,
740 (file_ptr
) 0, sec
->_raw_size
))
745 /* Try to eliminate an unconditional 8 bit pc-relative branch
746 which immediately follows a conditional 8 bit pc-relative
747 branch around the unconditional branch.
754 This happens when the bCC can't reach lab2 at assembly time,
755 but due to other relaxations it can reach at link time. */
756 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_M68HC11_RL_JUMP
)
758 Elf_Internal_Rela
*nrel
;
760 unsigned char roffset
;
762 prev_insn_branch
= 0;
765 /* Do nothing if this reloc is the last byte in the section. */
766 if (irel
->r_offset
+ 2 >= sec
->_cooked_size
)
769 /* See if the next instruction is an unconditional pc-relative
770 branch, more often than not this test will fail, so we
771 test it first to speed things up. */
772 code
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
+ 2);
776 /* Also make sure the next relocation applies to the next
777 instruction and that it's a pc-relative 8 bit branch. */
780 || irel
->r_offset
+ 3 != nrel
->r_offset
781 || ELF32_R_TYPE (nrel
->r_info
) != (int) R_M68HC11_16
)
784 /* Make sure our destination immediately follows the
785 unconditional branch. */
786 roffset
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
+ 1);
790 prev_insn_branch
= irel
;
795 /* Read this BFD's symbols if we haven't done so already. */
796 if (isymbuf
== NULL
&& symtab_hdr
->sh_info
!= 0)
798 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
800 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
,
801 symtab_hdr
->sh_info
, 0,
807 /* Get the value of the symbol referred to by the reloc. */
808 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
810 /* A local symbol. */
811 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
812 is_far
= isym
->st_other
& STO_M68HC12_FAR
;
813 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
814 symval
= (isym
->st_value
815 + sym_sec
->output_section
->vma
816 + sym_sec
->output_offset
);
821 struct elf_link_hash_entry
*h
;
823 /* An external symbol. */
824 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
825 h
= elf_sym_hashes (abfd
)[indx
];
826 BFD_ASSERT (h
!= NULL
);
827 if (h
->root
.type
!= bfd_link_hash_defined
828 && h
->root
.type
!= bfd_link_hash_defweak
)
830 /* This appears to be a reference to an undefined
831 symbol. Just ignore it--it will be caught by the
832 regular reloc processing. */
833 prev_insn_branch
= 0;
838 is_far
= h
->other
& STO_M68HC12_FAR
;
840 sym_sec
= h
->root
.u
.def
.section
;
841 symval
= (h
->root
.u
.def
.value
842 + sym_sec
->output_section
->vma
843 + sym_sec
->output_offset
);
846 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_M68HC11_RL_GROUP
)
848 prev_insn_branch
= 0;
851 /* Do nothing if this reloc is the last byte in the section. */
852 if (irel
->r_offset
== sec
->_cooked_size
)
855 prev_insn_group
= irel
;
856 insn_group_value
= isym
->st_value
;
860 /* When we relax some bytes, the size of our section changes.
861 This affects the layout of next input sections that go in our
862 output section. When the symbol is part of another section that
863 will go in the same output section as the current one, it's
864 final address may now be incorrect (too far). We must let the
865 linker re-compute all section offsets before processing this
869 .sect .text section size = 6 section size = 4
872 .sect .text.foo_bar output_offset = 6 output_offset = 4
876 If we process the reloc now, the jmp bar is replaced by a
877 relative branch to the initial bar address (output_offset 6). */
878 if (*again
&& sym_sec
!= sec
879 && sym_sec
->output_section
== sec
->output_section
)
882 prev_insn_branch
= 0;
887 /* Try to turn a far branch to a near branch. */
888 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_M68HC11_16
894 offset
= value
- (prev_insn_branch
->r_offset
895 + sec
->output_section
->vma
896 + sec
->output_offset
+ 2);
898 /* If the offset is still out of -128..+127 range,
899 leave that far branch unchanged. */
900 if ((offset
& 0xff80) != 0 && (offset
& 0xff80) != 0xff80)
902 prev_insn_branch
= 0;
906 /* Shrink the branch. */
907 code
= bfd_get_8 (abfd
, contents
+ prev_insn_branch
->r_offset
);
911 bfd_put_8 (abfd
, code
, contents
+ prev_insn_branch
->r_offset
);
912 bfd_put_8 (abfd
, 0xff,
913 contents
+ prev_insn_branch
->r_offset
+ 1);
914 irel
->r_offset
= prev_insn_branch
->r_offset
+ 1;
915 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
917 m68hc11_elf_relax_delete_bytes (abfd
, sec
,
918 irel
->r_offset
+ 1, 1);
923 bfd_put_8 (abfd
, code
, contents
+ prev_insn_branch
->r_offset
);
924 bfd_put_8 (abfd
, 0xff,
925 contents
+ prev_insn_branch
->r_offset
+ 1);
926 irel
->r_offset
= prev_insn_branch
->r_offset
+ 1;
927 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
929 m68hc11_elf_relax_delete_bytes (abfd
, sec
,
930 irel
->r_offset
+ 1, 3);
932 prev_insn_branch
= 0;
936 /* Try to turn a 16 bit address into a 8 bit page0 address. */
937 else if (ELF32_R_TYPE (irel
->r_info
) == (int) R_M68HC11_16
938 && (value
& 0xff00) == 0)
941 unsigned short offset
;
942 struct m68hc11_direct_relax
*rinfo
;
944 prev_insn_branch
= 0;
945 offset
= bfd_get_16 (abfd
, contents
+ irel
->r_offset
);
947 if ((offset
& 0xff00) != 0)
955 unsigned long old_sec_size
= sec
->_cooked_size
;
957 /* Note that we've changed the relocation contents, etc. */
958 elf_section_data (sec
)->relocs
= internal_relocs
;
961 elf_section_data (sec
)->this_hdr
.contents
= contents
;
962 free_contents
= NULL
;
964 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
967 m68hc11_relax_group (abfd
, sec
, contents
, offset
,
968 prev_insn_group
->r_offset
,
970 irel
= prev_insn_group
;
972 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
974 if (sec
->_cooked_size
!= old_sec_size
)
979 /* Get the opcode. */
980 code
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
- 1);
981 rinfo
= find_relaxable_insn (code
);
988 /* Note that we've changed the relocation contents, etc. */
989 elf_section_data (sec
)->relocs
= internal_relocs
;
992 elf_section_data (sec
)->this_hdr
.contents
= contents
;
993 free_contents
= NULL
;
995 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
998 /* Fix the opcode. */
999 /* printf ("A relaxable case : 0x%02x (%s)\n",
1000 code, rinfo->name); */
1001 bfd_put_8 (abfd
, rinfo
->direct_code
,
1002 contents
+ irel
->r_offset
- 1);
1004 /* Delete one byte of data (upper byte of address). */
1005 m68hc11_elf_relax_delete_bytes (abfd
, sec
, irel
->r_offset
, 1);
1007 /* Fix the relocation's type. */
1008 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1011 /* That will change things, so, we should relax again. */
1014 else if (ELF32_R_TYPE (irel
->r_info
) == R_M68HC11_16
&& !is_far
)
1019 prev_insn_branch
= 0;
1020 code
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
- 1);
1021 if (code
== 0x7e || code
== 0xbd)
1023 offset
= value
- (irel
->r_offset
1024 + sec
->output_section
->vma
1025 + sec
->output_offset
+ 1);
1026 offset
+= bfd_get_16 (abfd
, contents
+ irel
->r_offset
);
1028 /* If the offset is still out of -128..+127 range,
1029 leave that far branch unchanged. */
1030 if ((offset
& 0xff80) == 0 || (offset
& 0xff80) == 0xff80)
1033 /* Note that we've changed the relocation contents, etc. */
1034 elf_section_data (sec
)->relocs
= internal_relocs
;
1037 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1038 free_contents
= NULL
;
1040 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
1041 free_extsyms
= NULL
;
1043 /* Shrink the branch. */
1044 code
= (code
== 0x7e) ? 0x20 : 0x8d;
1045 bfd_put_8 (abfd
, code
,
1046 contents
+ irel
->r_offset
- 1);
1047 bfd_put_8 (abfd
, 0xff,
1048 contents
+ irel
->r_offset
);
1049 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1051 m68hc11_elf_relax_delete_bytes (abfd
, sec
,
1052 irel
->r_offset
+ 1, 1);
1053 /* That will change things, so, we should relax again. */
1058 prev_insn_branch
= 0;
1059 prev_insn_group
= 0;
1062 if (free_relocs
!= NULL
)
1068 if (free_contents
!= NULL
)
1070 if (! link_info
->keep_memory
)
1071 free (free_contents
);
1074 /* Cache the section contents for elf_link_input_bfd. */
1075 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1077 free_contents
= NULL
;
1080 if (free_extsyms
!= NULL
)
1082 if (! link_info
->keep_memory
)
1083 free (free_extsyms
);
1086 /* Cache the symbols for elf_link_input_bfd. */
1087 symtab_hdr
->contents
= (unsigned char *) isymbuf
;
1089 free_extsyms
= NULL
;
1095 if (free_relocs
!= NULL
)
1097 if (free_contents
!= NULL
)
1098 free (free_contents
);
1099 if (free_extsyms
!= NULL
)
1100 free (free_extsyms
);
1104 /* Delete some bytes from a section while relaxing. */
1107 m68hc11_elf_relax_delete_bytes (bfd
*abfd
, asection
*sec
,
1108 bfd_vma addr
, int count
)
1110 Elf_Internal_Shdr
*symtab_hdr
;
1111 unsigned int sec_shndx
;
1113 Elf_Internal_Rela
*irel
, *irelend
;
1115 Elf_Internal_Sym
*isymbuf
, *isym
, *isymend
;
1116 struct elf_link_hash_entry
**sym_hashes
;
1117 struct elf_link_hash_entry
**end_hashes
;
1118 unsigned int symcount
;
1120 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1121 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1123 sec_shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1125 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1127 toaddr
= sec
->_cooked_size
;
1129 irel
= elf_section_data (sec
)->relocs
;
1130 irelend
= irel
+ sec
->reloc_count
;
1132 /* Actually delete the bytes. */
1133 memmove (contents
+ addr
, contents
+ addr
+ count
,
1134 (size_t) (toaddr
- addr
- count
));
1136 sec
->_cooked_size
-= count
;
1138 /* Adjust all the relocs. */
1139 for (irel
= elf_section_data (sec
)->relocs
; irel
< irelend
; irel
++)
1142 unsigned char offset
;
1143 unsigned short raddr
;
1144 unsigned long old_offset
;
1147 old_offset
= irel
->r_offset
;
1149 /* See if this reloc was for the bytes we have deleted, in which
1150 case we no longer care about it. Don't delete relocs which
1151 represent addresses, though. */
1152 if (ELF32_R_TYPE (irel
->r_info
) != R_M68HC11_RL_JUMP
1153 && irel
->r_offset
>= addr
&& irel
->r_offset
< addr
+ count
)
1154 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1157 if (ELF32_R_TYPE (irel
->r_info
) == R_M68HC11_NONE
)
1160 /* Get the new reloc address. */
1161 if ((irel
->r_offset
> addr
1162 && irel
->r_offset
< toaddr
))
1163 irel
->r_offset
-= count
;
1165 /* If this is a PC relative reloc, see if the range it covers
1166 includes the bytes we have deleted. */
1167 switch (ELF32_R_TYPE (irel
->r_info
))
1172 case R_M68HC11_RL_JUMP
:
1173 code
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
);
1176 /* jsr and jmp instruction are also marked with RL_JUMP
1177 relocs but no adjustment must be made. */
1188 /* Special case when we translate a brclr N,y into brclr *<addr>
1189 In this case, the 0x18 page2 prefix is removed.
1190 The reloc offset is not modified but the instruction
1191 size is reduced by 1. */
1192 if (old_offset
== addr
)
1212 offset
= bfd_get_8 (abfd
, contents
+ irel
->r_offset
+ branch_pos
);
1213 raddr
+= old_offset
;
1214 raddr
+= ((unsigned short) offset
| ((offset
& 0x80) ? 0xff00 : 0));
1215 if (irel
->r_offset
< addr
&& raddr
> addr
)
1218 bfd_put_8 (abfd
, offset
, contents
+ irel
->r_offset
+ branch_pos
);
1220 else if (irel
->r_offset
>= addr
&& raddr
<= addr
)
1223 bfd_put_8 (abfd
, offset
, contents
+ irel
->r_offset
+ branch_pos
);
1227 /*printf ("Not adjusted 0x%04x [0x%4x 0x%4x]\n", raddr,
1228 irel->r_offset, addr);*/
1235 /* Adjust the local symbols defined in this section. */
1236 isymend
= isymbuf
+ symtab_hdr
->sh_info
;
1237 for (isym
= isymbuf
; isym
< isymend
; isym
++)
1239 if (isym
->st_shndx
== sec_shndx
1240 && isym
->st_value
> addr
1241 && isym
->st_value
<= toaddr
)
1242 isym
->st_value
-= count
;
1245 /* Now adjust the global symbols defined in this section. */
1246 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)
1247 - symtab_hdr
->sh_info
);
1248 sym_hashes
= elf_sym_hashes (abfd
);
1249 end_hashes
= sym_hashes
+ symcount
;
1250 for (; sym_hashes
< end_hashes
; sym_hashes
++)
1252 struct elf_link_hash_entry
*sym_hash
= *sym_hashes
;
1253 if ((sym_hash
->root
.type
== bfd_link_hash_defined
1254 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
1255 && sym_hash
->root
.u
.def
.section
== sec
1256 && sym_hash
->root
.u
.def
.value
> addr
1257 && sym_hash
->root
.u
.def
.value
<= toaddr
)
1259 sym_hash
->root
.u
.def
.value
-= count
;
1264 /* Specific sections:
1265 - The .page0 is a data section that is mapped in [0x0000..0x00FF].
1266 Page0 accesses are faster on the M68HC11. Soft registers used by GCC-m6811
1267 are located in .page0.
1268 - The .vectors is the section that represents the interrupt
1270 static struct bfd_elf_special_section
const elf32_m68hc11_special_sections
[]=
1272 { ".eeprom", 7, 0, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
},
1273 { ".softregs", 9, 0, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
},
1274 { ".page0", 6, 0, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
},
1275 { ".vectors", 8, 0, SHT_PROGBITS
, SHF_ALLOC
},
1276 { NULL
, 0, 0, 0, 0 }
1279 #define ELF_ARCH bfd_arch_m68hc11
1280 #define ELF_MACHINE_CODE EM_68HC11
1281 #define ELF_MAXPAGESIZE 0x1000
1283 #define TARGET_BIG_SYM bfd_elf32_m68hc11_vec
1284 #define TARGET_BIG_NAME "elf32-m68hc11"
1286 #define elf_info_to_howto 0
1287 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
1288 #define bfd_elf32_bfd_relax_section m68hc11_elf_relax_section
1289 #define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
1290 #define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
1291 #define elf_backend_check_relocs elf32_m68hc11_check_relocs
1292 #define elf_backend_relocate_section elf32_m68hc11_relocate_section
1293 #define elf_backend_add_symbol_hook elf32_m68hc11_add_symbol_hook
1294 #define elf_backend_object_p 0
1295 #define elf_backend_final_write_processing 0
1296 #define elf_backend_can_gc_sections 1
1297 #define elf_backend_special_sections elf32_m68hc11_special_sections
1299 #define bfd_elf32_bfd_link_hash_table_create \
1300 m68hc11_elf_bfd_link_hash_table_create
1301 #define bfd_elf32_bfd_link_hash_table_free \
1302 m68hc11_elf_bfd_link_hash_table_free
1303 #define bfd_elf32_bfd_merge_private_bfd_data \
1304 _bfd_m68hc11_elf_merge_private_bfd_data
1305 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc11_elf_set_private_flags
1306 #define bfd_elf32_bfd_print_private_bfd_data \
1307 _bfd_m68hc11_elf_print_private_bfd_data
1309 #include "elf32-target.h"