2003-05-02 Michael Snyder <msnyder@redhat.com>
[binutils.git] / bfd / elf32-m68hc1x.c
blob0696a3642517247d44d34683b749e116b76cd4d1
1 /* Motorola 68HC11/HC12-specific support for 32-bit ELF
2 Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Stephane Carrez (stcarrez@nerim.fr)
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "bfdlink.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf32-m68hc1x.h"
27 #include "elf/m68hc11.h"
28 #include "opcode/m68hc11.h"
31 #define m68hc12_stub_hash_lookup(table, string, create, copy) \
32 ((struct elf32_m68hc11_stub_hash_entry *) \
33 bfd_hash_lookup ((table), (string), (create), (copy)))
35 static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub
36 PARAMS((const char *stub_name,
37 asection *section,
38 struct m68hc11_elf_link_hash_table *htab));
40 static struct bfd_hash_entry *stub_hash_newfunc
41 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
43 static void m68hc11_elf_set_symbol
44 PARAMS ((bfd* abfd, struct bfd_link_info *info,
45 const char* name, bfd_vma value, asection* sec));
47 static bfd_boolean m68hc11_elf_export_one_stub
48 PARAMS((struct bfd_hash_entry *gen_entry, PTR in_arg));
50 static bfd_boolean m68hc11_get_relocation_value
51 PARAMS ((bfd* abfd,
52 struct bfd_link_info* info,
53 asection **local_sections,
54 Elf_Internal_Sym* local_syms,
55 Elf_Internal_Rela* rel,
56 const char** name,
57 bfd_vma* relocation,
58 bfd_boolean* is_far));
60 static void scan_sections_for_abi PARAMS ((bfd*, asection*, PTR));
62 struct m68hc11_scan_param
64 struct m68hc11_page_info* pinfo;
65 bfd_boolean use_memory_banks;
69 /* Create a 68HC11/68HC12 ELF linker hash table. */
71 struct m68hc11_elf_link_hash_table*
72 m68hc11_elf_hash_table_create (abfd)
73 bfd *abfd;
75 struct m68hc11_elf_link_hash_table *ret;
76 bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
78 ret = (struct m68hc11_elf_link_hash_table *) bfd_zalloc (abfd, amt);
79 if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
80 return NULL;
82 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
83 _bfd_elf_link_hash_newfunc))
85 bfd_release (abfd, ret);
86 return NULL;
89 /* Init the stub hash table too. */
90 amt = sizeof (struct bfd_hash_table);
91 ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
92 if (ret->stub_hash_table == NULL)
94 bfd_release (abfd, ret);
95 return NULL;
97 if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc))
98 return NULL;
100 ret->stub_bfd = NULL;
101 ret->stub_section = 0;
102 ret->add_stub_section = NULL;
103 ret->sym_sec.abfd = NULL;
105 return ret;
108 /* Free the derived linker hash table. */
110 void
111 m68hc11_elf_bfd_link_hash_table_free (hash)
112 struct bfd_link_hash_table *hash;
114 struct m68hc11_elf_link_hash_table *ret
115 = (struct m68hc11_elf_link_hash_table *) hash;
117 bfd_hash_table_free (ret->stub_hash_table);
118 free (ret->stub_hash_table);
119 _bfd_generic_link_hash_table_free (hash);
122 /* Assorted hash table functions. */
124 /* Initialize an entry in the stub hash table. */
126 static struct bfd_hash_entry *
127 stub_hash_newfunc (entry, table, string)
128 struct bfd_hash_entry *entry;
129 struct bfd_hash_table *table;
130 const char *string;
132 /* Allocate the structure if it has not already been allocated by a
133 subclass. */
134 if (entry == NULL)
136 entry = bfd_hash_allocate (table,
137 sizeof (struct elf32_m68hc11_stub_hash_entry));
138 if (entry == NULL)
139 return entry;
142 /* Call the allocation method of the superclass. */
143 entry = bfd_hash_newfunc (entry, table, string);
144 if (entry != NULL)
146 struct elf32_m68hc11_stub_hash_entry *eh;
148 /* Initialize the local fields. */
149 eh = (struct elf32_m68hc11_stub_hash_entry *) entry;
150 eh->stub_sec = NULL;
151 eh->stub_offset = 0;
152 eh->target_value = 0;
153 eh->target_section = NULL;
156 return entry;
159 /* Add a new stub entry to the stub hash. Not all fields of the new
160 stub entry are initialised. */
162 static struct elf32_m68hc11_stub_hash_entry *
163 m68hc12_add_stub (stub_name, section, htab)
164 const char *stub_name;
165 asection *section;
166 struct m68hc11_elf_link_hash_table *htab;
168 struct elf32_m68hc11_stub_hash_entry *stub_entry;
170 /* Enter this entry into the linker stub hash table. */
171 stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name,
172 TRUE, FALSE);
173 if (stub_entry == NULL)
175 (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
176 bfd_archive_filename (section->owner),
177 stub_name);
178 return NULL;
181 if (htab->stub_section == 0)
183 htab->stub_section = (*htab->add_stub_section) (".tramp",
184 htab->tramp_section);
187 stub_entry->stub_sec = htab->stub_section;
188 stub_entry->stub_offset = 0;
189 return stub_entry;
192 /* Hook called by the linker routine which adds symbols from an object
193 file. We use it for identify far symbols and force a loading of
194 the trampoline handler. */
196 bfd_boolean
197 elf32_m68hc11_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
198 bfd *abfd;
199 struct bfd_link_info *info;
200 const Elf_Internal_Sym *sym;
201 const char **namep ATTRIBUTE_UNUSED;
202 flagword *flagsp ATTRIBUTE_UNUSED;
203 asection **secp ATTRIBUTE_UNUSED;
204 bfd_vma *valp ATTRIBUTE_UNUSED;
206 if (sym->st_other & STO_M68HC12_FAR)
208 struct elf_link_hash_entry *h;
210 h = (struct elf_link_hash_entry *)
211 bfd_link_hash_lookup (info->hash, "__far_trampoline",
212 FALSE, FALSE, FALSE);
213 if (h == NULL)
215 struct bfd_link_hash_entry* entry = NULL;
217 _bfd_generic_link_add_one_symbol (info, abfd,
218 "__far_trampoline",
219 BSF_GLOBAL,
220 bfd_und_section_ptr,
221 (bfd_vma) 0, (const char*) NULL,
222 FALSE, FALSE, &entry);
226 return TRUE;
229 /* External entry points for sizing and building linker stubs. */
231 /* Set up various things so that we can make a list of input sections
232 for each output section included in the link. Returns -1 on error,
233 0 when no stubs will be needed, and 1 on success. */
236 elf32_m68hc11_setup_section_lists (output_bfd, info)
237 bfd *output_bfd;
238 struct bfd_link_info *info;
240 bfd *input_bfd;
241 unsigned int bfd_count;
242 int top_id, top_index;
243 asection *section;
244 asection **input_list, **list;
245 bfd_size_type amt;
246 asection *text_section;
247 struct m68hc11_elf_link_hash_table *htab;
249 htab = m68hc11_elf_hash_table (info);
251 if (htab->root.root.creator->flavour != bfd_target_elf_flavour)
252 return 0;
254 /* Count the number of input BFDs and find the top input section id.
255 Also search for an existing ".tramp" section so that we know
256 where generated trampolines must go. Default to ".text" if we
257 can't find it. */
258 htab->tramp_section = 0;
259 text_section = 0;
260 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
261 input_bfd != NULL;
262 input_bfd = input_bfd->link_next)
264 bfd_count += 1;
265 for (section = input_bfd->sections;
266 section != NULL;
267 section = section->next)
269 const char* name = bfd_get_section_name (input_bfd, section);
271 if (!strcmp (name, ".tramp"))
272 htab->tramp_section = section;
274 if (!strcmp (name, ".text"))
275 text_section = section;
277 if (top_id < section->id)
278 top_id = section->id;
281 htab->bfd_count = bfd_count;
282 if (htab->tramp_section == 0)
283 htab->tramp_section = text_section;
285 /* We can't use output_bfd->section_count here to find the top output
286 section index as some sections may have been removed, and
287 _bfd_strip_section_from_output doesn't renumber the indices. */
288 for (section = output_bfd->sections, top_index = 0;
289 section != NULL;
290 section = section->next)
292 if (top_index < section->index)
293 top_index = section->index;
296 htab->top_index = top_index;
297 amt = sizeof (asection *) * (top_index + 1);
298 input_list = (asection **) bfd_malloc (amt);
299 htab->input_list = input_list;
300 if (input_list == NULL)
301 return -1;
303 /* For sections we aren't interested in, mark their entries with a
304 value we can check later. */
305 list = input_list + top_index;
307 *list = bfd_abs_section_ptr;
308 while (list-- != input_list);
310 for (section = output_bfd->sections;
311 section != NULL;
312 section = section->next)
314 if ((section->flags & SEC_CODE) != 0)
315 input_list[section->index] = NULL;
318 return 1;
321 /* Determine and set the size of the stub section for a final link.
323 The basic idea here is to examine all the relocations looking for
324 PC-relative calls to a target that is unreachable with a "bl"
325 instruction. */
327 bfd_boolean
328 elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section)
329 bfd *output_bfd;
330 bfd *stub_bfd;
331 struct bfd_link_info *info;
332 asection * (*add_stub_section) PARAMS ((const char *, asection *));
334 bfd *input_bfd;
335 asection *section;
336 Elf_Internal_Sym *local_syms, **all_local_syms;
337 unsigned int bfd_indx, bfd_count;
338 bfd_size_type amt;
339 asection *stub_sec;
341 struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info);
343 /* Stash our params away. */
344 htab->stub_bfd = stub_bfd;
345 htab->add_stub_section = add_stub_section;
347 /* Count the number of input BFDs and find the top input section id. */
348 for (input_bfd = info->input_bfds, bfd_count = 0;
349 input_bfd != NULL;
350 input_bfd = input_bfd->link_next)
352 bfd_count += 1;
355 /* We want to read in symbol extension records only once. To do this
356 we need to read in the local symbols in parallel and save them for
357 later use; so hold pointers to the local symbols in an array. */
358 amt = sizeof (Elf_Internal_Sym *) * bfd_count;
359 all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
360 if (all_local_syms == NULL)
361 return FALSE;
363 /* Walk over all the input BFDs, swapping in local symbols. */
364 for (input_bfd = info->input_bfds, bfd_indx = 0;
365 input_bfd != NULL;
366 input_bfd = input_bfd->link_next, bfd_indx++)
368 Elf_Internal_Shdr *symtab_hdr;
369 Elf_Internal_Shdr *shndx_hdr;
370 Elf_Internal_Sym *isym;
371 Elf32_External_Sym *extsyms, *esym, *end_sy;
372 Elf_External_Sym_Shndx *shndx_buf, *shndx;
373 bfd_size_type sec_size;
375 /* We'll need the symbol table in a second. */
376 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
377 if (symtab_hdr->sh_info == 0)
378 continue;
380 /* We need an array of the local symbols attached to the input bfd.
381 Unfortunately, we're going to have to read & swap them in. */
382 sec_size = symtab_hdr->sh_info;
383 sec_size *= sizeof (Elf_Internal_Sym);
384 local_syms = (Elf_Internal_Sym *) bfd_malloc (sec_size);
385 if (local_syms == NULL)
386 goto error_ret_free_local;
388 all_local_syms[bfd_indx] = local_syms;
389 sec_size = symtab_hdr->sh_info;
390 sec_size *= sizeof (Elf32_External_Sym);
392 /* Get the cached copy. */
393 if (symtab_hdr->contents != NULL)
394 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
395 else
397 /* Go get them off disk. */
398 bfd_size_type amt = symtab_hdr->sh_size;
399 extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
400 if (extsyms == NULL)
401 goto error_ret_free_local;
403 if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
404 || bfd_bread ((PTR) extsyms, amt, input_bfd) != amt)
406 error_ret_free_ext_syms:
407 free (extsyms);
408 goto error_ret_free_local;
411 shndx_buf = NULL;
412 shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
413 if (shndx_hdr->sh_size != 0)
415 bfd_size_type amt;
417 amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
418 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
419 if (shndx_buf == NULL)
420 goto error_ret_free_ext_syms;
421 if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
422 || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
424 free (shndx_buf);
425 goto error_ret_free_ext_syms;
427 shndx_hdr->contents = (PTR) shndx_buf;
430 /* Swap the local symbols in. */
431 for (esym = extsyms, end_sy = esym + symtab_hdr->sh_info,
432 isym = local_syms, shndx = shndx_buf;
433 esym < end_sy;
434 esym++, isym++, shndx = (shndx ? shndx + 1 : NULL))
435 bfd_elf32_swap_symbol_in (input_bfd, esym, shndx, isym);
437 /* Now we can free the external symbols. */
438 free (shndx_buf);
441 for (input_bfd = info->input_bfds, bfd_indx = 0;
442 input_bfd != NULL;
443 input_bfd = input_bfd->link_next, bfd_indx++)
445 Elf_Internal_Shdr *symtab_hdr;
446 Elf_Internal_Sym *local_syms;
447 struct elf_link_hash_entry ** sym_hashes;
449 sym_hashes = elf_sym_hashes (input_bfd);
451 /* We'll need the symbol table in a second. */
452 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
453 if (symtab_hdr->sh_info == 0)
454 continue;
456 local_syms = all_local_syms[bfd_indx];
458 /* Walk over each section attached to the input bfd. */
459 for (section = input_bfd->sections;
460 section != NULL;
461 section = section->next)
463 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
465 /* If there aren't any relocs, then there's nothing more
466 to do. */
467 if ((section->flags & SEC_RELOC) == 0
468 || section->reloc_count == 0)
469 continue;
471 /* If this section is a link-once section that will be
472 discarded, then don't create any stubs. */
473 if (section->output_section == NULL
474 || section->output_section->owner != output_bfd)
475 continue;
477 /* Get the relocs. */
478 internal_relocs
479 = _bfd_elf32_link_read_relocs (input_bfd, section, NULL,
480 (Elf_Internal_Rela *) NULL,
481 info->keep_memory);
482 if (internal_relocs == NULL)
483 goto error_ret_free_local;
485 /* Now examine each relocation. */
486 irela = internal_relocs;
487 irelaend = irela + section->reloc_count;
488 for (; irela < irelaend; irela++)
490 unsigned int r_type, r_indx;
491 struct elf32_m68hc11_stub_hash_entry *stub_entry;
492 asection *sym_sec;
493 bfd_vma sym_value;
494 struct elf_link_hash_entry *hash;
495 const char *stub_name;
496 Elf_Internal_Sym *sym;
498 r_type = ELF32_R_TYPE (irela->r_info);
500 /* Only look at 16-bit relocs. */
501 if (r_type != (unsigned int) R_M68HC11_16)
502 continue;
504 /* Now determine the call target, its name, value,
505 section. */
506 r_indx = ELF32_R_SYM (irela->r_info);
507 if (r_indx < symtab_hdr->sh_info)
509 /* It's a local symbol. */
510 Elf_Internal_Shdr *hdr;
511 bfd_boolean is_far;
513 sym = local_syms + r_indx;
514 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
515 sym_sec = hdr->bfd_section;
516 is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
517 if (!is_far)
518 continue;
519 stub_name = (bfd_elf_string_from_elf_section
520 (input_bfd, symtab_hdr->sh_link,
521 sym->st_name));
522 sym_value = sym->st_value;
523 hash = NULL;
525 else
527 /* It's an external symbol. */
528 int e_indx;
530 e_indx = r_indx - symtab_hdr->sh_info;
531 hash = (struct elf_link_hash_entry *)
532 (sym_hashes[e_indx]);
534 while (hash->root.type == bfd_link_hash_indirect
535 || hash->root.type == bfd_link_hash_warning)
536 hash = ((struct elf_link_hash_entry *)
537 hash->root.u.i.link);
539 if (hash->root.type == bfd_link_hash_defined
540 || hash->root.type == bfd_link_hash_defweak)
542 if (!(hash->other & STO_M68HC12_FAR))
543 continue;
545 else if (hash->root.type == bfd_link_hash_undefweak)
547 continue;
549 else if (hash->root.type == bfd_link_hash_undefined)
551 continue;
553 else
555 bfd_set_error (bfd_error_bad_value);
556 goto error_ret_free_internal;
558 sym_sec = hash->root.u.def.section;
559 sym_value = hash->root.u.def.value;
560 stub_name = hash->root.root.string;
563 if (!stub_name)
564 goto error_ret_free_internal;
566 stub_entry = m68hc12_stub_hash_lookup
567 (htab->stub_hash_table,
568 stub_name,
569 FALSE, FALSE);
570 if (stub_entry == NULL)
572 if (add_stub_section == 0)
573 continue;
575 stub_entry = m68hc12_add_stub (stub_name, section, htab);
576 if (stub_entry == NULL)
578 error_ret_free_internal:
579 if (elf_section_data (section)->relocs == NULL)
580 free (internal_relocs);
581 goto error_ret_free_local;
585 stub_entry->target_value = sym_value;
586 stub_entry->target_section = sym_sec;
589 /* We're done with the internal relocs, free them. */
590 if (elf_section_data (section)->relocs == NULL)
591 free (internal_relocs);
595 if (add_stub_section)
597 /* OK, we've added some stubs. Find out the new size of the
598 stub sections. */
599 for (stub_sec = htab->stub_bfd->sections;
600 stub_sec != NULL;
601 stub_sec = stub_sec->next)
603 stub_sec->_raw_size = 0;
604 stub_sec->_cooked_size = 0;
607 bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
609 free (htab->all_local_syms);
610 return TRUE;
612 error_ret_free_local:
613 free (htab->all_local_syms);
614 return FALSE;
617 /* Export the trampoline addresses in the symbol table. */
618 static bfd_boolean
619 m68hc11_elf_export_one_stub (gen_entry, in_arg)
620 struct bfd_hash_entry *gen_entry;
621 PTR in_arg;
623 struct bfd_link_info *info;
624 struct m68hc11_elf_link_hash_table *htab;
625 struct elf32_m68hc11_stub_hash_entry *stub_entry;
626 char* name;
627 bfd_boolean result;
629 info = (struct bfd_link_info *) in_arg;
630 htab = m68hc11_elf_hash_table (info);
632 /* Massage our args to the form they really have. */
633 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
635 /* Generate the trampoline according to HC11 or HC12. */
636 result = (* htab->build_one_stub) (gen_entry, in_arg);
638 /* Make a printable name that does not conflict with the real function. */
639 name = alloca (strlen (stub_entry->root.string) + 16);
640 sprintf (name, "tramp.%s", stub_entry->root.string);
642 /* Export the symbol for debugging/disassembling. */
643 m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
644 stub_entry->stub_offset,
645 stub_entry->stub_sec);
646 return result;
649 /* Export a symbol or set its value and section. */
650 static void
651 m68hc11_elf_set_symbol (abfd, info, name, value, sec)
652 bfd* abfd;
653 struct bfd_link_info *info;
654 const char* name;
655 bfd_vma value;
656 asection* sec;
658 struct elf_link_hash_entry *h;
660 h = (struct elf_link_hash_entry *)
661 bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
662 if (h == NULL)
664 _bfd_generic_link_add_one_symbol (info, abfd,
665 name,
666 BSF_GLOBAL,
667 sec,
668 value,
669 (const char*) NULL,
670 TRUE, FALSE, NULL);
672 else
674 h->root.type = bfd_link_hash_defined;
675 h->root.u.def.value = value;
676 h->root.u.def.section = sec;
681 /* Build all the stubs associated with the current output file. The
682 stubs are kept in a hash table attached to the main linker hash
683 table. This function is called via m68hc12elf_finish in the
684 linker. */
686 bfd_boolean
687 elf32_m68hc11_build_stubs (abfd, info)
688 bfd* abfd;
689 struct bfd_link_info *info;
691 asection *stub_sec;
692 struct bfd_hash_table *table;
693 struct m68hc11_elf_link_hash_table *htab;
694 struct m68hc11_scan_param param;
696 m68hc11_elf_get_bank_parameters (info);
697 htab = m68hc11_elf_hash_table (info);
699 for (stub_sec = htab->stub_bfd->sections;
700 stub_sec != NULL;
701 stub_sec = stub_sec->next)
703 bfd_size_type size;
705 /* Allocate memory to hold the linker stubs. */
706 size = stub_sec->_raw_size;
707 stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
708 if (stub_sec->contents == NULL && size != 0)
709 return FALSE;
710 stub_sec->_raw_size = 0;
713 /* Build the stubs as directed by the stub hash table. */
714 table = htab->stub_hash_table;
715 bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
717 /* Scan the output sections to see if we use the memory banks.
718 If so, export the symbols that define how the memory banks
719 are mapped. This is used by gdb and the simulator to obtain
720 the information. It can be used by programs to burn the eprom
721 at the good addresses. */
722 param.use_memory_banks = FALSE;
723 param.pinfo = &htab->pinfo;
724 bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
725 if (param.use_memory_banks)
727 m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
728 htab->pinfo.bank_physical,
729 bfd_abs_section_ptr);
730 m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
731 htab->pinfo.bank_virtual,
732 bfd_abs_section_ptr);
733 m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
734 htab->pinfo.bank_size,
735 bfd_abs_section_ptr);
738 return TRUE;
741 void
742 m68hc11_elf_get_bank_parameters (info)
743 struct bfd_link_info *info;
745 unsigned i;
746 struct m68hc11_page_info *pinfo;
747 struct bfd_link_hash_entry *h;
749 pinfo = &m68hc11_elf_hash_table (info)->pinfo;
750 if (pinfo->bank_param_initialized)
751 return;
753 pinfo->bank_virtual = M68HC12_BANK_VIRT;
754 pinfo->bank_mask = M68HC12_BANK_MASK;
755 pinfo->bank_physical = M68HC12_BANK_BASE;
756 pinfo->bank_shift = M68HC12_BANK_SHIFT;
757 pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
759 h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
760 FALSE, FALSE, TRUE);
761 if (h != (struct bfd_link_hash_entry*) NULL
762 && h->type == bfd_link_hash_defined)
763 pinfo->bank_physical = (h->u.def.value
764 + h->u.def.section->output_section->vma
765 + h->u.def.section->output_offset);
767 h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
768 FALSE, FALSE, TRUE);
769 if (h != (struct bfd_link_hash_entry*) NULL
770 && h->type == bfd_link_hash_defined)
771 pinfo->bank_virtual = (h->u.def.value
772 + h->u.def.section->output_section->vma
773 + h->u.def.section->output_offset);
775 h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
776 FALSE, FALSE, TRUE);
777 if (h != (struct bfd_link_hash_entry*) NULL
778 && h->type == bfd_link_hash_defined)
779 pinfo->bank_size = (h->u.def.value
780 + h->u.def.section->output_section->vma
781 + h->u.def.section->output_offset);
783 pinfo->bank_shift = 0;
784 for (i = pinfo->bank_size; i != 0; i >>= 1)
785 pinfo->bank_shift++;
786 pinfo->bank_shift--;
787 pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
788 pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
789 pinfo->bank_param_initialized = 1;
791 h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
792 FALSE, TRUE);
793 if (h != (struct bfd_link_hash_entry*) NULL
794 && h->type == bfd_link_hash_defined)
795 pinfo->trampoline_addr = (h->u.def.value
796 + h->u.def.section->output_section->vma
797 + h->u.def.section->output_offset);
800 /* Return 1 if the address is in banked memory.
801 This can be applied to a virtual address and to a physical address. */
803 m68hc11_addr_is_banked (pinfo, addr)
804 struct m68hc11_page_info *pinfo;
805 bfd_vma addr;
807 if (addr >= pinfo->bank_virtual)
808 return 1;
810 if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
811 return 1;
813 return 0;
816 /* Return the physical address seen by the processor, taking
817 into account banked memory. */
818 bfd_vma
819 m68hc11_phys_addr (pinfo, addr)
820 struct m68hc11_page_info *pinfo;
821 bfd_vma addr;
823 if (addr < pinfo->bank_virtual)
824 return addr;
826 /* Map the address to the memory bank. */
827 addr -= pinfo->bank_virtual;
828 addr &= pinfo->bank_mask;
829 addr += pinfo->bank_physical;
830 return addr;
833 /* Return the page number corresponding to an address in banked memory. */
834 bfd_vma
835 m68hc11_phys_page (pinfo, addr)
836 struct m68hc11_page_info *pinfo;
837 bfd_vma addr;
839 if (addr < pinfo->bank_virtual)
840 return 0;
842 /* Map the address to the memory bank. */
843 addr -= pinfo->bank_virtual;
844 addr >>= pinfo->bank_shift;
845 addr &= 0x0ff;
846 return addr;
849 /* This function is used for relocs which are only used for relaxing,
850 which the linker should otherwise ignore. */
852 bfd_reloc_status_type
853 m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
854 output_bfd, error_message)
855 bfd *abfd ATTRIBUTE_UNUSED;
856 arelent *reloc_entry;
857 asymbol *symbol ATTRIBUTE_UNUSED;
858 PTR data ATTRIBUTE_UNUSED;
859 asection *input_section;
860 bfd *output_bfd;
861 char **error_message ATTRIBUTE_UNUSED;
863 if (output_bfd != NULL)
864 reloc_entry->address += input_section->output_offset;
865 return bfd_reloc_ok;
868 bfd_reloc_status_type
869 m68hc11_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
870 output_bfd, error_message)
871 bfd *abfd ATTRIBUTE_UNUSED;
872 arelent *reloc_entry;
873 asymbol *symbol;
874 PTR data ATTRIBUTE_UNUSED;
875 asection *input_section;
876 bfd *output_bfd;
877 char **error_message ATTRIBUTE_UNUSED;
879 if (output_bfd != (bfd *) NULL
880 && (symbol->flags & BSF_SECTION_SYM) == 0
881 && (! reloc_entry->howto->partial_inplace
882 || reloc_entry->addend == 0))
884 reloc_entry->address += input_section->output_offset;
885 return bfd_reloc_ok;
888 if (output_bfd != NULL)
889 return bfd_reloc_continue;
891 if (reloc_entry->address > input_section->_cooked_size)
892 return bfd_reloc_outofrange;
894 abort();
897 asection *
898 elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
899 asection *sec;
900 struct bfd_link_info *info ATTRIBUTE_UNUSED;
901 Elf_Internal_Rela *rel;
902 struct elf_link_hash_entry *h;
903 Elf_Internal_Sym *sym;
905 if (h != NULL)
907 switch (ELF32_R_TYPE (rel->r_info))
909 default:
910 switch (h->root.type)
912 case bfd_link_hash_defined:
913 case bfd_link_hash_defweak:
914 return h->root.u.def.section;
916 case bfd_link_hash_common:
917 return h->root.u.c.p->section;
919 default:
920 break;
924 else
925 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
927 return NULL;
930 bfd_boolean
931 elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
932 bfd *abfd ATTRIBUTE_UNUSED;
933 struct bfd_link_info *info ATTRIBUTE_UNUSED;
934 asection *sec ATTRIBUTE_UNUSED;
935 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
937 /* We don't use got and plt entries for 68hc11/68hc12. */
938 return TRUE;
941 /* Look through the relocs for a section during the first phase.
942 Since we don't do .gots or .plts, we just need to consider the
943 virtual table relocs for gc. */
945 bfd_boolean
946 elf32_m68hc11_check_relocs (abfd, info, sec, relocs)
947 bfd * abfd;
948 struct bfd_link_info * info;
949 asection * sec;
950 const Elf_Internal_Rela * relocs;
952 Elf_Internal_Shdr * symtab_hdr;
953 struct elf_link_hash_entry ** sym_hashes;
954 struct elf_link_hash_entry ** sym_hashes_end;
955 const Elf_Internal_Rela * rel;
956 const Elf_Internal_Rela * rel_end;
958 if (info->relocateable)
959 return TRUE;
961 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
962 sym_hashes = elf_sym_hashes (abfd);
963 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
964 if (!elf_bad_symtab (abfd))
965 sym_hashes_end -= symtab_hdr->sh_info;
967 rel_end = relocs + sec->reloc_count;
969 for (rel = relocs; rel < rel_end; rel++)
971 struct elf_link_hash_entry * h;
972 unsigned long r_symndx;
974 r_symndx = ELF32_R_SYM (rel->r_info);
976 if (r_symndx < symtab_hdr->sh_info)
977 h = NULL;
978 else
979 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
981 switch (ELF32_R_TYPE (rel->r_info))
983 /* This relocation describes the C++ object vtable hierarchy.
984 Reconstruct it for later use during GC. */
985 case R_M68HC11_GNU_VTINHERIT:
986 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
987 return FALSE;
988 break;
990 /* This relocation describes which C++ vtable entries are actually
991 used. Record for later use during GC. */
992 case R_M68HC11_GNU_VTENTRY:
993 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
994 return FALSE;
995 break;
999 return TRUE;
1002 static bfd_boolean
1003 m68hc11_get_relocation_value (abfd, info, local_sections, local_syms,
1004 rel, name,
1005 relocation, is_far)
1006 bfd *abfd;
1007 struct bfd_link_info *info;
1008 asection **local_sections;
1009 Elf_Internal_Sym* local_syms;
1010 Elf_Internal_Rela* rel;
1011 const char** name;
1012 bfd_vma* relocation;
1013 bfd_boolean* is_far;
1015 Elf_Internal_Shdr *symtab_hdr;
1016 struct elf_link_hash_entry **sym_hashes;
1017 unsigned long r_symndx;
1018 asection *sec;
1019 struct elf_link_hash_entry *h;
1020 Elf_Internal_Sym *sym;
1021 const char* stub_name = 0;
1023 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1024 sym_hashes = elf_sym_hashes (abfd);
1026 r_symndx = ELF32_R_SYM (rel->r_info);
1028 /* This is a final link. */
1029 h = NULL;
1030 sym = NULL;
1031 sec = NULL;
1032 if (r_symndx < symtab_hdr->sh_info)
1034 sym = local_syms + r_symndx;
1035 sec = local_sections[r_symndx];
1036 *relocation = (sec->output_section->vma
1037 + sec->output_offset
1038 + sym->st_value);
1039 *is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
1040 if (*is_far)
1041 stub_name = (bfd_elf_string_from_elf_section
1042 (abfd, symtab_hdr->sh_link,
1043 sym->st_name));
1045 else
1047 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1048 while (h->root.type == bfd_link_hash_indirect
1049 || h->root.type == bfd_link_hash_warning)
1050 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1051 if (h->root.type == bfd_link_hash_defined
1052 || h->root.type == bfd_link_hash_defweak)
1054 sec = h->root.u.def.section;
1055 *relocation = (h->root.u.def.value
1056 + sec->output_section->vma
1057 + sec->output_offset);
1059 else if (h->root.type == bfd_link_hash_undefweak)
1060 *relocation = 0;
1061 else
1063 if (!((*info->callbacks->undefined_symbol)
1064 (info, h->root.root.string, abfd,
1065 sec, rel->r_offset, TRUE)))
1066 return FALSE;
1067 *relocation = 0;
1069 *is_far = (h && (h->other & STO_M68HC12_FAR));
1070 stub_name = h->root.root.string;
1073 if (h != NULL)
1074 *name = h->root.root.string;
1075 else
1077 *name = (bfd_elf_string_from_elf_section
1078 (abfd, symtab_hdr->sh_link, sym->st_name));
1079 if (*name == NULL || **name == '\0')
1080 *name = bfd_section_name (input_bfd, sec);
1083 if (*is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
1085 struct elf32_m68hc11_stub_hash_entry* stub;
1086 struct m68hc11_elf_link_hash_table *htab;
1088 htab = m68hc11_elf_hash_table (info);
1089 stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
1090 *name, FALSE, FALSE);
1091 if (stub)
1093 *relocation = stub->stub_offset
1094 + stub->stub_sec->output_section->vma
1095 + stub->stub_sec->output_offset;
1096 *is_far = FALSE;
1099 return TRUE;
1102 /* Relocate a 68hc11/68hc12 ELF section. */
1103 bfd_boolean
1104 elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section,
1105 contents, relocs, local_syms, local_sections)
1106 bfd *output_bfd ATTRIBUTE_UNUSED;
1107 struct bfd_link_info *info;
1108 bfd *input_bfd;
1109 asection *input_section;
1110 bfd_byte *contents;
1111 Elf_Internal_Rela *relocs;
1112 Elf_Internal_Sym *local_syms;
1113 asection **local_sections;
1115 Elf_Internal_Shdr *symtab_hdr;
1116 struct elf_link_hash_entry **sym_hashes;
1117 Elf_Internal_Rela *rel, *relend;
1118 const char *name;
1119 struct m68hc11_page_info *pinfo;
1120 struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
1122 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1123 sym_hashes = elf_sym_hashes (input_bfd);
1125 /* Get memory bank parameters. */
1126 m68hc11_elf_get_bank_parameters (info);
1127 pinfo = &m68hc11_elf_hash_table (info)->pinfo;
1129 rel = relocs;
1130 relend = relocs + input_section->reloc_count;
1131 for (; rel < relend; rel++)
1133 int r_type;
1134 arelent arel;
1135 reloc_howto_type *howto;
1136 unsigned long r_symndx;
1137 Elf_Internal_Sym *sym;
1138 asection *sec;
1139 bfd_vma relocation;
1140 bfd_reloc_status_type r = bfd_reloc_undefined;
1141 bfd_vma phys_page;
1142 bfd_vma phys_addr;
1143 bfd_vma insn_addr;
1144 bfd_vma insn_page;
1145 bfd_boolean is_far;
1147 r_symndx = ELF32_R_SYM (rel->r_info);
1148 r_type = ELF32_R_TYPE (rel->r_info);
1150 if (r_type == R_M68HC11_GNU_VTENTRY
1151 || r_type == R_M68HC11_GNU_VTINHERIT )
1152 continue;
1154 if (info->relocateable)
1156 /* This is a relocateable link. We don't have to change
1157 anything, unless the reloc is against a section symbol,
1158 in which case we have to adjust according to where the
1159 section symbol winds up in the output section. */
1160 if (r_symndx < symtab_hdr->sh_info)
1162 sym = local_syms + r_symndx;
1163 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1165 sec = local_sections[r_symndx];
1166 rel->r_addend += sec->output_offset + sym->st_value;
1170 continue;
1172 (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
1173 howto = arel.howto;
1175 m68hc11_get_relocation_value (input_bfd, info,
1176 local_sections, local_syms,
1177 rel, &name, &relocation, &is_far);
1179 /* Do the memory bank mapping. */
1180 phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1181 phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1182 switch (r_type)
1184 case R_M68HC11_24:
1185 /* Reloc used by 68HC12 call instruction. */
1186 bfd_put_16 (input_bfd, phys_addr,
1187 (bfd_byte*) contents + rel->r_offset);
1188 bfd_put_8 (input_bfd, phys_page,
1189 (bfd_byte*) contents + rel->r_offset + 2);
1190 r = bfd_reloc_ok;
1191 r_type = R_M68HC11_NONE;
1192 break;
1194 case R_M68HC11_NONE:
1195 r = bfd_reloc_ok;
1196 break;
1198 case R_M68HC11_LO16:
1199 /* Reloc generated by %addr(expr) gas to obtain the
1200 address as mapped in the memory bank window. */
1201 relocation = phys_addr;
1202 break;
1204 case R_M68HC11_PAGE:
1205 /* Reloc generated by %page(expr) gas to obtain the
1206 page number associated with the address. */
1207 relocation = phys_page;
1208 break;
1210 case R_M68HC11_16:
1211 /* Get virtual address of instruction having the relocation. */
1212 if (is_far)
1214 const char* msg;
1215 char* buf;
1216 msg = _("Reference to the far symbol `%s' using a wrong "
1217 "relocation may result in incorrect execution");
1218 buf = alloca (strlen (msg) + strlen (name) + 10);
1219 sprintf (buf, msg, name);
1221 (* info->callbacks->warning)
1222 (info, buf, name, input_bfd, NULL, rel->r_offset);
1225 /* Get virtual address of instruction having the relocation. */
1226 insn_addr = input_section->output_section->vma
1227 + input_section->output_offset
1228 + rel->r_offset;
1230 insn_page = m68hc11_phys_page (pinfo, insn_addr);
1232 if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1233 && m68hc11_addr_is_banked (pinfo, insn_addr)
1234 && phys_page != insn_page)
1236 const char* msg;
1237 char* buf;
1239 msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1240 "as current banked address [%lx:%04lx] (%lx)");
1242 buf = alloca (strlen (msg) + 128);
1243 sprintf (buf, msg, phys_page, phys_addr,
1244 (long) (relocation + rel->r_addend),
1245 insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1246 (long) (insn_addr));
1247 if (!((*info->callbacks->warning)
1248 (info, buf, name, input_bfd, input_section,
1249 rel->r_offset)))
1250 return FALSE;
1251 break;
1253 if (phys_page != 0 && insn_page == 0)
1255 const char* msg;
1256 char* buf;
1258 msg = _("reference to a banked address [%lx:%04lx] in the "
1259 "normal address space at %04lx");
1261 buf = alloca (strlen (msg) + 128);
1262 sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1263 if (!((*info->callbacks->warning)
1264 (info, buf, name, input_bfd, input_section,
1265 insn_addr)))
1266 return FALSE;
1268 relocation = phys_addr;
1269 break;
1272 /* If this is a banked address use the phys_addr so that
1273 we stay in the banked window. */
1274 if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1275 relocation = phys_addr;
1276 break;
1278 if (r_type != R_M68HC11_NONE)
1279 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1280 contents, rel->r_offset,
1281 relocation, rel->r_addend);
1283 if (r != bfd_reloc_ok)
1285 const char * msg = (const char *) 0;
1287 switch (r)
1289 case bfd_reloc_overflow:
1290 if (!((*info->callbacks->reloc_overflow)
1291 (info, name, howto->name, (bfd_vma) 0,
1292 input_bfd, input_section, rel->r_offset)))
1293 return FALSE;
1294 break;
1296 case bfd_reloc_undefined:
1297 if (!((*info->callbacks->undefined_symbol)
1298 (info, name, input_bfd, input_section,
1299 rel->r_offset, TRUE)))
1300 return FALSE;
1301 break;
1303 case bfd_reloc_outofrange:
1304 msg = _ ("internal error: out of range error");
1305 goto common_error;
1307 case bfd_reloc_notsupported:
1308 msg = _ ("internal error: unsupported relocation error");
1309 goto common_error;
1311 case bfd_reloc_dangerous:
1312 msg = _ ("internal error: dangerous error");
1313 goto common_error;
1315 default:
1316 msg = _ ("internal error: unknown error");
1317 /* fall through */
1319 common_error:
1320 if (!((*info->callbacks->warning)
1321 (info, msg, name, input_bfd, input_section,
1322 rel->r_offset)))
1323 return FALSE;
1324 break;
1329 return TRUE;
1334 /* Set and control ELF flags in ELF header. */
1336 bfd_boolean
1337 _bfd_m68hc11_elf_set_private_flags (abfd, flags)
1338 bfd *abfd;
1339 flagword flags;
1341 BFD_ASSERT (!elf_flags_init (abfd)
1342 || elf_elfheader (abfd)->e_flags == flags);
1344 elf_elfheader (abfd)->e_flags = flags;
1345 elf_flags_init (abfd) = TRUE;
1346 return TRUE;
1349 /* Merge backend specific data from an object file to the output
1350 object file when linking. */
1352 bfd_boolean
1353 _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
1354 bfd *ibfd;
1355 bfd *obfd;
1357 flagword old_flags;
1358 flagword new_flags;
1359 bfd_boolean ok = TRUE;
1361 /* Check if we have the same endianess */
1362 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1363 return FALSE;
1365 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1366 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1367 return TRUE;
1369 new_flags = elf_elfheader (ibfd)->e_flags;
1370 elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1371 old_flags = elf_elfheader (obfd)->e_flags;
1373 if (! elf_flags_init (obfd))
1375 elf_flags_init (obfd) = TRUE;
1376 elf_elfheader (obfd)->e_flags = new_flags;
1377 elf_elfheader (obfd)->e_ident[EI_CLASS]
1378 = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1380 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1381 && bfd_get_arch_info (obfd)->the_default)
1383 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1384 bfd_get_mach (ibfd)))
1385 return FALSE;
1388 return TRUE;
1391 /* Check ABI compatibility. */
1392 if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1394 (*_bfd_error_handler)
1395 (_("%s: linking files compiled for 16-bit integers (-mshort) "
1396 "and others for 32-bit integers"),
1397 bfd_archive_filename (ibfd));
1398 ok = FALSE;
1400 if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1402 (*_bfd_error_handler)
1403 (_("%s: linking files compiled for 32-bit double (-fshort-double) "
1404 "and others for 64-bit double"),
1405 bfd_archive_filename (ibfd));
1406 ok = FALSE;
1408 new_flags &= ~EF_M68HC11_ABI;
1409 old_flags &= ~EF_M68HC11_ABI;
1411 /* Warn about any other mismatches */
1412 if (new_flags != old_flags)
1414 (*_bfd_error_handler)
1415 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1416 bfd_archive_filename (ibfd), (unsigned long) new_flags,
1417 (unsigned long) old_flags);
1418 ok = FALSE;
1421 if (! ok)
1423 bfd_set_error (bfd_error_bad_value);
1424 return FALSE;
1427 return TRUE;
1430 bfd_boolean
1431 _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
1432 bfd *abfd;
1433 PTR ptr;
1435 FILE *file = (FILE *) ptr;
1437 BFD_ASSERT (abfd != NULL && ptr != NULL);
1439 /* Print normal ELF private data. */
1440 _bfd_elf_print_private_bfd_data (abfd, ptr);
1442 /* xgettext:c-format */
1443 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1445 if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1446 fprintf (file, _("[abi=32-bit int, "));
1447 else
1448 fprintf (file, _("[abi=16-bit int, "));
1450 if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1451 fprintf (file, _("64-bit double, "));
1452 else
1453 fprintf (file, _("32-bit double, "));
1455 if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1456 fprintf (file, _("cpu=HC11]"));
1457 else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1458 fprintf (file, _("cpu=HCS12]"));
1459 else
1460 fprintf (file, _("cpu=HC12]"));
1462 if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1463 fprintf (file, _(" [memory=bank-model]"));
1464 else
1465 fprintf (file, _(" [memory=flat]"));
1467 fputc ('\n', file);
1469 return TRUE;
1472 static void scan_sections_for_abi (abfd, asect, arg)
1473 bfd* abfd ATTRIBUTE_UNUSED;
1474 asection* asect;
1475 PTR arg;
1477 struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1479 if (asect->vma >= p->pinfo->bank_virtual)
1480 p->use_memory_banks = TRUE;
1483 /* Tweak the OSABI field of the elf header. */
1485 void
1486 elf32_m68hc11_post_process_headers (abfd, link_info)
1487 bfd *abfd;
1488 struct bfd_link_info *link_info;
1490 struct m68hc11_scan_param param;
1492 if (link_info == 0)
1493 return;
1495 m68hc11_elf_get_bank_parameters (link_info);
1497 param.use_memory_banks = FALSE;
1498 param.pinfo = &m68hc11_elf_hash_table (link_info)->pinfo;
1499 bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1500 if (param.use_memory_banks)
1502 Elf_Internal_Ehdr * i_ehdrp;
1504 i_ehdrp = elf_elfheader (abfd);
1505 i_ehdrp->e_flags |= E_M68HC12_BANKS;