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