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