1/* Motorola 68HC11/HC12-specific support for 32-bit ELF
2   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3   Free Software Foundation, Inc.
4   Contributed by Stephane Carrez (stcarrez@nerim.fr)
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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
21
22#include "bfd.h"
23#include "sysdep.h"
24#include "bfdlink.h"
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "elf32-m68hc1x.h"
28#include "elf/m68hc11.h"
29#include "opcode/m68hc11.h"
30
31
32#define m68hc12_stub_hash_lookup(table, string, create, copy) \
33  ((struct elf32_m68hc11_stub_hash_entry *) \
34   bfd_hash_lookup ((table), (string), (create), (copy)))
35
36static struct elf32_m68hc11_stub_hash_entry* m68hc12_add_stub
37  (const char *stub_name,
38   asection *section,
39   struct m68hc11_elf_link_hash_table *htab);
40
41static struct bfd_hash_entry *stub_hash_newfunc
42  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
43
44static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
45                                    const char* name, bfd_vma value,
46                                    asection* sec);
47
48static bfd_boolean m68hc11_elf_export_one_stub
49  (struct bfd_hash_entry *gen_entry, void *in_arg);
50
51static void scan_sections_for_abi (bfd*, asection*, PTR);
52
53struct m68hc11_scan_param
54{
55   struct m68hc11_page_info* pinfo;
56   bfd_boolean use_memory_banks;
57};
58
59
60/* Create a 68HC11/68HC12 ELF linker hash table.  */
61
62struct m68hc11_elf_link_hash_table*
63m68hc11_elf_hash_table_create (bfd *abfd)
64{
65  struct m68hc11_elf_link_hash_table *ret;
66  bfd_size_type amt = sizeof (struct m68hc11_elf_link_hash_table);
67
68  ret = (struct m68hc11_elf_link_hash_table *) bfd_malloc (amt);
69  if (ret == (struct m68hc11_elf_link_hash_table *) NULL)
70    return NULL;
71
72  memset (ret, 0, amt);
73  if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
74				      _bfd_elf_link_hash_newfunc,
75				      sizeof (struct elf_link_hash_entry)))
76    {
77      free (ret);
78      return NULL;
79    }
80
81  /* Init the stub hash table too.  */
82  amt = sizeof (struct bfd_hash_table);
83  ret->stub_hash_table = (struct bfd_hash_table*) bfd_malloc (amt);
84  if (ret->stub_hash_table == NULL)
85    {
86      free (ret);
87      return NULL;
88    }
89  if (!bfd_hash_table_init (ret->stub_hash_table, stub_hash_newfunc,
90			    sizeof (struct elf32_m68hc11_stub_hash_entry)))
91    return NULL;
92
93  ret->stub_bfd = NULL;
94  ret->stub_section = 0;
95  ret->add_stub_section = NULL;
96  ret->sym_sec.abfd = NULL;
97
98  return ret;
99}
100
101/* Free the derived linker hash table.  */
102
103void
104m68hc11_elf_bfd_link_hash_table_free (struct bfd_link_hash_table *hash)
105{
106  struct m68hc11_elf_link_hash_table *ret
107    = (struct m68hc11_elf_link_hash_table *) hash;
108
109  bfd_hash_table_free (ret->stub_hash_table);
110  free (ret->stub_hash_table);
111  _bfd_generic_link_hash_table_free (hash);
112}
113
114/* Assorted hash table functions.  */
115
116/* Initialize an entry in the stub hash table.  */
117
118static struct bfd_hash_entry *
119stub_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
120                   const char *string)
121{
122  /* Allocate the structure if it has not already been allocated by a
123     subclass.  */
124  if (entry == NULL)
125    {
126      entry = bfd_hash_allocate (table,
127				 sizeof (struct elf32_m68hc11_stub_hash_entry));
128      if (entry == NULL)
129	return entry;
130    }
131
132  /* Call the allocation method of the superclass.  */
133  entry = bfd_hash_newfunc (entry, table, string);
134  if (entry != NULL)
135    {
136      struct elf32_m68hc11_stub_hash_entry *eh;
137
138      /* Initialize the local fields.  */
139      eh = (struct elf32_m68hc11_stub_hash_entry *) entry;
140      eh->stub_sec = NULL;
141      eh->stub_offset = 0;
142      eh->target_value = 0;
143      eh->target_section = NULL;
144    }
145
146  return entry;
147}
148
149/* Add a new stub entry to the stub hash.  Not all fields of the new
150   stub entry are initialised.  */
151
152static struct elf32_m68hc11_stub_hash_entry *
153m68hc12_add_stub (const char *stub_name, asection *section,
154                  struct m68hc11_elf_link_hash_table *htab)
155{
156  struct elf32_m68hc11_stub_hash_entry *stub_entry;
157
158  /* Enter this entry into the linker stub hash table.  */
159  stub_entry = m68hc12_stub_hash_lookup (htab->stub_hash_table, stub_name,
160                                         TRUE, FALSE);
161  if (stub_entry == NULL)
162    {
163      (*_bfd_error_handler) (_("%B: cannot create stub entry %s"),
164			     section->owner, stub_name);
165      return NULL;
166    }
167
168  if (htab->stub_section == 0)
169    {
170      htab->stub_section = (*htab->add_stub_section) (".tramp",
171                                                      htab->tramp_section);
172    }
173
174  stub_entry->stub_sec = htab->stub_section;
175  stub_entry->stub_offset = 0;
176  return stub_entry;
177}
178
179/* Hook called by the linker routine which adds symbols from an object
180   file.  We use it for identify far symbols and force a loading of
181   the trampoline handler.  */
182
183bfd_boolean
184elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
185                               Elf_Internal_Sym *sym,
186                               const char **namep ATTRIBUTE_UNUSED,
187                               flagword *flagsp ATTRIBUTE_UNUSED,
188                               asection **secp ATTRIBUTE_UNUSED,
189                               bfd_vma *valp ATTRIBUTE_UNUSED)
190{
191  if (sym->st_other & STO_M68HC12_FAR)
192    {
193      struct elf_link_hash_entry *h;
194
195      h = (struct elf_link_hash_entry *)
196	bfd_link_hash_lookup (info->hash, "__far_trampoline",
197                              FALSE, FALSE, FALSE);
198      if (h == NULL)
199        {
200          struct bfd_link_hash_entry* entry = NULL;
201
202          _bfd_generic_link_add_one_symbol (info, abfd,
203                                            "__far_trampoline",
204                                            BSF_GLOBAL,
205                                            bfd_und_section_ptr,
206                                            (bfd_vma) 0, (const char*) NULL,
207                                            FALSE, FALSE, &entry);
208        }
209
210    }
211  return TRUE;
212}
213
214/* External entry points for sizing and building linker stubs.  */
215
216/* Set up various things so that we can make a list of input sections
217   for each output section included in the link.  Returns -1 on error,
218   0 when no stubs will be needed, and 1 on success.  */
219
220int
221elf32_m68hc11_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
222{
223  bfd *input_bfd;
224  unsigned int bfd_count;
225  int top_id, top_index;
226  asection *section;
227  asection **input_list, **list;
228  bfd_size_type amt;
229  asection *text_section;
230  struct m68hc11_elf_link_hash_table *htab;
231
232  htab = m68hc11_elf_hash_table (info);
233
234  if (htab->root.root.creator->flavour != bfd_target_elf_flavour)
235    return 0;
236
237  /* Count the number of input BFDs and find the top input section id.
238     Also search for an existing ".tramp" section so that we know
239     where generated trampolines must go.  Default to ".text" if we
240     can't find it.  */
241  htab->tramp_section = 0;
242  text_section = 0;
243  for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
244       input_bfd != NULL;
245       input_bfd = input_bfd->link_next)
246    {
247      bfd_count += 1;
248      for (section = input_bfd->sections;
249	   section != NULL;
250	   section = section->next)
251	{
252          const char* name = bfd_get_section_name (input_bfd, section);
253
254          if (!strcmp (name, ".tramp"))
255            htab->tramp_section = section;
256
257          if (!strcmp (name, ".text"))
258            text_section = section;
259
260	  if (top_id < section->id)
261	    top_id = section->id;
262	}
263    }
264  htab->bfd_count = bfd_count;
265  if (htab->tramp_section == 0)
266    htab->tramp_section = text_section;
267
268  /* We can't use output_bfd->section_count here to find the top output
269     section index as some sections may have been removed, and
270     strip_excluded_output_sections doesn't renumber the indices.  */
271  for (section = output_bfd->sections, top_index = 0;
272       section != NULL;
273       section = section->next)
274    {
275      if (top_index < section->index)
276	top_index = section->index;
277    }
278
279  htab->top_index = top_index;
280  amt = sizeof (asection *) * (top_index + 1);
281  input_list = (asection **) bfd_malloc (amt);
282  htab->input_list = input_list;
283  if (input_list == NULL)
284    return -1;
285
286  /* For sections we aren't interested in, mark their entries with a
287     value we can check later.  */
288  list = input_list + top_index;
289  do
290    *list = bfd_abs_section_ptr;
291  while (list-- != input_list);
292
293  for (section = output_bfd->sections;
294       section != NULL;
295       section = section->next)
296    {
297      if ((section->flags & SEC_CODE) != 0)
298	input_list[section->index] = NULL;
299    }
300
301  return 1;
302}
303
304/* Determine and set the size of the stub section for a final link.
305
306   The basic idea here is to examine all the relocations looking for
307   PC-relative calls to a target that is unreachable with a "bl"
308   instruction.  */
309
310bfd_boolean
311elf32_m68hc11_size_stubs (bfd *output_bfd, bfd *stub_bfd,
312                          struct bfd_link_info *info,
313                          asection * (*add_stub_section) (const char*, asection*))
314{
315  bfd *input_bfd;
316  asection *section;
317  Elf_Internal_Sym *local_syms, **all_local_syms;
318  unsigned int bfd_indx, bfd_count;
319  bfd_size_type amt;
320  asection *stub_sec;
321
322  struct m68hc11_elf_link_hash_table *htab = m68hc11_elf_hash_table (info);
323
324  /* Stash our params away.  */
325  htab->stub_bfd = stub_bfd;
326  htab->add_stub_section = add_stub_section;
327
328  /* Count the number of input BFDs and find the top input section id.  */
329  for (input_bfd = info->input_bfds, bfd_count = 0;
330       input_bfd != NULL;
331       input_bfd = input_bfd->link_next)
332    {
333      bfd_count += 1;
334    }
335
336  /* We want to read in symbol extension records only once.  To do this
337     we need to read in the local symbols in parallel and save them for
338     later use; so hold pointers to the local symbols in an array.  */
339  amt = sizeof (Elf_Internal_Sym *) * bfd_count;
340  all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt);
341  if (all_local_syms == NULL)
342    return FALSE;
343
344  /* Walk over all the input BFDs, swapping in local symbols.  */
345  for (input_bfd = info->input_bfds, bfd_indx = 0;
346       input_bfd != NULL;
347       input_bfd = input_bfd->link_next, bfd_indx++)
348    {
349      Elf_Internal_Shdr *symtab_hdr;
350
351      /* We'll need the symbol table in a second.  */
352      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
353      if (symtab_hdr->sh_info == 0)
354	continue;
355
356      /* We need an array of the local symbols attached to the input bfd.  */
357      local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
358      if (local_syms == NULL)
359	{
360	  local_syms = bfd_elf_get_elf_syms (input_bfd, symtab_hdr,
361					     symtab_hdr->sh_info, 0,
362					     NULL, NULL, NULL);
363	  /* Cache them for elf_link_input_bfd.  */
364	  symtab_hdr->contents = (unsigned char *) local_syms;
365	}
366      if (local_syms == NULL)
367        {
368          free (all_local_syms);
369	  return FALSE;
370        }
371
372      all_local_syms[bfd_indx] = local_syms;
373    }
374
375  for (input_bfd = info->input_bfds, bfd_indx = 0;
376       input_bfd != NULL;
377       input_bfd = input_bfd->link_next, bfd_indx++)
378    {
379      Elf_Internal_Shdr *symtab_hdr;
380      Elf_Internal_Sym *local_syms;
381      struct elf_link_hash_entry ** sym_hashes;
382
383      sym_hashes = elf_sym_hashes (input_bfd);
384
385      /* We'll need the symbol table in a second.  */
386      symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
387      if (symtab_hdr->sh_info == 0)
388        continue;
389
390      local_syms = all_local_syms[bfd_indx];
391
392      /* Walk over each section attached to the input bfd.  */
393      for (section = input_bfd->sections;
394           section != NULL;
395           section = section->next)
396        {
397          Elf_Internal_Rela *internal_relocs, *irelaend, *irela;
398
399          /* If there aren't any relocs, then there's nothing more
400             to do.  */
401          if ((section->flags & SEC_RELOC) == 0
402              || section->reloc_count == 0)
403            continue;
404
405          /* If this section is a link-once section that will be
406             discarded, then don't create any stubs.  */
407          if (section->output_section == NULL
408              || section->output_section->owner != output_bfd)
409            continue;
410
411          /* Get the relocs.  */
412          internal_relocs
413            = _bfd_elf_link_read_relocs (input_bfd, section, NULL,
414					 (Elf_Internal_Rela *) NULL,
415					 info->keep_memory);
416          if (internal_relocs == NULL)
417            goto error_ret_free_local;
418
419          /* Now examine each relocation.  */
420          irela = internal_relocs;
421          irelaend = irela + section->reloc_count;
422          for (; irela < irelaend; irela++)
423            {
424              unsigned int r_type, r_indx;
425              struct elf32_m68hc11_stub_hash_entry *stub_entry;
426              asection *sym_sec;
427              bfd_vma sym_value;
428              struct elf_link_hash_entry *hash;
429              const char *stub_name;
430              Elf_Internal_Sym *sym;
431
432              r_type = ELF32_R_TYPE (irela->r_info);
433
434              /* Only look at 16-bit relocs.  */
435              if (r_type != (unsigned int) R_M68HC11_16)
436                continue;
437
438              /* Now determine the call target, its name, value,
439                 section.  */
440              r_indx = ELF32_R_SYM (irela->r_info);
441              if (r_indx < symtab_hdr->sh_info)
442                {
443                  /* It's a local symbol.  */
444                  Elf_Internal_Shdr *hdr;
445                  bfd_boolean is_far;
446
447                  sym = local_syms + r_indx;
448                  is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
449                  if (!is_far)
450                    continue;
451
452                  hdr = elf_elfsections (input_bfd)[sym->st_shndx];
453                  sym_sec = hdr->bfd_section;
454                  stub_name = (bfd_elf_string_from_elf_section
455                               (input_bfd, symtab_hdr->sh_link,
456                                sym->st_name));
457                  sym_value = sym->st_value;
458                  hash = NULL;
459                }
460              else
461                {
462                  /* It's an external symbol.  */
463                  int e_indx;
464
465                  e_indx = r_indx - symtab_hdr->sh_info;
466                  hash = (struct elf_link_hash_entry *)
467                    (sym_hashes[e_indx]);
468
469                  while (hash->root.type == bfd_link_hash_indirect
470                         || hash->root.type == bfd_link_hash_warning)
471                    hash = ((struct elf_link_hash_entry *)
472                            hash->root.u.i.link);
473
474                  if (hash->root.type == bfd_link_hash_defined
475                      || hash->root.type == bfd_link_hash_defweak
476                      || hash->root.type == bfd_link_hash_new)
477                    {
478                      if (!(hash->other & STO_M68HC12_FAR))
479                        continue;
480                    }
481                  else if (hash->root.type == bfd_link_hash_undefweak)
482                    {
483                      continue;
484                    }
485                  else if (hash->root.type == bfd_link_hash_undefined)
486                    {
487                      continue;
488                    }
489                  else
490                    {
491                      bfd_set_error (bfd_error_bad_value);
492                      goto error_ret_free_internal;
493                    }
494                  sym_sec = hash->root.u.def.section;
495                  sym_value = hash->root.u.def.value;
496                  stub_name = hash->root.root.string;
497                }
498
499              if (!stub_name)
500                goto error_ret_free_internal;
501
502              stub_entry = m68hc12_stub_hash_lookup
503                (htab->stub_hash_table,
504                 stub_name,
505                 FALSE, FALSE);
506              if (stub_entry == NULL)
507                {
508                  if (add_stub_section == 0)
509                    continue;
510
511                  stub_entry = m68hc12_add_stub (stub_name, section, htab);
512                  if (stub_entry == NULL)
513                    {
514                    error_ret_free_internal:
515                      if (elf_section_data (section)->relocs == NULL)
516                        free (internal_relocs);
517                      goto error_ret_free_local;
518                    }
519                }
520
521              stub_entry->target_value = sym_value;
522              stub_entry->target_section = sym_sec;
523            }
524
525          /* We're done with the internal relocs, free them.  */
526          if (elf_section_data (section)->relocs == NULL)
527            free (internal_relocs);
528        }
529    }
530
531  if (add_stub_section)
532    {
533      /* OK, we've added some stubs.  Find out the new size of the
534         stub sections.  */
535      for (stub_sec = htab->stub_bfd->sections;
536           stub_sec != NULL;
537           stub_sec = stub_sec->next)
538        {
539          stub_sec->size = 0;
540        }
541
542      bfd_hash_traverse (htab->stub_hash_table, htab->size_one_stub, htab);
543    }
544  free (all_local_syms);
545  return TRUE;
546
547 error_ret_free_local:
548  free (all_local_syms);
549  return FALSE;
550}
551
552/* Export the trampoline addresses in the symbol table.  */
553static bfd_boolean
554m68hc11_elf_export_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
555{
556  struct bfd_link_info *info;
557  struct m68hc11_elf_link_hash_table *htab;
558  struct elf32_m68hc11_stub_hash_entry *stub_entry;
559  char* name;
560  bfd_boolean result;
561
562  info = (struct bfd_link_info *) in_arg;
563  htab = m68hc11_elf_hash_table (info);
564
565  /* Massage our args to the form they really have.  */
566  stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
567
568  /* Generate the trampoline according to HC11 or HC12.  */
569  result = (* htab->build_one_stub) (gen_entry, in_arg);
570
571  /* Make a printable name that does not conflict with the real function.  */
572  name = alloca (strlen (stub_entry->root.string) + 16);
573  sprintf (name, "tramp.%s", stub_entry->root.string);
574
575  /* Export the symbol for debugging/disassembling.  */
576  m68hc11_elf_set_symbol (htab->stub_bfd, info, name,
577                          stub_entry->stub_offset,
578                          stub_entry->stub_sec);
579  return result;
580}
581
582/* Export a symbol or set its value and section.  */
583static void
584m68hc11_elf_set_symbol (bfd *abfd, struct bfd_link_info *info,
585                        const char *name, bfd_vma value, asection *sec)
586{
587  struct elf_link_hash_entry *h;
588
589  h = (struct elf_link_hash_entry *)
590    bfd_link_hash_lookup (info->hash, name, FALSE, FALSE, FALSE);
591  if (h == NULL)
592    {
593      _bfd_generic_link_add_one_symbol (info, abfd,
594                                        name,
595                                        BSF_GLOBAL,
596                                        sec,
597                                        value,
598                                        (const char*) NULL,
599                                        TRUE, FALSE, NULL);
600    }
601  else
602    {
603      h->root.type = bfd_link_hash_defined;
604      h->root.u.def.value = value;
605      h->root.u.def.section = sec;
606    }
607}
608
609
610/* Build all the stubs associated with the current output file.  The
611   stubs are kept in a hash table attached to the main linker hash
612   table.  This function is called via m68hc12elf_finish in the
613   linker.  */
614
615bfd_boolean
616elf32_m68hc11_build_stubs (bfd *abfd, struct bfd_link_info *info)
617{
618  asection *stub_sec;
619  struct bfd_hash_table *table;
620  struct m68hc11_elf_link_hash_table *htab;
621  struct m68hc11_scan_param param;
622
623  m68hc11_elf_get_bank_parameters (info);
624  htab = m68hc11_elf_hash_table (info);
625
626  for (stub_sec = htab->stub_bfd->sections;
627       stub_sec != NULL;
628       stub_sec = stub_sec->next)
629    {
630      bfd_size_type size;
631
632      /* Allocate memory to hold the linker stubs.  */
633      size = stub_sec->size;
634      stub_sec->contents = (unsigned char *) bfd_zalloc (htab->stub_bfd, size);
635      if (stub_sec->contents == NULL && size != 0)
636	return FALSE;
637      stub_sec->size = 0;
638    }
639
640  /* Build the stubs as directed by the stub hash table.  */
641  table = htab->stub_hash_table;
642  bfd_hash_traverse (table, m68hc11_elf_export_one_stub, info);
643
644  /* Scan the output sections to see if we use the memory banks.
645     If so, export the symbols that define how the memory banks
646     are mapped.  This is used by gdb and the simulator to obtain
647     the information.  It can be used by programs to burn the eprom
648     at the good addresses.  */
649  param.use_memory_banks = FALSE;
650  param.pinfo = &htab->pinfo;
651  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
652  if (param.use_memory_banks)
653    {
654      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_START_NAME,
655                              htab->pinfo.bank_physical,
656                              bfd_abs_section_ptr);
657      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_VIRTUAL_NAME,
658                              htab->pinfo.bank_virtual,
659                              bfd_abs_section_ptr);
660      m68hc11_elf_set_symbol (abfd, info, BFD_M68HC11_BANK_SIZE_NAME,
661                              htab->pinfo.bank_size,
662                              bfd_abs_section_ptr);
663    }
664
665  return TRUE;
666}
667
668void
669m68hc11_elf_get_bank_parameters (struct bfd_link_info *info)
670{
671  unsigned i;
672  struct m68hc11_page_info *pinfo;
673  struct bfd_link_hash_entry *h;
674
675  pinfo = &m68hc11_elf_hash_table (info)->pinfo;
676  if (pinfo->bank_param_initialized)
677    return;
678
679  pinfo->bank_virtual = M68HC12_BANK_VIRT;
680  pinfo->bank_mask = M68HC12_BANK_MASK;
681  pinfo->bank_physical = M68HC12_BANK_BASE;
682  pinfo->bank_shift = M68HC12_BANK_SHIFT;
683  pinfo->bank_size = 1 << M68HC12_BANK_SHIFT;
684
685  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_START_NAME,
686                            FALSE, FALSE, TRUE);
687  if (h != (struct bfd_link_hash_entry*) NULL
688      && h->type == bfd_link_hash_defined)
689    pinfo->bank_physical = (h->u.def.value
690                            + h->u.def.section->output_section->vma
691                            + h->u.def.section->output_offset);
692
693  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_VIRTUAL_NAME,
694                            FALSE, FALSE, TRUE);
695  if (h != (struct bfd_link_hash_entry*) NULL
696      && h->type == bfd_link_hash_defined)
697    pinfo->bank_virtual = (h->u.def.value
698                           + h->u.def.section->output_section->vma
699                           + h->u.def.section->output_offset);
700
701  h = bfd_link_hash_lookup (info->hash, BFD_M68HC11_BANK_SIZE_NAME,
702                            FALSE, FALSE, TRUE);
703  if (h != (struct bfd_link_hash_entry*) NULL
704      && h->type == bfd_link_hash_defined)
705    pinfo->bank_size = (h->u.def.value
706                        + h->u.def.section->output_section->vma
707                        + h->u.def.section->output_offset);
708
709  pinfo->bank_shift = 0;
710  for (i = pinfo->bank_size; i != 0; i >>= 1)
711    pinfo->bank_shift++;
712  pinfo->bank_shift--;
713  pinfo->bank_mask = (1 << pinfo->bank_shift) - 1;
714  pinfo->bank_physical_end = pinfo->bank_physical + pinfo->bank_size;
715  pinfo->bank_param_initialized = 1;
716
717  h = bfd_link_hash_lookup (info->hash, "__far_trampoline", FALSE,
718                            FALSE, TRUE);
719  if (h != (struct bfd_link_hash_entry*) NULL
720      && h->type == bfd_link_hash_defined)
721    pinfo->trampoline_addr = (h->u.def.value
722                              + h->u.def.section->output_section->vma
723                              + h->u.def.section->output_offset);
724}
725
726/* Return 1 if the address is in banked memory.
727   This can be applied to a virtual address and to a physical address.  */
728int
729m68hc11_addr_is_banked (struct m68hc11_page_info *pinfo, bfd_vma addr)
730{
731  if (addr >= pinfo->bank_virtual)
732    return 1;
733
734  if (addr >= pinfo->bank_physical && addr <= pinfo->bank_physical_end)
735    return 1;
736
737  return 0;
738}
739
740/* Return the physical address seen by the processor, taking
741   into account banked memory.  */
742bfd_vma
743m68hc11_phys_addr (struct m68hc11_page_info *pinfo, bfd_vma addr)
744{
745  if (addr < pinfo->bank_virtual)
746    return addr;
747
748  /* Map the address to the memory bank.  */
749  addr -= pinfo->bank_virtual;
750  addr &= pinfo->bank_mask;
751  addr += pinfo->bank_physical;
752  return addr;
753}
754
755/* Return the page number corresponding to an address in banked memory.  */
756bfd_vma
757m68hc11_phys_page (struct m68hc11_page_info *pinfo, bfd_vma addr)
758{
759  if (addr < pinfo->bank_virtual)
760    return 0;
761
762  /* Map the address to the memory bank.  */
763  addr -= pinfo->bank_virtual;
764  addr >>= pinfo->bank_shift;
765  addr &= 0x0ff;
766  return addr;
767}
768
769/* This function is used for relocs which are only used for relaxing,
770   which the linker should otherwise ignore.  */
771
772bfd_reloc_status_type
773m68hc11_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
774                          arelent *reloc_entry,
775                          asymbol *symbol ATTRIBUTE_UNUSED,
776                          void *data ATTRIBUTE_UNUSED,
777                          asection *input_section,
778                          bfd *output_bfd,
779                          char **error_message ATTRIBUTE_UNUSED)
780{
781  if (output_bfd != NULL)
782    reloc_entry->address += input_section->output_offset;
783  return bfd_reloc_ok;
784}
785
786bfd_reloc_status_type
787m68hc11_elf_special_reloc (bfd *abfd ATTRIBUTE_UNUSED,
788                           arelent *reloc_entry,
789                           asymbol *symbol,
790                           void *data ATTRIBUTE_UNUSED,
791                           asection *input_section,
792                           bfd *output_bfd,
793                           char **error_message ATTRIBUTE_UNUSED)
794{
795  if (output_bfd != (bfd *) NULL
796      && (symbol->flags & BSF_SECTION_SYM) == 0
797      && (! reloc_entry->howto->partial_inplace
798	  || reloc_entry->addend == 0))
799    {
800      reloc_entry->address += input_section->output_offset;
801      return bfd_reloc_ok;
802    }
803
804  if (output_bfd != NULL)
805    return bfd_reloc_continue;
806
807  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
808    return bfd_reloc_outofrange;
809
810  abort();
811}
812
813asection *
814elf32_m68hc11_gc_mark_hook (asection *sec,
815                            struct bfd_link_info *info ATTRIBUTE_UNUSED,
816                            Elf_Internal_Rela *rel,
817                            struct elf_link_hash_entry *h,
818                            Elf_Internal_Sym *sym)
819{
820  if (h != NULL)
821    {
822      switch (ELF32_R_TYPE (rel->r_info))
823	{
824	default:
825	  switch (h->root.type)
826	    {
827	    case bfd_link_hash_defined:
828	    case bfd_link_hash_defweak:
829	      return h->root.u.def.section;
830
831	    case bfd_link_hash_common:
832	      return h->root.u.c.p->section;
833
834	    default:
835	      break;
836	    }
837	}
838    }
839  else
840    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
841
842  return NULL;
843}
844
845bfd_boolean
846elf32_m68hc11_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
847                             struct bfd_link_info *info ATTRIBUTE_UNUSED,
848                             asection *sec ATTRIBUTE_UNUSED,
849                             const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED)
850{
851  /* We don't use got and plt entries for 68hc11/68hc12.  */
852  return TRUE;
853}
854
855/* Look through the relocs for a section during the first phase.
856   Since we don't do .gots or .plts, we just need to consider the
857   virtual table relocs for gc.  */
858
859bfd_boolean
860elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
861                            asection *sec, const Elf_Internal_Rela *relocs)
862{
863  Elf_Internal_Shdr *           symtab_hdr;
864  struct elf_link_hash_entry ** sym_hashes;
865  struct elf_link_hash_entry ** sym_hashes_end;
866  const Elf_Internal_Rela *     rel;
867  const Elf_Internal_Rela *     rel_end;
868
869  if (info->relocatable)
870    return TRUE;
871
872  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
873  sym_hashes = elf_sym_hashes (abfd);
874  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
875  if (!elf_bad_symtab (abfd))
876    sym_hashes_end -= symtab_hdr->sh_info;
877
878  rel_end = relocs + sec->reloc_count;
879
880  for (rel = relocs; rel < rel_end; rel++)
881    {
882      struct elf_link_hash_entry * h;
883      unsigned long r_symndx;
884
885      r_symndx = ELF32_R_SYM (rel->r_info);
886
887      if (r_symndx < symtab_hdr->sh_info)
888        h = NULL;
889      else
890	{
891	  h = sym_hashes [r_symndx - symtab_hdr->sh_info];
892	  while (h->root.type == bfd_link_hash_indirect
893		 || h->root.type == bfd_link_hash_warning)
894	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
895	}
896
897      switch (ELF32_R_TYPE (rel->r_info))
898        {
899        /* This relocation describes the C++ object vtable hierarchy.
900           Reconstruct it for later use during GC.  */
901        case R_M68HC11_GNU_VTINHERIT:
902          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
903            return FALSE;
904          break;
905
906        /* This relocation describes which C++ vtable entries are actually
907           used.  Record for later use during GC.  */
908        case R_M68HC11_GNU_VTENTRY:
909          if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
910            return FALSE;
911          break;
912        }
913    }
914
915  return TRUE;
916}
917
918static bfd_boolean
919m68hc11_get_relocation_value (bfd *input_bfd, struct bfd_link_info *info,
920			      asection *input_section,
921                              asection **local_sections,
922                              Elf_Internal_Sym *local_syms,
923                              Elf_Internal_Rela *rel,
924                              const char **name,
925                              bfd_vma *relocation, bfd_boolean *is_far)
926{
927  Elf_Internal_Shdr *symtab_hdr;
928  struct elf_link_hash_entry **sym_hashes;
929  unsigned long r_symndx;
930  asection *sec;
931  struct elf_link_hash_entry *h;
932  Elf_Internal_Sym *sym;
933  const char* stub_name = 0;
934
935  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
936  sym_hashes = elf_sym_hashes (input_bfd);
937
938  r_symndx = ELF32_R_SYM (rel->r_info);
939
940  /* This is a final link.  */
941  h = NULL;
942  sym = NULL;
943  sec = NULL;
944  if (r_symndx < symtab_hdr->sh_info)
945    {
946      sym = local_syms + r_symndx;
947      sec = local_sections[r_symndx];
948      *relocation = (sec->output_section->vma
949                     + sec->output_offset
950                     + sym->st_value);
951      *is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
952      if (*is_far)
953        stub_name = (bfd_elf_string_from_elf_section
954                     (input_bfd, symtab_hdr->sh_link,
955                      sym->st_name));
956    }
957  else
958    {
959      bfd_boolean unresolved_reloc, warned;
960
961      RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
962			       r_symndx, symtab_hdr, sym_hashes,
963			       h, sec, *relocation, unresolved_reloc, warned);
964
965      *is_far = (h && (h->other & STO_M68HC12_FAR));
966      stub_name = h->root.root.string;
967    }
968
969  if (h != NULL)
970    *name = h->root.root.string;
971  else
972    {
973      *name = (bfd_elf_string_from_elf_section
974               (input_bfd, symtab_hdr->sh_link, sym->st_name));
975      if (*name == NULL || **name == '\0')
976        *name = bfd_section_name (input_bfd, sec);
977    }
978
979  if (*is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
980    {
981      struct elf32_m68hc11_stub_hash_entry* stub;
982      struct m68hc11_elf_link_hash_table *htab;
983
984      htab = m68hc11_elf_hash_table (info);
985      stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
986                                       *name, FALSE, FALSE);
987      if (stub)
988        {
989          *relocation = stub->stub_offset
990            + stub->stub_sec->output_section->vma
991            + stub->stub_sec->output_offset;
992          *is_far = FALSE;
993        }
994    }
995  return TRUE;
996}
997
998/* Relocate a 68hc11/68hc12 ELF section.  */
999bfd_boolean
1000elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
1001                                struct bfd_link_info *info,
1002                                bfd *input_bfd, asection *input_section,
1003                                bfd_byte *contents, Elf_Internal_Rela *relocs,
1004                                Elf_Internal_Sym *local_syms,
1005                                asection **local_sections)
1006{
1007  Elf_Internal_Shdr *symtab_hdr;
1008  struct elf_link_hash_entry **sym_hashes;
1009  Elf_Internal_Rela *rel, *relend;
1010  const char *name = NULL;
1011  struct m68hc11_page_info *pinfo;
1012  const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
1013
1014  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1015  sym_hashes = elf_sym_hashes (input_bfd);
1016
1017  /* Get memory bank parameters.  */
1018  m68hc11_elf_get_bank_parameters (info);
1019  pinfo = &m68hc11_elf_hash_table (info)->pinfo;
1020
1021  rel = relocs;
1022  relend = relocs + input_section->reloc_count;
1023  for (; rel < relend; rel++)
1024    {
1025      int r_type;
1026      arelent arel;
1027      reloc_howto_type *howto;
1028      unsigned long r_symndx;
1029      Elf_Internal_Sym *sym;
1030      asection *sec;
1031      bfd_vma relocation = 0;
1032      bfd_reloc_status_type r = bfd_reloc_undefined;
1033      bfd_vma phys_page;
1034      bfd_vma phys_addr;
1035      bfd_vma insn_addr;
1036      bfd_vma insn_page;
1037      bfd_boolean is_far = FALSE;
1038
1039      r_symndx = ELF32_R_SYM (rel->r_info);
1040      r_type = ELF32_R_TYPE (rel->r_info);
1041
1042      if (r_type == R_M68HC11_GNU_VTENTRY
1043          || r_type == R_M68HC11_GNU_VTINHERIT )
1044        continue;
1045
1046      if (info->relocatable)
1047	{
1048	  /* This is a relocatable link.  We don't have to change
1049	     anything, unless the reloc is against a section symbol,
1050	     in which case we have to adjust according to where the
1051	     section symbol winds up in the output section.  */
1052	  if (r_symndx < symtab_hdr->sh_info)
1053	    {
1054	      sym = local_syms + r_symndx;
1055	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1056		{
1057		  sec = local_sections[r_symndx];
1058		  rel->r_addend += sec->output_offset + sym->st_value;
1059		}
1060	    }
1061
1062	  continue;
1063	}
1064      (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
1065      howto = arel.howto;
1066
1067      m68hc11_get_relocation_value (input_bfd, info, input_section,
1068				    local_sections, local_syms,
1069                                    rel, &name, &relocation, &is_far);
1070
1071      /* Do the memory bank mapping.  */
1072      phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1073      phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1074      switch (r_type)
1075        {
1076        case R_M68HC11_24:
1077          /* Reloc used by 68HC12 call instruction.  */
1078          bfd_put_16 (input_bfd, phys_addr,
1079                      (bfd_byte*) contents + rel->r_offset);
1080          bfd_put_8 (input_bfd, phys_page,
1081                     (bfd_byte*) contents + rel->r_offset + 2);
1082          r = bfd_reloc_ok;
1083          r_type = R_M68HC11_NONE;
1084          break;
1085
1086        case R_M68HC11_NONE:
1087          r = bfd_reloc_ok;
1088          break;
1089
1090        case R_M68HC11_LO16:
1091          /* Reloc generated by %addr(expr) gas to obtain the
1092             address as mapped in the memory bank window.  */
1093          relocation = phys_addr;
1094          break;
1095
1096        case R_M68HC11_PAGE:
1097          /* Reloc generated by %page(expr) gas to obtain the
1098             page number associated with the address.  */
1099          relocation = phys_page;
1100          break;
1101
1102        case R_M68HC11_16:
1103          /* Get virtual address of instruction having the relocation.  */
1104          if (is_far)
1105            {
1106              const char* msg;
1107              char* buf;
1108              msg = _("Reference to the far symbol `%s' using a wrong "
1109                      "relocation may result in incorrect execution");
1110              buf = alloca (strlen (msg) + strlen (name) + 10);
1111              sprintf (buf, msg, name);
1112
1113              (* info->callbacks->warning)
1114                (info, buf, name, input_bfd, NULL, rel->r_offset);
1115            }
1116
1117          /* Get virtual address of instruction having the relocation.  */
1118          insn_addr = input_section->output_section->vma
1119            + input_section->output_offset
1120            + rel->r_offset;
1121
1122          insn_page = m68hc11_phys_page (pinfo, insn_addr);
1123
1124          if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1125              && m68hc11_addr_is_banked (pinfo, insn_addr)
1126              && phys_page != insn_page)
1127            {
1128              const char* msg;
1129              char* buf;
1130
1131              msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1132                      "as current banked address [%lx:%04lx] (%lx)");
1133
1134              buf = alloca (strlen (msg) + 128);
1135              sprintf (buf, msg, phys_page, phys_addr,
1136                       (long) (relocation + rel->r_addend),
1137                       insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1138                       (long) (insn_addr));
1139              if (!((*info->callbacks->warning)
1140                    (info, buf, name, input_bfd, input_section,
1141                     rel->r_offset)))
1142                return FALSE;
1143              break;
1144            }
1145          if (phys_page != 0 && insn_page == 0)
1146            {
1147              const char* msg;
1148              char* buf;
1149
1150              msg = _("reference to a banked address [%lx:%04lx] in the "
1151                      "normal address space at %04lx");
1152
1153              buf = alloca (strlen (msg) + 128);
1154              sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1155              if (!((*info->callbacks->warning)
1156                    (info, buf, name, input_bfd, input_section,
1157                     insn_addr)))
1158                return FALSE;
1159
1160              relocation = phys_addr;
1161              break;
1162            }
1163
1164          /* If this is a banked address use the phys_addr so that
1165             we stay in the banked window.  */
1166          if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1167            relocation = phys_addr;
1168          break;
1169        }
1170      if (r_type != R_M68HC11_NONE)
1171        r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1172                                      contents, rel->r_offset,
1173                                      relocation, rel->r_addend);
1174
1175      if (r != bfd_reloc_ok)
1176	{
1177	  const char * msg = (const char *) 0;
1178
1179	  switch (r)
1180	    {
1181	    case bfd_reloc_overflow:
1182	      if (!((*info->callbacks->reloc_overflow)
1183		    (info, NULL, name, howto->name, (bfd_vma) 0,
1184		     input_bfd, input_section, rel->r_offset)))
1185		return FALSE;
1186	      break;
1187
1188	    case bfd_reloc_undefined:
1189	      if (!((*info->callbacks->undefined_symbol)
1190		    (info, name, input_bfd, input_section,
1191		     rel->r_offset, TRUE)))
1192		return FALSE;
1193	      break;
1194
1195	    case bfd_reloc_outofrange:
1196	      msg = _ ("internal error: out of range error");
1197	      goto common_error;
1198
1199	    case bfd_reloc_notsupported:
1200	      msg = _ ("internal error: unsupported relocation error");
1201	      goto common_error;
1202
1203	    case bfd_reloc_dangerous:
1204	      msg = _ ("internal error: dangerous error");
1205	      goto common_error;
1206
1207	    default:
1208	      msg = _ ("internal error: unknown error");
1209	      /* fall through */
1210
1211	    common_error:
1212	      if (!((*info->callbacks->warning)
1213		    (info, msg, name, input_bfd, input_section,
1214		     rel->r_offset)))
1215		return FALSE;
1216	      break;
1217	    }
1218	}
1219    }
1220
1221  return TRUE;
1222}
1223
1224
1225
1226/* Set and control ELF flags in ELF header.  */
1227
1228bfd_boolean
1229_bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
1230{
1231  BFD_ASSERT (!elf_flags_init (abfd)
1232	      || elf_elfheader (abfd)->e_flags == flags);
1233
1234  elf_elfheader (abfd)->e_flags = flags;
1235  elf_flags_init (abfd) = TRUE;
1236  return TRUE;
1237}
1238
1239/* Merge backend specific data from an object file to the output
1240   object file when linking.  */
1241
1242bfd_boolean
1243_bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1244{
1245  flagword old_flags;
1246  flagword new_flags;
1247  bfd_boolean ok = TRUE;
1248
1249  /* Check if we have the same endianess */
1250  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1251    return FALSE;
1252
1253  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1254      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1255    return TRUE;
1256
1257  new_flags = elf_elfheader (ibfd)->e_flags;
1258  elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1259  old_flags = elf_elfheader (obfd)->e_flags;
1260
1261  if (! elf_flags_init (obfd))
1262    {
1263      elf_flags_init (obfd) = TRUE;
1264      elf_elfheader (obfd)->e_flags = new_flags;
1265      elf_elfheader (obfd)->e_ident[EI_CLASS]
1266	= elf_elfheader (ibfd)->e_ident[EI_CLASS];
1267
1268      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1269	  && bfd_get_arch_info (obfd)->the_default)
1270	{
1271	  if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1272				   bfd_get_mach (ibfd)))
1273	    return FALSE;
1274	}
1275
1276      return TRUE;
1277    }
1278
1279  /* Check ABI compatibility.  */
1280  if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1281    {
1282      (*_bfd_error_handler)
1283	(_("%B: linking files compiled for 16-bit integers (-mshort) "
1284           "and others for 32-bit integers"), ibfd);
1285      ok = FALSE;
1286    }
1287  if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1288    {
1289      (*_bfd_error_handler)
1290	(_("%B: linking files compiled for 32-bit double (-fshort-double) "
1291           "and others for 64-bit double"), ibfd);
1292      ok = FALSE;
1293    }
1294
1295  /* Processor compatibility.  */
1296  if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1297    {
1298      (*_bfd_error_handler)
1299	(_("%B: linking files compiled for HCS12 with "
1300           "others compiled for HC12"), ibfd);
1301      ok = FALSE;
1302    }
1303  new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
1304               | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
1305
1306  elf_elfheader (obfd)->e_flags = new_flags;
1307
1308  new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1309  old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1310
1311  /* Warn about any other mismatches */
1312  if (new_flags != old_flags)
1313    {
1314      (*_bfd_error_handler)
1315	(_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1316	 ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
1317      ok = FALSE;
1318    }
1319
1320  if (! ok)
1321    {
1322      bfd_set_error (bfd_error_bad_value);
1323      return FALSE;
1324    }
1325
1326  return TRUE;
1327}
1328
1329bfd_boolean
1330_bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
1331{
1332  FILE *file = (FILE *) ptr;
1333
1334  BFD_ASSERT (abfd != NULL && ptr != NULL);
1335
1336  /* Print normal ELF private data.  */
1337  _bfd_elf_print_private_bfd_data (abfd, ptr);
1338
1339  /* xgettext:c-format */
1340  fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1341
1342  if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1343    fprintf (file, _("[abi=32-bit int, "));
1344  else
1345    fprintf (file, _("[abi=16-bit int, "));
1346
1347  if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1348    fprintf (file, _("64-bit double, "));
1349  else
1350    fprintf (file, _("32-bit double, "));
1351
1352  if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1353    fprintf (file, _("cpu=HC11]"));
1354  else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1355    fprintf (file, _("cpu=HCS12]"));
1356  else
1357    fprintf (file, _("cpu=HC12]"));
1358
1359  if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1360    fprintf (file, _(" [memory=bank-model]"));
1361  else
1362    fprintf (file, _(" [memory=flat]"));
1363
1364  fputc ('\n', file);
1365
1366  return TRUE;
1367}
1368
1369static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
1370                                   asection *asect, void *arg)
1371{
1372  struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1373
1374  if (asect->vma >= p->pinfo->bank_virtual)
1375    p->use_memory_banks = TRUE;
1376}
1377
1378/* Tweak the OSABI field of the elf header.  */
1379
1380void
1381elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
1382{
1383  struct m68hc11_scan_param param;
1384
1385  if (link_info == 0)
1386    return;
1387
1388  m68hc11_elf_get_bank_parameters (link_info);
1389
1390  param.use_memory_banks = FALSE;
1391  param.pinfo = &m68hc11_elf_hash_table (link_info)->pinfo;
1392  bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1393  if (param.use_memory_banks)
1394    {
1395      Elf_Internal_Ehdr * i_ehdrp;
1396
1397      i_ehdrp = elf_elfheader (abfd);
1398      i_ehdrp->e_flags |= E_M68HC12_BANKS;
1399    }
1400}
1401
1402