2005-06-20 H.J. Lu <hongjiu.lu@intel.com>
[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, 2005
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., 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
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      strip_excluded_output_sections 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         {
889           h = sym_hashes [r_symndx - symtab_hdr->sh_info];
890           while (h->root.type == bfd_link_hash_indirect
891                  || h->root.type == bfd_link_hash_warning)
892             h = (struct elf_link_hash_entry *) h->root.u.i.link;
893         }
894
895       switch (ELF32_R_TYPE (rel->r_info))
896         {
897         /* This relocation describes the C++ object vtable hierarchy.
898            Reconstruct it for later use during GC.  */
899         case R_M68HC11_GNU_VTINHERIT:
900           if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
901             return FALSE;
902           break;
903
904         /* This relocation describes which C++ vtable entries are actually
905            used.  Record for later use during GC.  */
906         case R_M68HC11_GNU_VTENTRY:
907           if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
908             return FALSE;
909           break;
910         }
911     }
912
913   return TRUE;
914 }
915
916 static bfd_boolean
917 m68hc11_get_relocation_value (bfd *input_bfd, struct bfd_link_info *info,
918                               asection *input_section,
919                               asection **local_sections,
920                               Elf_Internal_Sym *local_syms,
921                               Elf_Internal_Rela *rel,
922                               const char **name,
923                               bfd_vma *relocation, bfd_boolean *is_far)
924 {
925   Elf_Internal_Shdr *symtab_hdr;
926   struct elf_link_hash_entry **sym_hashes;
927   unsigned long r_symndx;
928   asection *sec;
929   struct elf_link_hash_entry *h;
930   Elf_Internal_Sym *sym;
931   const char* stub_name = 0;
932
933   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
934   sym_hashes = elf_sym_hashes (input_bfd);
935
936   r_symndx = ELF32_R_SYM (rel->r_info);
937
938   /* This is a final link.  */
939   h = NULL;
940   sym = NULL;
941   sec = NULL;
942   if (r_symndx < symtab_hdr->sh_info)
943     {
944       sym = local_syms + r_symndx;
945       sec = local_sections[r_symndx];
946       *relocation = (sec->output_section->vma
947                      + sec->output_offset
948                      + sym->st_value);
949       *is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
950       if (*is_far)
951         stub_name = (bfd_elf_string_from_elf_section
952                      (input_bfd, symtab_hdr->sh_link,
953                       sym->st_name));
954     }
955   else
956     {
957       bfd_boolean unresolved_reloc, warned;
958
959       RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
960                                r_symndx, symtab_hdr, sym_hashes,
961                                h, sec, *relocation, unresolved_reloc, warned);
962
963       *is_far = (h && (h->other & STO_M68HC12_FAR));
964       stub_name = h->root.root.string;
965     }
966
967   if (h != NULL)
968     *name = h->root.root.string;
969   else
970     {
971       *name = (bfd_elf_string_from_elf_section
972                (input_bfd, symtab_hdr->sh_link, sym->st_name));
973       if (*name == NULL || **name == '\0')
974         *name = bfd_section_name (input_bfd, sec);
975     }
976
977   if (*is_far && ELF32_R_TYPE (rel->r_info) == R_M68HC11_16)
978     {
979       struct elf32_m68hc11_stub_hash_entry* stub;
980       struct m68hc11_elf_link_hash_table *htab;
981
982       htab = m68hc11_elf_hash_table (info);
983       stub = m68hc12_stub_hash_lookup (htab->stub_hash_table,
984                                        *name, FALSE, FALSE);
985       if (stub)
986         {
987           *relocation = stub->stub_offset
988             + stub->stub_sec->output_section->vma
989             + stub->stub_sec->output_offset;
990           *is_far = FALSE;
991         }
992     }
993   return TRUE;
994 }
995
996 /* Relocate a 68hc11/68hc12 ELF section.  */
997 bfd_boolean
998 elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
999                                 struct bfd_link_info *info,
1000                                 bfd *input_bfd, asection *input_section,
1001                                 bfd_byte *contents, Elf_Internal_Rela *relocs,
1002                                 Elf_Internal_Sym *local_syms,
1003                                 asection **local_sections)
1004 {
1005   Elf_Internal_Shdr *symtab_hdr;
1006   struct elf_link_hash_entry **sym_hashes;
1007   Elf_Internal_Rela *rel, *relend;
1008   const char *name = NULL;
1009   struct m68hc11_page_info *pinfo;
1010   const struct elf_backend_data * const ebd = get_elf_backend_data (input_bfd);
1011
1012   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
1013   sym_hashes = elf_sym_hashes (input_bfd);
1014
1015   /* Get memory bank parameters.  */
1016   m68hc11_elf_get_bank_parameters (info);
1017   pinfo = &m68hc11_elf_hash_table (info)->pinfo;
1018
1019   rel = relocs;
1020   relend = relocs + input_section->reloc_count;
1021   for (; rel < relend; rel++)
1022     {
1023       int r_type;
1024       arelent arel;
1025       reloc_howto_type *howto;
1026       unsigned long r_symndx;
1027       Elf_Internal_Sym *sym;
1028       asection *sec;
1029       bfd_vma relocation = 0;
1030       bfd_reloc_status_type r = bfd_reloc_undefined;
1031       bfd_vma phys_page;
1032       bfd_vma phys_addr;
1033       bfd_vma insn_addr;
1034       bfd_vma insn_page;
1035       bfd_boolean is_far = FALSE;
1036
1037       r_symndx = ELF32_R_SYM (rel->r_info);
1038       r_type = ELF32_R_TYPE (rel->r_info);
1039
1040       if (r_type == R_M68HC11_GNU_VTENTRY
1041           || r_type == R_M68HC11_GNU_VTINHERIT )
1042         continue;
1043
1044       if (info->relocatable)
1045         {
1046           /* This is a relocatable link.  We don't have to change
1047              anything, unless the reloc is against a section symbol,
1048              in which case we have to adjust according to where the
1049              section symbol winds up in the output section.  */
1050           if (r_symndx < symtab_hdr->sh_info)
1051             {
1052               sym = local_syms + r_symndx;
1053               if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
1054                 {
1055                   sec = local_sections[r_symndx];
1056                   rel->r_addend += sec->output_offset + sym->st_value;
1057                 }
1058             }
1059
1060           continue;
1061         }
1062       (*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
1063       howto = arel.howto;
1064
1065       m68hc11_get_relocation_value (input_bfd, info, input_section, 
1066                                     local_sections, local_syms,
1067                                     rel, &name, &relocation, &is_far);
1068
1069       /* Do the memory bank mapping.  */
1070       phys_addr = m68hc11_phys_addr (pinfo, relocation + rel->r_addend);
1071       phys_page = m68hc11_phys_page (pinfo, relocation + rel->r_addend);
1072       switch (r_type)
1073         {
1074         case R_M68HC11_24:
1075           /* Reloc used by 68HC12 call instruction.  */
1076           bfd_put_16 (input_bfd, phys_addr,
1077                       (bfd_byte*) contents + rel->r_offset);
1078           bfd_put_8 (input_bfd, phys_page,
1079                      (bfd_byte*) contents + rel->r_offset + 2);
1080           r = bfd_reloc_ok;
1081           r_type = R_M68HC11_NONE;
1082           break;
1083
1084         case R_M68HC11_NONE:
1085           r = bfd_reloc_ok;
1086           break;
1087
1088         case R_M68HC11_LO16:
1089           /* Reloc generated by %addr(expr) gas to obtain the
1090              address as mapped in the memory bank window.  */
1091           relocation = phys_addr;
1092           break;
1093
1094         case R_M68HC11_PAGE:
1095           /* Reloc generated by %page(expr) gas to obtain the
1096              page number associated with the address.  */
1097           relocation = phys_page;
1098           break;
1099
1100         case R_M68HC11_16:
1101           /* Get virtual address of instruction having the relocation.  */
1102           if (is_far)
1103             {
1104               const char* msg;
1105               char* buf;
1106               msg = _("Reference to the far symbol `%s' using a wrong "
1107                       "relocation may result in incorrect execution");
1108               buf = alloca (strlen (msg) + strlen (name) + 10);
1109               sprintf (buf, msg, name);
1110               
1111               (* info->callbacks->warning)
1112                 (info, buf, name, input_bfd, NULL, rel->r_offset);
1113             }
1114
1115           /* Get virtual address of instruction having the relocation.  */
1116           insn_addr = input_section->output_section->vma
1117             + input_section->output_offset
1118             + rel->r_offset;
1119
1120           insn_page = m68hc11_phys_page (pinfo, insn_addr);
1121
1122           if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend)
1123               && m68hc11_addr_is_banked (pinfo, insn_addr)
1124               && phys_page != insn_page)
1125             {
1126               const char* msg;
1127               char* buf;
1128
1129               msg = _("banked address [%lx:%04lx] (%lx) is not in the same bank "
1130                       "as current banked address [%lx:%04lx] (%lx)");
1131
1132               buf = alloca (strlen (msg) + 128);
1133               sprintf (buf, msg, phys_page, phys_addr,
1134                        (long) (relocation + rel->r_addend),
1135                        insn_page, m68hc11_phys_addr (pinfo, insn_addr),
1136                        (long) (insn_addr));
1137               if (!((*info->callbacks->warning)
1138                     (info, buf, name, input_bfd, input_section,
1139                      rel->r_offset)))
1140                 return FALSE;
1141               break;
1142             }
1143           if (phys_page != 0 && insn_page == 0)
1144             {
1145               const char* msg;
1146               char* buf;
1147
1148               msg = _("reference to a banked address [%lx:%04lx] in the "
1149                       "normal address space at %04lx");
1150
1151               buf = alloca (strlen (msg) + 128);
1152               sprintf (buf, msg, phys_page, phys_addr, insn_addr);
1153               if (!((*info->callbacks->warning)
1154                     (info, buf, name, input_bfd, input_section,
1155                      insn_addr)))
1156                 return FALSE;
1157
1158               relocation = phys_addr;
1159               break;
1160             }
1161
1162           /* If this is a banked address use the phys_addr so that
1163              we stay in the banked window.  */
1164           if (m68hc11_addr_is_banked (pinfo, relocation + rel->r_addend))
1165             relocation = phys_addr;
1166           break;
1167         }
1168       if (r_type != R_M68HC11_NONE)
1169         r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1170                                       contents, rel->r_offset,
1171                                       relocation, rel->r_addend);
1172
1173       if (r != bfd_reloc_ok)
1174         {
1175           const char * msg = (const char *) 0;
1176
1177           switch (r)
1178             {
1179             case bfd_reloc_overflow:
1180               if (!((*info->callbacks->reloc_overflow)
1181                     (info, NULL, name, howto->name, (bfd_vma) 0,
1182                      input_bfd, input_section, rel->r_offset)))
1183                 return FALSE;
1184               break;
1185
1186             case bfd_reloc_undefined:
1187               if (!((*info->callbacks->undefined_symbol)
1188                     (info, name, input_bfd, input_section,
1189                      rel->r_offset, TRUE)))
1190                 return FALSE;
1191               break;
1192
1193             case bfd_reloc_outofrange:
1194               msg = _ ("internal error: out of range error");
1195               goto common_error;
1196
1197             case bfd_reloc_notsupported:
1198               msg = _ ("internal error: unsupported relocation error");
1199               goto common_error;
1200
1201             case bfd_reloc_dangerous:
1202               msg = _ ("internal error: dangerous error");
1203               goto common_error;
1204
1205             default:
1206               msg = _ ("internal error: unknown error");
1207               /* fall through */
1208
1209             common_error:
1210               if (!((*info->callbacks->warning)
1211                     (info, msg, name, input_bfd, input_section,
1212                      rel->r_offset)))
1213                 return FALSE;
1214               break;
1215             }
1216         }
1217     }
1218
1219   return TRUE;
1220 }
1221
1222
1223 \f
1224 /* Set and control ELF flags in ELF header.  */
1225
1226 bfd_boolean
1227 _bfd_m68hc11_elf_set_private_flags (bfd *abfd, flagword flags)
1228 {
1229   BFD_ASSERT (!elf_flags_init (abfd)
1230               || elf_elfheader (abfd)->e_flags == flags);
1231
1232   elf_elfheader (abfd)->e_flags = flags;
1233   elf_flags_init (abfd) = TRUE;
1234   return TRUE;
1235 }
1236
1237 /* Merge backend specific data from an object file to the output
1238    object file when linking.  */
1239
1240 bfd_boolean
1241 _bfd_m68hc11_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
1242 {
1243   flagword old_flags;
1244   flagword new_flags;
1245   bfd_boolean ok = TRUE;
1246
1247   /* Check if we have the same endianess */
1248   if (!_bfd_generic_verify_endian_match (ibfd, obfd))
1249     return FALSE;
1250
1251   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
1252       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
1253     return TRUE;
1254
1255   new_flags = elf_elfheader (ibfd)->e_flags;
1256   elf_elfheader (obfd)->e_flags |= new_flags & EF_M68HC11_ABI;
1257   old_flags = elf_elfheader (obfd)->e_flags;
1258
1259   if (! elf_flags_init (obfd))
1260     {
1261       elf_flags_init (obfd) = TRUE;
1262       elf_elfheader (obfd)->e_flags = new_flags;
1263       elf_elfheader (obfd)->e_ident[EI_CLASS]
1264         = elf_elfheader (ibfd)->e_ident[EI_CLASS];
1265
1266       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
1267           && bfd_get_arch_info (obfd)->the_default)
1268         {
1269           if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
1270                                    bfd_get_mach (ibfd)))
1271             return FALSE;
1272         }
1273
1274       return TRUE;
1275     }
1276
1277   /* Check ABI compatibility.  */
1278   if ((new_flags & E_M68HC11_I32) != (old_flags & E_M68HC11_I32))
1279     {
1280       (*_bfd_error_handler)
1281         (_("%B: linking files compiled for 16-bit integers (-mshort) "
1282            "and others for 32-bit integers"), ibfd);
1283       ok = FALSE;
1284     }
1285   if ((new_flags & E_M68HC11_F64) != (old_flags & E_M68HC11_F64))
1286     {
1287       (*_bfd_error_handler)
1288         (_("%B: linking files compiled for 32-bit double (-fshort-double) "
1289            "and others for 64-bit double"), ibfd);
1290       ok = FALSE;
1291     }
1292
1293   /* Processor compatibility.  */
1294   if (!EF_M68HC11_CAN_MERGE_MACH (new_flags, old_flags))
1295     {
1296       (*_bfd_error_handler)
1297         (_("%B: linking files compiled for HCS12 with "
1298            "others compiled for HC12"), ibfd);
1299       ok = FALSE;
1300     }
1301   new_flags = ((new_flags & ~EF_M68HC11_MACH_MASK)
1302                | (EF_M68HC11_MERGE_MACH (new_flags, old_flags)));
1303
1304   elf_elfheader (obfd)->e_flags = new_flags;
1305
1306   new_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1307   old_flags &= ~(EF_M68HC11_ABI | EF_M68HC11_MACH_MASK);
1308
1309   /* Warn about any other mismatches */
1310   if (new_flags != old_flags)
1311     {
1312       (*_bfd_error_handler)
1313         (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
1314          ibfd, (unsigned long) new_flags, (unsigned long) old_flags);
1315       ok = FALSE;
1316     }
1317
1318   if (! ok)
1319     {
1320       bfd_set_error (bfd_error_bad_value);
1321       return FALSE;
1322     }
1323
1324   return TRUE;
1325 }
1326
1327 bfd_boolean
1328 _bfd_m68hc11_elf_print_private_bfd_data (bfd *abfd, void *ptr)
1329 {
1330   FILE *file = (FILE *) ptr;
1331
1332   BFD_ASSERT (abfd != NULL && ptr != NULL);
1333
1334   /* Print normal ELF private data.  */
1335   _bfd_elf_print_private_bfd_data (abfd, ptr);
1336
1337   /* xgettext:c-format */
1338   fprintf (file, _("private flags = %lx:"), elf_elfheader (abfd)->e_flags);
1339
1340   if (elf_elfheader (abfd)->e_flags & E_M68HC11_I32)
1341     fprintf (file, _("[abi=32-bit int, "));
1342   else
1343     fprintf (file, _("[abi=16-bit int, "));
1344
1345   if (elf_elfheader (abfd)->e_flags & E_M68HC11_F64)
1346     fprintf (file, _("64-bit double, "));
1347   else
1348     fprintf (file, _("32-bit double, "));
1349
1350   if (strcmp (bfd_get_target (abfd), "elf32-m68hc11") == 0)
1351     fprintf (file, _("cpu=HC11]"));
1352   else if (elf_elfheader (abfd)->e_flags & EF_M68HCS12_MACH)
1353     fprintf (file, _("cpu=HCS12]"));
1354   else
1355     fprintf (file, _("cpu=HC12]"));    
1356
1357   if (elf_elfheader (abfd)->e_flags & E_M68HC12_BANKS)
1358     fprintf (file, _(" [memory=bank-model]"));
1359   else
1360     fprintf (file, _(" [memory=flat]"));
1361
1362   fputc ('\n', file);
1363
1364   return TRUE;
1365 }
1366
1367 static void scan_sections_for_abi (bfd *abfd ATTRIBUTE_UNUSED,
1368                                    asection *asect, void *arg)
1369 {
1370   struct m68hc11_scan_param* p = (struct m68hc11_scan_param*) arg;
1371
1372   if (asect->vma >= p->pinfo->bank_virtual)
1373     p->use_memory_banks = TRUE;
1374 }
1375   
1376 /* Tweak the OSABI field of the elf header.  */
1377
1378 void
1379 elf32_m68hc11_post_process_headers (bfd *abfd, struct bfd_link_info *link_info)
1380 {
1381   struct m68hc11_scan_param param;
1382
1383   if (link_info == 0)
1384     return;
1385
1386   m68hc11_elf_get_bank_parameters (link_info);
1387
1388   param.use_memory_banks = FALSE;
1389   param.pinfo = &m68hc11_elf_hash_table (link_info)->pinfo;
1390   bfd_map_over_sections (abfd, scan_sections_for_abi, &param);
1391   if (param.use_memory_banks)
1392     {
1393       Elf_Internal_Ehdr * i_ehdrp;
1394
1395       i_ehdrp = elf_elfheader (abfd);
1396       i_ehdrp->e_flags |= E_M68HC12_BANKS;
1397     }
1398 }
1399