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