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