1 /* Motorola 68HC12-specific support for 32-bit ELF
2 Copyright 1999, 2000, 2002 Free Software Foundation, Inc.
3 Contributed by Stephane Carrez (stcarrez@nerim.fr)
4 (Heavily copied from the D10V port by Martin Hunt (hunt@cygnus.com))
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. */
26 #include "elf/m68hc11.h"
27 #include "opcode/m68hc11.h"
29 static reloc_howto_type
*bfd_elf32_bfd_reloc_type_lookup
30 PARAMS ((bfd
*, bfd_reloc_code_real_type
));
31 static void m68hc11_info_to_howto_rel
32 PARAMS ((bfd
*, arelent
*, Elf_Internal_Rela
*));
34 static bfd_reloc_status_type m68hc11_elf_ignore_reloc
35 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
36 static bfd_reloc_status_type m68hc12_elf_special_reloc
37 PARAMS ((bfd
*, arelent
*, asymbol
*, PTR
, asection
*, bfd
*, char **));
38 static int m68hc12_addr_is_banked
PARAMS ((bfd_vma
));
39 static bfd_vma m68hc12_phys_addr
PARAMS ((bfd_vma
));
40 static bfd_vma m68hc12_phys_page
PARAMS ((bfd_vma
));
42 /* GC mark and sweep. */
43 static asection
*elf32_m68hc11_gc_mark_hook
44 PARAMS ((asection
*, struct bfd_link_info
*, Elf_Internal_Rela
*,
45 struct elf_link_hash_entry
*, Elf_Internal_Sym
*));
46 static bfd_boolean elf32_m68hc11_gc_sweep_hook
47 PARAMS ((bfd
*, struct bfd_link_info
*, asection
*,
48 const Elf_Internal_Rela
*));
50 static bfd_boolean m68hc12_elf_set_mach_from_flags
PARAMS ((bfd
*));
52 bfd_boolean _bfd_m68hc12_elf_merge_private_bfd_data
PARAMS ((bfd
*, bfd
*));
53 bfd_boolean _bfd_m68hc12_elf_set_private_flags
PARAMS ((bfd
*, flagword
));
54 bfd_boolean _bfd_m68hc12_elf_print_private_bfd_data
PARAMS ((bfd
*, PTR
));
58 /* Use REL instead of RELA to save space */
61 /* The Motorola 68HC11 microcontroler only addresses 64Kb.
62 We must handle 8 and 16-bit relocations. The 32-bit relocation
63 is defined but not used except by gas when -gstabs is used (which
66 The 68HC12 microcontroler has a memory bank switching system
67 with a 16Kb window in the 64Kb address space. The extended memory
68 is mapped in the 16Kb window (at 0x8000). The page register controls
69 which 16Kb bank is mapped. The call/rtc instructions take care of
70 bank switching in function calls/returns.
72 For GNU Binutils to work, we consider there is a physical memory
73 at 0..0x0ffff and a kind of virtual memory above that. Symbols
74 in virtual memory have their addresses treated in a special way
75 when disassembling and when linking.
77 For the linker to work properly, we must always relocate the virtual
78 memory as if it is mapped at 0x8000. When a 16-bit relocation is
79 made in the virtual memory, we check that it does not cross the
80 memory bank where it is used. This would involve a page change
81 which would be wrong. The 24-bit relocation is for that and it
82 treats the address as a physical address + page number.
88 +---------------+ 0x1010000
93 +---------------+ 0x100C000
98 +---------------+ 0x1008000
100 | | call _foo | Page 1
102 | +---------------+ 0x1004000
104 Address Space | | | Page 0
106 +-----------+ 0x00FFFF | +---------------+ 0x1000000
110 +-----------+ 0x00BFFF -+---/
115 +-----------+ 0x008000 -+
124 The 'call _foo' must be relocated with page 3 and 16-bit address
127 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
128 static reloc_howto_type elf_m68hc11_howto_table
[] = {
129 /* This reloc does nothing. */
130 HOWTO (R_M68HC11_NONE
, /* type */
132 2, /* size (0 = byte, 1 = short, 2 = long) */
134 FALSE
, /* pc_relative */
136 complain_overflow_dont
,/* complain_on_overflow */
137 bfd_elf_generic_reloc
, /* special_function */
138 "R_M68HC12_NONE", /* name */
139 FALSE
, /* partial_inplace */
142 FALSE
), /* pcrel_offset */
144 /* A 8 bit absolute relocation */
145 HOWTO (R_M68HC11_8
, /* type */
147 0, /* size (0 = byte, 1 = short, 2 = long) */
149 FALSE
, /* pc_relative */
151 complain_overflow_bitfield
, /* complain_on_overflow */
152 bfd_elf_generic_reloc
, /* special_function */
153 "R_M68HC12_8", /* name */
154 FALSE
, /* partial_inplace */
155 0x00ff, /* src_mask */
156 0x00ff, /* dst_mask */
157 FALSE
), /* pcrel_offset */
159 /* A 8 bit absolute relocation (upper address) */
160 HOWTO (R_M68HC11_HI8
, /* type */
162 0, /* size (0 = byte, 1 = short, 2 = long) */
164 FALSE
, /* pc_relative */
166 complain_overflow_bitfield
, /* complain_on_overflow */
167 bfd_elf_generic_reloc
, /* special_function */
168 "R_M68HC12_HI8", /* name */
169 FALSE
, /* partial_inplace */
170 0x00ff, /* src_mask */
171 0x00ff, /* dst_mask */
172 FALSE
), /* pcrel_offset */
174 /* A 8 bit absolute relocation (upper address) */
175 HOWTO (R_M68HC11_LO8
, /* type */
177 0, /* size (0 = byte, 1 = short, 2 = long) */
179 FALSE
, /* pc_relative */
181 complain_overflow_dont
, /* complain_on_overflow */
182 bfd_elf_generic_reloc
, /* special_function */
183 "R_M68HC12_LO8", /* name */
184 FALSE
, /* partial_inplace */
185 0x00ff, /* src_mask */
186 0x00ff, /* dst_mask */
187 FALSE
), /* pcrel_offset */
189 /* A 8 bit PC-rel relocation */
190 HOWTO (R_M68HC11_PCREL_8
, /* type */
192 0, /* size (0 = byte, 1 = short, 2 = long) */
194 TRUE
, /* pc_relative */
196 complain_overflow_bitfield
, /* complain_on_overflow */
197 bfd_elf_generic_reloc
, /* special_function */
198 "R_M68HC12_PCREL_8", /* name */
199 FALSE
, /* partial_inplace */
200 0x00ff, /* src_mask */
201 0x00ff, /* dst_mask */
202 FALSE
), /* pcrel_offset */
204 /* A 16 bit absolute relocation */
205 HOWTO (R_M68HC11_16
, /* type */
207 1, /* size (0 = byte, 1 = short, 2 = long) */
209 FALSE
, /* pc_relative */
211 complain_overflow_dont
/*bitfield */ , /* complain_on_overflow */
212 m68hc12_elf_special_reloc
, /* special_function */
213 "R_M68HC12_16", /* name */
214 FALSE
, /* partial_inplace */
215 0xffff, /* src_mask */
216 0xffff, /* dst_mask */
217 FALSE
), /* pcrel_offset */
219 /* A 32 bit absolute relocation. This one is never used for the
220 code relocation. It's used by gas for -gstabs generation. */
221 HOWTO (R_M68HC11_32
, /* type */
223 2, /* size (0 = byte, 1 = short, 2 = long) */
225 FALSE
, /* pc_relative */
227 complain_overflow_bitfield
, /* complain_on_overflow */
228 bfd_elf_generic_reloc
, /* special_function */
229 "R_M68HC12_32", /* name */
230 FALSE
, /* partial_inplace */
231 0xffffffff, /* src_mask */
232 0xffffffff, /* dst_mask */
233 FALSE
), /* pcrel_offset */
235 /* A 3 bit absolute relocation */
236 HOWTO (R_M68HC11_3B
, /* type */
238 0, /* size (0 = byte, 1 = short, 2 = long) */
240 FALSE
, /* pc_relative */
242 complain_overflow_bitfield
, /* complain_on_overflow */
243 bfd_elf_generic_reloc
, /* special_function */
244 "R_M68HC12_4B", /* name */
245 FALSE
, /* partial_inplace */
246 0x003, /* src_mask */
247 0x003, /* dst_mask */
248 FALSE
), /* pcrel_offset */
250 /* A 16 bit PC-rel relocation */
251 HOWTO (R_M68HC11_PCREL_16
, /* type */
253 1, /* size (0 = byte, 1 = short, 2 = long) */
255 TRUE
, /* pc_relative */
257 complain_overflow_dont
, /* complain_on_overflow */
258 bfd_elf_generic_reloc
, /* special_function */
259 "R_M68HC12_PCREL_16", /* name */
260 FALSE
, /* partial_inplace */
261 0xffff, /* src_mask */
262 0xffff, /* dst_mask */
263 FALSE
), /* pcrel_offset */
265 /* GNU extension to record C++ vtable hierarchy */
266 HOWTO (R_M68HC11_GNU_VTINHERIT
, /* type */
268 1, /* size (0 = byte, 1 = short, 2 = long) */
270 FALSE
, /* pc_relative */
272 complain_overflow_dont
, /* complain_on_overflow */
273 NULL
, /* special_function */
274 "R_M68HC11_GNU_VTINHERIT", /* name */
275 FALSE
, /* partial_inplace */
278 FALSE
), /* pcrel_offset */
280 /* GNU extension to record C++ vtable member usage */
281 HOWTO (R_M68HC11_GNU_VTENTRY
, /* type */
283 1, /* size (0 = byte, 1 = short, 2 = long) */
285 FALSE
, /* pc_relative */
287 complain_overflow_dont
, /* complain_on_overflow */
288 _bfd_elf_rel_vtable_reloc_fn
, /* special_function */
289 "R_M68HC11_GNU_VTENTRY", /* name */
290 FALSE
, /* partial_inplace */
293 FALSE
), /* pcrel_offset */
295 /* A 24 bit relocation */
296 HOWTO (R_M68HC11_24
, /* type */
298 1, /* size (0 = byte, 1 = short, 2 = long) */
300 FALSE
, /* pc_relative */
302 complain_overflow_dont
, /* complain_on_overflow */
303 m68hc12_elf_special_reloc
, /* special_function */
304 "R_M68HC12_24", /* name */
305 FALSE
, /* partial_inplace */
306 0xffff, /* src_mask */
307 0xffff, /* dst_mask */
308 FALSE
), /* pcrel_offset */
310 /* A 16-bit low relocation */
311 HOWTO (R_M68HC11_LO16
, /* type */
313 1, /* size (0 = byte, 1 = short, 2 = long) */
315 FALSE
, /* pc_relative */
317 complain_overflow_dont
, /* complain_on_overflow */
318 m68hc12_elf_special_reloc
,/* special_function */
319 "R_M68HC12_LO16", /* name */
320 FALSE
, /* partial_inplace */
321 0xffff, /* src_mask */
322 0xffff, /* dst_mask */
323 FALSE
), /* pcrel_offset */
325 /* A page relocation */
326 HOWTO (R_M68HC11_PAGE
, /* type */
328 0, /* size (0 = byte, 1 = short, 2 = long) */
330 FALSE
, /* pc_relative */
332 complain_overflow_dont
, /* complain_on_overflow */
333 m68hc12_elf_special_reloc
,/* special_function */
334 "R_M68HC12_PAGE", /* name */
335 FALSE
, /* partial_inplace */
336 0x00ff, /* src_mask */
337 0x00ff, /* dst_mask */
338 FALSE
), /* pcrel_offset */
347 /* Mark beginning of a jump instruction (any form). */
348 HOWTO (R_M68HC11_RL_JUMP
, /* type */
350 1, /* size (0 = byte, 1 = short, 2 = long) */
352 FALSE
, /* pc_relative */
354 complain_overflow_dont
, /* complain_on_overflow */
355 m68hc11_elf_ignore_reloc
, /* special_function */
356 "R_M68HC12_RL_JUMP", /* name */
357 TRUE
, /* partial_inplace */
360 TRUE
), /* pcrel_offset */
362 /* Mark beginning of Gcc relaxation group instruction. */
363 HOWTO (R_M68HC11_RL_GROUP
, /* type */
365 1, /* size (0 = byte, 1 = short, 2 = long) */
367 FALSE
, /* pc_relative */
369 complain_overflow_dont
, /* complain_on_overflow */
370 m68hc11_elf_ignore_reloc
, /* special_function */
371 "R_M68HC12_RL_GROUP", /* name */
372 TRUE
, /* partial_inplace */
375 TRUE
), /* pcrel_offset */
378 /* Map BFD reloc types to M68HC11 ELF reloc types. */
380 struct m68hc11_reloc_map
382 bfd_reloc_code_real_type bfd_reloc_val
;
383 unsigned char elf_reloc_val
;
386 static const struct m68hc11_reloc_map m68hc11_reloc_map
[] = {
387 {BFD_RELOC_NONE
, R_M68HC11_NONE
,},
388 {BFD_RELOC_8
, R_M68HC11_8
},
389 {BFD_RELOC_M68HC11_HI8
, R_M68HC11_HI8
},
390 {BFD_RELOC_M68HC11_LO8
, R_M68HC11_LO8
},
391 {BFD_RELOC_8_PCREL
, R_M68HC11_PCREL_8
},
392 {BFD_RELOC_16_PCREL
, R_M68HC11_PCREL_16
},
393 {BFD_RELOC_16
, R_M68HC11_16
},
394 {BFD_RELOC_32
, R_M68HC11_32
},
395 {BFD_RELOC_M68HC11_3B
, R_M68HC11_3B
},
397 {BFD_RELOC_VTABLE_INHERIT
, R_M68HC11_GNU_VTINHERIT
},
398 {BFD_RELOC_VTABLE_ENTRY
, R_M68HC11_GNU_VTENTRY
},
400 {BFD_RELOC_M68HC11_LO16
, R_M68HC11_LO16
},
401 {BFD_RELOC_M68HC11_PAGE
, R_M68HC11_PAGE
},
402 {BFD_RELOC_M68HC11_24
, R_M68HC11_24
},
404 {BFD_RELOC_M68HC11_RL_JUMP
, R_M68HC11_RL_JUMP
},
405 {BFD_RELOC_M68HC11_RL_GROUP
, R_M68HC11_RL_GROUP
},
408 static reloc_howto_type
*
409 bfd_elf32_bfd_reloc_type_lookup (abfd
, code
)
410 bfd
*abfd ATTRIBUTE_UNUSED
;
411 bfd_reloc_code_real_type code
;
416 i
< sizeof (m68hc11_reloc_map
) / sizeof (struct m68hc11_reloc_map
);
419 if (m68hc11_reloc_map
[i
].bfd_reloc_val
== code
)
420 return &elf_m68hc11_howto_table
[m68hc11_reloc_map
[i
].elf_reloc_val
];
426 /* This function is used for relocs which are only used for relaxing,
427 which the linker should otherwise ignore. */
429 static bfd_reloc_status_type
430 m68hc11_elf_ignore_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
431 output_bfd
, error_message
)
432 bfd
*abfd ATTRIBUTE_UNUSED
;
433 arelent
*reloc_entry
;
434 asymbol
*symbol ATTRIBUTE_UNUSED
;
435 PTR data ATTRIBUTE_UNUSED
;
436 asection
*input_section
;
438 char **error_message ATTRIBUTE_UNUSED
;
440 if (output_bfd
!= NULL
)
441 reloc_entry
->address
+= input_section
->output_offset
;
446 m68hc12_addr_is_banked (addr
)
449 return (addr
>= M68HC12_BANK_VIRT
) ? 1 : 0;
452 /* Return the physical address seen by the processor, taking
453 into account banked memory. */
455 m68hc12_phys_addr (addr
)
458 if (addr
< M68HC12_BANK_VIRT
)
461 /* Map the address to the memory bank. */
462 addr
-= M68HC12_BANK_VIRT
;
463 addr
&= M68HC12_BANK_MASK
;
464 addr
+= M68HC12_BANK_BASE
;
468 /* Return the page number corresponding to an address in banked memory. */
470 m68hc12_phys_page (addr
)
473 if (addr
< M68HC12_BANK_VIRT
)
476 /* Map the address to the memory bank. */
477 addr
-= M68HC12_BANK_VIRT
;
478 addr
>>= M68HC12_BANK_SHIFT
;
479 addr
&= M68HC12_BANK_PAGE_MASK
;
483 static bfd_reloc_status_type
484 m68hc12_elf_special_reloc (abfd
, reloc_entry
, symbol
, data
, input_section
,
485 output_bfd
, error_message
)
487 arelent
*reloc_entry
;
490 asection
*input_section
;
492 char **error_message ATTRIBUTE_UNUSED
;
494 reloc_howto_type
*howto
;
501 if (output_bfd
!= (bfd
*) NULL
502 && (symbol
->flags
& BSF_SECTION_SYM
) == 0
503 && (! reloc_entry
->howto
->partial_inplace
504 || reloc_entry
->addend
== 0))
506 reloc_entry
->address
+= input_section
->output_offset
;
510 if (output_bfd
!= NULL
)
511 return bfd_reloc_continue
;
513 if (reloc_entry
->address
> input_section
->_cooked_size
)
514 return bfd_reloc_outofrange
;
516 /* Compute relocation. */
517 relocation
= (symbol
->value
518 + symbol
->section
->output_section
->vma
519 + symbol
->section
->output_offset
);
520 relocation
+= reloc_entry
->addend
;
521 relocation
+= bfd_get_16 (abfd
, (bfd_byte
*) data
+ reloc_entry
->address
);
523 /* Do the memory bank mapping. */
524 phys_addr
= m68hc12_phys_addr (relocation
);
525 phys_page
= m68hc12_phys_page (relocation
);
527 howto
= reloc_entry
->howto
;
528 if (howto
->complain_on_overflow
!= complain_overflow_dont
529 && (phys_addr
& (((bfd_vma
) -1) << 16)))
530 return bfd_reloc_overflow
;
535 /* Get virtual address of instruction having the relocation. */
536 insn_addr
= input_section
->output_section
->vma
537 + input_section
->output_offset
538 + reloc_entry
->address
;
540 insn_page
= m68hc12_phys_page (insn_addr
);
542 if (m68hc12_addr_is_banked (relocation
)
543 && m68hc12_addr_is_banked (insn_addr
)
544 && phys_page
!= insn_page
)
546 *error_message
= _("address is not in the same bank");
547 return bfd_reloc_dangerous
;
549 if (m68hc12_addr_is_banked (relocation
)
550 && !m68hc12_addr_is_banked (insn_addr
))
552 *error_message
= _("reference to a banked address in "
553 "the normal address space");
554 return bfd_reloc_dangerous
;
558 bfd_put_16 (abfd
, phys_addr
, (bfd_byte
*) data
+ reloc_entry
->address
);
562 bfd_put_16 (abfd
, phys_addr
, (bfd_byte
*) data
+ reloc_entry
->address
);
563 bfd_put_8 (abfd
, phys_page
, (bfd_byte
*) data
+ reloc_entry
->address
+ 2);
567 bfd_put_8 (abfd
, phys_page
, (bfd_byte
*) data
+ reloc_entry
->address
);
578 /* Set the howto pointer for an M68HC11 ELF reloc. */
581 m68hc11_info_to_howto_rel (abfd
, cache_ptr
, dst
)
582 bfd
*abfd ATTRIBUTE_UNUSED
;
584 Elf_Internal_Rela
*dst
;
588 r_type
= ELF32_R_TYPE (dst
->r_info
);
589 BFD_ASSERT (r_type
< (unsigned int) R_M68HC11_max
);
590 cache_ptr
->howto
= &elf_m68hc11_howto_table
[r_type
];
594 elf32_m68hc11_gc_mark_hook (sec
, info
, rel
, h
, sym
)
596 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
597 Elf_Internal_Rela
*rel
;
598 struct elf_link_hash_entry
*h
;
599 Elf_Internal_Sym
*sym
;
603 switch (ELF32_R_TYPE (rel
->r_info
))
606 switch (h
->root
.type
)
608 case bfd_link_hash_defined
:
609 case bfd_link_hash_defweak
:
610 return h
->root
.u
.def
.section
;
612 case bfd_link_hash_common
:
613 return h
->root
.u
.c
.p
->section
;
621 return bfd_section_from_elf_index (sec
->owner
, sym
->st_shndx
);
627 elf32_m68hc11_gc_sweep_hook (abfd
, info
, sec
, relocs
)
628 bfd
*abfd ATTRIBUTE_UNUSED
;
629 struct bfd_link_info
*info ATTRIBUTE_UNUSED
;
630 asection
*sec ATTRIBUTE_UNUSED
;
631 const Elf_Internal_Rela
*relocs ATTRIBUTE_UNUSED
;
633 /* We don't use got and plt entries for 68hc11/68hc12. */
639 m68hc12_elf_set_mach_from_flags (abfd
)
642 flagword flags
= elf_elfheader (abfd
)->e_flags
;
644 switch (flags
& EF_M68HC11_MACH_MASK
)
646 case EF_M68HC12_MACH
:
647 bfd_default_set_arch_mach (abfd
, bfd_arch_m68hc12
, bfd_mach_m6812
);
649 case EF_M68HCS12_MACH
:
650 bfd_default_set_arch_mach (abfd
, bfd_arch_m68hc12
, bfd_mach_m6812s
);
652 case EF_M68HC11_GENERIC
:
653 bfd_default_set_arch_mach (abfd
, bfd_arch_m68hc12
,
654 bfd_mach_m6812_default
);
662 /* Set and control ELF flags in ELF header. */
665 _bfd_m68hc12_elf_set_private_flags (abfd
, flags
)
669 BFD_ASSERT (!elf_flags_init (abfd
)
670 || elf_elfheader (abfd
)->e_flags
== flags
);
672 elf_elfheader (abfd
)->e_flags
= flags
;
673 elf_flags_init (abfd
) = TRUE
;
674 return m68hc12_elf_set_mach_from_flags (abfd
);
677 /* Merge backend specific data from an object file to the output
678 object file when linking. */
681 _bfd_m68hc12_elf_merge_private_bfd_data (ibfd
, obfd
)
687 bfd_boolean ok
= TRUE
;
689 /* Check if we have the same endianess */
690 if (!_bfd_generic_verify_endian_match (ibfd
, obfd
))
693 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
694 || bfd_get_flavour (obfd
) != bfd_target_elf_flavour
)
697 new_flags
= elf_elfheader (ibfd
)->e_flags
;
698 old_flags
= elf_elfheader (obfd
)->e_flags
;
700 if (! elf_flags_init (obfd
))
702 elf_flags_init (obfd
) = TRUE
;
703 elf_elfheader (obfd
)->e_flags
= new_flags
;
704 elf_elfheader (obfd
)->e_ident
[EI_CLASS
]
705 = elf_elfheader (ibfd
)->e_ident
[EI_CLASS
];
707 if (bfd_get_arch (obfd
) == bfd_get_arch (ibfd
)
708 && bfd_get_arch_info (obfd
)->the_default
)
710 if (! bfd_set_arch_mach (obfd
, bfd_get_arch (ibfd
),
711 bfd_get_mach (ibfd
)))
718 /* Check ABI compatibility. */
719 if ((new_flags
& E_M68HC11_I32
) != (old_flags
& E_M68HC11_I32
))
721 (*_bfd_error_handler
)
722 (_("%s: linking files compiled for 16-bit integers (-mshort) "
723 "and others for 32-bit integers"),
724 bfd_archive_filename (ibfd
));
727 if ((new_flags
& E_M68HC11_F64
) != (old_flags
& E_M68HC11_F64
))
729 (*_bfd_error_handler
)
730 (_("%s: linking files compiled for 32-bit double (-fshort-double) "
731 "and others for 64-bit double"),
732 bfd_archive_filename (ibfd
));
736 /* Processor compatibility. */
737 if (!EF_M68HC11_CAN_MERGE_MACH (new_flags
, old_flags
))
739 (*_bfd_error_handler
)
740 (_("%s: linking files compiled for HCS12 with "
741 "others compiled for HC12"),
742 bfd_archive_filename (ibfd
));
745 new_flags
= ((new_flags
& ~EF_M68HC11_MACH_MASK
)
746 | (EF_M68HC11_MERGE_MACH (new_flags
, old_flags
)));
748 elf_elfheader (obfd
)->e_flags
= new_flags
;
750 /* Warn about any other mismatches */
751 new_flags
&= ~(EF_M68HC11_ABI
| EF_M68HC11_MACH_MASK
);
752 old_flags
&= ~(EF_M68HC11_ABI
| EF_M68HC11_MACH_MASK
);
753 if (new_flags
!= old_flags
)
755 (*_bfd_error_handler
)
756 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
757 bfd_archive_filename (ibfd
), (unsigned long) new_flags
,
758 (unsigned long) old_flags
);
764 bfd_set_error (bfd_error_bad_value
);
772 _bfd_m68hc12_elf_print_private_bfd_data (abfd
, ptr
)
776 FILE *file
= (FILE *) ptr
;
778 BFD_ASSERT (abfd
!= NULL
&& ptr
!= NULL
);
780 /* Print normal ELF private data. */
781 _bfd_elf_print_private_bfd_data (abfd
, ptr
);
783 /* xgettext:c-format */
784 fprintf (file
, _("private flags = %lx:"), elf_elfheader (abfd
)->e_flags
);
786 if (elf_elfheader (abfd
)->e_flags
& E_M68HC11_I32
)
787 fprintf (file
, _("[abi=32-bit int,"));
789 fprintf (file
, _("[abi=16-bit int,"));
791 if (elf_elfheader (abfd
)->e_flags
& E_M68HC11_F64
)
792 fprintf (file
, _(" 64-bit double,"));
794 fprintf (file
, _(" 32-bit double,"));
796 if (elf_elfheader (abfd
)->e_flags
& EF_M68HCS12_MACH
)
797 fprintf (file
, _(" cpu=HCS12]"));
799 fprintf (file
, _(" cpu=HC12]"));
805 #define ELF_ARCH bfd_arch_m68hc12
806 #define ELF_MACHINE_CODE EM_68HC12
807 #define ELF_MAXPAGESIZE 0x1000
809 #define TARGET_BIG_SYM bfd_elf32_m68hc12_vec
810 #define TARGET_BIG_NAME "elf32-m68hc12"
812 #define elf_info_to_howto 0
813 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
814 #define elf_backend_gc_mark_hook elf32_m68hc11_gc_mark_hook
815 #define elf_backend_gc_sweep_hook elf32_m68hc11_gc_sweep_hook
816 #define elf_backend_object_p m68hc12_elf_set_mach_from_flags
817 #define elf_backend_final_write_processing 0
818 /* Disabled as this backend uses the generic linker. */
819 #define elf_backend_can_gc_sections 0
821 #define bfd_elf32_bfd_merge_private_bfd_data \
822 _bfd_m68hc12_elf_merge_private_bfd_data
823 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc12_elf_set_private_flags
824 #define bfd_elf32_bfd_print_private_bfd_data \
825 _bfd_m68hc12_elf_print_private_bfd_data
827 #include "elf32-target.h"