Do not skip section symbols that are used in relocs.
[binutils.git] / bfd / elf32-m68hc1x.c
blobb31fc7b454b6cae20a7bfe9b8d5ce6af06030283
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_malloc (amt);
79 if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
80 return NULL;
82 memset (ret, 0, amt);
83 if (! _bfd_elf_link_hash_table_init (&ret->root, abfd,
84 _bfd_elf_link_hash_newfunc))
86 free (ret);
87 return NULL;
90 /* Init the stub hash table too. */
91 amt = sizeof (struct bfd_hash_table);
92 ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
93 if (ret->stub_hash_table == NULL)
95 free (ret);
96 return NULL;
98 if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc))
99 return NULL;
101 ret->stub_bfd = NULL;
102 ret->stub_section = 0;
103 ret->add_stub_section = NULL;
104 ret->sym_sec.abfd = NULL;
106 return ret;
109 /* Free the derived linker hash table. */
111 void
112 m68hc11_elf_bfd_link_hash_table_free (hash)
113 struct bfd_link_hash_table *hash;
115 struct m68hc11_elf_link_hash_table *ret
116 = (struct m68hc11_elf_link_hash_table *) hash;
118 bfd_hash_table_free (ret->stub_hash_table);
119 free (ret->stub_hash_table);
120 _bfd_generic_link_hash_table_free (hash);
123 /* Assorted hash table functions. */
125 /* Initialize an entry in the stub hash table. */
127 static struct bfd_hash_entry *
128 stub_hash_newfunc (entry, table, string)
129 struct bfd_hash_entry *entry;
130 struct bfd_hash_table *table;
131 const char *string;
133 /* Allocate the structure if it has not already been allocated by a
134 subclass. */
135 if (entry == NULL)
137 entry = bfd_hash_allocate (table,
138 sizeof (struct elf32_m68hc11_stub_hash_entry));
139 if (entry == NULL)
140 return entry;
143 /* Call the allocation method of the superclass. */
144 entry = bfd_hash_newfunc (entry, table, string);
145 if (entry != NULL)
147 struct elf32_m68hc11_stub_hash_entry *eh;
149 /* Initialize the local fields. */
150 eh = (struct elf32_m68hc11_stub_hash_entry *) entry;
151 eh->stub_sec = NULL;
152 eh->stub_offset = 0;
153 eh->target_value = 0;
154 eh->target_section = NULL;
157 return entry;
160 /* Add a new stub entry to the stub hash. Not all fields of the new
161 stub entry are initialised. */
163 static struct elf32_m68hc11_stub_hash_entry *
164 m68hc12_add_stub (stub_name, section, htab)
165 const char *stub_name;
166 asection *section;
167 struct m68hc11_elf_link_hash_table *htab;
169 struct elf32_m68hc11_stub_hash_entry *stub_entry;
171 /* Enter this entry into the linker stub hash table. */
172 stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name,
173 TRUE, FALSE);
174 if (stub_entry == NULL)
176 (*_bfd_error_handler) (_("%s: cannot create stub entry %s"),
177 bfd_archive_filename (section->owner),
178 stub_name);
179 return NULL;
182 if (htab->stub_section == 0)
184 htab->stub_section = (*htab->add_stub_section) (".tramp",
185 htab->tramp_section);
188 stub_entry->stub_sec = htab->stub_section;
189 stub_entry->stub_offset = 0;
190 return stub_entry;
193 /* Hook called by the linker routine which adds symbols from an object
194 file. We use it for identify far symbols and force a loading of
195 the trampoline handler. */
197 bfd_boolean
198 elf32_m68hc11_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
199 bfd *abfd;
200 struct bfd_link_info *info;
201 const Elf_Internal_Sym *sym;
202 const char **namep ATTRIBUTE_UNUSED;
203 flagword *flagsp ATTRIBUTE_UNUSED;
204 asection **secp ATTRIBUTE_UNUSED;
205 bfd_vma *valp ATTRIBUTE_UNUSED;
207 if (sym->st_other & STO_M68HC12_FAR)
209 struct elf_link_hash_entry *h;
211 h = (struct elf_link_hash_entry *)
212 bfd_link_hash_lookup (info->hash, "__far_trampoline",
213 FALSE, FALSE, FALSE);
214 if (h == NULL)
216 struct bfd_link_hash_entry* entry = NULL;
218 _bfd_generic_link_add_one_symbol (info, abfd,
219 "__far_trampoline",
220 BSF_GLOBAL,
221 bfd_und_section_ptr,
222 (bfd_vma) 0, (const char*) NULL,
223 FALSE, FALSE, &entry);
227 return TRUE;
230 /* External entry points for sizing and building linker stubs. */
232 /* Set up various things so that we can make a list of input sections
233 for each output section included in the link. Returns -1 on error,
234 0 when no stubs will be needed, and 1 on success. */
237 elf32_m68hc11_setup_section_lists (output_bfd, info)
238 bfd *output_bfd;
239 struct bfd_link_info *info;
241 bfd *input_bfd;
242 unsigned int bfd_count;
243 int top_id, top_index;
244 asection *section;
245 asection **input_list, **list;
246 bfd_size_type amt;
247 asection *text_section;
248 struct m68hc11_elf_link_hash_table *htab;
250 htab = m68hc11_elf_hash_table (info);
252 if (htab->root.root.creator->flavour != bfd_target_elf_flavour)
253 return 0;
255 /* Count the number of input BFDs and find the top input section id.
256 Also search for an existing ".tramp" section so that we know
257 where generated trampolines must go. Default to ".text" if we
258 can't find it. */
259 htab->tramp_section = 0;
260 text_section = 0;
261 for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
262 input_bfd != NULL;
263 input_bfd = input_bfd->link_next)
265 bfd_count += 1;
266 for (section = input_bfd->sections;
267 section != NULL;
268 section = section->next)
270 const char* name = bfd_get_section_name (input_bfd, section);
272 if (!strcmp (name, ".tramp"))
273 htab->tramp_section = section;
275 if (!strcmp (name, ".text"))
276 text_section = section;
278 if (top_id < section->id)
279 top_id = section->id;
282 htab->bfd_count = bfd_count;
283 if (htab->tramp_section == 0)
284 htab->tramp_section = text_section;
286 /* We can't use output_bfd->section_count here to find the top output
287 section index as some sections may have been removed, and
288 _bfd_strip_section_from_output doesn't renumber the indices. */
289 for (section = output_bfd->sections, top_index = 0;
290 section != NULL;
291 section = section->next)
293 if (top_index < section->index)
294 top_index = section->index;
297 htab->top_index = top_index;
298 amt = sizeof (asection *) * (top_index + 1);
299 input_list = (asection **) bfd_malloc (amt);
300 htab->input_list = input_list;
301 if (input_list == NULL)
302 return -1;
304 /* For sections we aren't interested in, mark their entries with a
305 value we can check later. */
306 list = input_list + top_index;
308 *list = bfd_abs_section_ptr;
309 while (list-- != input_list);
311 for (section = output_bfd->sections;
312 section != NULL;
313 section = section->next)
315 if ((section->flags & SEC_CODE) != 0)
316 input_list[section->index] = NULL;
319 return 1;
322 /* Determine and set the size of the stub section for a final link.
324 The basic idea here is to examine all the relocations looking for
325 PC-relative calls to a target that is unreachable with a "bl"
326 instruction. */
328 bfd_boolean
329 elf32_m68hc11_size_stubs (output_bfd, stub_bfd, info, add_stub_section)
330 bfd *output_bfd;
331 bfd *stub_bfd;
332 struct bfd_link_info *info;
333 asection * (*add_stub_section) PARAMS ((const char *, asection *));
335 bfd *input_bfd;
336 asection *section;
337 Elf_Internal_Sym *local_syms, **all_local_syms;
338 unsigned int bfd_indx, bfd_count;
339 bfd_size_type amt;
340 asection *stub_sec;
342 struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info);
344 /* Stash our params away. */
345 htab->stub_bfd = stub_bfd;
346 htab->add_stub_section = add_stub_section;
348 /* Count the number of input BFDs and find the top input section id. */
349 for (input_bfd = info->input_bfds, bfd_count = 0;
350 input_bfd != NULL;
351 input_bfd = input_bfd->link_next)
353 bfd_count += 1;
356 /* We want to read in symbol extension records only once. To do this
357 we need to read in the local symbols in parallel and save them for
358 later use; so hold pointers to the local symbols in an array. */
359 amt = sizeof (Elf_Internal_Sym *) * bfd_count;
360 all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
361 if (all_local_syms == NULL)
362 return FALSE;
364 /* Walk over all the input BFDs, swapping in local symbols. */
365 for (input_bfd = info->input_bfds, bfd_indx = 0;
366 input_bfd != NULL;
367 input_bfd = input_bfd->link_next, bfd_indx++)
369 Elf_Internal_Shdr *symtab_hdr;
370 Elf_Internal_Shdr *shndx_hdr;
371 Elf_Internal_Sym *isym;
372 Elf32_External_Sym *extsyms, *esym, *end_sy;
373 Elf_External_Sym_Shndx *shndx_buf, *shndx;
374 bfd_size_type sec_size;
376 /* We'll need the symbol table in a second. */
377 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
378 if (symtab_hdr->sh_info == 0)
379 continue;
381 /* We need an array of the local symbols attached to the input bfd.
382 Unfortunately, we're going to have to read & swap them in. */
383 sec_size = symtab_hdr->sh_info;
384 sec_size *= sizeof (Elf_Internal_Sym);
385 local_syms = (Elf_Internal_Sym *) bfd_malloc (sec_size);
386 if (local_syms == NULL)
387 goto error_ret_free_local;
389 all_local_syms[bfd_indx] = local_syms;
390 sec_size = symtab_hdr->sh_info;
391 sec_size *= sizeof (Elf32_External_Sym);
393 /* Get the cached copy. */
394 if (symtab_hdr->contents != NULL)
395 extsyms = (Elf32_External_Sym *) symtab_hdr->contents;
396 else
398 /* Go get them off disk. */
399 bfd_size_type amt = symtab_hdr->sh_size;
400 extsyms = (Elf32_External_Sym *) bfd_malloc (amt);
401 if (extsyms == NULL)
402 goto error_ret_free_local;
404 if (bfd_seek (input_bfd, symtab_hdr->sh_offset, SEEK_SET) != 0
405 || bfd_bread ((PTR) extsyms, amt, input_bfd) != amt)
407 error_ret_free_ext_syms:
408 free (extsyms);
409 goto error_ret_free_local;
412 shndx_buf = NULL;
413 shndx_hdr = &elf_tdata (input_bfd)->symtab_shndx_hdr;
414 if (shndx_hdr->sh_size != 0)
416 bfd_size_type amt;
418 amt = symtab_hdr->sh_info * sizeof (Elf_External_Sym_Shndx);
419 shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
420 if (shndx_buf == NULL)
421 goto error_ret_free_ext_syms;
422 if (bfd_seek (input_bfd, shndx_hdr->sh_offset, SEEK_SET) != 0
423 || bfd_bread ((PTR) shndx_buf, amt, input_bfd) != amt)
425 free (shndx_buf);
426 goto error_ret_free_ext_syms;
428 shndx_hdr->contents = (PTR) shndx_buf;
431 /* Swap the local symbols in. */
432 for (esym = extsyms, end_sy = esym + symtab_hdr->sh_info,
433 isym = local_syms, shndx = shndx_buf;
434 esym < end_sy;
435 esym++, isym++, shndx = (shndx ? shndx + 1 : NULL))
436 bfd_elf32_swap_symbol_in (input_bfd, esym, shndx, isym);
438 /* Now we can free the external symbols. */
439 free (shndx_buf);
442 for (input_bfd = info->input_bfds, bfd_indx = 0;
443 input_bfd != NULL;
444 input_bfd = input_bfd->link_next, bfd_indx++)
446 Elf_Internal_Shdr *symtab_hdr;
447 Elf_Internal_Sym *local_syms;
448 struct elf_link_hash_entry ** sym_hashes;
450 sym_hashes = elf_sym_hashes (input_bfd);
452 /* We'll need the symbol table in a second. */
453 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
454 if (symtab_hdr->sh_info == 0)
455 continue;
457 local_syms = all_local_syms[bfd_indx];
459 /* Walk over each section attached to the input bfd. */
460 for (section = input_bfd->sections;
461 section != NULL;
462 section = section->next)
464 Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
466 /* If there aren't any relocs, then there's nothing more
467 to do. */
468 if ((section->flags & SEC_RELOC) == 0
469 || section->reloc_count == 0)
470 continue;
472 /* If this section is a link-once section that will be
473 discarded, then don't create any stubs. */
474 if (section->output_section == NULL
475 || section->output_section->owner != output_bfd)
476 continue;
478 /* Get the relocs. */
479 internal_relocs
480 = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
481 (Elf_Internal_Rela *) NULL,
482 info->keep_memory);
483 if (internal_relocs == NULL)
484 goto error_ret_free_local;
486 /* Now examine each relocation. */
487 irela = internal_relocs;
488 irelaend = irela + section->reloc_count;
489 for (; irela < irelaend; irela++)
491 unsigned int r_type, r_indx;
492 struct elf32_m68hc11_stub_hash_entry *stub_entry;
493 asection *sym_sec;
494 bfd_vma sym_value;
495 struct elf_link_hash_entry *hash;
496 const char *stub_name;
497 Elf_Internal_Sym *sym;
499 r_type = ELF32_R_TYPE (irela->r_info);
501 /* Only look at 16-bit relocs. */
502 if (r_type != (unsigned int) R_M68HC11_16)
503 continue;
505 /* Now determine the call target, its name, value,
506 section. */
507 r_indx = ELF32_R_SYM (irela->r_info);
508 if (r_indx < symtab_hdr->sh_info)
510 /* It's a local symbol. */
511 Elf_Internal_Shdr *hdr;
512 bfd_boolean is_far;
514 sym = local_syms + r_indx;
515 is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
516 if (!is_far)
517 continue;
519 hdr = elf_elfsections (input_bfd)[sym->st_shndx];
520 sym_sec = hdr->bfd_section;
521 stub_name = (bfd_elf_string_from_elf_section
522 (input_bfd, symtab_hdr->sh_link,
523 sym->st_name));
524 sym_value = sym->st_value;
525 hash = NULL;
527 else
529 /* It's an external symbol. */
530 int e_indx;
532 e_indx = r_indx - symtab_hdr->sh_info;
533 hash = (struct elf_link_hash_entry *)
534 (sym_hashes[e_indx]);
536 while (hash->root.type == bfd_link_hash_indirect
537 || hash->root.type == bfd_link_hash_warning)
538 hash = ((struct elf_link_hash_entry *)
539 hash->root.u.i.link);
541 if (hash->root.type == bfd_link_hash_defined
542 || hash->root.type == bfd_link_hash_defweak)
544 if (!(hash->other & STO_M68HC12_FAR))
545 continue;
547 else if (hash->root.type == bfd_link_hash_undefweak)
549 continue;
551 else if (hash->root.type == bfd_link_hash_undefined)
553 continue;
555 else
557 bfd_set_error (bfd_error_bad_value);
558 goto error_ret_free_internal;
560 sym_sec = hash->root.u.def.section;
561 sym_value = hash->root.u.def.value;
562 stub_name = hash->root.root.string;
565 if (!stub_name)
566 goto error_ret_free_internal;
568 stub_entry = m68hc12_stub_hash_lookup
569 (htab->stub_hash_table,
570 stub_name,
571 FALSE, FALSE);
572 if (stub_entry == NULL)
574 if (add_stub_section == 0)
575 continue;
577 stub_entry = m68hc12_add_stub (stub_name, section, htab);
578 if (stub_entry == NULL)
580 error_ret_free_internal:
581 if (elf_section_data (section)->relocs == NULL)
582 free (internal_relocs);
583 goto error_ret_free_local;
587 stub_entry->target_value = sym_value;
588 stub_entry->target_section = sym_sec;
591 /* We're done with the internal relocs, free them. */
592 if (elf_section_data (section)->relocs == NULL)
593 free (internal_relocs);
597 if (add_stub_section)
599 /* OK, we've added some stubs. Find out the new size of the
600 stub sections. */
601 for (stub_sec = htab->stub_bfd->sections;
602 stub_sec != NULL;
603 stub_sec = stub_sec->next)
605 stub_sec->_raw_size = 0;
606 stub_sec->_cooked_size = 0;
609 bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
611 free (htab->all_local_syms);
612 return TRUE;
614 error_ret_free_local:
615 free (htab->all_local_syms);
616 return FALSE;
619 /* Export the trampoline addresses in the symbol table. */
620 static bfd_boolean
621 m68hc11_elf_export_one_stub (gen_entry, in_arg)
622 struct bfd_hash_entry *gen_entry;
623 PTR in_arg;
625 struct bfd_link_info *info;
626 struct m68hc11_elf_link_hash_table *htab;
627 struct elf32_m68hc11_stub_hash_entry *stub_entry;
628 char* name;
629 bfd_boolean result;
631 info = (struct bfd_link_info *) in_arg;
632 htab = m68hc11_elf_hash_table (info);
634 /* Massage our args to the form they really have. */
635 stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
637 /* Generate the trampoline according to HC11 or HC12. */
638 result = (* htab->build_one_stub) (gen_entry, in_arg);
640 /* Make a printable name that does not conflict with the real function. */
641 name = alloca (strlen (stub_entry->root.string) + 16);
642 sprintf (name, "tramp.%s", stub_entry->root.string);
644 /* Export the symbol for debugging/disassembling. */
645 m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
646 stub_entry->stub_offset,
647 stub_entry->stub_sec);
648 return result;
651 /* Export a symbol or set its value and section. */
652 static void
653 m68hc11_elf_set_symbol (abfd, info, name, value, sec)
654 bfd* abfd;
655 struct bfd_link_info *info;
656 const char* name;
657 bfd_vma value;
658 asection* sec;
660 struct elf_link_hash_entry *h;
662 h = (struct elf_link_hash_entry *)
663 bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
664 if (h == NULL)
666 _bfd_generic_link_add_one_symbol (info, abfd,
667 name,
668 BSF_GLOBAL,
669 sec,
670 value,
671 (const char*) NULL,
672 TRUE, FALSE, NULL);
674 else
676 h->root.type = bfd_link_hash_defined;
677 h->root.u.def.value = value;
678 h->root.u.def.section = sec;
683 /* Build all the stubs associated with the current output file. The
684 stubs are kept in a hash table attached to the main linker hash
685 table. This function is called via m68hc12elf_finish in the
686 linker. */
688 bfd_boolean
689 elf32_m68hc11_build_stubs (abfd, info)
690 bfd* abfd;
691 struct bfd_link_info *info;
693 asection *stub_sec;
694 struct bfd_hash_table *table;
695 struct m68hc11_elf_link_hash_table *htab;
696 struct m68hc11_scan_param param;
698 m68hc11_elf_get_bank_parameters (info);
699 htab = m68hc11_elf_hash_table (info);
701 for (stub_sec = htab->stub_bfd->sections;
702 stub_sec != NULL;
703 stub_sec = stub_sec->next)
705 bfd_size_type size;
707 /* Allocate memory to hold the linker stubs. */
708 size = stub_sec->_raw_size;
709 stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
710 if (stub_sec->contents == NULL && size != 0)
711 return FALSE;
712 stub_sec->_raw_size = 0;
715 /* Build the stubs as directed by the stub hash table. */
716 table = htab->stub_hash_table;
717 bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
719 /* Scan the output sections to see if we use the memory banks.
720 If so, export the symbols that define how the memory banks
721 are mapped. This is used by gdb and the simulator to obtain
722 the information. It can be used by programs to burn the eprom
723 at the good addresses. */
724 param.use_memory_banks = FALSE;
725 param.pinfo = &htab->pinfo;
726 bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
727 if (param.use_memory_banks)
729 m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
730 htab->pinfo.bank_physical,
731 bfd_abs_section_ptr);
732 m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
733 htab->pinfo.bank_virtual,
734 bfd_abs_section_ptr);
735 m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
736 htab->pinfo.bank_size,
737 bfd_abs_section_ptr);
740 return TRUE;
743 void
744 m68hc11_elf_get_bank_parameters (info)
745 struct bfd_link_info *info;
747 unsigned i;
748 struct m68hc11_page_info *pinfo;
749 struct bfd_link_hash_entry *h;
751 pinfo = &m68hc11_elf_hash_table (info)->pinfo;
752 if (pinfo->bank_param_initialized)
753 return;
755 pinfo->bank_virtual = M68HC12_BANK_VIRT;
756 pinfo->bank_mask = M68HC12_BANK_MASK;
757 pinfo->bank_physical = M68HC12_BANK_BASE;
758 pinfo->bank_shift = M68HC12_BANK_SHIFT;
759 pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
761 h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
762 FALSE, FALSE, TRUE);
763 if (h != (struct bfd_link_hash_entry*) NULL
764 && h->type == bfd_link_hash_defined)
765 pinfo->bank_physical = (h->u.def.value
766 + h->u.def.section->output_section->vma
767 + h->u.def.section->output_offset);
769 h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
770 FALSE, FALSE, TRUE);
771 if (h != (struct bfd_link_hash_entry*) NULL
772 && h->type == bfd_link_hash_defined)
773 pinfo->bank_virtual = (h->u.def.value
774 + h->u.def.section->output_section->vma
775 + h->u.def.section->output_offset);
777 h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
778 FALSE, FALSE, TRUE);
779 if (h != (struct bfd_link_hash_entry*) NULL
780 && h->type == bfd_link_hash_defined)
781 pinfo->bank_size = (h->u.def.value
782 + h->u.def.section->output_section->vma
783 + h->u.def.section->output_offset);
785 pinfo->bank_shift = 0;
786 for (i = pinfo->bank_size; i != 0; i >>= 1)
787 pinfo->bank_shift++;
788 pinfo->bank_shift--;
789 pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
790 pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
791 pinfo->bank_param_initialized = 1;
793 h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
794 FALSE, TRUE);
795 if (h != (struct bfd_link_hash_entry*) NULL
796 && h->type == bfd_link_hash_defined)
797 pinfo->trampoline_addr = (h->u.def.value
798 + h->u.def.section->output_section->vma
799 + h->u.def.section->output_offset);
802 /* Return 1 if the address is in banked memory.
803 This can be applied to a virtual address and to a physical address. */
805 m68hc11_addr_is_banked (pinfo, addr)
806 struct m68hc11_page_info *pinfo;
807 bfd_vma addr;
809 if (addr >= pinfo->bank_virtual)
810 return 1;
812 if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
813 return 1;
815 return 0;
818 /* Return the physical address seen by the processor, taking
819 into account banked memory. */
820 bfd_vma
821 m68hc11_phys_addr (pinfo, addr)
822 struct m68hc11_page_info *pinfo;
823 bfd_vma addr;
825 if (addr < pinfo->bank_virtual)
826 return addr;
828 /* Map the address to the memory bank. */
829 addr -= pinfo->bank_virtual;
830 addr &= pinfo->bank_mask;
831 addr += pinfo->bank_physical;
832 return addr;
835 /* Return the page number corresponding to an address in banked memory. */
836 bfd_vma
837 m68hc11_phys_page (pinfo, addr)
838 struct m68hc11_page_info *pinfo;
839 bfd_vma addr;
841 if (addr < pinfo->bank_virtual)
842 return 0;
844 /* Map the address to the memory bank. */
845 addr -= pinfo->bank_virtual;
846 addr >>= pinfo->bank_shift;
847 addr &= 0x0ff;
848 return addr;
851 /* This function is used for relocs which are only used for relaxing,
852 which the linker should otherwise ignore. */
854 bfd_reloc_status_type
855 m68hc11_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
856 output_bfd, error_message)
857 bfd *abfd ATTRIBUTE_UNUSED;
858 arelent *reloc_entry;
859 asymbol *symbol ATTRIBUTE_UNUSED;
860 PTR data ATTRIBUTE_UNUSED;
861 asection *input_section;
862 bfd *output_bfd;
863 char **error_message ATTRIBUTE_UNUSED;
865 if (output_bfd != NULL)
866 reloc_entry->address += input_section->output_offset;
867 return bfd_reloc_ok;
870 bfd_reloc_status_type
871 m68hc11_elf_special_reloc (abfd, reloc_entry, symbol, data, input_section,
872 output_bfd, error_message)
873 bfd *abfd ATTRIBUTE_UNUSED;
874 arelent *reloc_entry;
875 asymbol *symbol;
876 PTR data ATTRIBUTE_UNUSED;
877 asection *input_section;
878 bfd *output_bfd;
879 char **error_message ATTRIBUTE_UNUSED;
881 if (output_bfd != (bfd *) NULL
882 && (symbol->flags & BSF_SECTION_SYM) == 0
883 && (! reloc_entry->howto->partial_inplace
884 || reloc_entry->addend == 0))
886 reloc_entry->address += input_section->output_offset;
887 return bfd_reloc_ok;
890 if (output_bfd != NULL)
891 return bfd_reloc_continue;
893 if (reloc_entry->address > input_section->_cooked_size)
894 return bfd_reloc_outofrange;
896 abort();
899 asection *
900 elf32_m68hc11_gc_mark_hook (sec, info, rel, h, sym)
901 asection *sec;
902 struct bfd_link_info *info ATTRIBUTE_UNUSED;
903 Elf_Internal_Rela *rel;
904 struct elf_link_hash_entry *h;
905 Elf_Internal_Sym *sym;
907 if (h != NULL)
909 switch (ELF32_R_TYPE (rel->r_info))
911 default:
912 switch (h->root.type)
914 case bfd_link_hash_defined:
915 case bfd_link_hash_defweak:
916 return h->root.u.def.section;
918 case bfd_link_hash_common:
919 return h->root.u.c.p->section;
921 default:
922 break;
926 else
927 return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
929 return NULL;
932 bfd_boolean
933 elf32_m68hc11_gc_sweep_hook (abfd, info, sec, relocs)
934 bfd *abfd ATTRIBUTE_UNUSED;
935 struct bfd_link_info *info ATTRIBUTE_UNUSED;
936 asection *sec ATTRIBUTE_UNUSED;
937 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
939 /* We don't use got and plt entries for 68hc11/68hc12. */
940 return TRUE;
943 /* Look through the relocs for a section during the first phase.
944 Since we don't do .gots or .plts, we just need to consider the
945 virtual table relocs for gc. */
947 bfd_boolean
948 elf32_m68hc11_check_relocs (abfd, info, sec, relocs)
949 bfd * abfd;
950 struct bfd_link_info * info;
951 asection * sec;
952 const Elf_Internal_Rela * relocs;
954 Elf_Internal_Shdr * symtab_hdr;
955 struct elf_link_hash_entry ** sym_hashes;
956 struct elf_link_hash_entry ** sym_hashes_end;
957 const Elf_Internal_Rela * rel;
958 const Elf_Internal_Rela * rel_end;
960 if (info->relocatable)
961 return TRUE;
963 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
964 sym_hashes = elf_sym_hashes (abfd);
965 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
966 if (!elf_bad_symtab (abfd))
967 sym_hashes_end -= symtab_hdr->sh_info;
969 rel_end = relocs + sec->reloc_count;
971 for (rel = relocs; rel < rel_end; rel++)
973 struct elf_link_hash_entry * h;
974 unsigned long r_symndx;
976 r_symndx = ELF32_R_SYM (rel->r_info);
978 if (r_symndx < symtab_hdr->sh_info)
979 h = NULL;
980 else
981 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
983 switch (ELF32_R_TYPE (rel->r_info))
985 /* This relocation describes the C++ object vtable hierarchy.
986 Reconstruct it for later use during GC. */
987 case R_M68HC11_GNU_VTINHERIT:
988 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
989 return FALSE;
990 break;
992 /* This relocation describes which C++ vtable entries are actually
993 used. Record for later use during GC. */
994 case R_M68HC11_GNU_VTENTRY:
995 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
996 return FALSE;
997 break;
1001 return TRUE;
1004 static bfd_boolean
1005 m68hc11_get_relocation_value (abfd, info, local_sections, local_syms,
1006 rel, name,
1007 relocation, is_far)
1008 bfd *abfd;
1009 struct bfd_link_info *info;
1010 asection **local_sections;
1011 Elf_Internal_Sym* local_syms;
1012 Elf_Internal_Rela* rel;
1013 const char** name;
1014 bfd_vma* relocation;
1015 bfd_boolean* is_far;
1017 Elf_Internal_Shdr *symtab_hdr;
1018 struct elf_link_hash_entry **sym_hashes;
1019 unsigned long r_symndx;
1020 asection *sec;
1021 struct elf_link_hash_entry *h;
1022 Elf_Internal_Sym *sym;
1023 const char* stub_name = 0;
1025 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1026 sym_hashes = elf_sym_hashes (abfd);
1028 r_symndx = ELF32_R_SYM (rel->r_info);
1030 /* This is a final link. */
1031 h = NULL;
1032 sym = NULL;
1033 sec = NULL;
1034 if (r_symndx < symtab_hdr->sh_info)
1036 sym = local_syms + r_symndx;
1037 sec = local_sections[r_symndx];
1038 *relocation = (sec->output_section->vma
1039 + sec->output_offset
1040 + sym->st_value);
1041 *is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
1042 if (*is_far)
1043 stub_name = (bfd_elf_string_from_elf_section
1044 (abfd, symtab_hdr->sh_link,
1045 sym->st_name));
1047 else
1049 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1050 while (h->root.type == bfd_link_hash_indirect
1051 || h->root.type == bfd_link_hash_warning)
1052 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1053 if (h->root.type == bfd_link_hash_defined
1054 || h->root.type == bfd_link_hash_defweak)
1056 sec = h->root.u.def.section;
1057 *relocation = (h->root.u.def.value
1058 + sec->output_section->vma
1059 + sec->output_offset);
1061 else if (h->root.type == bfd_link_hash_undefweak)
1062 *relocation = 0;
1063 else
1065 if (!((*info->callbacks->undefined_symbol)
1066 (info, h->root.root.string, abfd,
1067 sec, rel->r_offset, TRUE)))
1068 return FALSE;
1069 *relocation = 0;
1071 *is_far = (h && (h->other & STO_M68HC12_FAR));
1072 stub_name = h->root.root.string;
1075 if (h != NULL)
1076 *name = h->root.root.string;
1077 else
1079 *name = (bfd_elf_string_from_elf_section
1080 (abfd, symtab_hdr->sh_link, sym->st_name));
1081 if (*name == NULL || **name == '\0')
1082 *name = bfd_section_name (input_bfd, sec);
1085 if (*is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
1087 struct elf32_m68hc11_stub_hash_entry* stub;
1088 struct m68hc11_elf_link_hash_table *htab;
1090 htab = m68hc11_elf_hash_table (info);
1091 stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
1092 *name, FALSE, FALSE);
1093 if (stub)
1095 *relocation = stub->stub_offset
1096 + stub->stub_sec->output_section->vma
1097 + stub->stub_sec->output_offset;
1098 *is_far = FALSE;
1101 return TRUE;
1104 /* Relocate a 68hc11/68hc12 ELF section. */
1105 bfd_boolean
1106 elf32_m68hc11_relocate_section (output_bfd, info, input_bfd, input_section,
1107 contents, relocs, local_syms, local_sections)
1108 bfd *output_bfd ATTRIBUTE_UNUSED;
1109 struct bfd_link_info *info;
1110 bfd *input_bfd;
1111 asection *input_section;
1112 bfd_byte *contents;
1113 Elf_Internal_Rela *relocs;
1114 Elf_Internal_Sym *local_syms;
1115 asection **local_sections;
1117 Elf_Internal_Shdr *symtab_hdr;
1118 struct elf_link_hash_entry **sym_hashes;
1119 Elf_Internal_Rela *rel, *relend;
1120 const char *name;
1121 struct m68hc11_page_info *pinfo;
1122 const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
1124 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1125 sym_hashes = elf_sym_hashes (input_bfd);
1127 /* Get memory bank parameters. */
1128 m68hc11_elf_get_bank_parameters (info);
1129 pinfo = &m68hc11_elf_hash_table (info)->pinfo;
1131 rel = relocs;
1132 relend = relocs + input_section->reloc_count;
1133 for (; rel < relend; rel++)
1135 int r_type;
1136 arelent arel;
1137 reloc_howto_type *howto;
1138 unsigned long r_symndx;
1139 Elf_Internal_Sym *sym;
1140 asection *sec;
1141 bfd_vma relocation;
1142 bfd_reloc_status_type r = bfd_reloc_undefined;
1143 bfd_vma phys_page;
1144 bfd_vma phys_addr;
1145 bfd_vma insn_addr;
1146 bfd_vma insn_page;
1147 bfd_boolean is_far;
1149 r_symndx = ELF32_R_SYM (rel->r_info);
1150 r_type = ELF32_R_TYPE (rel->r_info);
1152 if (r_type == R_M68HC11_GNU_VTENTRY
1153 || r_type == R_M68HC11_GNU_VTINHERIT )
1154 continue;
1156 if (info->relocatable)
1158 /* This is a relocatable link. We don't have to change
1159 anything, unless the reloc is against a section symbol,
1160 in which case we have to adjust according to where the
1161 section symbol winds up in the output section. */
1162 if (r_symndx < symtab_hdr->sh_info)
1164 sym = local_syms + r_symndx;
1165 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1167 sec = local_sections[r_symndx];
1168 rel->r_addend += sec->output_offset + sym->st_value;
1172 continue;
1174 (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
1175 howto = arel.howto;
1177 m68hc11_get_relocation_value (input_bfd, info,
1178 local_sections, local_syms,
1179 rel, &name, &relocation, &is_far);
1181 /* Do the memory bank mapping. */
1182 phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1183 phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1184 switch (r_type)
1186 case R_M68HC11_24:
1187 /* Reloc used by 68HC12 call instruction. */
1188 bfd_put_16 (input_bfd, phys_addr,
1189 (bfd_byte*) contents + rel->r_offset);
1190 bfd_put_8 (input_bfd, phys_page,
1191 (bfd_byte*) contents + rel->r_offset + 2);
1192 r = bfd_reloc_ok;
1193 r_type = R_M68HC11_NONE;
1194 break;
1196 case R_M68HC11_NONE:
1197 r = bfd_reloc_ok;
1198 break;
1200 case R_M68HC11_LO16:
1201 /* Reloc generated by %addr(expr) gas to obtain the
1202 address as mapped in the memory bank window. */
1203 relocation = phys_addr;
1204 break;
1206 case R_M68HC11_PAGE:
1207 /* Reloc generated by %page(expr) gas to obtain the
1208 page number associated with the address. */
1209 relocation = phys_page;
1210 break;
1212 case R_M68HC11_16:
1213 /* Get virtual address of instruction having the relocation. */
1214 if (is_far)
1216 const char* msg;
1217 char* buf;
1218 msg = _("Reference to the far symbol `%s' using a wrong "
1219 "relocation may result in incorrect execution");
1220 buf = alloca (strlen (msg) + strlen (name) + 10);
1221 sprintf (buf, msg, name);
1223 (* info->callbacks->warning)
1224 (info, buf, name, input_bfd, NULL, rel->r_offset);
1227 /* Get virtual address of instruction having the relocation. */
1228 insn_addr = input_section->output_section->vma
1229 + input_section->output_offset
1230 + rel->r_offset;
1232 insn_page = m68hc11_phys_page (pinfo, insn_addr);
1234 if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1235 && m68hc11_addr_is_banked (pinfo, insn_addr)
1236 && phys_page != insn_page)
1238 const char* msg;
1239 char* buf;
1241 msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1242 "as current banked address [%lx:%04lx] (%lx)");
1244 buf = alloca (strlen (msg) + 128);
1245 sprintf (buf, msg, phys_page, phys_addr,
1246 (long) (relocation + rel->r_addend),
1247 insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1248 (long) (insn_addr));
1249 if (!((*info->callbacks->warning)
1250 (info, buf, name, input_bfd, input_section,
1251 rel->r_offset)))
1252 return FALSE;
1253 break;
1255 if (phys_page != 0 && insn_page == 0)
1257 const char* msg;
1258 char* buf;
1260 msg = _("reference to a banked address [%lx:%04lx] in the "
1261 "normal address space at %04lx");
1263 buf = alloca (strlen (msg) + 128);
1264 sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1265 if (!((*info->callbacks->warning)
1266 (info, buf, name, input_bfd, input_section,
1267 insn_addr)))
1268 return FALSE;
1270 relocation = phys_addr;
1271 break;
1274 /* If this is a banked address use the phys_addr so that
1275 we stay in the banked window. */
1276 if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1277 relocation = phys_addr;
1278 break;
1280 if (r_type != R_M68HC11_NONE)
1281 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1282 contents, rel->r_offset,
1283 relocation, rel->r_addend);
1285 if (r != bfd_reloc_ok)
1287 const char * msg = (const char *) 0;
1289 switch (r)
1291 case bfd_reloc_overflow:
1292 if (!((*info->callbacks->reloc_overflow)
1293 (info, name, howto->name, (bfd_vma) 0,
1294 input_bfd, input_section, rel->r_offset)))
1295 return FALSE;
1296 break;
1298 case bfd_reloc_undefined:
1299 if (!((*info->callbacks->undefined_symbol)
1300 (info, name, input_bfd, input_section,
1301 rel->r_offset, TRUE)))
1302 return FALSE;
1303 break;
1305 case bfd_reloc_outofrange:
1306 msg = _ ("internal error: out of range error");
1307 goto common_error;
1309 case bfd_reloc_notsupported:
1310 msg = _ ("internal error: unsupported relocation error");
1311 goto common_error;
1313 case bfd_reloc_dangerous:
1314 msg = _ ("internal error: dangerous error");
1315 goto common_error;
1317 default:
1318 msg = _ ("internal error: unknown error");
1319 /* fall through */
1321 common_error:
1322 if (!((*info->callbacks->warning)
1323 (info, msg, name, input_bfd, input_section,
1324 rel->r_offset)))
1325 return FALSE;
1326 break;
1331 return TRUE;
1336 /* Set and control ELF flags in ELF header. */
1338 bfd_boolean
1339 _bfd_m68hc11_elf_set_private_flags (abfd, flags)
1340 bfd *abfd;
1341 flagword flags;
1343 BFD_ASSERT (!elf_flags_init (abfd)
1344 || elf_elfheader (abfd)->e_flags == flags);
1346 elf_elfheader (abfd)->e_flags = flags;
1347 elf_flags_init (abfd) = TRUE;
1348 return TRUE;
1351 /* Merge backend specific data from an object file to the output
1352 object file when linking. */
1354 bfd_boolean
1355 _bfd_m68hc11_elf_merge_private_bfd_data (ibfd, obfd)
1356 bfd *ibfd;
1357 bfd *obfd;
1359 flagword old_flags;
1360 flagword new_flags;
1361 bfd_boolean ok = TRUE;
1363 /* Check if we have the same endianess */
1364 if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1365 return FALSE;
1367 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1368 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1369 return TRUE;
1371 new_flags = elf_elfheader (ibfd)->e_flags;
1372 elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1373 old_flags = elf_elfheader (obfd)->e_flags;
1375 if (! elf_flags_init (obfd))
1377 elf_flags_init (obfd) = TRUE;
1378 elf_elfheader (obfd)->e_flags = new_flags;
1379 elf_elfheader (obfd)->e_ident[EI_CLASS]
1380 = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1382 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1383 && bfd_get_arch_info (obfd)->the_default)
1385 if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1386 bfd_get_mach (ibfd)))
1387 return FALSE;
1390 return TRUE;
1393 /* Check ABI compatibility. */
1394 if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1396 (*_bfd_error_handler)
1397 (_("%s: linking files compiled for 16-bit integers (-mshort) "
1398 "and others for 32-bit integers"),
1399 bfd_archive_filename (ibfd));
1400 ok = FALSE;
1402 if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1404 (*_bfd_error_handler)
1405 (_("%s: linking files compiled for 32-bit double (-fshort-double) "
1406 "and others for 64-bit double"),
1407 bfd_archive_filename (ibfd));
1408 ok = FALSE;
1411 /* Processor compatibility. */
1412 if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1414 (*_bfd_error_handler)
1415 (_("%s: linking files compiled for HCS12 with "
1416 "others compiled for HC12"),
1417 bfd_archive_filename (ibfd));
1418 ok = FALSE;
1420 new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
1421 | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
1423 elf_elfheader (obfd)->e_flags = new_flags;
1425 new_flags &= ~EF_M68HC11_ABI;
1426 old_flags &= ~EF_M68HC11_ABI;
1428 /* Warn about any other mismatches */
1429 if (new_flags != old_flags)
1431 (*_bfd_error_handler)
1432 (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1433 bfd_archive_filename (ibfd), (unsigned long) new_flags,
1434 (unsigned long) old_flags);
1435 ok = FALSE;
1438 if (! ok)
1440 bfd_set_error (bfd_error_bad_value);
1441 return FALSE;
1444 return TRUE;
1447 bfd_boolean
1448 _bfd_m68hc11_elf_print_private_bfd_data (abfd, ptr)
1449 bfd *abfd;
1450 PTR ptr;
1452 FILE *file = (FILE *) ptr;
1454 BFD_ASSERT (abfd != NULL && ptr != NULL);
1456 /* Print normal ELF private data. */
1457 _bfd_elf_print_private_bfd_data (abfd, ptr);
1459 /* xgettext:c-format */
1460 fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1462 if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1463 fprintf (file, _("[abi=32-bit int, "));
1464 else
1465 fprintf (file, _("[abi=16-bit int, "));
1467 if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1468 fprintf (file, _("64-bit double, "));
1469 else
1470 fprintf (file, _("32-bit double, "));
1472 if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1473 fprintf (file, _("cpu=HC11]"));
1474 else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1475 fprintf (file, _("cpu=HCS12]"));
1476 else
1477 fprintf (file, _("cpu=HC12]"));
1479 if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1480 fprintf (file, _(" [memory=bank-model]"));
1481 else
1482 fprintf (file, _(" [memory=flat]"));
1484 fputc ('\n', file);
1486 return TRUE;
1489 static void scan_sections_for_abi (abfd, asect, arg)
1490 bfd* abfd ATTRIBUTE_UNUSED;
1491 asection* asect;
1492 PTR arg;
1494 struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1496 if (asect->vma >= p->pinfo->bank_virtual)
1497 p->use_memory_banks = TRUE;
1500 /* Tweak the OSABI field of the elf header. */
1502 void
1503 elf32_m68hc11_post_process_headers (abfd, link_info)
1504 bfd *abfd;
1505 struct bfd_link_info *link_info;
1507 struct m68hc11_scan_param param;
1509 if (link_info == 0)
1510 return;
1512 m68hc11_elf_get_bank_parameters (link_info);
1514 param.use_memory_banks = FALSE;
1515 param.pinfo = &m68hc11_elf_hash_table (link_info)->pinfo;
1516 bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1517 if (param.use_memory_banks)
1519 Elf_Internal_Ehdr * i_ehdrp;
1521 i_ehdrp = elf_elfheader (abfd);
1522 i_ehdrp->e_flags |= E_M68HC12_BANKS;