]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf32-m68hc12.c
* elf32-m68hc11.c (_bfd_m68hc11_elf_print_private_bfd_data): New.
[thirdparty/binutils-gdb.git] / bfd / elf32-m68hc12.c
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))
5
6 This file is part of BFD, the Binary File Descriptor library.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 #include "bfd.h"
23 #include "sysdep.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/m68hc11.h"
27 #include "opcode/m68hc11.h"
28
29 static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
30 PARAMS ((bfd * abfd, bfd_reloc_code_real_type code));
31 static void m68hc11_info_to_howto_rel
32 PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
33
34 static bfd_reloc_status_type m68hc11_elf_ignore_reloc
35 PARAMS ((bfd *abfd, arelent *reloc_entry,
36 asymbol *symbol, PTR data, asection *input_section,
37 bfd *output_bfd, char **error_message));
38 static bfd_reloc_status_type m68hc12_elf_special_reloc
39 PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
40 static int m68hc12_addr_is_banked PARAMS ((bfd_vma));
41 static bfd_vma m68hc12_phys_addr PARAMS ((bfd_vma));
42 static bfd_vma m68hc12_phys_page PARAMS ((bfd_vma));
43
44 boolean _bfd_m68hc12_elf_merge_private_bfd_data PARAMS ((bfd*, bfd*));
45 boolean _bfd_m68hc12_elf_set_private_flags PARAMS ((bfd*, flagword));
46 boolean _bfd_m68hc12_elf_print_private_bfd_data PARAMS ((bfd*, PTR));
47
48
49
50 /* Use REL instead of RELA to save space */
51 #define USE_REL
52
53 /* The Motorola 68HC11 microcontroler only addresses 64Kb.
54 We must handle 8 and 16-bit relocations. The 32-bit relocation
55 is defined but not used except by gas when -gstabs is used (which
56 is wrong).
57
58 The 68HC12 microcontroler has a memory bank switching system
59 with a 16Kb window in the 64Kb address space. The extended memory
60 is mapped in the 16Kb window (at 0x8000). The page register controls
61 which 16Kb bank is mapped. The call/rtc instructions take care of
62 bank switching in function calls/returns.
63
64 For GNU Binutils to work, we consider there is a physical memory
65 at 0..0x0ffff and a kind of virtual memory above that. Symbols
66 in virtual memory have their addresses treated in a special way
67 when disassembling and when linking.
68
69 For the linker to work properly, we must always relocate the virtual
70 memory as if it is mapped at 0x8000. When a 16-bit relocation is
71 made in the virtual memory, we check that it does not cross the
72 memory bank where it is used. This would involve a page change
73 which would be wrong. The 24-bit relocation is for that and it
74 treats the address as a physical address + page number.
75
76
77 Banked
78 Address Space
79 | | Page n
80 +---------------+ 0x1010000
81 | |
82 | jsr _foo |
83 | .. | Page 3
84 | _foo: |
85 +---------------+ 0x100C000
86 | |
87 | call _bar |
88 | .. | Page 2
89 | _bar: |
90 +---------------+ 0x1008000
91 /------>| |
92 | | call _foo | Page 1
93 | | |
94 | +---------------+ 0x1004000
95 Physical | | |
96 Address Space | | | Page 0
97 | | |
98 +-----------+ 0x00FFFF | +---------------+ 0x1000000
99 | | |
100 | call _foo | |
101 | | |
102 +-----------+ 0x00BFFF -+---/
103 | | |
104 | | |
105 | | 16K |
106 | | |
107 +-----------+ 0x008000 -+
108 | |
109 | |
110 = =
111 | |
112 | |
113 +-----------+ 0000
114
115
116 The 'call _foo' must be relocated with page 3 and 16-bit address
117 mapped at 0x8000.
118
119 The 3-bit and 16-bit PC rel relocation is only used by 68HC12. */
120 static reloc_howto_type elf_m68hc11_howto_table[] = {
121 /* This reloc does nothing. */
122 HOWTO (R_M68HC11_NONE, /* type */
123 0, /* rightshift */
124 2, /* size (0 = byte, 1 = short, 2 = long) */
125 32, /* bitsize */
126 false, /* pc_relative */
127 0, /* bitpos */
128 complain_overflow_dont,/* complain_on_overflow */
129 bfd_elf_generic_reloc, /* special_function */
130 "R_M68HC12_NONE", /* name */
131 false, /* partial_inplace */
132 0, /* src_mask */
133 0, /* dst_mask */
134 false), /* pcrel_offset */
135
136 /* A 8 bit absolute relocation */
137 HOWTO (R_M68HC11_8, /* type */
138 0, /* rightshift */
139 0, /* size (0 = byte, 1 = short, 2 = long) */
140 8, /* bitsize */
141 false, /* pc_relative */
142 0, /* bitpos */
143 complain_overflow_bitfield, /* complain_on_overflow */
144 bfd_elf_generic_reloc, /* special_function */
145 "R_M68HC12_8", /* name */
146 false, /* partial_inplace */
147 0x00ff, /* src_mask */
148 0x00ff, /* dst_mask */
149 false), /* pcrel_offset */
150
151 /* A 8 bit absolute relocation (upper address) */
152 HOWTO (R_M68HC11_HI8, /* type */
153 8, /* rightshift */
154 0, /* size (0 = byte, 1 = short, 2 = long) */
155 8, /* bitsize */
156 false, /* pc_relative */
157 0, /* bitpos */
158 complain_overflow_bitfield, /* complain_on_overflow */
159 bfd_elf_generic_reloc, /* special_function */
160 "R_M68HC12_HI8", /* name */
161 false, /* partial_inplace */
162 0x00ff, /* src_mask */
163 0x00ff, /* dst_mask */
164 false), /* pcrel_offset */
165
166 /* A 8 bit absolute relocation (upper address) */
167 HOWTO (R_M68HC11_LO8, /* type */
168 0, /* rightshift */
169 0, /* size (0 = byte, 1 = short, 2 = long) */
170 8, /* bitsize */
171 false, /* pc_relative */
172 0, /* bitpos */
173 complain_overflow_dont, /* complain_on_overflow */
174 bfd_elf_generic_reloc, /* special_function */
175 "R_M68HC12_LO8", /* name */
176 false, /* partial_inplace */
177 0x00ff, /* src_mask */
178 0x00ff, /* dst_mask */
179 false), /* pcrel_offset */
180
181 /* A 8 bit PC-rel relocation */
182 HOWTO (R_M68HC11_PCREL_8, /* type */
183 0, /* rightshift */
184 0, /* size (0 = byte, 1 = short, 2 = long) */
185 8, /* bitsize */
186 true, /* pc_relative */
187 0, /* bitpos */
188 complain_overflow_bitfield, /* complain_on_overflow */
189 bfd_elf_generic_reloc, /* special_function */
190 "R_M68HC12_PCREL_8", /* name */
191 false, /* partial_inplace */
192 0x00ff, /* src_mask */
193 0x00ff, /* dst_mask */
194 false), /* pcrel_offset */
195
196 /* A 16 bit absolute relocation */
197 HOWTO (R_M68HC11_16, /* type */
198 0, /* rightshift */
199 1, /* size (0 = byte, 1 = short, 2 = long) */
200 16, /* bitsize */
201 false, /* pc_relative */
202 0, /* bitpos */
203 complain_overflow_dont /*bitfield */ , /* complain_on_overflow */
204 m68hc12_elf_special_reloc, /* special_function */
205 "R_M68HC12_16", /* name */
206 false, /* partial_inplace */
207 0xffff, /* src_mask */
208 0xffff, /* dst_mask */
209 false), /* pcrel_offset */
210
211 /* A 32 bit absolute relocation. This one is never used for the
212 code relocation. It's used by gas for -gstabs generation. */
213 HOWTO (R_M68HC11_32, /* type */
214 0, /* rightshift */
215 2, /* size (0 = byte, 1 = short, 2 = long) */
216 32, /* bitsize */
217 false, /* pc_relative */
218 0, /* bitpos */
219 complain_overflow_bitfield, /* complain_on_overflow */
220 bfd_elf_generic_reloc, /* special_function */
221 "R_M68HC12_32", /* name */
222 false, /* partial_inplace */
223 0xffffffff, /* src_mask */
224 0xffffffff, /* dst_mask */
225 false), /* pcrel_offset */
226
227 /* A 3 bit absolute relocation */
228 HOWTO (R_M68HC11_3B, /* type */
229 0, /* rightshift */
230 0, /* size (0 = byte, 1 = short, 2 = long) */
231 3, /* bitsize */
232 false, /* pc_relative */
233 0, /* bitpos */
234 complain_overflow_bitfield, /* complain_on_overflow */
235 bfd_elf_generic_reloc, /* special_function */
236 "R_M68HC12_4B", /* name */
237 false, /* partial_inplace */
238 0x003, /* src_mask */
239 0x003, /* dst_mask */
240 false), /* pcrel_offset */
241
242 /* A 16 bit PC-rel relocation */
243 HOWTO (R_M68HC11_PCREL_16, /* type */
244 0, /* rightshift */
245 1, /* size (0 = byte, 1 = short, 2 = long) */
246 16, /* bitsize */
247 true, /* pc_relative */
248 0, /* bitpos */
249 complain_overflow_dont, /* complain_on_overflow */
250 bfd_elf_generic_reloc, /* special_function */
251 "R_M68HC12_PCREL_16", /* name */
252 false, /* partial_inplace */
253 0xffff, /* src_mask */
254 0xffff, /* dst_mask */
255 false), /* pcrel_offset */
256
257 /* GNU extension to record C++ vtable hierarchy */
258 HOWTO (R_M68HC11_GNU_VTINHERIT, /* type */
259 0, /* rightshift */
260 1, /* size (0 = byte, 1 = short, 2 = long) */
261 0, /* bitsize */
262 false, /* pc_relative */
263 0, /* bitpos */
264 complain_overflow_dont, /* complain_on_overflow */
265 NULL, /* special_function */
266 "R_M68HC11_GNU_VTINHERIT", /* name */
267 false, /* partial_inplace */
268 0, /* src_mask */
269 0, /* dst_mask */
270 false), /* pcrel_offset */
271
272 /* GNU extension to record C++ vtable member usage */
273 HOWTO (R_M68HC11_GNU_VTENTRY, /* type */
274 0, /* rightshift */
275 1, /* size (0 = byte, 1 = short, 2 = long) */
276 0, /* bitsize */
277 false, /* pc_relative */
278 0, /* bitpos */
279 complain_overflow_dont, /* complain_on_overflow */
280 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
281 "R_M68HC11_GNU_VTENTRY", /* name */
282 false, /* partial_inplace */
283 0, /* src_mask */
284 0, /* dst_mask */
285 false), /* pcrel_offset */
286
287 /* A 24 bit relocation */
288 HOWTO (R_M68HC11_24, /* type */
289 0, /* rightshift */
290 1, /* size (0 = byte, 1 = short, 2 = long) */
291 24, /* bitsize */
292 false, /* pc_relative */
293 0, /* bitpos */
294 complain_overflow_dont, /* complain_on_overflow */
295 m68hc12_elf_special_reloc, /* special_function */
296 "R_M68HC12_24", /* name */
297 false, /* partial_inplace */
298 0xffff, /* src_mask */
299 0xffff, /* dst_mask */
300 false), /* pcrel_offset */
301
302 /* A 16-bit low relocation */
303 HOWTO (R_M68HC11_LO16, /* type */
304 0, /* rightshift */
305 1, /* size (0 = byte, 1 = short, 2 = long) */
306 16, /* bitsize */
307 false, /* pc_relative */
308 0, /* bitpos */
309 complain_overflow_dont, /* complain_on_overflow */
310 m68hc12_elf_special_reloc,/* special_function */
311 "R_M68HC12_LO16", /* name */
312 false, /* partial_inplace */
313 0xffff, /* src_mask */
314 0xffff, /* dst_mask */
315 false), /* pcrel_offset */
316
317 /* A page relocation */
318 HOWTO (R_M68HC11_PAGE, /* type */
319 0, /* rightshift */
320 0, /* size (0 = byte, 1 = short, 2 = long) */
321 8, /* bitsize */
322 false, /* pc_relative */
323 0, /* bitpos */
324 complain_overflow_dont, /* complain_on_overflow */
325 m68hc12_elf_special_reloc,/* special_function */
326 "R_M68HC12_PAGE", /* name */
327 false, /* partial_inplace */
328 0x00ff, /* src_mask */
329 0x00ff, /* dst_mask */
330 false), /* pcrel_offset */
331
332 EMPTY_HOWTO (14),
333 EMPTY_HOWTO (15),
334 EMPTY_HOWTO (16),
335 EMPTY_HOWTO (17),
336 EMPTY_HOWTO (18),
337 EMPTY_HOWTO (19),
338
339 /* Mark beginning of a jump instruction (any form). */
340 HOWTO (R_M68HC11_RL_JUMP, /* type */
341 0, /* rightshift */
342 1, /* size (0 = byte, 1 = short, 2 = long) */
343 0, /* bitsize */
344 false, /* pc_relative */
345 0, /* bitpos */
346 complain_overflow_dont, /* complain_on_overflow */
347 m68hc11_elf_ignore_reloc, /* special_function */
348 "R_M68HC12_RL_JUMP", /* name */
349 true, /* partial_inplace */
350 0, /* src_mask */
351 0, /* dst_mask */
352 true), /* pcrel_offset */
353
354 /* Mark beginning of Gcc relaxation group instruction. */
355 HOWTO (R_M68HC11_RL_GROUP, /* type */
356 0, /* rightshift */
357 1, /* size (0 = byte, 1 = short, 2 = long) */
358 0, /* bitsize */
359 false, /* pc_relative */
360 0, /* bitpos */
361 complain_overflow_dont, /* complain_on_overflow */
362 m68hc11_elf_ignore_reloc, /* special_function */
363 "R_M68HC12_RL_GROUP", /* name */
364 true, /* partial_inplace */
365 0, /* src_mask */
366 0, /* dst_mask */
367 true), /* pcrel_offset */
368 };
369
370 /* Map BFD reloc types to M68HC11 ELF reloc types. */
371
372 struct m68hc11_reloc_map
373 {
374 bfd_reloc_code_real_type bfd_reloc_val;
375 unsigned char elf_reloc_val;
376 };
377
378 static const struct m68hc11_reloc_map m68hc11_reloc_map[] = {
379 {BFD_RELOC_NONE, R_M68HC11_NONE,},
380 {BFD_RELOC_8, R_M68HC11_8},
381 {BFD_RELOC_M68HC11_HI8, R_M68HC11_HI8},
382 {BFD_RELOC_M68HC11_LO8, R_M68HC11_LO8},
383 {BFD_RELOC_8_PCREL, R_M68HC11_PCREL_8},
384 {BFD_RELOC_16_PCREL, R_M68HC11_PCREL_16},
385 {BFD_RELOC_16, R_M68HC11_16},
386 {BFD_RELOC_32, R_M68HC11_32},
387 {BFD_RELOC_M68HC11_3B, R_M68HC11_3B},
388
389 {BFD_RELOC_VTABLE_INHERIT, R_M68HC11_GNU_VTINHERIT},
390 {BFD_RELOC_VTABLE_ENTRY, R_M68HC11_GNU_VTENTRY},
391
392 {BFD_RELOC_M68HC11_LO16, R_M68HC11_LO16},
393 {BFD_RELOC_M68HC11_PAGE, R_M68HC11_PAGE},
394 {BFD_RELOC_M68HC11_24, R_M68HC11_24},
395
396 {BFD_RELOC_M68HC11_RL_JUMP, R_M68HC11_RL_JUMP},
397 {BFD_RELOC_M68HC11_RL_GROUP, R_M68HC11_RL_GROUP},
398 };
399
400 static reloc_howto_type *
401 bfd_elf32_bfd_reloc_type_lookup (abfd, code)
402 bfd *abfd ATTRIBUTE_UNUSED;
403 bfd_reloc_code_real_type code;
404 {
405 unsigned int i;
406
407 for (i = 0;
408 i < sizeof (m68hc11_reloc_map) / sizeof (struct m68hc11_reloc_map);
409 i++)
410 {
411 if (m68hc11_reloc_map[i].bfd_reloc_val == code)
412 return &elf_m68hc11_howto_table[m68hc11_reloc_map[i].elf_reloc_val];
413 }
414
415 return NULL;
416 }
417
418 /* This function is used for relocs which are only used for relaxing,
419 which the linker should otherwise ignore. */
420
421 static bfd_reloc_status_type
422 m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
423 output_bfd, error_message)
424 bfd *abfd ATTRIBUTE_UNUSED;
425 arelent *reloc_entry;
426 asymbol *symbol ATTRIBUTE_UNUSED;
427 PTR data ATTRIBUTE_UNUSED;
428 asection *input_section;
429 bfd *output_bfd;
430 char **error_message ATTRIBUTE_UNUSED;
431 {
432 if (output_bfd != NULL)
433 reloc_entry->address += input_section->output_offset;
434 return bfd_reloc_ok;
435 }
436
437 static int
438 m68hc12_addr_is_banked (addr)
439 bfd_vma addr;
440 {
441 return (addr >= M68HC12_BANK_VIRT) ? 1 : 0;
442 }
443
444 /* Return the physical address seen by the processor, taking
445 into account banked memory. */
446 static bfd_vma
447 m68hc12_phys_addr (addr)
448 bfd_vma addr;
449 {
450 if (addr < M68HC12_BANK_VIRT)
451 return addr;
452
453 /* Map the address to the memory bank. */
454 addr -= M68HC12_BANK_VIRT;
455 addr &= M68HC12_BANK_MASK;
456 addr += M68HC12_BANK_BASE;
457 return addr;
458 }
459
460 /* Return the page number corresponding to an address in banked memory. */
461 static bfd_vma
462 m68hc12_phys_page (addr)
463 bfd_vma addr;
464 {
465 if (addr < M68HC12_BANK_VIRT)
466 return 0;
467
468 /* Map the address to the memory bank. */
469 addr -= M68HC12_BANK_VIRT;
470 addr >>= M68HC12_BANK_SHIFT;
471 addr &= M68HC12_BANK_PAGE_MASK;
472 return addr;
473 }
474
475 static bfd_reloc_status_type
476 m68hc12_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
477 output_bfd, error_message)
478 bfd *abfd;
479 arelent *reloc_entry;
480 asymbol *symbol;
481 PTR data;
482 asection *input_section;
483 bfd *output_bfd;
484 char **error_message ATTRIBUTE_UNUSED;
485 {
486 reloc_howto_type *howto;
487 bfd_vma relocation;
488 bfd_vma phys_addr;
489 bfd_vma phys_page;
490 bfd_vma insn_page;
491 bfd_vma insn_addr;
492
493 if (output_bfd != (bfd *) NULL
494 && (symbol->flags & BSF_SECTION_SYM) == 0
495 && (! reloc_entry->howto->partial_inplace
496 || reloc_entry->addend == 0))
497 {
498 reloc_entry->address += input_section->output_offset;
499 return bfd_reloc_ok;
500 }
501
502 if (output_bfd != NULL)
503 return bfd_reloc_continue;
504
505 if (reloc_entry->address > input_section->_cooked_size)
506 return bfd_reloc_outofrange;
507
508 /* Compute relocation. */
509 relocation = (symbol->value
510 + symbol->section->output_section->vma
511 + symbol->section->output_offset);
512 relocation += reloc_entry->addend;
513 relocation += bfd_get_16 (abfd, (bfd_byte*) data + reloc_entry->address);
514
515 /* Do the memory bank mapping. */
516 phys_addr = m68hc12_phys_addr (relocation);
517 phys_page = m68hc12_phys_page (relocation);
518
519 howto = reloc_entry->howto;
520 if (howto->complain_on_overflow != complain_overflow_dont
521 && (phys_addr & (((bfd_vma) -1) << 16)))
522 return bfd_reloc_overflow;
523
524 switch (howto->type)
525 {
526 case R_M68HC11_16:
527 /* Get virtual address of instruction having the relocation. */
528 insn_addr = input_section->output_section->vma
529 + input_section->output_offset
530 + reloc_entry->address;
531
532 insn_page = m68hc12_phys_page (insn_addr);
533
534 if (m68hc12_addr_is_banked (relocation)
535 && m68hc12_addr_is_banked (insn_addr)
536 && phys_page != insn_page)
537 {
538 *error_message = _("address is not in the same bank");
539 return bfd_reloc_dangerous;
540 }
541 if (m68hc12_addr_is_banked (relocation)
542 && !m68hc12_addr_is_banked (insn_addr))
543 {
544 *error_message = _("reference to a banked address in "
545 "the normal address space");
546 return bfd_reloc_dangerous;
547 }
548
549 case R_M68HC11_LO16:
550 bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
551 break;
552
553 case R_M68HC11_24:
554 bfd_put_16 (abfd, phys_addr, (bfd_byte*) data + reloc_entry->address);
555 bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address + 2);
556 break;
557
558 case R_M68HC11_PAGE:
559 bfd_put_8 (abfd, phys_page, (bfd_byte*) data + reloc_entry->address);
560 break;
561
562 default:
563 abort ();
564 break;
565 }
566
567 return bfd_reloc_ok;
568 }
569
570 /* Set the howto pointer for an M68HC11 ELF reloc. */
571
572 static void
573 m68hc11_info_to_howto_rel (abfd, cache_ptr, dst)
574 bfd *abfd ATTRIBUTE_UNUSED;
575 arelent *cache_ptr;
576 Elf32_Internal_Rel *dst;
577 {
578 unsigned int r_type;
579
580 r_type = ELF32_R_TYPE (dst->r_info);
581 BFD_ASSERT (r_type < (unsigned int) R_M68HC11_max);
582 cache_ptr->howto = &elf_m68hc11_howto_table[r_type];
583 }
584
585 \f
586 /* Set and control ELF flags in ELF header. */
587
588 boolean
589 _bfd_m68hc12_elf_set_private_flags (abfd, flags)
590 bfd *abfd;
591 flagword flags;
592 {
593 BFD_ASSERT (!elf_flags_init (abfd)
594 || elf_elfheader (abfd)->e_flags == flags);
595
596 elf_elfheader (abfd)->e_flags = flags;
597 elf_flags_init (abfd) = true;
598 return true;
599 }
600
601 /* Merge backend specific data from an object file to the output
602 object file when linking. */
603
604 boolean
605 _bfd_m68hc12_elf_merge_private_bfd_data (ibfd, obfd)
606 bfd *ibfd;
607 bfd *obfd;
608 {
609 flagword old_flags;
610 flagword new_flags;
611 boolean ok = true;
612
613 /* Check if we have the same endianess */
614 if (_bfd_generic_verify_endian_match (ibfd, obfd) == false)
615 return false;
616
617 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
618 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
619 return true;
620
621 new_flags = elf_elfheader (ibfd)->e_flags;
622 elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
623 old_flags = elf_elfheader (obfd)->e_flags;
624
625 if (! elf_flags_init (obfd))
626 {
627 elf_flags_init (obfd) = true;
628 elf_elfheader (obfd)->e_flags = new_flags;
629 elf_elfheader (obfd)->e_ident[EI_CLASS]
630 = elf_elfheader (ibfd)->e_ident[EI_CLASS];
631
632 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
633 && bfd_get_arch_info (obfd)->the_default)
634 {
635 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
636 bfd_get_mach (ibfd)))
637 return false;
638 }
639
640 return true;
641 }
642
643 /* Check ABI compatibility. */
644 if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
645 {
646 (*_bfd_error_handler)
647 (_("%s: linking files compiled for 16-bit integers (-mshort) "
648 "and others for 32-bit integers"),
649 bfd_archive_filename (ibfd));
650 ok = false;
651 }
652 if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
653 {
654 (*_bfd_error_handler)
655 (_("%s: linking files compiled for 32-bit double (-fshort-double) "
656 "and others for 64-bit double"),
657 bfd_archive_filename (ibfd));
658 ok = false;
659 }
660 new_flags &= ~EF_M68HC11_ABI;
661 old_flags &= ~EF_M68HC11_ABI;
662
663 /* Warn about any other mismatches */
664 if (new_flags != old_flags)
665 {
666 (*_bfd_error_handler)
667 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
668 bfd_archive_filename (ibfd), (unsigned long) new_flags,
669 (unsigned long) old_flags);
670 ok = false;
671 }
672
673 if (! ok)
674 {
675 bfd_set_error (bfd_error_bad_value);
676 return false;
677 }
678
679 return true;
680 }
681
682 boolean
683 _bfd_m68hc12_elf_print_private_bfd_data (abfd, ptr)
684 bfd *abfd;
685 PTR ptr;
686 {
687 FILE *file = (FILE *) ptr;
688
689 BFD_ASSERT (abfd != NULL && ptr != NULL);
690
691 /* Print normal ELF private data. */
692 _bfd_elf_print_private_bfd_data (abfd, ptr);
693
694 /* xgettext:c-format */
695 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
696
697 if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
698 fprintf (file, _("[abi=32-bit int,"));
699 else
700 fprintf (file, _("[abi=16-bit int,"));
701
702 if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
703 fprintf (file, _(" 64-bit double]"));
704 else
705 fprintf (file, _(" 32-bit double]"));
706
707 fputc ('\n', file);
708
709 return true;
710 }
711
712 /* Below is the only difference between elf32-m68hc12.c and elf32-m68hc11.c.
713 The Motorola spec says to use a different Elf machine code. */
714 #define ELF_ARCH bfd_arch_m68hc12
715 #define ELF_MACHINE_CODE EM_68HC12
716 #define ELF_MAXPAGESIZE 0x1000
717
718 #define TARGET_BIG_SYM bfd_elf32_m68hc12_vec
719 #define TARGET_BIG_NAME "elf32-m68hc12"
720
721 #define elf_info_to_howto 0
722 #define elf_info_to_howto_rel m68hc11_info_to_howto_rel
723 #define elf_backend_object_p 0
724 #define elf_backend_final_write_processing 0
725
726 #define bfd_elf32_bfd_merge_private_bfd_data \
727 _bfd_m68hc12_elf_merge_private_bfd_data
728 #define bfd_elf32_bfd_set_private_flags _bfd_m68hc12_elf_set_private_flags
729 #define bfd_elf32_bfd_print_private_bfd_data \
730 _bfd_m68hc12_elf_print_private_bfd_data
731
732 #include "elf32-target.h"